The branch main has been updated by mjg:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ff80dd034a8ca73274b7861e1b3fc801c837a385

commit ff80dd034a8ca73274b7861e1b3fc801c837a385
Author:     Mateusz Guzik <m...@freebsd.org>
AuthorDate: 2022-05-04 19:53:12 +0000
Commit:     Mateusz Guzik <m...@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

Reply via email to