From ff80dd034a8ca73274b7861e1b3fc801c837a385 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Wed, 4 May 2022 19:53:12 +0000 Subject: [PATCH] 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 65839d1d31d..6b8d63b8bdc 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