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 <p...@delphinusdns.org> 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
> 

Reply via email to