Date: Thu, 23 Jul 2026 12:41:13 +0000 From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 850041b02548 - main - pf: include direction in fragment key Message-ID: <6a620be9.1e608.63f7d9a6@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=850041b025486614243fb2d481b3adb0382b02e7 commit 850041b025486614243fb2d481b3adb0382b02e7 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2026-07-22 15:13:51 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2026-07-23 11:27:30 +0000 pf: include direction in fragment key pf(4) currently ignores fragment direction (in vs. out) in pf_frnode_compare() function. Issue noticed and reported by Frank Denis OK @bluhm Obtained from: OpenBSD, sashan <sashan@openbsd.org>, eaa2c80721 Sponsored by: Rubicon Communications, LLC ("Netgate") --- sys/netpfil/pf/pf_norm.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 348c1cafbd49..45463fc7b6d8 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -82,6 +82,7 @@ struct pf_frnode { struct pf_addr fn_dst; /* ip destination address */ sa_family_t fn_af; /* address family */ u_int8_t fn_proto; /* protocol for fragments in fn_tree */ + u_int8_t fn_direction; /* pf packet direction */ u_int32_t fn_fragments; /* number of entries in fn_tree */ RB_ENTRY(pf_frnode) fn_entry; @@ -155,22 +156,23 @@ static struct pf_fragment *pf_fillup_fragment(struct pf_frnode *, u_int32_t, struct pf_frent *, u_short *); static struct mbuf *pf_join_fragment(struct pf_fragment *); #ifdef INET -static int pf_reassemble(struct mbuf **, u_short *); +static int pf_reassemble(struct mbuf **, uint8_t, u_short *); #endif /* INET */ #ifdef INET6 static int pf_reassemble6(struct mbuf **, - struct ip6_frag *, uint16_t, uint16_t, u_short *); + struct ip6_frag *, uint16_t, uint16_t, uint8_t, u_short *); #endif /* INET6 */ #ifdef INET static void -pf_ip2key(struct ip *ip, struct pf_frnode *key) +pf_ip2key(struct ip *ip, struct pf_frnode *key, uint8_t dir) { key->fn_src.v4 = ip->ip_src; key->fn_dst.v4 = ip->ip_dst; key->fn_af = AF_INET; key->fn_proto = ip->ip_p; + key->fn_direction = dir; } #endif /* INET */ @@ -226,6 +228,8 @@ pf_frnode_compare(struct pf_frnode *a, struct pf_frnode *b) return (diff); if ((diff = a->fn_af - b->fn_af) != 0) return (diff); + if ((diff = a->fn_direction - b->fn_direction) != 0) + return (diff); if ((diff = pf_addr_cmp(&a->fn_src, &b->fn_src, a->fn_af)) != 0) return (diff); if ((diff = pf_addr_cmp(&a->fn_dst, &b->fn_dst, a->fn_af)) != 0) @@ -807,7 +811,7 @@ pf_join_fragment(struct pf_fragment *frag) #ifdef INET static int -pf_reassemble(struct mbuf **m0, u_short *reason) +pf_reassemble(struct mbuf **m0, uint8_t dir, u_short *reason) { struct mbuf *m = *m0; struct ip *ip = mtod(m, struct ip *); @@ -831,7 +835,7 @@ pf_reassemble(struct mbuf **m0, u_short *reason) frent->fe_off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3; frent->fe_mff = ntohs(ip->ip_off) & IP_MF; - pf_ip2key(ip, &key); + pf_ip2key(ip, &key, dir); if ((frag = pf_fillup_fragment(&key, ip->ip_id, frent, reason)) == NULL) return (PF_DROP); @@ -902,7 +906,7 @@ pf_reassemble(struct mbuf **m0, u_short *reason) #ifdef INET6 static int pf_reassemble6(struct mbuf **m0, struct ip6_frag *fraghdr, - uint16_t hdrlen, uint16_t extoff, u_short *reason) + uint16_t hdrlen, uint16_t extoff, uint8_t dir, u_short *reason) { struct mbuf *m = *m0; struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); @@ -936,6 +940,7 @@ pf_reassemble6(struct mbuf **m0, struct ip6_frag *fraghdr, key.fn_af = AF_INET6; /* Only the first fragment's protocol is relevant. */ key.fn_proto = 0; + key.fn_direction = dir; if ((frag = pf_fillup_fragment(&key, fraghdr->ip6f_ident, frent, reason)) == NULL) { PF_FRAG_UNLOCK(); @@ -1274,7 +1279,7 @@ pf_normalize_ip(u_short *reason, struct pf_pdesc *pd) PF_FRAG_LOCK(); DPFPRINTF(PF_DEBUG_MISC, "reass frag %d @ %d-%d", h->ip_id, fragoff, max); - verdict = pf_reassemble(&pd->m, reason); + verdict = pf_reassemble(&pd->m, pd->dir, reason); PF_FRAG_UNLOCK(); if (verdict != PF_PASS) @@ -1375,7 +1380,8 @@ pf_normalize_ip6(int off, u_short *reason, if (pd->virtual_proto == PF_VPROTO_FRAGMENT) { /* Returns PF_DROP or *m0 is NULL or completely reassembled * mbuf. */ - if (pf_reassemble6(&pd->m, &frag, off, pd->extoff, reason) != PF_PASS) + if (pf_reassemble6(&pd->m, &frag, off, pd->extoff, pd->dir, reason) + != PF_PASS) return (PF_DROP); if (pd->m == NULL) return (PF_DROP);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a620be9.1e608.63f7d9a6>
