git: e893ec49afb2 - releng/13.4 - pf: rework pf_icmp_state_lookup() failure mode
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 05 Sep 2024 07:35:39 UTC
The branch releng/13.4 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=e893ec49afb2caf05a2c28df4434905fa4213537 commit e893ec49afb2caf05a2c28df4434905fa4213537 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2024-08-30 11:36:39 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2024-09-05 07:35:12 +0000 pf: rework pf_icmp_state_lookup() failure mode If pf_icmp_state_lookup() finds a state but rejects it for not matching the expected direction we should unlock the state (and NULL out *state). This simplifies life for callers, and also ensures there's no confusion about what a non-NULL returned state means. Previously it could have been left in there by the caller, resulting in callers unlocking the same state twice. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") (cherry picked from commit 0578fe492284ded4745167060be794032e6e22f0) (cherry picked from commit d6e5f8643d37e925aa51fc8224cfc05aba0813f7) Approved-by: re (cperciva) --- sys/net/pfvar.h | 4 ++-- sys/netpfil/pf/pf.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index e6c2d1f290cf..66bdbf43e212 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -330,8 +330,8 @@ struct pfi_dynaddr { mtx_unlock(_s->lock); \ } while (0) #else -#define PF_STATE_LOCK(s) mtx_lock(s->lock) -#define PF_STATE_UNLOCK(s) mtx_unlock(s->lock) +#define PF_STATE_LOCK(s) mtx_lock((s)->lock) +#define PF_STATE_UNLOCK(s) mtx_unlock((s)->lock) #endif #ifdef INVARIANTS diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 9c1aa4d0a77a..ccd6b54f7b37 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6103,6 +6103,8 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, pf_print_state(*state); printf("\n"); } + PF_STATE_UNLOCK(*state); + *state = NULL; return (PF_DROP); } return (-1); @@ -6155,15 +6157,16 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 0); if (ret >= 0) { + MPASS(*state == NULL); if (ret == PF_DROP && pd->af == AF_INET6 && icmp_dir == PF_OUT) { - if (*state != NULL) - PF_STATE_UNLOCK((*state)); ret = pf_icmp_state_lookup(&key, pd, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 0); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } } else return (ret); } @@ -6570,8 +6573,10 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd2.dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } /* translate source/destination address, if necessary */ if ((*state)->key[PF_SK_WIRE] != @@ -6626,16 +6631,17 @@ pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, PF_ICMP_MULTI_NONE, 1); if (ret >= 0) { + MPASS(*state == NULL); if (ret == PF_DROP && pd2.af == AF_INET6 && icmp_dir == PF_OUT) { - if (*state != NULL) - PF_STATE_UNLOCK((*state)); ret = pf_icmp_state_lookup(&key, &pd2, state, m, off, pd->dir, kif, virtual_id, virtual_type, icmp_dir, &iidx, multi, 1); - if (ret >= 0) + if (ret >= 0) { + MPASS(*state == NULL); return (ret); + } } else return (ret); }