Skip to content

Commit

Permalink
pf: copy out rather than m_pullup() in pf_test_eth_rule()
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kprovost committed Jun 22, 2022
1 parent 028065f commit 38ca787
Showing 1 changed file with 8 additions and 20 deletions.
28 changes: 8 additions & 20 deletions sys/netpfil/pf/pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3820,6 +3820,8 @@ pf_match_eth_addr(const uint8_t *a, const struct pf_keth_rule_addr *r)
static int
pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
{
struct ip ip;
struct ip6_hdr ip6;
struct mbuf *m = *m0;
struct ether_header *e;
struct pf_keth_rule *r, *rm, *a = NULL;
Expand Down Expand Up @@ -3862,31 +3864,17 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)

switch (proto) {
case ETHERTYPE_IP: {
struct ip *ip;
m = m_pullup(m, sizeof(struct ether_header) +
sizeof(struct ip));
if (m == NULL) {
*m0 = NULL;
return (PF_DROP);
}
m_copydata(m, sizeof(struct ether_header), sizeof(ip), (caddr_t)&ip);
af = AF_INET;
ip = mtodo(m, sizeof(struct ether_header));
src = (struct pf_addr *)&ip->ip_src;
dst = (struct pf_addr *)&ip->ip_dst;
src = (struct pf_addr *)&ip.ip_src;
dst = (struct pf_addr *)&ip.ip_dst;
break;
}
case ETHERTYPE_IPV6: {
struct ip6_hdr *ip6;
m = m_pullup(m, sizeof(struct ether_header) +
sizeof(struct ip6_hdr));
if (m == NULL) {
*m0 = NULL;
return (PF_DROP);
}
m_copydata(m, sizeof(struct ether_header), sizeof(ip6), (caddr_t)&ip6);
af = AF_INET6;
ip6 = mtodo(m, sizeof(struct ether_header));
src = (struct pf_addr *)&ip6->ip6_src;
dst = (struct pf_addr *)&ip6->ip6_dst;
src = (struct pf_addr *)&ip6.ip6_src;
dst = (struct pf_addr *)&ip6.ip6_dst;
break;
}
}
Expand Down

0 comments on commit 38ca787

Please sign in to comment.