radvd-project / radvd

radvd | Official repository: https://github.com/radvd-project/radvd
https://radvd.litech.org/
Other
203 stars 107 forks source link

Segmentation fault when client is our link-local #157

Closed jsarenik closed 3 years ago

jsarenik commented 3 years ago

I successfully use radvd with the same config (see below) on armv7l glibc Linux. Now moving the service to x86_64 Musl-libc (Alpine Linux) and experiencing this issue:

Tested with current master 81862e7b36cb20c6cea80a2edd0c472888f4ce1e

# radvd -n -C /etc/radvd.conf -d5 -m stderr_clean
...
sending RA to fe80::aa20:66ff:fe3f:1909 on eth0 (fe80::aa20:66ff:fe3f:1909), 5 options (using 120/1210 bytes)
eth0 next scheduled RA in 16 second(s)
polling for 16 second(s), next iface is eth0
Exiting, privsep_read_loop had readn return 0 bytes
Exiting, privsep_read_loop is complete.
Segmentation fault

Sometimes the last two lines of output are flapped, i.e. last-1 line shows Segmentation fault.

The config file:

interface eth0
{
   AdvSendAdvert on;
   AdvLinkMTU 1472;
   AdvManagedFlag on;
   AdvHomeAgentFlag off;
   prefix TUNNELBROKER_PREFIX::/64
   {
     AdvOnLink on;
     AdvAutonomous on;
     AdvRouterAddr off;
   };
   clients
   {
     fe80::aa20:66ff:fe3f:1909;
     fe80::1f9e:868a:eb03:58d7;
     fe80::c3a9:bc9:97ae:a481;
   };

   prefix YGGDRASIL_PREFIX::/64
   {
     AdvOnLink on;
     AdvAutonomous on;
   };
   route 200::/7 {};
};

If AdvSendAdvert is set to off then it does not segfault but it also does not send any RAs.

Thank you for radvd! I use it for many years and it works great!

stappersg commented 3 years ago

On Sun, May 02, 2021 at 01:30:53AM -0700, Ján Sáreník wrote:

x86_64 Musl-libc (Alpine Linux) current master 81862e7b36cb20c6cea80a2edd0c472888f4ce1e

radvd -n -C /etc/radvd.conf -d5 -m stderr_clean

... sending RA to fe80::aa20:66ff:fe3f:1909 on eth0 (fe80::aa20:66ff:fe3f:1909), 5 options (using 120/1210 bytes) eth0 next scheduled RA in 16 second(s) polling for 16 second(s), next iface is eth0 Exiting, privsep_read_loop had readn return 0 bytes Exiting, privsep_read_loop is complete. Segmentation fault

Advice: Reproduce with gdb radvd -n -C /etc/radvd.conf -d5 -m stderr_clean and report the backtrace

jsarenik commented 3 years ago

Using gdb (GDB) 10.2 like this:

cd path/to/cloned/and/built/radvd
cat > gdb-commands <<EOF
run
bt
c
q
EOF
gdb -x gdb-commands --args $PWD/radvd -n -C /etc/radvd.conf -d5 -m stderr_clean

This is the output:

GNU gdb (GDB) 10.2
Copyright (C) 2021 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 "x86_64-alpine-linux-musl".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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 /home/nsm/tmp/radvd/radvd...

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7fb6e81 in memchr (src=src@entry=0xffffffffffffe240, c=c@entry=0, 
    n=n@entry=2147483647) at src/string/memchr.c:17
#0  0x00007ffff7fb6e81 in memchr (src=src@entry=0xffffffffffffe240, 
    c=c@entry=0, n=n@entry=2147483647) at src/string/memchr.c:17
#1  0x00007ffff7fb7932 in strnlen (
    s=s@entry=0xffffffffffffe240 <error: Cannot access memory at address 0xffffffffffffe240>, n=n@entry=2147483647) at src/string/strnlen.c:5
#2  0x00007ffff7fb369d in printf_core (f=f@entry=0x7fffffffdb88, 
    fmt=fmt@entry=0x5555555620fa "%s recvmsg len=%d", 
    ap=ap@entry=0x7fffffffda00, nl_arg=nl_arg@entry=0x7fffffffda90, 
    nl_type=<optimized out>) at src/stdio/vfprintf.c:594
