The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=6efe8e6be4135643d8283fcb6773da641326f427
commit 6efe8e6be4135643d8283fcb6773da641326f427 Author: Mark Johnston <ma...@freebsd.org> AuthorDate: 2025-07-27 13:23:22 +0000 Commit: Mark Johnston <ma...@freebsd.org> CommitDate: 2025-07-28 15:40:20 +0000 pf: Fix a lock leak in pf_ioctl_addrule() The ERROUT macro assumes that the rules lock is held, but some error paths arise before that lock is acquired. Introduce ERROUT_UNLOCKED for that case. Reviewed by: kp Reported by: syzkaller Fixes: cc68decda316 ("pf: Reject rules with invalid port ranges") Differential Revision: https://reviews.freebsd.org/D51571 --- sys/amd64/conf/SYZKALLER | 5 +++++ sys/netpfil/pf/pf_ioctl.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/amd64/conf/SYZKALLER b/sys/amd64/conf/SYZKALLER new file mode 100644 index 000000000000..49059302793b --- /dev/null +++ b/sys/amd64/conf/SYZKALLER @@ -0,0 +1,5 @@ +include GENERIC +ident SYZKALLER + +options COVERAGE +options KCOV diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index ea9f7fe441c6..9abc07c36788 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2092,19 +2092,18 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, int rs_num; int error = 0; - if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) { - error = EINVAL; - goto errout_unlocked; - } +#define ERROUT(x) ERROUT_FUNCTION(errout, x) +#define ERROUT_UNLOCKED(x) ERROUT_FUNCTION(errout_unlocked, x) -#define ERROUT(x) ERROUT_FUNCTION(errout, x) + if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) + ERROUT_UNLOCKED(EINVAL); if ((error = pf_rule_checkaf(rule))) - ERROUT(error); + ERROUT_UNLOCKED(error); if (pf_validate_range(rule->src.port_op, rule->src.port)) - ERROUT(EINVAL); + ERROUT_UNLOCKED(EINVAL); if (pf_validate_range(rule->dst.port_op, rule->dst.port)) - ERROUT(EINVAL); + ERROUT_UNLOCKED(EINVAL); if (rule->ifname[0]) kif = pf_kkif_create(M_WAITOK); @@ -2294,6 +2293,7 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket, return (0); #undef ERROUT +#undef ERROUT_UNLOCKED errout: PF_RULES_WUNLOCK(); PF_CONFIG_UNLOCK();