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 */
|
||||
|
||||
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
|
||||
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)
|
||||
return (EINVAL);
|
||||
tree = malloc(sizeof(struct pf_krule_global), M_TEMP, M_NOWAIT);
|
||||
tree = pf_rule_tree_alloc(M_NOWAIT);
|
||||
if (tree == NULL)
|
||||
return (ENOMEM);
|
||||
RB_INIT(tree);
|
||||
rs = pf_find_or_create_kruleset(anchor);
|
||||
if (rs == NULL) {
|
||||
free(tree, M_TEMP);
|
||||
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;
|
||||
|
||||
while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
|
||||
@ -3455,6 +3473,22 @@ DIOCGETRULENV_error:
|
||||
if (rs_num >= PF_RULESET_MAX)
|
||||
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) {
|
||||
pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
|
||||
ERROUT(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user