git: b4d2c9835c0e - main - pf: check AH header length.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 12 Oct 2026 16:06:00 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=b4d2c9835c0edfddd1d6742afa86d4873ccfad16
commit b4d2c9835c0edfddd1d6742afa86d4873ccfad16
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2026-10-12 12:28:22 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-10-12 13:08:59 +0000
pf: check AH header length.
pf_walk_header() advances the packet offset for each AH extension
header. It was not checked that this does not exceed the packet
length if no next header was processed. Fix it like in IPv6.
OK henning@ sashan@
MFC after: 1 week
Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, fcd4e5522e
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 46f9f044accb..dffaabf77434 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -10825,7 +10825,7 @@ static int
pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
{
struct ah ext;
- u_int32_t hlen, end;
+ u_int32_t hlen, end, extlen;
int hdr_cnt;
hlen = h->ip_hl << 2;
@@ -10873,7 +10873,16 @@ pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason)
DPFPRINTF(PF_DEBUG_MISC, "IP short exthdr");
return (PF_DROP);
}
- pd->off += (ext.ah_len + 2) * 4;
+ extlen = (ext.ah_len + 2) * 4;
+ if (end < pd->off + extlen) {
+ if ((h->ip_off & htons(IP_MF | IP_OFFMASK))
+ != 0)
+ return (PF_PASS);
+ DPFPRINTF(PF_DEBUG_MISC, "IP long exthdr");
+ REASON_SET(reason, PFRES_SHORT);
+ return (PF_DROP);
+ }
+ pd->off += extlen;
pd->proto = ext.ah_nxt;
break;
default: