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:		cc68decda3 ("pf: Reject rules with invalid port ranges")
Differential Revision:	https://reviews.freebsd.org/D51571
This commit is contained in:
Mark Johnston committed 2025-07-28 15:40:20 +00:00
1 parent e40a2c4927
commit 6efe8e6be4
2 files changed
+13 -8

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
include GENERIC
ident SYZKALLER
options COVERAGE
options KCOV
+8 -8
View File
@@ -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();