git: ff80dd034a8c - main - pf: fix DIOCCHANGERULE after pf config and rb tree of rules
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 10 May 2022 21:17:06 UTC
The branch main has been updated by mjg:
URL: https://cgit.FreeBSD.org/src/commit/?id=ff80dd034a8ca73274b7861e1b3fc801c837a385
commit ff80dd034a8ca73274b7861e1b3fc801c837a385
Author: Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-05-04 19:53:12 +0000
Commit: Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-05-10 21:16:47 +0000
pf: fix DIOCCHANGERULE after pf config and rb tree of rules
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf_ioctl.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 65839d1d31d9..6b8d63b8bdce 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -3432,6 +3432,7 @@ DIOCGETRULENV_error:
}
#define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x)
+ PF_CONFIG_LOCK();
PF_RULES_WLOCK();
#ifdef PF_WANT_32_TO_64_COUNTER
if (newrule != NULL) {
@@ -3540,6 +3541,7 @@ DIOCGETRULENV_error:
if (error) {
pf_free_rule(newrule);
PF_RULES_WUNLOCK();
+ PF_CONFIG_UNLOCK();
break;
}
@@ -3562,6 +3564,7 @@ DIOCGETRULENV_error:
if (newrule != NULL)
pf_free_rule(newrule);
PF_RULES_WUNLOCK();
+ PF_CONFIG_UNLOCK();
error = EINVAL;
break;
}
@@ -3570,8 +3573,20 @@ DIOCGETRULENV_error:
if (pcr->action == PF_CHANGE_REMOVE) {
pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
oldrule);
+ RB_REMOVE(pf_krule_global,
+ ruleset->rules[rs_num].active.tree, oldrule);
ruleset->rules[rs_num].active.rcount--;
} else {
+ pf_hash_rule(newrule);
+ if (RB_INSERT(pf_krule_global,
+ ruleset->rules[rs_num].active.tree, newrule) != NULL) {
+ pf_free_rule(newrule);
+ PF_RULES_WUNLOCK();
+ PF_CONFIG_UNLOCK();
+ error = EEXIST;
+ break;
+ }
+
if (oldrule == NULL)
TAILQ_INSERT_TAIL(
ruleset->rules[rs_num].active.ptr,
@@ -3597,6 +3612,7 @@ DIOCGETRULENV_error:
pf_remove_if_empty_kruleset(ruleset);
PF_RULES_WUNLOCK();
+ PF_CONFIG_UNLOCK();
break;
#undef ERROUT