From nobody Fri Jun 6 11:17:09 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bDJgV3nPBz5yC24; Fri, 06 Jun 2025 11:17:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bDJgV1CKBz3Jl7; Fri, 06 Jun 2025 11:17:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1749208630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wGP/M5h0Tc05N7bhC2ShZXyAZHPtQCPPaSF23BLwiE4=; b=FLMJVGdLpbKU1hzQXXoeQ+ZQddKDQyJlWRc8E/nmk5QCBxSlVdYAgYNGefFPtfeJOgeb6r pGWrbS5SMUEdVhXdxfs4wP5rKAlXRIPdR7+xpWjF/qmJR4wvcF+qsLYAhgbrinHI+Fbmjg rMB0Vwnh/bi7BQ95RJc9EnZDuSzmT2+H37OMLy2EnbLEkWxTYwqhzPg7wXtGD0ySXkl7c/ KjUph0PtKbL4epg5USyFDywtzwKNjxB7m93I9T+NQDltbbuJ8yGK0uXgz7/VjKJ77Ev3rg Qk0XNACc07UXcpj8IiX4OYRoLVRQn1X75j2XqxQD2yGe2+cTzbih7uWUUnqiJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1749208630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wGP/M5h0Tc05N7bhC2ShZXyAZHPtQCPPaSF23BLwiE4=; b=cGiuQM4maGn8fu7yKWZFFfB8u3K1oUlhWJWq2md/3RqhzlQrenKHZFHyQWiefN7KqFnvCw 5+x5knNgqcZHulHDOyVBIuUHLr44JALgnwdHGw2I+wohsPjTWjapkzrhvIzzkAYpOEKos3 DNr9BHsB/u6gsVqJX3fkCtB6nUQbWrzslTR2I7PgpjnOcpFU/7fs2BuInrKZoIZ4oXFuaG SQmiXegHgeB29v20lSGZMNzIfIJs/kiB8Mf0KF/vqQf7jq5XDFCGnNkFJddpV6hZcygM0G 5A6TtIz9WPwKv/eSlabYIbL3UIs1tFJ52mbbaFNKO2OLqxHi/PXKoAiTMSY8mg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1749208630; a=rsa-sha256; cv=none; b=s7YxYNcl7+/PZCmHHc/GdbO1UWm/6at8NftIbz931AKhA8wIZjk/6Ck+9lTUr/EQLrsGyT xH/H8vFGg1Z6n31iC/MRcmNxtF7SqhmDNaoqxQjDp2kzmWVEy09PUngBpzaK6kLkzu3mAg nVwzEhZxT6fKjZtcImSoaZ62D7oCKzB8uhxbQG4D8TF2sdMrEXLapAJQwOdqSwOnRidRAv JU/Jjq5nZbK10rrs9sLwmE3YvFyuRgi8MaCXuKjBqdyBx8Shi0pBUt+e+n/3Oa0dps6Gqk AmUcraLwJQVdgMgZD6sTTQ2MUtrn3QrNkiYlz1jCmLXEicjAI8hDLHYZtG65zw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bDJgV0ccwzsBM; Fri, 06 Jun 2025 11:17:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 556BH9Bx083577; Fri, 6 Jun 2025 11:17:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 556BH9h1083574; Fri, 6 Jun 2025 11:17:09 GMT (envelope-from git) Date: Fri, 6 Jun 2025 11:17:09 GMT Message-Id: <202506061117.556BH9h1083574@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 09d62e0658d1 - main - pf: align IPv4 and IPv6 AH header handling List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 09d62e0658d11cda80678bb9fc0ed5a48c0e838e Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=09d62e0658d11cda80678bb9fc0ed5a48c0e838e commit 09d62e0658d11cda80678bb9fc0ed5a48c0e838e Author: Kristof Provost AuthorDate: 2025-05-26 09:21:27 +0000 Commit: Kristof Provost CommitDate: 2025-06-06 11:15:59 +0000 pf: align IPv4 and IPv6 AH header handling Pf was handling IPv4 and IPv6 differently regarding AH extension headers. pf_walk_header6() steps over it and detects the real protocol. So to implement a minimal header walking function pf_walk_header() for IPv4. It does the header checks and jumps over AH. Then pf does not understand AH as a protocol, it is just an extension that authenticates the packet. Move some header and option checks to pf_walk_header() for consistency with IPv6. This also improves the header check for IPv4 packets in ICMP payload. OK henning@ Obtained from: OpenBSD, bluhm , 22ef11432c Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50657 --- sys/netpfil/pf/pf.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 4451cca76842..69a68d0249b2 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -372,6 +372,7 @@ static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, int, u_int16_t); static int pf_check_proto_cksum(struct mbuf *, int, int, u_int8_t, sa_family_t); +static int pf_walk_header(struct pf_pdesc *, struct ip *, u_short *); static int pf_walk_option6(struct pf_pdesc *, struct ip6_hdr *, int, int, u_short *); static int pf_walk_header6(struct pf_pdesc *, struct ip6_hdr *, @@ -7911,9 +7912,10 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, } /* offset of protocol header that follows h2 */ - pd2.off = ipoff2 + (h2.ip_hl << 2); + pd2.off = ipoff2; + if (pf_walk_header(&pd2, &h2, reason) != PF_PASS) + return (PF_DROP); - pd2.proto = h2.ip_p; pd2.tot_len = ntohs(h2.ip_len); pd2.src = (struct pf_addr *)&h2.ip_src; pd2.dst = (struct pf_addr *)&h2.ip_dst; @@ -9689,6 +9691,44 @@ pf_dummynet_route(struct pf_pdesc *pd, struct pf_kstate *s, return (0); } +static int +pf_walk_header(struct pf_pdesc *pd, struct ip *h, u_short *reason) +{ + struct ip6_ext ext; + u_int32_t hlen, end; + + hlen = h->ip_hl << 2; + if (hlen < sizeof(struct ip) || hlen > ntohs(h->ip_len)) { + REASON_SET(reason, PFRES_SHORT); + return (PF_DROP); + } + end = pd->off + ntohs(h->ip_len); + pd->off += hlen; + pd->proto = h->ip_p; + /* stop walking over non initial fragments */ + if ((h->ip_off & htons(IP_OFFMASK)) != 0) + return (PF_PASS); + for (;;) { + switch (pd->proto) { + case IPPROTO_AH: + /* fragments may be short */ + if ((h->ip_off & htons(IP_MF | IP_OFFMASK)) != 0 && + end < pd->off + sizeof(ext)) + return (PF_PASS); + if (!pf_pull_hdr(pd->m, pd->off, &ext, sizeof(ext), + NULL, reason, AF_INET)) { + DPFPRINTF(PF_DEBUG_MISC, ("IP short exthdr")); + return (PF_DROP); + } + pd->off += (ext.ip6e_len + 2) * 4; + pd->proto = ext.ip6e_nxt; + break; + default: + return (PF_PASS); + } + } +} + #ifdef INET6 static int pf_walk_option6(struct pf_pdesc *pd, struct ip6_hdr *h, int off, int end, @@ -9936,18 +9976,22 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, *m0 = pd->m; h = mtod(pd->m, struct ip *); - pd->off = h->ip_hl << 2; - if (pd->off < (int)sizeof(*h)) { + if (pd->m->m_pkthdr.len < ntohs(h->ip_len)) { *action = PF_DROP; REASON_SET(reason, PFRES_SHORT); return (-1); } + + if (pf_walk_header(pd, h, reason) != PF_PASS) { + *action = PF_DROP; + return (-1); + } + pd->src = (struct pf_addr *)&h->ip_src; pd->dst = (struct pf_addr *)&h->ip_dst; PF_ACPY(&pd->osrc, pd->src, af); PF_ACPY(&pd->odst, pd->dst, af); pd->ip_sum = &h->ip_sum; - pd->virtual_proto = pd->proto = h->ip_p; pd->tos = h->ip_tos & ~IPTOS_ECN_MASK; pd->ttl = h->ip_ttl; pd->tot_len = ntohs(h->ip_len); @@ -9957,8 +10001,8 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, if (h->ip_hl > 5) /* has options */ pd->badopts++; - if (h->ip_off & htons(IP_MF | IP_OFFMASK)) - pd->virtual_proto = PF_VPROTO_FRAGMENT; + pd->virtual_proto = (h->ip_off & htons(IP_MF | IP_OFFMASK)) ? + PF_VPROTO_FRAGMENT : pd->proto; break; } @@ -9978,7 +10022,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, } h = mtod(pd->m, struct ip6_hdr *); - pd->off = 0; + if (pf_walk_header6(pd, h, reason) != PF_PASS) { *action = PF_DROP; return (-1); @@ -9993,11 +10037,10 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0, pd->tos = IPV6_DSCP(h); pd->ttl = h->ip6_hlim; pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); - pd->virtual_proto = pd->proto = h->ip6_nxt; pd->act.rtableid = -1; - if (pd->fragoff != 0) - pd->virtual_proto = PF_VPROTO_FRAGMENT; + pd->virtual_proto = (pd->fragoff != 0) ? + PF_VPROTO_FRAGMENT : pd->proto; /* * we do not support jumbogram. if we keep going, zero ip6_plen