https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=212873

            Bug ID: 212873
           Summary: pf kernel abort at boot in pf_purge_expired_fragments
           Product: Base System
           Version: CURRENT
          Hardware: arm
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: p-fbsd-b...@ziemba.us

My analysis: it looks as if there is a null pointer dereference inside
TAILQ_LAST on line 225 of pf_norm.c.

Version:

I obtained sources 15 Sep 2016 14:38 PDT via svn from
https://svn0.us-west.freebsd.org/base/head and built with crochet, resulting in
FreeBSD-armv6-12.0-RPI2-305849.img.

Hardware:

Raspberry PI 2

Conditions:

1. There is no pf.conf file
2. pf_enable="YES" in rc.conf
3. pflog_enable="YES" in rc.conf
4. ue1 not attached to USB (i.e., presence/absence made no difference)
5. ue0 is the onboard usb ethernet

Here is /etc/rc.conf:

---- start /etc/rc.conf ----
hostname="bogart.ziemba.us"
defaultrouter="10.0.0.1"
ifconfig_ue0="inet 10.0.0.84/16"
ifconfig_ue1="inet 192.168.0.2/24 fib 1"
ifconfig_DEFAULT="DHCP"

vlans_ue0="101"
create_args_ue0_101="fib 1"
ifconfig_ue0_101="inet 10.126.0.3/16 fib 1"
static_routes="fib1default"
route_fib1default="default 10.126.0.2 -fib 1"

dhcpd_enable="YES"
dhcpd_conf="/usr/local/etc/dhcpd.conf"
dhcpd_ifaces=""
dhcpd_withumask="022"

sshd_enable="YES"
inetd_enable="YES"

sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

growfs_enable="YES"

fsck_y_enable="YES"
saver="blank"
ntpd_enable="YES"
ntpd_sync_on_start="YES"

# NO /etc/pf.conf is present for this test
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
# uncommenting the following two lines results in failure at boot
#pflog_enable="YES"
#pflog_logfile="/tmp/pflog"
---- end /etc/rc.conf ----


At boot, the console displays the following (hand-transcribed, it should be
character-for-character correct):

---- begin console transcription ----
Kernel page fault with the following non-sleepable locks held:
exclusive sleep mutex pf fragments (pf fragments) r = 0 (0xc4e03808) locked 0
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm.c:224
stack backtrace:
Fatal kernel mode data abort: 'Translation Fault (L1)' on read
trapframe: 0xeb4c2d40
FSR=00000005, FAR=00000004, spsr=80000013
r0 =00000000, r1 =00000001, r2 =ffffffff, r3 =c087b774
r4 =0000000f, r5 =c4df839a, r6 =c4e03800, r7 =00000000
r8 =c4e0343c, r9 =c4e03458, r10=00000000, r11=eb4c2df0
r12=c4e03808, ssp=eb4c2dd0, slr=c02a6514, pc =c4deb88c

[ thread pid 358 tid 100084 ]
Stopped at      pf_purge_expired_fragments+0x44:       ldr    r0, [r0, #0x004]
db>
---- end console transcription ----

Note that r0 is NULL.

Typing on my USB keyboard does not produce anything at the db> prompt, and I
don't have a serial console yet (awaiting special rpi cable in the mail), so I
haven't been able to interact with the debugger.

Here is the output of objdump:

---- from objdump output start ----
00024848 <pf_purge_expired_fragments>:
pf_purge_expired_fragments():
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm
.c:219
        return (0);
}

void
pf_purge_expired_fragments(void)
{
        struct pf_fragment      *frag;
        u_int32_t                expire = time_uptime -
   24864:       e5904000        ldr     r4, [r0]
   24868:       e5900004        ldr     r0, [r0, #4]
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm.c:222
                                    V_pf_default_rule.timeout[PFTM_FRAG];
   2486c:       e59f00ac        ldr     r0, [pc, #172]  ; 24920
<pf_purge_expired_fragments+0xd8>
   24870:       e59072a4        ldr     r7, [r0, #676]
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm.c:224

        PF_FRAG_LOCK();
   24874:       e59f00a8        ldr     r0, [pc, #168]  ; 24924
<pf_purge_expired_fragments+0xdc>
   24878:       e2800010        add     r0, r0, #16     ; 0x10
   2487c:       e58d0000        str     r0, [sp]
   24880:       ebff810d        bl      4cbc <pf_addr_cmp-0x228>
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm.c:225
        while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) {
   24884:       e59f60a0        ldr     r6, [pc, #160]  ; 2492c
<pf_purge_expired_fragments+0xe4>
   24888:       e5960004        ldr     r0, [r6, #4]
   2488c:       e5900004        ldr     r0, [r0, #4]
   24890:       e5905000        ldr     r5, [r0]
   24894:       e3550000        cmp     r5, #0  ; 0x0
   24898:       0a000018        beq     24900 <pf_purge_expired_fragments+0xb8>
/v2/Source/public/freebsd/pi/crochet/src/sys/modules/pf/../../netpfil/pf/pf_norm.c:221
---- from objdump output end ----

Here is the relevant bit of sys/queue.h:

---- from sys/queue.h start ----
#define TAILQ_LAST(head, headname)                                      \
        (*(((struct headname *)((head)->tqh_last))->tqh_last))
---- from sys/queue.h end ----

1. The console message indicates stop at pf_purge_expired_fragments+0x44,
   which is 0x24848 + 0x44 = 8x2488c

2. The various LDRs at 24884 - 24890 are the dereferences in the
   TAILQ_LAST macro.

3. 24894 is the NULL test called out in the C code at line 225, but it's
   too late by then.

-- 
You are receiving this mail because:
You are the assignee for the bug.
_______________________________________________
freebsd-bugs@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to