On Mon, May 03, 2021 at 09:42:10AM -0600, Theo de Raadt wrote:
> You didn't use a -g binary as I suggested, then gdb will show more.
Apologies, I did compile with -g but since I cherry picked the source over
to the router (which is extremely low on space) it installed the binary in
the wrong spot and stripped it. Murphy's law I guess :-(.
So I finally compiled it with -ggdb and copied it right out of the obj to the
/usr/sbin. I now have a nice traceback for you all:
----------->
Loaded symbols for /usr/libexec/ld.so
#0 wg_print (bp=0x2c2d3d8044 "\004", length=Variable "length" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-wg.c:146
146 letoh32(data->receiver), letoh64(data->nonce));
(gdb) bt
#0 wg_print (bp=0x2c2d3d8044 "\004", length=Variable "length" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-wg.c:146
#1 0x00000027cd281880 in udp_print (bp=Variable "bp" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-udp.c:586
#2 0x00000027cd27d5f8 in ip_print (bp=Variable "bp" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-ip.c:394
#3 0x00000027cd27c4f8 in ether_encap_print (ethertype=Variable "ethertype" is n
ot available.
)
at /usr/src/usr.sbin/tcpdump/print-ether.c:228
#4 0x00000027cd27bf10 in ether_tryprint (p=Variable "p" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-ether.c:148
#5 0x00000027cd27bcc4 in ether_if_print (user=Variable "user" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-ether.c:100
#6 0x0000002cc2283f98 in pcap_read (p=0x2c2055ec00, cnt=-1,
callback=0x27cd27bc40 <ether_if_print>, user=0x0)
at /usr/src/lib/libpcap/pcap-bpf.c:188
----- cut -----
(gdb) down
#0 wg_print (bp=0x2c2d3d8044 "\004", length=Variable "length" is not available.
)
at /usr/src/usr.sbin/tcpdump/print-wg.c:146
146 letoh32(data->receiver), letoh64(data->nonce));
(gdb) print bp
$1 = (const u_char *) 0x2c2d3d8044 "\004"
(gdb) print data
$2 = (struct wg_data *) 0x2c2d3d8044
(gdb) print data->receiver
$3 = 3979343260
(gdb) print &data->receiver
$4 = (uint32_t *) 0x2c2d3d8048
(gdb) print data->nonce
$5 = 2017612633061982208
(gdb) print &data->nonce
$6 = (uint64_t *) 0x2c2d3d804c
I produced a patch for you, but it's not complete but works around the SIGBUS:
Index: print-wg.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-wg.c,v
retrieving revision 1.6
diff -u -p -u -r1.6 print-wg.c
--- print-wg.c 14 Apr 2021 19:34:56 -0000 1.6
+++ print-wg.c 3 May 2021 16:29:29 -0000
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stddef.h>
+#include <string.h>
#include "interface.h"
#include "extract.h"
@@ -104,6 +105,9 @@ wg_print(const u_char *bp, u_int length)
struct wg_data *data = (void *)bp;
u_int caplen;
+ uint32_t receiver;
+ uint64_t nonce;
+
caplen = snapend - bp;
if (caplen < sizeof(type))
goto trunc;
@@ -142,8 +146,12 @@ wg_print(const u_char *bp, u_int length)
printf("[wg] keepalive ");
if (caplen < offsetof(struct wg_data, mac))
goto trunc;
+
+ memcpy((void *)&receiver, (void *)&data->receiver,
sizeof(receiver));
+ memcpy((void *)&nonce, (void *)&data->nonce, sizeof(nonce));
+
printf("to 0x%08x nonce %llu",
- letoh32(data->receiver), letoh64(data->nonce));
+ letoh32(receiver), letoh64(nonce));
break;
}
return;
There may be other variables that need the same treatment... if that looks ok
for you I'll work on that and submit the patch formally.
Best Regards,
-peter
> Peter J. Philipp <[email protected]> wrote:
>
> > On Mon, May 03, 2021 at 08:27:57AM -0600, Theo de Raadt wrote:
> > > Can you reproduce this, and capture core files?
> >
> > Yes after a reboot I could reproduce it, I didn't even have to cycle the
> > interfaces. I got a coredump like you descriped for me. See below:
> >
> > > Since our tcpdump is a privsep program, getting a core is a bit harder.
> > >
> > > mkdir /var/crash/tcpdump
> > > echo kern.nosuidcoredump=3 >> /etc/sysctl.conf
> > > reboot
> > >
> > > You could recompile tcpdump with -g or -ggdb, to gain better symbols.
> > >
> > > If you manage to create a coredump, run gdb against the unstripped
> > > binary (src/usr.sbin/tcpdump/obj/tcpdump) and let's see what the trace is.
> >
> > Loaded symbols for /usr/libexec/ld.so
> > #0 0x00000032fd8d2f74 in wg_print () from /usr/sbin/tcpdump
> > (gdb) bt
> > #0 0x00000032fd8d2f74 in wg_print () from /usr/sbin/tcpdump
> > #1 0x00000032fd891880 in udp_print () from /usr/sbin/tcpdump
> > #2 0x00000032fd88d5f8 in ip_print () from /usr/sbin/tcpdump
> > #3 0x00000032fd88c4f8 in ether_encap_print () from /usr/sbin/tcpdump
> > #4 0x00000032fd88bf10 in ether_tryprint () from /usr/sbin/tcpdump
> > #5 0x00000032fd88bcc4 in ether_if_print () from /usr/sbin/tcpdump
> > #6 0x0000003766337f98 in pcap_read (p=0x37aa410e00, cnt=-1,
> > callback=0x32fd88bc40 <ether_if_print>, user=0x0)
> > at /usr/src/lib/libpcap/pcap-bpf.c:188
> > #7 0x00000037663359d4 in pcap_loop (p=0x37aa410e00, cnt=-1,
> > callback=0x32fd88bc40 <ether_if_print>, user=0x0)
> > at /usr/src/lib/libpcap/pcap.c:76
> > #8 0x00000032fd8818e8 in main () from /usr/sbin/tcpdump
> >
> > It looks like it's in wg_print() I looked at this, but was unable to find
> > a solution. Perhaps memcpy'ing bp in wg_print() to another aligned buffer
> > and then trying to get the values out of it. I spent days fixing my
> > programs
> > on octeon similar to that, but I used an unpack8, unpack16, unpack32,
> > unpack64
> > and unpack() to do so, which in the latter case memcpy'd. I know too little
> > though of how tcpdump is best worked with, just writing memcpy's in there is
> > probably not a good idea.
> >
> > Best Regards,
> > -peter
>