George Helffrich
2001-Jan-22 17:47 UTC
Patches for failing build & bus error on SPARC/Linux
All - For those installs on crusty old hardware and OS releases, here are patches to fix two OpenSSH problems on sparc redhat 4.2 systems. 1. `Old PAM' #defines different - build fails with undefined symbols when PAM used. 2. Running ssh on sparc hardware results in bus error on some connection negotiations. Unaligned data on call to inet_ntoa() results in bus error. Compiled with gcc 2.7.2.1. Patches and a test program follows. George Helffrich (george at geology.bristol.ac.uk) *** defines.h.orig Thu Oct 19 23:14:05 2000 --- defines.h Mon Jan 22 16:52:05 2001 *************** *** 338,345 **** --- 338,349 ---- /* Function replacement / compatibility hacks */ /* In older versions of libpam, pam_strerror takes a single argument */ + /* Older versions of PAM (1.10) don't define some symbols the same way */ #ifdef HAVE_OLD_PAM # define PAM_STRERROR(a,b) pam_strerror((b)) + # define PAM_DELETE_CRED PAM_CRED_DELETE + # define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH + # define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD #else # define PAM_STRERROR(a,b) pam_strerror((a),(b)) #endif *** fake-getnameinfo.c.orig Fri Sep 29 00:59:14 2000 --- fake-getnameinfo.c Mon Jan 22 16:19:39 2001 *************** *** 30,39 **** if (host) { if (flags & NI_NUMERICHOST) { ! if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen) return EAI_MEMORY; ! strcpy(host, inet_ntoa(sin->sin_addr)); return 0; } else { hp = gethostbyaddr((char *)&sin->sin_addr, --- 30,43 ---- if (host) { if (flags & NI_NUMERICHOST) { ! /* inet_ntoa wants aligned data on SPARC */ ! struct in_addr align; ! bcopy((char *)&sin->sin_addr, ! (char *)&align, sizeof(struct in_addr)); ! if (strlen(inet_ntoa(align)) >= hostlen) return EAI_MEMORY; ! strcpy(host,inet_ntoa(align)); return 0; } else { hp = gethostbyaddr((char *)&sin->sin_addr, *** /dev/null Tue Jan 1 04:00:00 1980 --- /tmp/testinet.c Mon Jan 22 16:44:17 2001 *************** *** 0 **** --- 1,47 ---- + /* Test program to exercise bug arising from assumed alignment of + struct sockaddr_in in some SPARC versions of inet_ntoa. Appears under + config with host sparc-unknown-linux-gnulibc1. + + To try, compile e.g. + gcc -g -I/usr/src/local/openssh-2.3.0p1 -I/usr/local/ssl/include \ + -o testinet testinet.c + + G. Helffrich/U. Bristol Earth Sciences + */ + #include "includes.h" + #include "ssh.h" + + int sub(const struct sockaddr *sa, char *host, size_t hostlen) { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + char *str = inet_ntoa(sin->sin_addr); + + if (strlen(str) > hostlen) + return -1; + else + strcpy(host,str); + return 0; + } + + main(argc,argv) + int argc; + char *argv[]; + { + struct sockaddr_in sin; + char host[1025]; + + char *ptr = malloc(sizeof(struct sockaddr_in)+8); + + char *unaligned = ptr+1; + + sin.sin_family = 2; + sin.sin_port = 22; + sin.sin_addr = inet_makeaddr(137<<24 | 222<<16 | 20<<8 , 17); + + bcopy((char *)&sin, unaligned, sizeof(struct sockaddr_in)); + + (void)sub((struct sockaddr *)unaligned,host,(size_t)sizeof(host)); + + printf("%s\n",host); + return 0; + }