troglobit/pim6sd

segfaults when system has >32 interfaces

Closed this issue · 5 comments

T-X commented

On startup I get the following segfault:

$ sudo gdb --args ./src/pim6sd -f ./pim6sd.conf                                                                                                                                     <─(Fri,May03)─┘
GNU gdb (Debian 8.2.1-1) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
    .

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./src/pim6sd...done.
(gdb) run
Starting program: /home/linus/dev-priv/pim6sd/src/pim6sd -f ./pim6sd.conf
BFD: /usr/lib/debug/.build-id/75/5312dcb2382eb2fde78494879bb2104028ae80.debug: unable to initialize decompress status for section .debug_aranges
BFD: /usr/lib/debug/.build-id/75/5312dcb2382eb2fde78494879bb2104028ae80.debug: unable to initialize decompress status for section .debug_aranges
warning: File "/usr/lib/debug/.build-id/75/5312dcb2382eb2fde78494879bb2104028ae80.debug" has no build-id, file skipped
BFD: /usr/lib/debug/.build-id/55/e7de84df6813c82c5b12822219c17d19c9c4b0.debug: unable to initialize decompress status for section .debug_aranges
BFD: /usr/lib/debug/.build-id/55/e7de84df6813c82c5b12822219c17d19c9c4b0.debug: unable to initialize decompress status for section .debug_aranges
warning: File "/usr/lib/debug/.build-id/55/e7de84df6813c82c5b12822219c17d19c9c4b0.debug" has no build-id, file skipped
pim6sd: 00:44:23.767 warning - setsockopt(IPV6_ROUTER_ALERT): Protocol not available
pim6sd: 00:44:23.768 warning - add_phaddr: found more than one link-local address on ip6gre1
pim6sd: 00:44:23.768 warning - add_phaddr: found more than one link-local address on vmtap20
pim6sd: 00:44:23.768 warning - add_phaddr: found more than one link-local address on vmtap22

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e6b6e6 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff7e6b6e6 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7e5f2fa in open_memstream () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7edab30 in __vsyslog_chk () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007ffff7edb09c in syslog () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x000055555555e23e in log_msg (severity=severity@entry=4, syserr=syserr@entry=0, format=format@entry=0x55555557aed8 "add_phaddr: found more than one link-local address on %s") at debug.c:755
#5  0x000055555555cf70 in add_phaddr (v=v@entry=0x55555558d2c0, addr=addr@entry=0x7fffffffe200, mask=mask@entry=0x7fffffffe1f0, rmt=rmt@entry=0x0) at config.c:311
#6  0x000055555555d1be in config_vifs_from_kernel () at config.c:246
#7  0x0000555555576139 in init_vifs () at vif.c:173
#8  0x0000555555556776 in main (argc=, argv=) at main.c:448
(gdb) bt full
#0  0x00007ffff7e6b6e6 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#1  0x00007ffff7e5f2fa in open_memstream () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#2  0x00007ffff7edab30 in __vsyslog_chk () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#3  0x00007ffff7edb09c in syslog () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#4  0x000055555555e23e in log_msg (severity=severity@entry=4, syserr=syserr@entry=0, format=format@entry=0x55555557aed8 "add_phaddr: found more than one link-local address on %s") at debug.c:755
        ap = {{gp_offset = 32, fp_offset = 48, overflow_arg_area = 0x7fffffffe1a0, reg_save_area = 0x7fffffffe0c0}}
        fmt = "warning - add_phaddr: found more than one link-local address on vmtap22", '\000' 
        msg = 
        now = {tv_sec = 1556837063, tv_usec = 768495}
        thyme = 
#5  0x000055555555cf70 in add_phaddr (v=v@entry=0x55555558d2c0, addr=addr@entry=0x7fffffffe200, mask=mask@entry=0x7fffffffe1f0, rmt=rmt@entry=0x0) at config.c:311
        pa = 0x55555558dc80
        i = 
