summaryrefslogtreecommitdiff
path: root/sbin/iked/policy.c
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2015-07-07 19:13:32 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2015-07-07 19:13:32 +0000
commit671b92a07833645621215afe7c48c04df7aee3d7 (patch)
tree204ba0341d25b1f37d5a28157000307392a1835a /sbin/iked/policy.c
parentb84cd61057b6917d36e95f086d16f10e988858bb (diff)
repair policy-ikesa-linking by replacing the broken RB_TREE w/TAILQ
(e.g. the policy might be used-after-free on 'ikectl reconfig') ok mikeb@
Diffstat (limited to 'sbin/iked/policy.c')
-rw-r--r--sbin/iked/policy.c52
1 files changed, 15 insertions, 37 deletions
diff --git a/sbin/iked/policy.c b/sbin/iked/policy.c
index 99e55dccf6b..86087ef2df7 100644
--- a/sbin/iked/policy.c
+++ b/sbin/iked/policy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: policy.c,v 1.36 2015/01/16 06:39:58 deraadt Exp $ */
+/* $OpenBSD: policy.c,v 1.37 2015/07/07 19:13:31 markus Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -214,6 +214,16 @@ policy_unref(struct iked *env, struct iked_policy *pol)
return;
if (--(pol->pol_refcnt) <= 0)
config_free_policy(env, pol);
+ else {
+ struct iked_sa *tmp;
+ int count = 0;
+
+ TAILQ_FOREACH(tmp, &pol->pol_sapeers, sa_peer_entry)
+ count++;
+ if (count != pol->pol_refcnt)
+ log_warnx("%s: ERROR pol %p pol_refcnt %d != count %d",
+ __func__, pol, pol->pol_refcnt, count);
+ }
}
void
@@ -332,9 +342,10 @@ sa_new(struct iked *env, u_int64_t ispi, u_int64_t rspi,
if (initiator && sa->sa_hdr.sh_rspi == 0 && rspi)
sa->sa_hdr.sh_rspi = rspi;
- if (sa->sa_policy == NULL)
+ if (sa->sa_policy == NULL) {
sa->sa_policy = pol;
- else
+ TAILQ_INSERT_TAIL(&pol->pol_sapeers, sa, sa_peer_entry);
+ } else
pol = sa->sa_policy;
sa->sa_statevalid = IKED_REQ_AUTH|IKED_REQ_AUTHVALID|IKED_REQ_SA;
@@ -401,15 +412,8 @@ sa_free_flows(struct iked *env, struct iked_saflows *head)
int
sa_address(struct iked_sa *sa, struct iked_addr *addr,
- struct sockaddr_storage *peer, int initiator)
+ struct sockaddr_storage *peer)
{
- struct iked_policy *pol = sa->sa_policy;
-
- if (sa->sa_state != IKEV2_STATE_CLOSING && pol == NULL) {
- log_debug("%s: missing policy", __func__);
- return (-1);
- }
-
bzero(addr, sizeof(*addr));
addr->addr_af = peer->ss_family;
addr->addr_port = htons(socket_getport((struct sockaddr *)peer));
@@ -418,15 +422,6 @@ sa_address(struct iked_sa *sa, struct iked_addr *addr,
log_debug("%s: invalid address", __func__);
return (-1);
}
-
- if (addr == &sa->sa_peer && pol) {
- /* XXX Re-insert node into the tree */
- RB_REMOVE(iked_sapeers, &pol->pol_sapeers, sa);
- memcpy(&sa->sa_polpeer, initiator ? &pol->pol_peer :
- &sa->sa_peer, sizeof(sa->sa_polpeer));
- RB_INSERT(iked_sapeers, &pol->pol_sapeers, sa);
- }
-
return (0);
}
@@ -519,22 +514,6 @@ sa_cmp(struct iked_sa *a, struct iked_sa *b)
return (0);
}
-struct iked_sa *
-sa_peer_lookup(struct iked_policy *pol, struct sockaddr_storage *peer)
-{
- struct iked_sa key;
-
- memcpy(&key.sa_polpeer.addr, peer, sizeof(*peer));
- return (RB_FIND(iked_sapeers, &pol->pol_sapeers, &key));
-}
-
-static __inline int
-sa_peer_cmp(struct iked_sa *a, struct iked_sa *b)
-{
- return (sockaddr_cmp((struct sockaddr *)&a->sa_polpeer.addr,
- (struct sockaddr *)&b->sa_polpeer.addr, -1));
-}
-
static __inline int
sa_addrpool_cmp(struct iked_sa *a, struct iked_sa *b)
{
@@ -603,7 +582,6 @@ flow_cmp(struct iked_flow *a, struct iked_flow *b)
}
RB_GENERATE(iked_sas, iked_sa, sa_entry, sa_cmp);
-RB_GENERATE(iked_sapeers, iked_sa, sa_peer_entry, sa_peer_cmp);
RB_GENERATE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
RB_GENERATE(iked_users, iked_user, usr_entry, user_cmp);
RB_GENERATE(iked_activesas, iked_childsa, csa_node, childsa_cmp);