Sebastien Marie <sema...@online.fr> wrote: > On Sat, Dec 07, 2019 at 11:47:58AM +0100, Sebastien Marie wrote: > > > > For now, I recompiled slaacd with debug symbols, and will keep it running > > like > > that in order to catch it the next time. But such switchs aren't very > > frequent... > > A new one, with symbols this time. I still saw it only i386 and aarch64 (not > on amd64). > > $ sysctl kern.version > kern.version=OpenBSD 6.6-current (GENERIC.MP) #103: Wed Dec 4 20:10:51 CET > 2019 > semarie@bert.local:/home/openbsd/src/sys/arch/i386/compile/GENERIC.MP > > $ doas egdb /sbin/slaacd /slaacd.core > GNU gdb (GDB) 7.12.1 > Copyright (C) 2017 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> > This is free software: you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. Type "show copying" > and "show warranty" for details. > This GDB was configured as "i386-unknown-openbsd6.5". > Type "show configuration" for configuration details. > For bug reporting instructions, please see: > <http://www.gnu.org/software/gdb/bugs/>. > Find the GDB manual and other documentation resources online at: > <http://www.gnu.org/software/gdb/documentation/>. > For help, type "help". > Type "apropos word" to search for commands related to "word"... > Reading symbols from /sbin/slaacd...done. > [New process 221665] > > warning: Unexpected size of section `.reg2/221665' in core file. > Core was generated by `slaacd'. > Program terminated with signal SIGABRT, Aborted. > > warning: Unexpected size of section `.reg2/221665' in core file. > #0 thrkill () at -:3 > 3 -: No such file or directory. > (gdb) bt > #0 thrkill () at -:3 > #1 0x15dcde20 in _libc_raise (s=6) at > /home/openbsd/src/lib/libc/gen/raise.c:37 > #2 0x15dcddab in _libc_abort () at > /home/openbsd/src/lib/libc/stdlib/abort.c:51 > #3 0x15dcdd60 in memcpy (dst0=0xcf7f4c88, src0=0xcf7f4c3c, length=272) at > /home/openbsd/src/lib/libc/string/memcpy.c:74 > #4 0x15d8f1a2 in delete_address (address=<optimized out>) at > /home/openbsd/src/sbin/slaacd/slaacd.c:730 > #5 main_dispatch_engine (fd=<optimized out>, event=2, bula=0x761bd000) at > /home/openbsd/src/sbin/slaacd/slaacd.c:534 > #6 0x15d91058 in event_process_active (base=<optimized out>) at > /home/openbsd/src/lib/libevent/event.c:333 > #7 event_base_loop (base=0x49a33c00, flags=0) at > /home/openbsd/src/lib/libevent/event.c:483 > #8 0x15d90af1 in event_loop (flags=<error reading variable: Cannot access > memory at address 0x0>) at /home/openbsd/src/lib/libevent/event.c:409 > #9 event_dispatch () at /home/openbsd/src/lib/libevent/event.c:347 > #10 0x15d8e92e in main (argc=<optimized out>, argv=0xcf7f5064) at > /home/openbsd/src/sbin/slaacd/slaacd.c:305 > > From frame #3, it means: > > memcpy(&in6_ridreq.ifr_ifru, &address->addr, > sizeof(in6_ridreq.ifr_ifru)); > > &in6_ridreq.ifr_ifru is at 0xcf7f4c88 > &address->addr is at 0xcf7f4c3c > sizeof(in6_ridreq.ifr_ifru) is 272 > > `address' is from the stack in frame #5 (main_dispatch_engine), and > `in6_ridreq' is > from the stack in frame #4 (delete_address). > > `address->addr' is a `struct sockaddr_in6' and the sizeof() is 26 bytes. > `in6_ridreq.ifr_ifru' is a union with `struct sockaddr_in6' in member, but > the > total sizeof() is 272 (I assume due to bigger members). > > so memcpy() will read 272 bytes from the stack, even if the source is only 26 > bytes long. some bytes will come from outside the variable, specially from the > next variable on the stack, and in this case it is from `in6_ridreq' itself, > resulting in backwards memcpy.
It should use the specific element in the union, so this might be the fix. Index: slaacd.c =================================================================== RCS file: /cvs/src/sbin/slaacd/slaacd.c,v retrieving revision 1.45 diff -u -p -u -r1.45 slaacd.c --- slaacd.c 23 Nov 2019 08:17:39 -0000 1.45 +++ slaacd.c 15 Dec 2019 06:31:02 -0000 @@ -727,8 +727,8 @@ delete_address(struct imsg_configure_add return; } - memcpy(&in6_ridreq.ifr_ifru, &address->addr, - sizeof(in6_ridreq.ifr_ifru)); + memcpy(&in6_ridreq.ifr_ifru.ifru_addr, &address->addr, + sizeof(in6_ridreq.ifr_ifru.ifru_addr)); log_debug("%s: %s", __func__, if_name);