#6  0x000055555555d1be in config_vifs_from_kernel () at config.c:246
        v = 0x55555558d2c0
        i = 
        addr = {sin6_family = 10, sin6_port = 0, sin6_flowinfo = 0, sin6_addr = {__in6_u = {__u6_addr8 = "\376\200\000\000\000\000\000\000<\t\272\377\376\222\060\\", __u6_addr16 = {33022, 0, 0, 0, 2364, 65466, 
                37630, 23600}, __u6_addr32 = {33022, 0, 4290382140, 1546687230}}}, sin6_scope_id = 1324}
        rmt_addr = {sin6_family = 0, sin6_port = 0, sin6_flowinfo = 0, sin6_addr = {__in6_u = {__u6_addr8 = '\000' , __u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}}, 
          sin6_scope_id = 0}
        rmt = 
        mask = {__in6_u = {__u6_addr8 = "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000", __u6_addr16 = {65535, 65535, 65535, 65535, 0, 0, 0, 0}, __u6_addr32 = {4294967295, 4294967295, 0, 0}}}
        flags = 4163
        ifap = 0x5555555e7b40
        ifa = 0x5555555eb350
        __a = 
#7  0x0000555555576139 in init_vifs () at vif.c:173
        vifi = 
        v = 
        enabled_vifs = 0
#8  0x0000555555556776 in main (argc=, argv=) at main.c:448
        dummy = 
        dummysigalrm = 32767
        fp = 
        tv = {tv_sec = 140737488348020, tv_usec = 140737354129665}
        difftime = 
        curtime = {tv_sec = 140733193388032, tv_usec = 140737353953944}
        lasttime = 
        timeout = 
        rfds = {fds_bits = {140737353953704, 140737353514535, 1700966438, 140737488348384, 26577600, 140737488348224, 140737488348208, 140737488348024, 140737354131288, 1, 0, 0, 1, 1700966438, 140737354132160, 
            140737488348376}}
        readers = {fds_bits = {140737354131248, 0, 140737488348432, 140737354003295, 0, 140737488348432, 0, 0, 0, 140737354131248, 140737353514535, 896, 140737488348208, 140737488348224, 140737354132160, 0}}
        nfds = 0
        n = 
        i = 
        secs = 
        sa = {__sigaction_handler = {sa_handler = 0x38000000380, sa_sigaction = 0x38000000380}, sa_mask = {__val = {3848290698112, 4294967295, 3848290698112, 140737353953896, 140737354131248, 0, 0, 0, 0, 0, 0, 
              0, 15775231, 194, 140737488348358, 1}}, sa_flags = -135750363, sa_restorer = 0x0}
        d = 
        c = 
        tmpd = 
(gdb)
T-X commented

Ok, an error in the external call to syslog() seemed very suspicous and a bug in there quite unlikely.

So my suspicion was that there is probably some stack corruption earlier. And adding some printf()s often moved the segfault to other locations.

It seems that there is some length check missing for v = &uvifs[numvifs++]; in find_vif()s. uvifs has MAXMIFS = 32 elements and I have more than 32 interfaces. With an added printf() I could confirm that find_vif() increased numvifs to 37 and returned the non-existent &uvifs[37] shortly before crashing.

Disabling interfaces via "phyint <iface> disable;" in the config file does not help as it seems that find_vif() is called for all interfaces regardless of their usage.

I guess back in 2001 people thought no one would ever have more than 32 interfaces on a single system :-).

Heh, classic. I fixed this in pimd over ten years ago 😆 ... oh how this little puppy need some tender love and care.

I'll look into fixing this bug later today (after work) when I'll port the pimd --disable-vifs from #4.

There, with the discovery in #4 and fixes on master you should be set to go. Thank you for taking the time to test pim6sd!

T-X commented

Yes, works great! I can't reproduce any segmentation faults with this patch. Thanks a lot ❤️!

(One thing I noticed is that having >32 "phyint <iface> disabled;" statements still gives an error on startup. However just using "default_phyint_status disable;" and enabling the two interfaces I need works just fine.)

Also thanks a lot for your swiftness and help with everything 😃. (I hope @mweinelt and I are not causing any inconveniences. From our side, no need for hurry ☺️)

Cool, good to hear the fix worked! :)

The code really needs more attention, there are too many assumptions that should be explicitly checked and warnings added. I recognize much of it from my restoration of pimd, so bear with me.

No problem, just happy to help out. Really great to have a couple of knowledgeable testers trying things out. I have a couple of other projects that also need attention, but I'm taking this one as a great opportunity to learn IPv6 :-)