Re: dhcpcd 6.11.3 core dumps on FreeBSD with link disconnect/connect sequence
Roy Marples
Tue Aug 30 16:47:14 2016
Hi Guy
On 27/08/2016 11:57, Guy Yur wrote:
> dhcpcd 6.11.3 crashed on my machine running FreeBSD during a
> link disconnect/connect sequence.
>
> I was able to replicate the crash with the following sequence:
> ifconfig lan0 down
> disconnect link
> ifconfig lan0 up
>
> backtrace:
> #0 0x00000000004320d4 in ipv4_deladdr (addr=0x80142a4c0, keeparp=0)
> at ipv4.c:858
> #1 0x000000000043292b in delete_address (ifp=0x80143d100) at ipv4.c:902
> #2 0x0000000000432aa3 in ipv4_applyaddr (arg=0x80143d100) at ipv4.c:1123
> #3 0x0000000000427f7d in dhcp_drop (ifp=0x80143d100, reason=0x44fffa
> "EXPIRE") at dhcp.c:2575
> #4 0x0000000000406dee in dhcpcd_drop (ifp=0x80143d100, stop=0) at dhcpcd.c:372
> #5 0x0000000000406b33 in dhcpcd_handlecarrier (ctx=0x7fffffffeb10,
> carrier=-1, flags=34883, ifname=0x80143d118 "lan0")
> at dhcpcd.c:740
> #6 0x000000000042220e in if_ifinfo (ctx=0x7fffffffeb10,
> ifm=0x7fffffffe100) at if-bsd.c:1294
> #7 0x000000000042171b in if_dispatch (ctx=0x7fffffffeb10,
> rtm=0x7fffffffe100) at if-bsd.c:1457
> #8 0x000000000042165e in if_handlelink (ctx=0x7fffffffeb10) at if-bsd.c:1490
> #9 0x000000000040b2cd in dhcpcd_handlelink (arg=0x7fffffffeb10) at
> dhcpcd.c:1002
> #10 0x000000000040d9fe in eloop_start (eloop=0x801428840,
> signals=0x7fffffffebdc) at eloop.c:935
> #11 0x000000000040abc0 in main (argc=1, argv=0x7fffffffed50) at dhcpcd.c:1937
>
> (gdb) frame 3
> (gdb) p state->added
> $1 = 1 '\001'
>
> state->addr is garbage, for example:
> (gdb) p *state->addr->iface
> Cannot access memory at address 0x2f7273752f3a6e69
>
> With some debug prints added, I see the following:
>
> 1. ipv4_handleifa called with RTM_DELADDR, removes ia from the tailq.
> TAILQ_REMOVE(&state->addrs, ia, next);
>
> 2. ipv4_handleifa calls dhcp_handleifa with ia.
> dhcp_handleifa ... ipv4_deladdr.
> ipv4_deladdr doesn't find addr in state->addrs because it
> was removed above and so doesn't set 'dstate->added = 0'
> and 'dstate->addr = NULL'.
>
> 3. ipv4_handleifa frees ia.
>
> 4. ipv4_applyaddr is called, sees state->added and tries to delete
> the address with a pointer to an already freed ipv4_addr.
The attached patch should resolve it.
I have a techincal issue with my FreeBSD image right now so can't test
it directly, but will memory test it on Linux later as the code path is
similar.
Let me know if it works for you!
Roy
Index: dhcp.c
==================================================================
--- dhcp.c
+++ dhcp.c
@@ -3651,13 +3651,15 @@
state = D_STATE(ifp);
if (state == NULL)
return;
if (cmd == RTM_DELADDR) {
- if (IPV4_BRD_EQ(state->addr, ia)) {
+ if (state->addr == ia) {
logger(ifp->ctx, LOG_INFO,
"%s: deleted IP address %s", ifp->name, ia->saddr);
+ state->added = 0;
+ state->addr = NULL;
dhcp_drop(ifp, "EXPIRE");
}
return;
}
Archive administrator: postmaster@marples.name