pf: make sure the rule tree is allocated in DIOCCHANGERULE
Original patch by: peter Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
parent
81ffb45f02
commit
a3d9740825
@ -1152,6 +1152,25 @@ out:
|
|||||||
}
|
}
|
||||||
#endif /* ALTQ */
|
#endif /* ALTQ */
|
||||||
|
|
||||||
|
static struct pf_krule_global *
|
||||||
|
pf_rule_tree_alloc(int flags)
|
||||||
|
{
|
||||||
|
struct pf_krule_global *tree;
|
||||||
|
|
||||||
|
tree = malloc(sizeof(struct pf_krule_global), M_TEMP, flags);
|
||||||
|
if (tree == NULL)
|
||||||
|
return (NULL);
|
||||||
|
RB_INIT(tree);
|
||||||
|
return (tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pf_rule_tree_free(struct pf_krule_global *tree)
|
||||||
|
{
|
||||||
|
|
||||||
|
free(tree, M_TEMP);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
|
pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
|
||||||
{
|
{
|
||||||
@ -1163,16 +1182,15 @@ pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
|
|||||||
|
|
||||||
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
|
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
tree = malloc(sizeof(struct pf_krule_global), M_TEMP, M_NOWAIT);
|
tree = pf_rule_tree_alloc(M_NOWAIT);
|
||||||
if (tree == NULL)
|
if (tree == NULL)
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
RB_INIT(tree);
|
|
||||||
rs = pf_find_or_create_kruleset(anchor);
|
rs = pf_find_or_create_kruleset(anchor);
|
||||||
if (rs == NULL) {
|
if (rs == NULL) {
|
||||||
free(tree, M_TEMP);
|
free(tree, M_TEMP);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
free(rs->rules[rs_num].inactive.tree, M_TEMP);
|
pf_rule_tree_free(rs->rules[rs_num].inactive.tree);
|
||||||
rs->rules[rs_num].inactive.tree = tree;
|
rs->rules[rs_num].inactive.tree = tree;
|
||||||
|
|
||||||
while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
|
while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
|
||||||
@ -3455,6 +3473,22 @@ DIOCGETRULENV_error:
|
|||||||
if (rs_num >= PF_RULESET_MAX)
|
if (rs_num >= PF_RULESET_MAX)
|
||||||
ERROUT(EINVAL);
|
ERROUT(EINVAL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXXMJG: there is no guarantee that the ruleset was
|
||||||
|
* created by the usual route of calling DIOCXBEGIN.
|
||||||
|
* As a result it is possible the rule tree will not
|
||||||
|
* be allocated yet. Hack around it by doing it here.
|
||||||
|
* Note it is fine to let the tree persist in case of
|
||||||
|
* error as it will be freed down the road on future
|
||||||
|
* updates (if need be).
|
||||||
|
*/
|
||||||
|
if (ruleset->rules[rs_num].active.tree == NULL) {
|
||||||
|
ruleset->rules[rs_num].active.tree = pf_rule_tree_alloc(M_NOWAIT);
|
||||||
|
if (ruleset->rules[rs_num].active.tree == NULL) {
|
||||||
|
ERROUT(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pcr->action == PF_CHANGE_GET_TICKET) {
|
if (pcr->action == PF_CHANGE_GET_TICKET) {
|
||||||
pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
|
pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
|
||||||
ERROUT(0);
|
ERROUT(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user