summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorsashan <sashan@cvs.openbsd.org>2015-07-19 23:13:59 +0000
committersashan <sashan@cvs.openbsd.org>2015-07-19 23:13:59 +0000
commit8c5b2644ab48a5945d85d411ec082a08b9766175 (patch)
treed67af3d5d7abfcb10a33950ee5e6b85fdfd40546 /sys/net/pf.c
parent73fc313f0793b90cee8af36317de5457b9342a6d (diff)
rule_item might leak, when pf_create_state() fails
OK @mcbride
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 89aa5d9021a..2c68f9f5738 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.931 2015/07/19 05:48:11 sashan Exp $ */
+/* $OpenBSD: pf.c,v 1.932 2015/07/19 23:13:58 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -3068,6 +3068,7 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
int state_icmp = 0, icmp_dir = 0;
u_int16_t virtual_type, virtual_id;
u_int8_t icmptype = 0, icmpcode = 0;
+ int action = PF_DROP;
bzero(&act, sizeof(act));
bzero(sns, sizeof(sns));
@@ -3351,7 +3352,6 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
if (pd->virtual_proto != PF_VPROTO_FRAGMENT
&& !state_icmp && r->keep_state) {
- int action;
if (r->rule_flag & PFRULE_SRCTRACK &&
pf_insert_src_node(&sns[PF_SN_NONE], r, PF_SN_NONE, pd->af,
@@ -3370,7 +3370,7 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
sm, tag, &rules, &act, sns);
if (action != PF_PASS)
- return (action);
+ goto cleanup;
if (sks != skw) {
struct pf_state_key *sk;
@@ -3428,7 +3428,7 @@ cleanup:
pool_put(&pf_rule_item_pl, ri);
}
- return (PF_DROP);
+ return (action);
}
static __inline int
@@ -3451,7 +3451,6 @@ pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule *a,
s->rule.ptr = r;
s->anchor.ptr = a;
s->natrule.ptr = nr;
- memcpy(&s->match_rules, rules, sizeof(s->match_rules));
if (r->allow_opts)
s->state_flags |= PFSTATE_ALLOWOPTS;
if (r->rule_flag & PFRULE_STATESLOPPY)
@@ -3580,6 +3579,11 @@ pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule *a,
} else
*sm = s;
+ /*
+ * Make state responsible for rules it binds here.
+ */
+ memcpy(&s->match_rules, rules, sizeof(s->match_rules));
+ bzero(rules, sizeof(*rules));
STATE_INC_COUNTERS(s);
if (tag > 0) {