Skip to content

Commit

Permalink
pf: handle multiple IPv6 fragment headers
Browse files Browse the repository at this point in the history
With 'scrub fragment reassemble' if a packet contains multiple IPv6
fragment headers we would reassemble the packet and immediately
continue processing it.

That is, we'd remove the first fragment header and expect the next
header to be a final header (i.e. TCP, UDP, ICMPv6, ...). However, if
it's another fragment header we'd not treat the packet correctly.
That is, we'd fail to recognise the payload and treat it as if it were
an IPv6 fragment rather than as its actual payload.

Fix this by restarting the normalisation on the reassembled packet.
If there are multiple fragment headers drop the packet.

Reported by:	Enrico Bassetti bassetti@di.uniroma1.it (NetSecurityLab @ Sapienza University of Rome)
MFC after:	instant
Sponsored by:	Rubicon Communications, LLC ("Netgate")
  • Loading branch information
kprovost committed Aug 4, 2023
1 parent bbe017e commit 76afcbb
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion sys/netpfil/pf/pf_norm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,8 @@ pf_normalize_ip6(struct mbuf **m0, struct pfi_kkif *kif,
if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
goto drop;

again:
h = mtod(m, struct ip6_hdr *);
plen = ntohs(h->ip6_plen);
/* jumbo payload option not supported */
if (plen == 0)
Expand Down Expand Up @@ -1322,6 +1324,8 @@ pf_normalize_ip6(struct mbuf **m0, struct pfi_kkif *kif,
return (PF_PASS);

fragment:
if (pd->flags & PFDESC_IP_REAS)
return (PF_DROP);
if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
goto shortpkt;

Expand All @@ -1339,7 +1343,7 @@ pf_normalize_ip6(struct mbuf **m0, struct pfi_kkif *kif,
return (PF_DROP);

pd->flags |= PFDESC_IP_REAS;
return (PF_PASS);
goto again;

shortpkt:
REASON_SET(reason, PFRES_SHORT);
Expand Down

0 comments on commit 76afcbb

Please sign in to comment.