Skip to content

Commit 38ca787

Browse files
committed
pf: copy out rather than m_pullup() in pf_test_eth_rule()
Don't change the mbuf chain layout. We've encountered alignment issues in the tcp syncookie code on armv7, which appear to result from the m_pullup() here. eg: Kernel page fault with the following non-sleepable locks held: exclusive sleep mutex tcp_sc_head (tcp_sc_head) r = 0 (0xdbfc4058) locked @ /usr/src/sys/netinet/tcp_syncache.c:534 exclusive rw tcpinp (tcpinp) r = 0 (0xded8ee28) locked @ /usr/src/sys/netinet/in_pcb.c:2436 stack backtrace: #0 0xc0421480 at witness_debugger+0x6c #1 0xc0422514 at witness_warn+0x430 #2 0xc07d8830 at abort_handler+0x1d8 #3 0xc07bb1cc at exception_exit+0 #4 0xc06320bc at syncookie_lookup+0x4c #5 0xc0630cb0 at syncache_expand+0xc4 #6 0xc061be00 at tcp_input+0x11b0 #7 0xc058f8b4 at ip_input+0x264 #8 0xc04f5ca8 at netisr_dispatch_src+0xec #9 0xc04d39e8 at ether_demux+0x204 #10 0xc04d5088 at ether_nh_input+0x3e8 #11 0xc04f5ca8 at netisr_dispatch_src+0xec #12 0xc04d3f10 at ether_input+0xfc #13 0xc07fa750 at mvneta_rxtxth_intr+0x2b4 #14 0xc037f784 at ithread_loop+0x1cc #15 0xc037c4c8 at fork_exit+0xa0 #16 0xc07bb15c at swi_exit+0 Fatal kernel mode data abort: 'Alignment Fault' on read trapframe: 0xc7d28980 FSR=00000001, FAR=dbf7886e, spsr=60000013 r0 =00000025, r1 =00000001, r2 =c7d2894c, r3 =60000013 r4 =c7d28a58, r5 =c7d28bc8, r6 =dbf7886a, r7 =dbfc4058 r8 =dbfc4058, r9 =c7d28b98, r10=c7d28bfc, r11=c7d28a30 r12=20000000, ssp=c7d28a10, slr=c06320bc, pc =c06320bc Redmine: 8287
1 parent 028065f commit 38ca787

File tree

1 file changed

+8
-20
lines changed

1 file changed

+8
-20
lines changed

sys/netpfil/pf/pf.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,6 +3820,8 @@ pf_match_eth_addr(const uint8_t *a, const struct pf_keth_rule_addr *r)
38203820
static int
38213821
pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
38223822
{
3823+
struct ip ip;
3824+
struct ip6_hdr ip6;
38233825
struct mbuf *m = *m0;
38243826
struct ether_header *e;
38253827
struct pf_keth_rule *r, *rm, *a = NULL;
@@ -3862,31 +3864,17 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
38623864

38633865
switch (proto) {
38643866
case ETHERTYPE_IP: {
3865-
struct ip *ip;
3866-
m = m_pullup(m, sizeof(struct ether_header) +
3867-
sizeof(struct ip));
3868-
if (m == NULL) {
3869-
*m0 = NULL;
3870-
return (PF_DROP);
3871-
}
3867+
m_copydata(m, sizeof(struct ether_header), sizeof(ip), (caddr_t)&ip);
38723868
af = AF_INET;
3873-
ip = mtodo(m, sizeof(struct ether_header));
3874-
src = (struct pf_addr *)&ip->ip_src;
3875-
dst = (struct pf_addr *)&ip->ip_dst;
3869+
src = (struct pf_addr *)&ip.ip_src;
3870+
dst = (struct pf_addr *)&ip.ip_dst;
38763871
break;
38773872
}
38783873
case ETHERTYPE_IPV6: {
3879-
struct ip6_hdr *ip6;
3880-
m = m_pullup(m, sizeof(struct ether_header) +
3881-
sizeof(struct ip6_hdr));
3882-
if (m == NULL) {
3883-
*m0 = NULL;
3884-
return (PF_DROP);
3885-
}
3874+
m_copydata(m, sizeof(struct ether_header), sizeof(ip6), (caddr_t)&ip6);
38863875
af = AF_INET6;
3887-
ip6 = mtodo(m, sizeof(struct ether_header));
3888-
src = (struct pf_addr *)&ip6->ip6_src;
3889-
dst = (struct pf_addr *)&ip6->ip6_dst;
3876+
src = (struct pf_addr *)&ip6.ip6_src;
3877+
dst = (struct pf_addr *)&ip6.ip6_dst;
38903878
break;
38913879
}
38923880
}

0 commit comments

Comments
 (0)