[Bug 212873] pf kernel abort at boot in pf_purge_expired_fragments
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Wed Sep 21 04:24:47 UTC 2016
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 at FreeBSD.org
Reporter: p-fbsd-bugs at 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.
More information about the freebsd-bugs
mailing list