Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault on OpenBSD when configuring wireguard interface for prefix delegation #394

Closed
kensimon opened this issue Oct 29, 2024 · 3 comments · Fixed by #395
Closed

Segfault on OpenBSD when configuring wireguard interface for prefix delegation #394

kensimon opened this issue Oct 29, 2024 · 3 comments · Fixed by #395

Comments

@kensimon
Copy link
Contributor

kensimon commented Oct 29, 2024

Running 10.1.0 on OpenBSD 7.6. dhcpcd config:

debug
hostname
duid <DUID HERE>
vendorclassid
option domain_name_servers, domain_name, domain_search
option classless_static_routes
option interface_mtu
option rapid_commit
require dhcp_server_identifier
slaac private
noipv6rs
interface em0
    iaid 0
    ipv6rs
    ia_na 0
    ia_pd 0/::/56 em1/1 vlan2/2 vlan3/3 wg0/15
interface em1
    nodhcp
    nodhcp6
    noipv4ll
interface vlan2
    nodhcp
    nodhcp6
    noipv4ll
interface vlan3
    nodhcp
    nodhcp6
    noipv4ll
interface wg0
    nodhcp
    nodhcp6
    noipv4ll

After compiling with -g for debug symbols, I get the following with dhcpcd -d -M -B:

GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-unknown-openbsd7.6"...
(gdb) run -d -M -B
Starting program: /usr/ports/pobj/dhcpcd-10.1.0/dhcpcd-10.1.0/src/dhcpcd -d -M -B
Error while reading shared library symbols:
Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/libexec/ld.so]
dhcpcd-10.1.0 starting
[New process 48786]
spawned privileged proxy on PID 81414
spawned network proxy on PID 51412
spawned controller proxy on PID 99342
DUID <duid>
sandbox: pledge
lo0: ignoring due to interface type and no config
enc0: unsupported interface type 0xf4
wg0: unsupported interface type 0xfb
pflog0: unsupported interface type 0xf5
em0: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em0: executing: /usr/local/libexec/dhcpcd-run-hooks CARRIER
em1: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em1: executing: /usr/local/libexec/dhcpcd-run-hooks CARRIER
em2: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em2: executing: /usr/local/libexec/dhcpcd-run-hooks NOCARRIER
em3: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em3: executing: /usr/local/libexec/dhcpcd-run-hooks NOCARRIER
em4: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em4: executing: /usr/local/libexec/dhcpcd-run-hooks NOCARRIER
em5: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em5: executing: /usr/local/libexec/dhcpcd-run-hooks NOCARRIER
vlan2: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
vlan2: executing: /usr/local/libexec/dhcpcd-run-hooks CARRIER
vlan3: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
vlan3: executing: /usr/local/libexec/dhcpcd-run-hooks CARRIER
wg0: executing: /usr/local/libexec/dhcpcd-run-hooks PREINIT
em0: IAID 00:00:00:00
em0: delaying IPv6 router solicitation for 0.2 seconds
em0: reading lease: /var/db/dhcpcd/em0.lease6
em0: rebinding prior DHCPv6 lease
em0: delaying REBIND6 (xid 0x9a14db), next in 1.1 seconds
em0: delaying IPv4 for 1.3 seconds
em1: IAID 67:2b:cc:85
em1: delaying IPv4 for 1.5 seconds
em2: waiting for carrier
em3: waiting for carrier
em4: waiting for carrier
em5: waiting for carrier
vlan2: IAID ff:00:00:02
vlan2: delaying IPv4 for 0.3 seconds
vlan3: IAID ff:00:00:03
vlan3: delaying IPv4 for 1.1 seconds
wg0: IAID 77:67:30:00
wg0: delaying IPv4 for 1.9 seconds
em0: soliciting an IPv6 router
em0: sending Router Solicitation
em0: Router Advertisement from <redacted>
em0: adding route to <redacted>
em0: adding route to <redacted>
em0: adding default route via <redacted>
lo0: adding reject route to <redacted>::/60 via ::1
em0: executing: /usr/local/libexec/dhcpcd-run-hooks ROUTERADVERT
em0: multicasting REBIND6 (xid 0x9a14db), next in 1.1 seconds
em0: REPLY6 received from <redacted>
em0: adding address <redacted>/128
em0: pltime 286581 seconds, vltime 286581 seconds
em0: renew in 113781, rebind in 217461, expire in 286581 seconds
em0: writing lease: /var/db/dhcpcd/em0.lease6
em0: delegated prefix <redacted>::/60
em1: adding address <redacted>01::1/64
em1: pltime 286581 seconds, vltime 286581 seconds
em1: waiting for DHCPv6 DAD to complete
vlan2: adding address <redacted>02::1/64
vlan2: pltime 286581 seconds, vltime 286581 seconds
vlan2: waiting for DHCPv6 DAD to complete
vlan3: adding address <redacted>03::1/64
vlan3: pltime 286581 seconds, vltime 286581 seconds
vlan3: waiting for DHCPv6 DAD to complete
wg0: adding address <redacted>0f::1/64
wg0: pltime 286581 seconds, vltime 286581 seconds

