Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140156552
D54292.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D54292.id.diff
View Options
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2087,19 +2087,20 @@
int
pf_ioctl_getrules(struct pfioc_rule *pr)
{
+ PF_RULES_RLOCK_TRACKER;
struct pf_kruleset *ruleset;
struct pf_krule *tail;
int rs_num;
- PF_RULES_WLOCK();
+ PF_RULES_RLOCK();
ruleset = pf_find_kruleset(pr->anchor);
if (ruleset == NULL) {
- PF_RULES_WUNLOCK();
+ PF_RULES_RUNLOCK();
return (EINVAL);
}
rs_num = pf_get_ruleset_number(pr->rule.action);
if (rs_num >= PF_RULESET_MAX) {
- PF_RULES_WUNLOCK();
+ PF_RULES_RUNLOCK();
return (EINVAL);
}
tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
@@ -2109,7 +2110,7 @@
else
pr->nr = 0;
pr->ticket = ruleset->rules[rs_num].active.ticket;
- PF_RULES_WUNLOCK();
+ PF_RULES_RUNLOCK();
return (0);
}
@@ -3692,6 +3693,7 @@
}
case DIOCGETRULENV: {
+ PF_RULES_RLOCK_TRACKER;
struct pfioc_nv *nv = (struct pfioc_nv *)addr;
nvlist_t *nvrule = NULL;
nvlist_t *nvl = NULL;
@@ -3702,6 +3704,13 @@
bool clear_counter = false;
#define ERROUT(x) ERROUT_IOCTL(DIOCGETRULENV_error, x)
+#define ERROUT_LOCKED(x) do { \
+ if (clear_counter) \
+ PF_RULES_WUNLOCK(); \
+ else \
+ PF_RULES_RUNLOCK(); \
+ ERROUT(x); \
+} while (0)
if (nv->len > pf_ioctl_maxcount)
ERROUT(ENOMEM);
@@ -3733,78 +3742,64 @@
nr = nvlist_get_number(nvl, "nr");
- PF_RULES_WLOCK();
+ if (clear_counter)
+ PF_RULES_WLOCK();
+ else
+ PF_RULES_RLOCK();
ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor"));
- if (ruleset == NULL) {
- PF_RULES_WUNLOCK();
- ERROUT(ENOENT);
- }
+ if (ruleset == NULL)
+ ERROUT_LOCKED(ENOENT);
rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset"));
- if (rs_num >= PF_RULESET_MAX) {
- PF_RULES_WUNLOCK();
- ERROUT(EINVAL);
- }
+ if (rs_num >= PF_RULESET_MAX)
+ ERROUT_LOCKED(EINVAL);
if (nvlist_get_number(nvl, "ticket") !=
- ruleset->rules[rs_num].active.ticket) {
- PF_RULES_WUNLOCK();
- ERROUT(EBUSY);
- }
+ ruleset->rules[rs_num].active.ticket)
+ ERROUT_LOCKED(EBUSY);
- if ((error = nvlist_error(nvl))) {
- PF_RULES_WUNLOCK();
- ERROUT(error);
- }
+ if ((error = nvlist_error(nvl)))
+ ERROUT_LOCKED(error);
rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
while ((rule != NULL) && (rule->nr != nr))
rule = TAILQ_NEXT(rule, entries);
- if (rule == NULL) {
- PF_RULES_WUNLOCK();
- ERROUT(EBUSY);
- }
+ if (rule == NULL)
+ ERROUT_LOCKED(EBUSY);
nvrule = pf_krule_to_nvrule(rule);
nvlist_destroy(nvl);
nvl = nvlist_create(0);
- if (nvl == NULL) {
- PF_RULES_WUNLOCK();
- ERROUT(ENOMEM);
- }
+ if (nvl == NULL)
+ ERROUT_LOCKED(ENOMEM);
nvlist_add_number(nvl, "nr", nr);
nvlist_add_nvlist(nvl, "rule", nvrule);
nvlist_destroy(nvrule);
nvrule = NULL;
- if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) {
- PF_RULES_WUNLOCK();
- ERROUT(EBUSY);
- }
+ if (pf_kanchor_nvcopyout(ruleset, rule, nvl))
+ ERROUT_LOCKED(EBUSY);
free(nvlpacked, M_NVLIST);
nvlpacked = nvlist_pack(nvl, &nv->len);
- if (nvlpacked == NULL) {
- PF_RULES_WUNLOCK();
- ERROUT(ENOMEM);
- }
+ if (nvlpacked == NULL)
+ ERROUT_LOCKED(ENOMEM);
- if (nv->size == 0) {
- PF_RULES_WUNLOCK();
- ERROUT(0);
- }
- else if (nv->size < nv->len) {
- PF_RULES_WUNLOCK();
- ERROUT(ENOSPC);
- }
+ if (nv->size == 0)
+ ERROUT_LOCKED(0);
+ else if (nv->size < nv->len)
+ ERROUT_LOCKED(ENOSPC);
- if (clear_counter)
+ if (clear_counter) {
pf_krule_clear_counters(rule);
-
- PF_RULES_WUNLOCK();
+ PF_RULES_WUNLOCK();
+ } else {
+ PF_RULES_RUNLOCK();
+ }
error = copyout(nvlpacked, nv->data, nv->len);
+#undef ERROUT_LOCKED
#undef ERROUT
DIOCGETRULENV_error:
free(nvlpacked, M_NVLIST);
diff --git a/sys/netpfil/pf/pf_nv.h b/sys/netpfil/pf/pf_nv.h
--- a/sys/netpfil/pf/pf_nv.h
+++ b/sys/netpfil/pf/pf_nv.h
@@ -78,7 +78,7 @@
int pf_check_rule_addr(const struct pf_rule_addr *);
-nvlist_t *pf_krule_to_nvrule(struct pf_krule *);
+nvlist_t *pf_krule_to_nvrule(const struct pf_krule *);
int pf_nvrule_to_krule(const nvlist_t *, struct pf_krule *);
int pf_nvstate_kill_to_kstate_kill(const nvlist_t *,
struct pf_kstate_kill *);
diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c
--- a/sys/netpfil/pf/pf_nv.c
+++ b/sys/netpfil/pf/pf_nv.c
@@ -684,7 +684,7 @@
}
nvlist_t *
-pf_krule_to_nvrule(struct pf_krule *rule)
+pf_krule_to_nvrule(const struct pf_krule *rule)
{
nvlist_t *nvl, *tmp;
u_int64_t src_nodes_total = 0;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 21, 11:13 PM (16 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27109718
Default Alt Text
D54292.id.diff (4 KB)
Attached To
Mode
D54292: pf: Avoid taking the pf rules write lock in a couple of ioctls
Attached
Detach File
Event Timeline
Log In to Comment