[openssl.org #2363] bug: memory allocated by DH_new() may never be free()ed
If a library containing a function which calls DH_new() followed by a DH_free() is dlopen()ed, the function called and then dlclosed() memory is leaked. The bug was found on Solaris and the following report uses some Solaris specific tools (for memory leak searching, for example). The following inline code example should demonstrate the issue: $ cat test.c #include #include #include int main() { void (*run)(); void *handle; handle = dlopen("./run.so", RTLD_NOW); run = (void (*)()) dlsym(handle, "run"); (*run)(); dlclose(handle); abort(); } $ cat run.c #include int run() { DH *test; test = DH_new(); DH_free(test); } $ cc run.c -shared -R/usr/sfw/lib -I/usr/sfw -lcrypto -o run.so $ cc test.c -o test $ echo $LD_PRELOAD $UMEM_DEBUG libumem.so.1 default $ ./test zsh: IOT instruction (core dumped) ./test $ echo ::findleaks | mdb ./core CACHE LEAKED BUFCTL CALLER 08067c10 1 08082998 main+0x31 08067c10 1 08082a10 main+0x31 08067e10 1 08086048 main+0x31 0806a810 1 0807ea70 main+0x31 0806ac10 1 0807bea0 main+0x31 08067c10 1 08082920 main+0x31 Total 6 buffers, 296 bytes Playing a bit with mdb (and using a slightly different version of the above inline example) here are the various stacks associated with the allocations: libumem.so.1`umem_cache_alloc_debug+0x144 libumem.so.1`umem_cache_alloc+0x19a libumem.so.1`umem_alloc+0xcd libumem.so.1`malloc+0x2a libcrypto.so.0.9.8`default_malloc_ex+0x21 libcrypto.so.0.9.8`CRYPTO_malloc+0x5d libcrypto.so.0.9.8`sk_new+0x40 libcrypto.so.0.9.8`sk_new_null+0x1d libcrypto.so.0.9.8`def_get_class+0xb8 libcrypto.so.0.9.8`int_new_ex_data+0x20 libcrypto.so.0.9.8`CRYPTO_new_ex_data+0x38 libcrypto.so.0.9.8`DH_new_method+0xcc libcrypto.so.0.9.8`DH_new+0x1d openssl_test.so`run+0x2c main+0x7d libumem.so.1`umem_cache_alloc_debug+0x144 libumem.so.1`umem_cache_alloc+0x19a libumem.so.1`umem_alloc+0xcd libumem.so.1`malloc+0x2a libcrypto.so.0.9.8`default_malloc_ex+0x21 libcrypto.so.0.9.8`CRYPTO_malloc+0x5d libcrypto.so.0.9.8`lh_insert+0x80 libcrypto.so.0.9.8`def_get_class+0xcf libcrypto.so.0.9.8`int_new_ex_data+0x20 libcrypto.so.0.9.8`CRYPTO_new_ex_data+0x38 libcrypto.so.0.9.8`DH_new_method+0xcc libcrypto.so.0.9.8`DH_new+0x1d openssl_test.so`run+0x2c main+0x7d _start+0x80 libumem.so.1`umem_cache_alloc_debug+0x144 libumem.so.1`umem_cache_alloc+0x19a libumem.so.1`umem_alloc+0xcd libumem.so.1`malloc+0x2a libcrypto.so.0.9.8`default_malloc_ex+0x21 libcrypto.so.0.9.8`CRYPTO_malloc+0x5d libcrypto.so.0.9.8`sk_new+0x24 libcrypto.so.0.9.8`sk_new_null+0x1d libcrypto.so.0.9.8`def_get_class+0xb8 libcrypto.so.0.9.8`int_new_ex_data+0x20 libcrypto.so.0.9.8`CRYPTO_new_ex_data+0x38 libcrypto.so.0.9.8`DH_new_method+0xcc libcrypto.so.0.9.8`DH_new+0x1d openssl_test.so`run+0x2c main+0x7d libumem.so.1`umem_cache_alloc_debug+0x144 libumem.so.1`umem_cache_alloc+0x19a libumem.so.1`umem_alloc+0xcd libumem.so.1`malloc+0x2a libcrypto.so.0.9.8`default_malloc_ex+0x21 libcrypto.so.0.9.8`CRYPTO_malloc+0x5d libcrypto.so.0.9.8`def_get_class+0x9c libcrypto.so.0.9.8`int_new_ex_data+0x20 libcrypto.so.0.9.8`CRYPTO_new_ex_data+0x38 libcrypto.so.0.9.8`DH_new_method+0xcc libcrypto.so.0.9.8`DH_new+0x1d openssl_test.so`run+0x2c main+0x7d _start+0x80 libumem.so.1`umem_cache_alloc_debug+0x144 libumem.so.1`umem_cache_alloc+0x19a libumem.so.1`umem_alloc+0xcd libumem.so.1`malloc+0x2a libcrypto.so.0.9.8`default_malloc_ex+0x21 libcrypto.so.0.9.8`CRYPTO_malloc+0x5d libcrypto.so.0.9.8`lh_new+0x4a libcrypto.so.0.9.8`ex_data_check+0x4d libcrypto.so.0.9.8`def_get_class+0x29 libcrypto.so.0.9.8`int_new_ex_data+0x20 libcrypto.so.0.9.8`CRYPTO_new_ex_data+0
[openssl.org #2325] memory corruption after libssl is unloaded from memory
hi, this has been shortly discussed on the OpenSSL dev list (sent on Aug 10, 2010). I understand that given the conditions needed to reproduce this error it will not be a priority but we believe it is a bug worth fixing so we would like to document it in the OpenSSL RT. Thank you. the initial email follows: hi, when libssl is linked against modules that can be dlopen()ed and dlclose()d multiple times during the process life time, we hit a memory corruption where the hash table built in memory for the error strings references SSL strings in the address range previously occupied by libssl. The behaviour depends on what other shared objects are loaded in between and when etc. but in general the hash table can end up referencing some "wrong" memory. Verified with 0.9.8e, 0.9.8o, 1.0.0a. For 1.0.0a, a modification of the attached program might be needed, details in the code. we hit the problem on OpenSolaris where Apache started to crash when loading mod_ssl. It loads all built-in engines and on Solaris we end up in the PKCS#11 engine loading libpkcs11.so.1 with other modules being dlopen()ed and some of them are linked against libssl. We however believe this is a generic problem and other systems could be hit by that sooner or later. the attached program simulates the problem using dlopen() directly on libssl and can be built on FreeBSD (we used 7.2) and OpenSolaris. It also contains instructions on how to simulate the problem on Linux (modifications needed depending on the distro) as well. To show the problem we mmap() some anonymous memory with the PROT_NONE flag right after dlclose() on libssl but before another dlopen() is called on it. The next SSL_load_error_strings() causes a crash then: $ gcc -g -lcrypto ssl-dlopen-crash.c $ ./a.out Opening libssl.so... Initializing with SSL_load_error_strings... Closing libssl.so... Opening libssl.so... Initializing with SSL_load_error_strings... Segmentation Fault (core dumped) $ mdb core mdb: core file data for mapping at fe84f000 not saved: Bad address Loading modules: [ libuutil.so.1 ld.so.1 ] > $c libcrypto.so.0.9.8`err_cmp+6(fecb70b0, 8047758, 8047748, feeda26e) libcrypto.so.0.9.8`getrn+0x7d(8061558, 8047758, 804770c, 110) libcrypto.so.0.9.8`lh_retrieve+0x1e(8061558, 8047758, fef4b408, 12a) libcrypto.so.0.9.8`int_err_get_item+0x51(8047758, fef69000, 8047768, feedd808) libcrypto.so.0.9.8`ERR_func_error_string+0x47(14064000, fef69000, 8047788, fe82cff8) libssl.so.0.9.8`ERR_load_SSL_strings+0x23(8051270) libssl.so.0.9.8`SSL_load_error_strings+0x1d(fe822330, feac0b80, 80477cc, 80511a9, fed2, 80511ba) testssl+0x83(fed2, 80511ba, 80612ec, 80477ac, 80477cc, 80511fa) main+0x5f(1, 80477f0, 80477f8) _start+0x80(1, 8047900, 0, 8047908, 8047921, 8047943) we think that the proper fix is to make a copy of those strings when bulding the hash table. Using ERR_free_strings() is not a solution since that frees all the strings, also those needed by libcrypto. A new function in the libssl's fini section removing only SSL strings would also probably solve the problem. the workaround is simple. Either use LD_PRELOAD on libssl to lock it in the memory: $ LD_PRELOAD=/lib/libssl.so.0.9.8 ./a.out Opening libssl.so... Initializing with SSL_load_error_strings... Closing libssl.so... Opening libssl.so... Initializing with SSL_load_error_strings... Closing libssl.so... or build the library with "-znodelete". The linker on Solaris supports this option. This ensures that libssl is never unloaded. I think we should file a bug in the RT. Is there anything else we should provide? thanks, Jan. -- Jan Pechanec http://blogs.sun.com/janp /* * Demo for the SSL memory corruption bug. The problem is if libssl is * dlopen()ed, SSL error strings loaded, and the library is dlclose()d then. The * hash string table built in memory still uses references to the memory * previously occupied by libssl since there is no clean-up. If we map * non-accessible memory to that address range, the next * SSL_load_error_strings() causes a SIGSEGV. * * Tested with 0.9.8e, 0.9.8o, and 1.0.0a. See a comment with mmap() below in * the code if you want to run this with 1.0.0. * * Compile: * * $ gcc -g -lcrypto ssl-dlopen-crash.c * * Stack trace on FreeBSD 7.2: * #0 0x2813da5a in ERR_unload_strings () from /lib/libcrypto.so.5 * #1 0x2818393e in lh_retrieve () from /lib/libcrypto.so.5 * #2 0x2813e38e in ERR_get_implementation () from /lib/libcrypto.so.5 * #3 0x2813dd77 in ERR_func_error_string () from /lib/libcrypto.so.5 * #4 0x2844e1c0 in ERR_load_SSL_strings () from /usr/lib/libssl.so * #5 0x2844e18c in SSL_load_error_strings () from /usr/lib/libssl.so * #6 0x080488f4 in testssl () at ssl-dlopen-freebsd.c:53 * #7 0x08048a11 in main () at ssl-dlopen-freebsd.c:113 * * Stack trace on OpenSolaris: * libcrypto.so.0.9.8`err_cmp+6(fecb70b0, 804775c, 804774c, f
[openssl.org #2183] 0.9.8m broke "-multi" option in openssl(1) on unix(-like) systems
commit 18494 changed how HAVE_FORK is dealt with in speed.c. The original submitter (http://www.mail-archive.com/openssl-dev@openssl.org/msg26278.html) correctly stated that HAVE_FORK should be defined by the configure script but wrongly assumed that it really was. it's not the case. Maybe autoconf does that, I'm not sure about that. Anyway, the outcome of the change is this on any unix or unix-like system because HAVE_FORK is not defined: $ cd openssl-0.9.8m $ LD_LIBRARY_PATH=. apps/openssl speed rsa -multi 4 Error: bad option or value Available values: Available options: -elapsedmeasure time in real time instead of CPU user time. -engine e use engine e, possibly a hardware device. -evp e use EVP e. -decrypttime decryption instead of encryption (only EVP). -mr produce machine readable output. as you can see, "multi" is ifdef'ed out from the helper string as well. I'd send a patch but I'm not sure how you would like to fix it. Use -DHAVE_FORK for all apropriate architectures in the Configure script? Or do another fix in the speed.c source code? I guess the former aproach might be better, fixing it in speed.c could bring the problem back again, just for yet another architecture not specified in the #ifdef. cheers, Jan. -- Jan Pechanec http://blogs.sun.com/janp __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: [openssl.org #2124] memory mismanagement in OpenSSL (patch included against 0.9.8l)
On Tue, 8 Dec 2009, Jan Pechanec wrote: sorry, forgot to include a link to the OpenSolaris bugster: http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6441083 with an explanation of a person who reported the problem. J. > > hi, > > there are some places where functions allocating memory are not >checked against NULL, or are checked too late (LHASH code). We run some >tests with libumem(3lib) and "mtbf=5000" (mean time between failure) in >UMEM_DEBUG, simulating occasional memory shortages and that was causing >OpenSSL to crash. > > the changes have been used here at Sun internally for 2 years >against 0.9.8a. Attached is a patch generated against 0.9.8l. "make >test" passes on the changed code after rebuilding it. > > thanks, Jan. > > -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
[openssl.org #2124] memory mismanagement in OpenSSL (patch included against 0.9.8l)
hi, there are some places where functions allocating memory are not checked against NULL, or are checked too late (LHASH code). We run some tests with libumem(3lib) and "mtbf=5000" (mean time between failure) in UMEM_DEBUG, simulating occasional memory shortages and that was causing OpenSSL to crash. the changes have been used here at Sun internally for 2 years against 0.9.8a. Attached is a patch generated against 0.9.8l. "make test" passes on the changed code after rebuilding it. thanks, Jan. -- Jan Pechanec diff -ur openssl-0.9.8l/crypto/evp/digest.c openssl-0.9.8l-patched//crypto/evp/digest.c --- openssl-0.9.8l/crypto/evp/digest.c Tue Sep 16 00:21:40 2008 +++ openssl-0.9.8l-patched//crypto/evp/digest.c Tue Dec 8 12:06:21 2009 @@ -127,7 +127,8 @@ { EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx); - EVP_MD_CTX_init(ctx); + if (ctx) + EVP_MD_CTX_init(ctx); return ctx; } @@ -299,7 +300,14 @@ OPENSSL_free(ctx->md_data); ctx->digest=type; if (type->ctx_size) + { ctx->md_data=OPENSSL_malloc(type->ctx_size); + if (!ctx->md_data) + { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } } #ifndef OPENSSL_NO_ENGINE skip_to_init: @@ -380,8 +388,17 @@ if (out->digest->ctx_size) { - if (tmp_buf) out->md_data = tmp_buf; - else out->md_data=OPENSSL_malloc(out->digest->ctx_size); + if (tmp_buf) + out->md_data = tmp_buf; + else + { + out->md_data=OPENSSL_malloc(out->digest->ctx_size); + if (!out->md_data) + { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE); + return 0; + } + } memcpy(out->md_data,in->md_data,out->digest->ctx_size); } diff -ur openssl-0.9.8l/crypto/lhash/lhash.c openssl-0.9.8l-patched//crypto/lhash/lhash.c --- openssl-0.9.8l/crypto/lhash/lhash.c Sun Jan 21 14:16:32 2007 +++ openssl-0.9.8l-patched//crypto/lhash/lhash.cTue Dec 8 12:06:21 2009 @@ -305,16 +305,40 @@ static void expand(LHASH *lh) { LHASH_NODE **n,**n1,**n2,*np; - unsigned int p,i,j; + unsigned int p,i,j,pmax; unsigned long hash,nni; + p=(int)lh->p++; + nni=lh->num_alloc_nodes; + pmax=lh->pmax; + + if ((lh->p) >= lh->pmax) + { + j=(int)lh->num_alloc_nodes*2; + n=(LHASH_NODE **)OPENSSL_realloc(lh->b, + (int)sizeof(LHASH_NODE *)*j); + if (n == NULL) + { +/* fputs("realloc error in lhash",stderr); */ + lh->error++; + lh->p=0; + return; + } + /* else */ + for (i=(int)lh->num_alloc_nodes; ipmax=lh->num_alloc_nodes; + lh->num_alloc_nodes=j; + lh->num_expand_reallocs++; + lh->p=0; + lh->b=n; + } + lh->num_nodes++; lh->num_expands++; - p=(int)lh->p++; n1= &(lh->b[p]); - n2= &(lh->b[p+(int)lh->pmax]); + n2= &(lh->b[p+pmax]); *n2=NULL;/* 27/07/92 - eay - undefined pointer bug */ - nni=lh->num_alloc_nodes; for (np= *n1; np != NULL; ) { @@ -335,35 +359,14 @@ np= *n1; } - if ((lh->p) >= lh->pmax) - { - j=(int)lh->num_alloc_nodes*2; - n=(LHASH_NODE **)OPENSSL_realloc(lh->b, - (int)(sizeof(LHASH_NODE *)*j)); - if (n == NULL) - { -/* fputs("realloc error in lhash",stderr); */ - lh->error++; - lh->p=0; - return; - } - /* else */ - for (i=(int)lh->num_alloc_nodes; ipmax=lh->num_alloc_nodes; - lh->num_alloc_nodes=j; - lh->num_expand_reallocs++; - lh->p=0; - lh->b=n; - } } static void contract(LHASH *lh) { LHASH_NODE **n,*n1,*np; + int idx = lh->p+lh->pmax-1; - np=lh->b[lh->p+lh->pmax-1]; - lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */ + np=lh->b[idx]; if (lh->p == 0) { n=(LHASH_NODE
[openssl.org #1564] bug: FIPS module can't be built on Solaris
building the fips module ends with a tricky error: /usr/ccs/bin/ld: illegal option -- n usage: ld [-6:abc:d:e:f:h:il:mo:p:rstu:z:B:CD:F:GI:L:M:N:P:Q:R:S:VY:?] file(s) [-64] enforce a 64-bit link-edit ... ... the problem is that in general Solaris's echo's don't have '-n' so this is a problem in fips-1.0/Makefile: fipscanister.o: fips_start.o $(LIBOBJ) $(FIPS_OBJ_LISTS) fips_end.o @FIPS_BN_ASM=`for i in $(BN_ASM) ; do echo -n "../crypto/bn/$$i " ; done`; \ not sure what is the best fix here, whether test for Solaris and set it to "printf", or to replace it with printf right away, or something different. After the fix the module builds fine. For more information about echo's in Solaris, see: man -M /usr/man echo regards, Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1531] typo: 'rouines' should read 'routines' in all Copyright sections
as per $subj: * The word 'cryptographic' can be left out if the rouines from the library it seems to be everywhere: janp:ananke:/export/openssl$ ggrep -e rouines -R openssl-0.9.8e/* | wc -l 541 -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1530] bug/typo: incorrent comment in s3_srvr.c
0.9.8e, s3_srvr.c claims this in a comment: * s->tmp.new_cipher- the new cipher to use. it should read "s->s3->tmp.new_cipher ..." Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1529] doc: AES support not documented in enc(1) manual page
this is 0.9.8e, and enc(1) command can do AES: -aes-128-cbc -aes-128-cfb -aes-128-cfb1 -aes-128-cfb8 -aes-128-ecb -aes-128-ofb -aes128 however, it's not documented in enc(1) manual page. Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1528] bug/typo: TLS_DEBUG section prints "pre-master" instead of "master"
in t1_enc.c, there is: #ifdef TLS_DEBUG printf("client random\n"); { int z; for (z=0; zs3->client_random[z],((z+1)%16)?' ':'\n'); } printf("server random\n"); { int z; for (z=0; zs3->server_random[z],((z+1)%16)?' ':'\n'); } printf("pre-master\n"); { int z; for (z=0; zsession->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif which uses "pre-master\n" in printf(). However, s->session->master_key is a master key. Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1475] TYPO in crypto/des/INSTALL
hi, there is a misspelled word "relevent" in crypto/des/INSTALL, should be "relevant". It's the last version 0.9.8d. There is also a missing fullstop in the same sentence. Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1438] BUG: extra backslash in openssl macros (version 0.9.8d)
hi, this is bug ID 6368841 on OpenSolaris.Org: http://bugs.opensolaris.org/view_bug.do?bug_id=6368841 following macros have a backslash on the last line of the macro (line numbers are where the macro starts), checked against OpenSSL 0.9.8d release: ASN1_ITEM_start (usr/src/common/openssl/crypto/asn1/asn1t.h), line 99 BLOCK_CIPHER_ecb_loop (usr/src/common/openssl/crypto/evp/evp_locl.h), 63 idea_mul (usr/src/common/openssl/crypto/idea/idea_lcl.h), 62 IMPLEMENT_PEM_read_fp (usr/src/common/openssl/crypto/pem/pem.h), 220 these backslashes are unnecessary, and they're a maintenance hazard. If somebody puts non-null text on the following line, it will get sucked into the macro. thanks, Jan. -- Jan Pechanec Software Engineer Security Technologies | OS Hardening __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1355] patch: bug in CONF_modules_free.pod
hi, man page for CONF_modules_free mistakenly mentions CONF_modules_load instead of CONF_modules_finish (CONF_modules_load has its own manual page). Patch attached. checked against snapshot from 2006-06-20. Jan. -- Jan Pechanec __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]
[openssl.org #1354] patch: SSL_SESSION_get_time.pod mentions SSL_SESSION_get_timeout twice
hi, SSL_SESSION_get_time(3) mentions SSL_SESSION_get_timeout twice in NAME section instead of SSL_SESSION_set_timeout. Patch included. Jan. -- Jan Pechanec Software Engineer Security Technologies | OS Hardening __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]