probable malloc()/free() bug in arlad: hashtabadd()

Ray Jones rjones at pobox.com
Wed Oct 7 20:20:14 CEST 1998


(this is with arla-0.13)

arlad seems to be calling free() on memory not allocated via malloc.
here is the backtrace of the crash (modulo uninteresting
top-of-stack):

#3  0x8078198 in free (p=0x80f20b4) at wrapper.c:391
#4  0x806c8c4 in hashtabadd (htab=0x80e4720, ptr=0x80f1718) at hash.c:124
#5  0x8056a39 in get_info (e=0x80f1550, volname=0xbffff1e8 "536873038", ce=0x81325a8)
    at volcache.c:397
#6  0x8056bb0 in add_entry (volname=0xbffff1e8 "536873038", cell=0, ce=0x81325a8) at volcache.c:448
#7  0x8056ca2 in volcache_getbyid (id=536873038, cell=0, ce=0x81325a8) at volcache.c:510
#8  0x804e406 in fcache_recover_state () at fcache.c:780
#9  0x804e855 in fcache_init (alowvnodes=3000, ahighvnodes=4000, alowbytes=94371840, 
    ahighbytes=104857600, recover=1) at fcache.c:944
#10 0x804c0d4 in main (argc=2, argv=0xbffffdd8) at arla.c:816

the pointer passed to free() is not a pointer from malloc().

the relevant lines from get_info are:

393         if (e->entry.flags & VLF_RWEXISTS) {
394             e->num_ptr[RWVOL].cell = e->cell;
395             e->num_ptr[RWVOL].vol  = e->entry.volumeId[RWVOL];
396             e->num_ptr[RWVOL].ptr  = e;
397             hashtabadd (volidhashtab, (void *)&e->num_ptr[RWVOL]);


the relevant lines from hashtabadd are:

116     hashtabadd(Hashtab * htab, void *ptr)
117     {
118         Hashentry *h = _search(htab, ptr);
119         Hashentry **tabptr;
120
121         assert(htab && ptr);
122
123         if (h)
124             free((void *) h->ptr);
125         else {

my best guess is that:
1- get_info adds some volid to the hashtable.  h->ptr in the new hash
   entry points to the interior of 'e' (see line 397 above).  i don't
   know, but i suspect that 'e' was created by malloc().
2- get_info adds the same volid to the hashtable, again.  line 124
   calls free() on the interior pointer from the previous step.

here's some possibly relevant information about the volid being added
to the hashtable (from within hastabadd()), and the one that was
already there:

(gdb) p *((struct num_ptr *) ptr)->ptr
$15 = {entry = {name = "home.smith", '\000' <repeats 54 times>,
volumeType = 0, nServers = 1, serverNumber = {-2098337235, 0, 0, 0, 0,
0, 0, 0}, serverPartition = {5, 0, 0, 0, 0, 0, 0, 0}, serverFlags =
{4, 0, 0, 0, 0, 0, 0, 0}, volumeId = {536873037, 536873038,
536873039}, cloneId = 0, flags = 20480}, volsync = {spare1 = 0, spare2
= 0, spare3 = 0, spare4 = 0, spare5 = 0, spare6 = 0}, cell = 0,
refcount = 0, flags = {validp = 0}, name_ptr = {{cell = 0, name =
'\000' <repeats 64 times>, ptr = 0x0}, {cell = 0, name = '\000'
<repeats 64 times>, ptr = 0x0}, {cell = 0, name = '\000' <repeats 64
times>, ptr = 0x0}}, num_ptr = {{cell = 0, vol = 536873037, ptr =
0x80f1550}, {cell = 0, vol = 0, ptr = 0x0}, {cell = 0, vol = 0, ptr =
0x0}}}

(gdb) p *((struct num_ptr *) h->ptr)->ptr
$16 = {entry = {name = "home.smith", '\000' <repeats 54 times>,
volumeType = 0, nServers = 1, serverNumber = {-2098337235, 0, 0, 0, 0,
0, 0, 0}, serverPartition = {5, 0, 0, 0, 0, 0, 0, 0}, serverFlags =
{4, 0, 0, 0, 0, 0, 0, 0}, volumeId = {536873037, 536873038,
536873039}, cloneId = 0, flags = 20480}, volsync = {spare1 = 0, spare2
= 0, spare3 = 0, spare4 = 0, spare5 = 0, spare6 = 0}, cell = 0,
refcount = 1, flags = {validp = 1}, name_ptr = {{cell = 0, name =
"home.smith", '\000' <repeats 54 times>, ptr = 0x80f1eec}, {cell = 0,
name = '\000' <repeats 64 times>, ptr = 0x0}, {cell = 0, name =
"home.smith.backup", '\000' <repeats 47 times>, ptr = 0x80f1eec}},
num_ptr = {{ cell = 0, vol = 536873037, ptr = 0x80f1eec}, {cell = 0,
vol = 0, ptr = 0x0}, {cell = 0, vol = 536873039, ptr = 0x80f1eec}}}

i don't have a suggested fix at this time.  perhaps hashtabadd should
take an argument 'freep' that indicates in the hashentry whether the
value should be freed if the hashentry is replaced or deleted.  (this
would supersede the freep argument to hastabdel.)

btw, this is a linux 2.0.35, glibc system.  i was running "arlad -t"
with the default configs.  if there is something i can do to provide
more info, let me know.

ray jones





More information about the Arla-drinkers mailing list