[Dnsmasq-discuss] crash on double free
Simon Kelley
simon at thekelleys.org.uk
Sun Sep 19 21:25:36 BST 2010
On 15/09/10 12:07, Ferenc Wagner wrote:
> Simon Kelley<simon at thekelleys.org.uk> writes:
>
>> Ferenc Wagner wrote:
>>
>>> ElectricFence Aborting: free(b7215f8c): address not from malloc().
>>> Illegal instruction (core dumped)
>>>
>>> and the backtrace is:
>>>
>>> #0 0xb7782416 in __kernel_vsyscall ()
>>> #1 0xb75dc956 in kill () from /lib/i686/cmov/libc.so.6
>>> #2 0xb770edd5 in EF_Abort () from /usr/lib/libefence.so.0
>>> #3 0xb770e159 in free () from /usr/lib/libefence.so.0
>>> #4 0x080623aa in add_extradata_data (lease=0xb71c7fac,
>>> data=0xb720fb68 "Linux ipconfigÿ\001þ\006\004\nú\001þ\017\talma.grid\f\02152-54-00-12-34-56\021\020/var/lib/nfsrootÿ", len=14, delim=0) at rfc2131.c:1525
>>> #5 0x0806242c in add_extradata_opt (lease=0xb71c7fac, opt=<value optimized out>) at rfc2131.c:1555
>>> #6 0x08067040 in dhcp_reply (context=0xb7549fc4, iface_name=0xbfdb6854 "br-alma-g", int_index=10,
>>> sz=283, now=1284475079, unicast_dest=0, is_inform=0xbfdb68d4, pxe=0) at rfc2131.c:1240
>>> #7 0x0805fb3e in dhcp_packet (now=1284475079, pxe_fd=0) at dhcp.c:301
>>> #8 0x0805d7de in main (argc=Cannot access memory at address 0x4
>>> ) at dnsmasq.c:688
>>>
>>> which points at
>>>
>>> static void add_extradata_data(struct dhcp_lease *lease, unsigned char *data, size_t len, int delim)
>>> {
>>> if ((lease->extradata_size - lease->extradata_len)< (len + 1))
>>> {
>>> size_t newsz = lease->extradata_len + len + 100;
>>> unsigned char *new = whine_malloc(newsz);
>>>
>>> if (!new)
>>> return;
>>>
>>> if (lease->extradata)
>>> {
>>> memcpy(new, lease->extradata, lease->extradata_len);
>>> HERE ==> free(lease->extradata);
>>> }
>>>
>>> lease->extradata = new;
>>> lease->extradata_size = newsz;
>>> }
>>>
>>> if (len != 0)
>>> memcpy(lease->extradata + lease->extradata_len, data, len);
>>> lease->extradata[lease->extradata_len + len] = delim;
>>> lease->extradata_len += len + 1;
>>> }
>>>
>>> So I seems lease->extradata isn't a pointer returned by malloc(), thus
>>> you should try to free it. I've got to leave now, hope it gives you
>>> enough info to actually pinpoint the problem. I'm keeping the core
>>> files for further investigation (and also send them if needed).
>>
>> Many thanks for taking the time to get this, I think I see the problem.
>> Could you try the following?
>>
>> at src/rfc2131.c line 1237 which is
>>
>> free(lease->extradata);
>>
>> add an extra line
>>
>> lease->extradata = NULL;
>>
>> and see if that fixes the crashes.
>
> Looks like that's a good move, I haven't got a crash since inserting
> that extra line!
>
> However, I also got a different crash with the original binary. I hope
> it's a different realisation of the same problem, can you confirm?
>
> (gdb) bt
> #0 0xb7599d5a in memcpy () from /lib/i686/cmov/libc.so.6
> #1 0x080623d0 in add_extradata_data (lease=0xb74f6fac,
> data=0xb7182b68 "Linux ipconfigÿ\001þ\006\004\nú\001þ\017\talma.grid\f\02152-54-00-12-34-56\021\020/var/lib/nfsrootÿ", len=3071814504, delim=0) at rfc2131.c:1533
> #2 0x0806242c in add_extradata_opt (lease=0xb74f6fac, opt=<value optimized out>) at rfc2131.c:1555
> #3 0x08067040 in dhcp_reply (context=0xb74bafc4, iface_name=0xbfda1124 "br-alma-g", int_index=10,
> sz=283, now=1284499746, unicast_dest=0, is_inform=0xbfda11a4, pxe=0) at rfc2131.c:1240
> #4 0x0805fb3e in dhcp_packet (now=1284499746, pxe_fd=0) at dhcp.c:301
> #5 0x0805d7de in main (argc=Cannot access memory at address 0x3
> ) at dnsmasq.c:688
> (gdb) up
> #1 0x080623d0 in add_extradata_data (lease=0xb74f6fac,
> data=0xb7182b68 "Linux ipconfigÿ\001þ\006\004\nú\001þ\017\talma.grid\f\02152-54-00-12-34-56\021\020/var/lib/nfsrootÿ", len=3071814504, delim=0) at rfc2131.c:1533
> 1533 memcpy(lease->extradata + lease->extradata_len, data, len);
>
> The passed-in value of "len" is obviously bogus here.
>
> (gdb) p lease->extradata
> $1 = (unsigned char *) 0xb7184f8c "Linux ipconfig"
> (gdb) p lease->extradata_len
> $2 = 0
> (gdb) p data
> $3 = (
> unsigned char *) 0xb7182b68 "Linux ipconfigÿ\001þ\006\004\nú\001þ\017\talma.grid\f\02152-54-00-12-34-56\021\020/var/lib/nfsrootÿ"
I can't see any other reason for this problem, I'm pretty sure it's down
to heap corruption from an earlier double-free.
>
> I'm continuing testing the fix. It usually took me tens of minutes to
> reproduce the crash, but with the change it already survived more than
> an hour. Unfortunately, it isn't fully automatic (because of other bugs
> in other software).
To trigger this bug, there needs to be a dhcp-script, obviously. But
also the rate of DHCP transactions needs to be fast enough and/or the
script needs to be slow enough so that a second DHCP transaction happens
on a lease before the first one has been sent to the DHCP-script. This
is pretty rare, hence no-one has seen this bug, as far as I know, even
though it has been lurking for some time (years).
Cheers,
Simon.
More information about the Dnsmasq-discuss
mailing list