#3  0x00007ffff7fb3ab2 in vfprintf (f=f@entry=0x7fffffffdb88, 
    fmt=0x5555555620fa "%s recvmsg len=%d", fmt@entry=0x7fffffffe118 "\030", 
    ap=<optimized out>) at src/stdio/vfprintf.c:683
#4  0x00007ffff7fb5b80 in vsnprintf (s=s@entry=0x7fffffffdcd0 "", 
    n=n@entry=1024, fmt=fmt@entry=0x7fffffffe118 "\030", 
    ap=ap@entry=0x7fffffffe038) at src/stdio/vsnprintf.c:54
#5  0x00005555555575fa in vsnprintf (__v=0x7fffffffe038, __f=<optimized out>, 
    __n=1024, __s=0x7fffffffdcd0 "") at /usr/include/fortify/stdio.h:77
#6  vlog (prio=7, format=format@entry=0x5555555620fa "%s recvmsg len=%d", 
    ap=ap@entry=0x7fffffffe118) at log.c:76
#7  0x00005555555579b0 in dlog (prio=prio@entry=7, level=level@entry=5, 
    format=format@entry=0x5555555620fa "%s recvmsg len=%d") at log.c:124
#8  0x0000555555557c82 in recv_rs_ra (sock=sock@entry=3, 
    msg=msg@entry=0x7fffffffe4c0 "\206", addr=addr@entry=0x7fffffffe460, 
    pkt_info=pkt_info@entry=0x7fffffffe2a8, 
    hoplimit=hoplimit@entry=0x7fffffffe2a4, chdr=chdr@entry=0x7fffffffe480 "$")
    at recv.c:85
#9  0x000055555555aefb in main_loop (sock=sock@entry=3, 
    ifaces=ifaces@entry=0x7ffff7ffe0f0, 
    conf_path=conf_path@entry=0x7fffffffee95 "/etc/radvd.conf") at radvd.c:545
#10 0x0000555555556df7 in main (argc=<optimized out>, argv=<optimized out>)
    at radvd.c:436

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
jsarenik commented 3 years ago

With the missing stderr output it looks like this.

stappersg commented 3 years ago

The

0x00007ffff7fb6e81 in memchr (src=src@entry=0xffffffffffffe240, c=c@entry=0, 
    n=n@entry=2147483647) at src/string/memchr.c:17
17  src/string/memchr.c: No such file or directory.
#0  0x00007ffff7fb6e81 in memchr (src=src@entry=0xffffffffffffe240, 
    c=c@entry=0, n=n@entry=2147483647) at src/string/memchr.c:17
#1  0x00007ffff7fb7932 in strnlen (
    s=s@entry=0xffffffffffffe240 <error: Cannot access memory at address 0xffffffffffffe240>,
      n=n@entry=2147483647) at src/string/strnlen.c:5

is a clue to make Musl-libc and compiling for Alpine Linux prime suspect.

Advice: Do a websearch on musl-libc alpine memchr strlen.

jsarenik commented 3 years ago

Thank you @stappersg! Problem fixed.

I had fe80::aa20:66ff:fe3f:1909 listed in clients and it is the link-local address of the host where I am moving radvd to now. After removing this address everything works well.

Thank you!

reubenhwk commented 3 years ago

Is there still a segfault in the code? Sounds like something needs to be fixed.

Sent from my iPhone

On May 2, 2021, at 5:42 AM, Ján Sáreník @.***> wrote:

 Thank you @stappersg! Problem fixed.

I had fe80::aa20:66ff:fe3f:1909 listed in clients and it is the link-local address of the host where I am moving radvd now. After removing this address everything works well.

Thank you!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

jsarenik commented 3 years ago

@reubenhwk Yes please. The code does not check if one of clients is our link-local address and segfaults probably when trying to send RA to this address.

It would be nice if radvd's config file check would complain about it.

stappersg commented 3 years ago

Patches welcome.

stappersg commented 3 years ago

In case that is too much effort in a near future, start with making a fresh issue about the idea this issue did bring.

jsarenik commented 3 years ago

In case that is too much effort in a near future, start with making a fresh issue about the idea this issue did bring.

@stappersg done: https://github.com/radvd-project/radvd/issues/158

Actually I have no idea how to fix it.