Discussion:
[Dnsmasq-discuss] [PATCH] dhcpv6: fix unaligned access crash on aarch64
Vladislav Grishenko
2018-08-21 13:04:16 UTC
Permalink
Hi, Simon



Faced with dnsmasq crash on aarch64 (32bit userspace, arm-buildroot-linux-gnueabi-gcc 5.3.0) with dhcpv6 stateful configured.

Unaligned packet’s req_addr is used in lease6_allocate() for struct copy since 2.67test15 (commit 89500e31f199e9ae1eadc86213b911ff44d30d6f).

As for other places, seems well-aligned stack-local vars are used.

Please refer proposed patch attached and gdb trace:



Program received signal SIGBUS, Bus error.

0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822

822 lease->addr6 = *addrp;

(gdb) bt

#0 0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822

#1 0x00055fac in update_leases (state=0xfffef8ac, context=0xa7ee8, addr=0xa55e6, lease_time=900, now=14609) at rfc3315.c:1825

#2 0x00055ab4 in add_address (state=0xfffef8ac, context=0xa7ee8, lease_time=900, ia_option=0xa55e2, min_time=0xfffef6d0, addr=0xa55e6, now=14609) at rfc3315.c:1684

#3 0x00053764 in dhcp6_no_relay (state=0xfffef8ac, msg_type=3, inbuff=0xa55a8, sz=128, is_unicast=0, now=14609) at rfc3315.c:938

#4 0x00051744 in dhcp6_maybe_relay (state=0xfffef8ac, inbuff=0xa55a8, sz=128, client_addr=0xfffef9a0, is_unicast=0, now=14609) at rfc3315.c:172

#5 0x000513b8 in dhcp6_reply (context=0xa7ee8, interface=23, iface_name=0xfffef978, fallback=0xfffef9f8, ll_addr=0xfffefa18, ula_addr=0xfffefa28, sz=128, client_addr=0xfffef9a0,

now=14609) at rfc3315.c:103

#6 0x0004f4b4 in dhcp6_packet (now=14609) at dhcp6.c:233

#7 0x00038c78 in main (argc=3, argv=0xfffefd34) at dnsmasq.c:1099



Best Regards, Vladislav Grishenko
Simon Kelley
2018-08-21 21:11:13 UTC
Permalink
Thanks for chasing that down. Your patch will fix it, but I think it's
probably better to solve the problem at source, where we copy addresses
out of packets, rather than pass unaligned pointers to struct in6_addr
around and patch things up at the other end. That stops this coming and
biting us again.

That makes a much bigger patch, unfortunately.

I just pushed my attempt at doing that. Does it work OK for you?


Cheers,
Simon.
Post by Vladislav Grishenko
Hi, Simon
 
Faced with dnsmasq crash on aarch64 (32bit userspace,
arm-buildroot-linux-gnueabi-gcc 5.3.0) with dhcpv6 stateful configured.
Unaligned packet’s req_addr is used in lease6_allocate() for struct copy
since 2.67test15 (commit 89500e31f199e9ae1eadc86213b911ff44d30d6f).
As for other places, seems well-aligned stack-local vars are used.
 
Program received signal SIGBUS, Bus error.
0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822
822           lease->addr6 = *addrp;
(gdb) bt
#0  0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at
lease.c:822
#1  0x00055fac in update_leases (state=0xfffef8ac, context=0xa7ee8,
addr=0xa55e6, lease_time=900, now=14609) at rfc3315.c:1825
#2  0x00055ab4 in add_address (state=0xfffef8ac, context=0xa7ee8,
lease_time=900, ia_option=0xa55e2, min_time=0xfffef6d0, addr=0xa55e6,
now=14609) at rfc3315.c:1684
#3  0x00053764 in dhcp6_no_relay (state=0xfffef8ac, msg_type=3,
inbuff=0xa55a8, sz=128, is_unicast=0, now=14609) at rfc3315.c:938
#4  0x00051744 in dhcp6_maybe_relay (state=0xfffef8ac, inbuff=0xa55a8,
sz=128, client_addr=0xfffef9a0, is_unicast=0, now=14609) at rfc3315.c:172
#5  0x000513b8 in dhcp6_reply (context=0xa7ee8, interface=23,
iface_name=0xfffef978, fallback=0xfffef9f8, ll_addr=0xfffefa18,
ula_addr=0xfffefa28, sz=128, client_addr=0xfffef9a0,
    now=14609) at rfc3315.c:103
#6  0x0004f4b4 in dhcp6_packet (now=14609) at dhcp6.c:233
#7  0x00038c78 in main (argc=3, argv=0xfffefd34) at dnsmasq.c:1099
 
Best Regards, Vladislav Grishenko
 
Vladislav Grishenko
2018-08-22 09:41:32 UTC
Permalink
Yep, it works as expected, thanks.
Unfortunately, struct copying is still there and need to keep in mind
that pointers must be aligned or absence of protection will crash it
again in any possible future.
Btw, alignment rule was applied to DECLINE, but seems missed in
DHCPRELEASE part, put_opt6(opt6_ptr(ia_option, 0)...) is still there
instead of put_opt6(&addr...).

Best Regards, Vladislav Grishenko
Post by Simon Kelley
Thanks for chasing that down. Your patch will fix it, but I think it's
probably better to solve the problem at source, where we copy addresses
out of packets, rather than pass unaligned pointers to struct in6_addr
around and patch things up at the other end. That stops this coming and
biting us again.
That makes a much bigger patch, unfortunately.
I just pushed my attempt at doing that. Does it work OK for you?
Cheers,
Simon.
Post by Vladislav Grishenko
Hi, Simon
Faced with dnsmasq crash on aarch64 (32bit userspace,
arm-buildroot-linux-gnueabi-gcc 5.3.0) with dhcpv6 stateful configured.
Unaligned packet’s req_addr is used in lease6_allocate() for struct copy
since 2.67test15 (commit 89500e31f199e9ae1eadc86213b911ff44d30d6f).
As for other places, seems well-aligned stack-local vars are used.
Program received signal SIGBUS, Bus error.
0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822
822 lease->addr6 = *addrp;
(gdb) bt
#0 0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822
#1 0x00055fac in update_leases (state=0xfffef8ac, context=0xa7ee8,
addr=0xa55e6, lease_time=900, now=14609) at rfc3315.c:1825
#2 0x00055ab4 in add_address (state=0xfffef8ac, context=0xa7ee8,
lease_time=900, ia_option=0xa55e2, min_time=0xfffef6d0, addr=0xa55e6,
now=14609) at rfc3315.c:1684
#3 0x00053764 in dhcp6_no_relay (state=0xfffef8ac, msg_type=3,
inbuff=0xa55a8, sz=128, is_unicast=0, now=14609) at rfc3315.c:938
#4 0x00051744 in dhcp6_maybe_relay (state=0xfffef8ac, inbuff=0xa55a8,
sz=128, client_addr=0xfffef9a0, is_unicast=0, now=14609) at rfc3315.c:172
#5 0x000513b8 in dhcp6_reply (context=0xa7ee8, interface=23,
iface_name=0xfffef978, fallback=0xfffef9f8, ll_addr=0xfffefa18,
ula_addr=0xfffefa28, sz=128, client_addr=0xfffef9a0,
now=14609) at rfc3315.c:103
#6 0x0004f4b4 in dhcp6_packet (now=14609) at dhcp6.c:233
#7 0x00038c78 in main (argc=3, argv=0xfffefd34) at dnsmasq.c:1099
Best Regards, Vladislav Grishenko
--
Best regards, Vladislav Grishenko
Loading...