Program received signal SIGSEGV, Segmentation fault.
ipv6_addaddr (ia=0x5226fc74280, now=Unhandled dwarf expression opcode 0xa3
) at ipv6.c:789
789             TAILQ_FOREACH(ia2, &state->addrs, next) {
Current language:  auto; currently minimal
(gdb) bt
#0  ipv6_addaddr (ia=0x5226fc74280, now=Unhandled dwarf expression opcode 0xa3
) at ipv6.c:789
#1  0x0000051f732a45ce in ipv6_doaddr (ia=0x5226fc74280, now=0x7849ef3c6f00) at ipv6.c:965
#2  0x0000051f732a4697 in ipv6_addaddrs (iaddrs=0x5226fc4f438) at ipv6.c:979
#3  0x0000051f732b1151 in dhcp6_bind (ifp=0x5226fc67200, op=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:2990
#4  0x0000051f732ab7a0 in dhcp6_recvif (ifp=0x5226fc67200, sfrom=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:3607
#5  0x0000051f732aac52 in dhcp6_recvmsg (ctx=0x7849ef3d7440, msg=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:3745
#6  0x0000051f732b6801 in ps_inet_dispatch (arg=Unhandled dwarf expression opcode 0xa3
) at privsep-inet.c:335
#7  0x0000051f732b4244 in ps_recvpsmsg (ctx=0x7849ef3d7440, fd=Unhandled dwarf expression opcode 0xa3
) at privsep.c:1173
#8  0x0000051f732b699e in ps_inet_dodispatch (arg=Unhandled dwarf expression opcode 0xa3
) at privsep-inet.c:350
#9  0x0000051f73285955 in eloop_start (eloop=0x5226fc6bd20, signals=0x7849ef3d7680) at eloop.c:1106
#10 0x0000051f73283566 in main (argc=4, argv=0x7849ef3d7918, envp=Unhandled dwarf expression opcode 0xa3
) at dhcpcd.c:2650
(gdb) p ia2
No symbol "ia2" in current context.
(gdb) p state
$1 = (int32_t *) 0x52175e7b054
(gdb) p state->addrs
Attempt to extract a component of a value that is not a structure pointer.
(gdb) The program is running.  Exit anyway? (y or n) y

It seems to be segfaulting in ipv6.c:789, reading from the state->addrs field, which is in turn coming from the ifp pointer.

Notes:

  • I only get this if I'm trying to delegate a prefix to my wireguard interface (wg0). Removing wg0/15 from my ia_pd line makes the issue go away.
  • If I revert this commit , the issue goes away. (This is my workaround for now.)

It would appear that either the change in this commit is causing the issue, or something with my wireguard interface is leading to a corrupted value for the ifp pointer, leading to a corrupted value when reading it via IPV6_STATE? I'm a bit out of my depth on reading the code here.

If you need any more info about the segfault let me know, I'm unfortunately not getting a core file so it's tough to debug for long (this is on my home router so debugging a stopped dhcpcd means my internet is out 😅)

@kensimon
Copy link
Contributor Author

Some more info from a gdb session:

(gdb) p ((struct ipv6_state *)state)->addrs->tqh_first
$5 = (struct ipv6_addr *) 0x16a5bce3991539b1
(gdb) p *(((struct ipv6_state *)state)->addrs->tqh_first)
Cannot access memory at address 0x16a5bce3991539b1

It looks like state.addrs.tqh_first is pointing to an unmapped address, so this may be a freed pointer?

@kensimon
Copy link
Contributor Author

Pulling latest master, the crash is on a different line, but still in accessing state->addrs:

wg0: pltime 283002 seconds, vltime 283002 seconds

Program received signal SIGSEGV, Segmentation fault.
0x00000bb9ee776389 in ipv6_addaddr (ia=0xbbbfd38f780, now=Unhandled dwarf expression opcode 0xa3
) at ipv6.c:795
795                     TAILQ_INSERT_TAIL(&state->addrs, iaf, next);
Current language:  auto; currently minimal
(gdb) bt
#0  0x00000bb9ee776389 in ipv6_addaddr (ia=0xbbbfd38f780, now=Unhandled dwarf expression opcode 0xa3
) at ipv6.c:795
#1  0x00000bb9ee77658e in ipv6_doaddr (ia=0xbbbfd38f780, now=0x70ed863183a0) at ipv6.c:961
#2  0x00000bb9ee776657 in ipv6_addaddrs (iaddrs=0xbbbfd3737b8) at ipv6.c:975
#3  0x00000bb9ee782d81 in dhcp6_bind (ifp=0xbbbfd370400, op=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:2997
#4  0x00000bb9ee77d7ef in dhcp6_recvif (ifp=0xbbbfd370400, sfrom=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:3626
#5  0x00000bb9ee77cca2 in dhcp6_recvmsg (ctx=0x70ed863288e0, msg=Unhandled dwarf expression opcode 0xa3
) at dhcp6.c:3764
#6  0x00000bb9ee7887e1 in ps_inet_dispatch (arg=Unhandled dwarf expression opcode 0xa3
) at privsep-inet.c:335
#7  0x00000bb9ee7862c4 in ps_recvpsmsg (ctx=0x70ed863288e0, fd=Unhandled dwarf expression opcode 0xa3
) at privsep.c:1175
#8  0x00000bb9ee78897e in ps_inet_dodispatch (arg=Unhandled dwarf expression opcode 0xa3
) at privsep-inet.c:350
#9  0x00000bb9ee757915 in eloop_start (eloop=0xbbbfd38bbe0, signals=0x70ed86328b20) at eloop.c:1106
#10 0x00000bb9ee755526 in main (argc=4, argv=0x70ed86328db8, envp=Unhandled dwarf expression opcode 0xa3
) at dhcpcd.c:2650
(gdb) p ((struct ipv6_state *)state)->addrs->tqh_first
$1 = (struct ipv6_addr *) 0x16a5bce3991539b1
(gdb) p *(((struct ipv6_state *)state)->addrs->tqh_first)
Cannot access memory at address 0x16a5bce3991539b1
(gdb) The program is running.  Exit anyway? (y or n) y

@rsmarples
Copy link
Member

Just a note about your config ... it could be improved by adding the nodhcp etc clauses to the top section and just enable them again in the interface em0 section by removing the no prefix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants