Converting crypto/bio/b_sock.c and ssl/ssl-cert.c to call gethostbyname_r(), getservbyname_r(), and readdir_r() instead of the non-reentrant functions when threads are enabled turns out to be ugly. The reentrant function semantics aren't standard across popular platforms that support threads (Solaris 2.X, HPUX 10.X, etc.). Apparently those functions were added to the platforms before POSIX standardized them. Also the xxx_r() functions require large buffers that complicate life on limited memory systems (Win 3.1). Here are patches that instead use locks to serialize access to the non-reentrant functions. The purpose of the existing lock CRYPTO_LOCK_BIO_GETHOSTBYNAME is slightly changed and it's name is changed to CRYPTO_LOCK_GETHOSTBYNAME, and there are 2 new locks CRYPTO_LOCK_GETSERVBYNAME and CRYPTO_LOCK_READDIR. There's a new define BIO_F_BIO_GETHOSTBYNAME in bio.h. Does anything else need to be done to add it, or is the define in bio.h enough? These patches also fix some bugs in b_sock.c where it didn't correctly handle Malloc() returning NULL and didn't report an error when it happened, and it sometimes didn't unlock. With these changes threaded apps will need to wrap calls they make to the non- reentrant C library functions that are used within openssl with CRYPTO_w_lock() / CRYPTO_w_unlock(). Openssl provides BIO_gethostbyname() and BIO_get_port() to perform gethostbyname() and getservbyname() safely. Apps should not wrap them with more locks. Index: crypto/cryptlib.c =================================================================== RCS file: /e/openssl/cvs/openssl/crypto/cryptlib.c,v retrieving revision 1.6 diff -u -r1.6 cryptlib.c --- cryptlib.c 1999/04/26 22:20:02 1.6 +++ cryptlib.c 1999/05/06 17:11:42 @@ -88,8 +88,10 @@ "rand", "debug_malloc", "BIO", - "bio_gethostbyname", + "gethostbyname", "RSA_blinding", + "getservbyname", + "readdir", }; static STACK *app_locks=NULL; Index: crypto/crypto.h =================================================================== RCS file: /e/openssl/cvs/openssl/crypto/crypto.h,v retrieving revision 1.12 diff -u -r1.12 crypto.h --- crypto.h 1999/04/26 16:40:15 1.12 +++ crypto.h 1999/05/06 17:12:19 @@ -102,9 +102,11 @@ #define CRYPTO_LOCK_RAND 16 #define CRYPTO_LOCK_MALLOC 17 #define CRYPTO_LOCK_BIO 18 -#define CRYPTO_LOCK_BIO_GETHOSTBYNAME 19 +#define CRYPTO_LOCK_GETHOSTBYNAME 19 #define CRYPTO_LOCK_RSA_BLINDING 20 -#define CRYPTO_NUM_LOCKS 21 +#define CRYPTO_LOCK_GETSERVBYNAME 21 +#define CRYPTO_LOCK_READDIR 22 +#define CRYPTO_NUM_LOCKS 23 #define CRYPTO_LOCK 1 #define CRYPTO_UNLOCK 2 Index: crypto/bio/b_sock.c =================================================================== RCS file: /e/openssl/cvs/openssl/crypto/bio/b_sock.c,v retrieving revision 1.10 diff -u -r1.10 b_sock.c --- b_sock.c 1999/04/26 16:40:58 1.10 +++ b_sock.c 1999/05/06 16:31:16 @@ -139,6 +139,7 @@ { int i; struct servent *s; + unsigned short s_port; if (str == NULL) { @@ -150,26 +151,30 @@ *port_ptr=(unsigned short)i; else { + CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); s=getservbyname(str,"tcp"); + if(s != NULL) + s_port=s->s_port; + CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); if (s == NULL) { if (strcmp(str,"http") == 0) - *port_ptr=80; + s_port=80; else if (strcmp(str,"telnet") == 0) - *port_ptr=23; + s_port=23; else if (strcmp(str,"socks") == 0) - *port_ptr=1080; + s_port=1080; else if (strcmp(str,"https") == 0) - *port_ptr=443; + s_port=443; else if (strcmp(str,"ssl") == 0) - *port_ptr=443; + s_port=443; else if (strcmp(str,"ftp") == 0) - *port_ptr=21; + s_port=21; else if (strcmp(str,"gopher") == 0) - *port_ptr=70; + s_port=70; #if 0 else if (strcmp(str,"wais") == 0) - *port_ptr=21; + s_port=21; #endif else { @@ -177,9 +182,8 @@ ERR_add_error_data(3,"service='",str,"'"); return(0); } - return(1); } - *port_ptr=htons((unsigned short)s->s_port); + *port_ptr=htons(s_port); } return(1); } @@ -253,16 +257,16 @@ for (i=0; a->h_aliases[i] != NULL; i++) ; i++; - ret->h_aliases=(char **)Malloc(sizeof(char *)*i); + if((ret->h_aliases=(char **)Malloc(sizeof(char *)*i)) == NULL) + goto err; memset(ret->h_aliases,0,sizeof(char *)*i); - if (ret == NULL) goto err; for (i=0; a->h_addr_list[i] != NULL; i++) ; i++; - ret->h_addr_list=(char **)Malloc(sizeof(char *)*i); + if((ret->h_addr_list=(char **)Malloc(sizeof(char *)*i)) == NULL) + goto err; memset(ret->h_addr_list,0,sizeof(char *)*i); - if (ret->h_addr_list == NULL) goto err; j=strlen(a->h_name)+1; if ((ret->h_name=Malloc(j)) == NULL) goto err; @@ -323,7 +327,7 @@ /* return(gethostbyname(name)); */ - CRYPTO_w_lock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); + CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); j=strlen(name); if (j < 128) { @@ -349,15 +353,22 @@ BIO_ghbn_miss++; ret=gethostbyname(name); - if (ret == NULL) return(NULL); - if (j > 128) return(ret); /* too big to cache */ + if (ret == NULL) + goto end; + if (j > 128) /* too big to cache */ + goto end; /* else add to cache */ if (ghbn_cache[lowi].ent != NULL) ghbn_free(ghbn_cache[lowi].ent); + ghbn_cache[lowi].name[0] = '\0'; + if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL) + { + BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE); + goto end; + } strncpy(ghbn_cache[lowi].name,name,128); - ghbn_cache[lowi].ent=ghbn_dup(ret); ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits; } else @@ -366,7 +377,8 @@ ret= ghbn_cache[i].ent; ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits; } - CRYPTO_w_unlock(CRYPTO_LOCK_BIO_GETHOSTBYNAME); +end: + CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); return(ret); } Index: crypto/bio/bio.h =================================================================== RCS file: /e/openssl/cvs/openssl/crypto/bio/bio.h,v retrieving revision 1.15 diff -u -r1.15 bio.h --- bio.h 1999/05/05 12:35:19 1.15 +++ bio.h 1999/05/06 14:50:42 @@ -562,6 +562,7 @@ #define BIO_F_MEM_WRITE 117 #define BIO_F_SSL_NEW 118 #define BIO_F_WSASTARTUP 119 +#define BIO_F_BIO_GETHOSTBYNAME 120 /* Reason codes. */ #define BIO_R_ACCEPT_ERROR 100 Index: ssl/ssl_cert.c =================================================================== RCS file: /e/openssl/cvs/openssl/ssl/ssl_cert.c,v retrieving revision 1.14 diff -u -r1.14 ssl_cert.c --- ssl_cert.c 1999/05/03 19:55:00 1.14 +++ ssl_cert.c 1999/05/06 16:28:26 @@ -448,18 +448,20 @@ SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,ERR_R_MALLOC_FAILURE); return 0; } - + CRYPTO_w_lock(CRYPTO_LOCK_READDIR); while((dstruct=readdir(d))) { char buf[1024]; if(strlen(dir)+strlen(dstruct->d_name)+2 > sizeof buf) { + CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); return 0; } sprintf(buf,"%s/%s",dir,dstruct->d_name); + CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); if(!SSL_add_file_cert_subjects_to_stack(stack,buf)) return 0; } ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]