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