pf: avoid use-after-free on reassembly

Ensure we update the mbuf pointer returned by pf_normalize_ip() or
pf_normalize_ip6() even if they fail.
Otherwise we'd risk using a freed mbuf.

PR:             283705
Reported by:    Yichen Chai <yichen.chai@gmail.com>, Zhuo Ying Jiang Li <zyj20@cl.cam.ac.uk>
Sponsored by:   Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 5d28f4cab8d5919aba1365e885a91a96c0655b59)
This commit is contained in:
Kristof Provost 2025-01-06 21:08:04 +01:00 committed by Franco Fichtner
parent 063f4fdfc9
commit 9a175a2dc0

View File

@ -8379,6 +8379,7 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
if (mtag != NULL)
m_tag_delete(m, mtag);
} else if (pf_normalize_ip(m0, kif, &reason, &pd) != PF_PASS) {
m = *m0;
/* We do IP header normalization and packet reassembly here */
action = PF_DROP;
goto done;
@ -8584,6 +8585,10 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0,
done:
PF_RULES_RUNLOCK();
if (m == NULL)
goto out;
if (action == PF_PASS && h->ip_hl > 5 &&
!((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
action = PF_DROP;
@ -8927,6 +8932,7 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
/* We do IP header normalization and packet reassembly here */
if (pf_normalize_ip6(m0, kif, &reason, &pd) != PF_PASS) {
m = *m0;
action = PF_DROP;
goto done;
}
@ -9196,6 +9202,9 @@ done:
n = NULL;
}
if (m == NULL)
goto out;
/* handle dangerous IPv6 extension headers. */
if (action == PF_PASS && rh_cnt &&
!((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {