diff -ru openssl-0.9.8h/crypto/cryptlib.c
openssl-0.9.8h-patched/crypto/cryptlib.c
--- openssl-0.9.8h/crypto/cryptlib.c 2007-09-06 12:43:46.000000000 +0000
+++ openssl-0.9.8h-patched/crypto/cryptlib.c 2008-09-11 18:21:33.000000000
+0000
@@ -166,7 +166,8 @@
"ec_pre_comp",
"store",
"comp",
-#if CRYPTO_NUM_LOCKS != 39
+ "names_lh",
+#if CRYPTO_NUM_LOCKS != 40
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
diff -ru openssl-0.9.8h/crypto/crypto.h openssl-0.9.8h-patched/crypto/crypto.h
--- openssl-0.9.8h/crypto/crypto.h 2005-05-08 19:54:33.000000000 +0000
+++ openssl-0.9.8h-patched/crypto/crypto.h 2008-09-11 18:20:59.000000000
+0000
@@ -219,7 +219,8 @@
#define CRYPTO_LOCK_EC_PRE_COMP 36
#define CRYPTO_LOCK_STORE 37
#define CRYPTO_LOCK_COMP 38
-#define CRYPTO_NUM_LOCKS 39
+#define CRYPTO_LOCK_NAMES_LH 39
+#define CRYPTO_NUM_LOCKS 40
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
diff -ru openssl-0.9.8h/crypto/objects/o_names.c
openssl-0.9.8h-patched/crypto/objects/o_names.c
--- openssl-0.9.8h/crypto/objects/o_names.c 2005-04-05 10:29:42.000000000
+0000
+++ openssl-0.9.8h-patched/crypto/objects/o_names.c 2008-09-11
18:35:12.000000000 +0000
@@ -48,11 +48,19 @@
int OBJ_NAME_init(void)
{
- if (names_lh != NULL) return(1);
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
+ if (names_lh != NULL)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
+ return(1);
+ }
MemCheck_off();
names_lh=lh_new(obj_name_hash, obj_name_cmp);
MemCheck_on();
- return(names_lh != NULL);
+ ret = (names_lh != NULL);
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
+ return(ret);
}
int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
@@ -164,7 +172,9 @@
for (;;)
{
+ CRYPTO_r_lock(CRYPTO_LOCK_NAMES_LH);
ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
+ CRYPTO_r_unlock(CRYPTO_LOCK_NAMES_LH);
if (ret == NULL) return(NULL);
if ((ret->alias) && !alias)
{
@@ -200,7 +210,9 @@
onp->type=type;
onp->data=data;
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
ret=(OBJ_NAME *)lh_insert(names_lh,onp);
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
if (ret != NULL)
{
/* free things */
@@ -217,7 +229,11 @@
}
else
{
- if (lh_error(names_lh))
+ int names_lh_error;
+ CRYPTO_r_lock(CRYPTO_LOCK_NAMES_LH);
+ names_lh_error = lh_error(names_lh);
+ CRYPTO_r_unlock(CRYPTO_LOCK_NAMES_LH);
+ if (names_lh_error)
{
/* ERROR */
return(0);
@@ -235,7 +251,9 @@
type&= ~OBJ_NAME_ALIAS;
on.name=name;
on.type=type;
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
ret=(OBJ_NAME *)lh_delete(names_lh,&on);
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
if (ret != NULL)
{
/* free things */
@@ -278,7 +296,9 @@
d.fn=fn;
d.arg=arg;
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d);
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
}
struct doall_sorted
@@ -313,7 +333,9 @@
int n;
d.type=type;
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names);
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
d.n=0;
OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
@@ -352,6 +374,9 @@
if (names_lh == NULL) return;
free_type=type;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_NAMES_LH);
+
down_load=names_lh->down_load;
names_lh->down_load=0;
@@ -365,5 +390,6 @@
}
else
names_lh->down_load=down_load;
- }
+ CRYPTO_w_unlock(CRYPTO_LOCK_NAMES_LH);
+ }OpenSSL version: openssl-0.9.8h To reproduce more than one thread must call SSL_library_init or other functions that modify names_lh at approximiately the same time. The stack traces will look something like: #0 0x0097aa52 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 #1 0x001503ae in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67 #2 0x001518f8 in *__GI_abort () at ../sysdeps/generic/abort.c:88 #3 0x0017ecf9 in __libc_message (do_abort=2, fmt=0x220da0 "*** glibc detected *** %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:145 #4 0x00183e1a in malloc_printerr (action=2, str=0x220e0c "double free or corruption (fasttop)", ptr=0xb7401fb8) at malloc.c:5525 #5 0x001857d5 in _int_realloc (av=0xb7400010, oldmem=0xb7401fb8, bytes=0) at malloc.c:4668 #6 0x00186684 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3487 #7 0x00186c9c in realloc_hook_ini (ptr=0xb7401fb8, sz=128, caller=0x81cced6) at hooks.c:54 #8 0x001865d1 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3425 #9 0x081cced6 in default_realloc_ex (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:86 #10 0x081cd4ff in CRYPTO_realloc (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:331 #11 0x081e851a in expand (lh=0xb7401f50) at lhash.c:341 #12 0x081e81a0 in lh_insert (lh=0xb7401f50, data=0xb7402280) at lhash.c:187 #13 0x081cfbd8 in OBJ_NAME_add (name=0x828ef27 "ssl2-md5", type=1, data=0x828ef23 "MD5") at o_names.c:203 #14 0x081cc5a4 in SSL_library_init () at ssl_algs.c:100 See attached patch file for fix. This doesn't appear to be an exploitable security vulnerability as far as I can tell. This bug appears to have existed as far back as 1999 based on looking at http://cvs.openssl.org/rlog?f=openssl/crypto/objects/o_names.c
OpenSSL version: openssl-0.9.8h
To reproduce more than one thread must call
SSL_library_init or other functions that modify names_lh at approximiately the
same time.
The stack traces will look something
like:
#0 0x0097aa52 in _dl_sysinfo_int80 () from
/lib/ld-linux.so.2
#1 0x001503ae in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#2 0x001518f8 in *__GI_abort () at ../sysdeps/generic/abort.c:88
#3 0x0017ecf9 in __libc_message (do_abort=2, fmt=0x220da0 "*** glibc detected *** %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:145
#4 0x00183e1a in malloc_printerr (action="" str=0x220e0c "double free or corruption (fasttop)", ptr=0xb7401fb8) at malloc.c:5525
#5 0x001857d5 in _int_realloc (av=0xb7400010, oldmem=0xb7401fb8, bytes=0) at malloc.c:4668
#6 0x00186684 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3487
#7 0x00186c9c in realloc_hook_ini (ptr=0xb7401fb8, sz=128, caller=0x81cced6) at hooks.c:54
#8 0x001865d1 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3425
#9 0x081cced6 in default_realloc_ex (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:86
#10 0x081cd4ff in CRYPTO_realloc (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:331
#11 0x081e851a in expand (lh=0xb7401f50) at lhash.c:341
#12 0x081e81a0 in lh_insert (lh=0xb7401f50, data="" at lhash.c:187
#13 0x081cfbd8 in OBJ_NAME_add (name=0x828ef27 "ssl2-md5", type=1, data="" "MD5") at o_names.c:203
#14 0x081cc5a4 in SSL_library_init () at ssl_algs.c:100
#1 0x001503ae in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#2 0x001518f8 in *__GI_abort () at ../sysdeps/generic/abort.c:88
#3 0x0017ecf9 in __libc_message (do_abort=2, fmt=0x220da0 "*** glibc detected *** %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:145
#4 0x00183e1a in malloc_printerr (action="" str=0x220e0c "double free or corruption (fasttop)", ptr=0xb7401fb8) at malloc.c:5525
#5 0x001857d5 in _int_realloc (av=0xb7400010, oldmem=0xb7401fb8, bytes=0) at malloc.c:4668
#6 0x00186684 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3487
#7 0x00186c9c in realloc_hook_ini (ptr=0xb7401fb8, sz=128, caller=0x81cced6) at hooks.c:54
#8 0x001865d1 in *__GI___libc_realloc (oldmem=0xb7401fb8, bytes=128) at malloc.c:3425
#9 0x081cced6 in default_realloc_ex (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:86
#10 0x081cd4ff in CRYPTO_realloc (str=0xb7401fb8, num=128, file=0x829df09 "lhash.c", line=342) at mem.c:331
#11 0x081e851a in expand (lh=0xb7401f50) at lhash.c:341
#12 0x081e81a0 in lh_insert (lh=0xb7401f50, data="" at lhash.c:187
#13 0x081cfbd8 in OBJ_NAME_add (name=0x828ef27 "ssl2-md5", type=1, data="" "MD5") at o_names.c:203
#14 0x081cc5a4 in SSL_library_init () at ssl_algs.c:100
See attached patch file for
fix.
This doesn't appear to be an
exploitable security vulnerability as far as I can tell. This bug
appears to have existed as far back as 1999 based on looking
at http://cvs.openssl.org/rlog?f=openssl/crypto/objects/o_names.c
