diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-03-10 21:13:18 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-03-10 21:13:18 +0000 |
commit | 4e14ed7d5988837eeb94032fe124a1b85520ec03 (patch) | |
tree | ffc6833aecfde74251dbf03c47ecec9e89375595 /src | |
parent | c587052624be4219d869e38f45b9f00a4db3b4e9 (diff) | |
download | strongswan-4e14ed7d5988837eeb94032fe124a1b85520ec03.tar.bz2 strongswan-4e14ed7d5988837eeb94032fe124a1b85520ec03.tar.xz |
fixed a use-after-free bug in dpd_timeout()
Diffstat (limited to 'src')
-rw-r--r-- | src/pluto/connections.c | 2 | ||||
-rw-r--r-- | src/pluto/ipsec_doi.c | 19 | ||||
-rw-r--r-- | src/pluto/state.c | 9 |
3 files changed, 20 insertions, 10 deletions
diff --git a/src/pluto/connections.c b/src/pluto/connections.c index 941c6ad85..0dbabd9d6 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -2995,6 +2995,8 @@ terminate_connection(const char *nm) c->policy &= ~POLICY_UP; flush_pending_by_connection(c); delete_states_by_connection(c, FALSE); + if (c->kind == CK_INSTANCE) + delete_connection(c, FALSE); reset_cur_connection(); } c = n; diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c index d68000540..b59fe3c87 100644 --- a/src/pluto/ipsec_doi.c +++ b/src/pluto/ipsec_doi.c @@ -5592,6 +5592,7 @@ dpd_timeout(struct state *st) struct state *newest_phase1_st; struct connection *c = st->st_connection; int action = st->st_connection->dpd_action; + char cname[BUF_LEN]; passert(action == DPD_ACTION_HOLD || action == DPD_ACTION_CLEAR @@ -5622,20 +5623,30 @@ dpd_timeout(struct state *st) * leak traffic. Also, being in %trap means new packets will * force an initiation of the conn again. */ - loglog(RC_LOG_SERIOUS, "DPD: Putting connection into %%trap"); + loglog(RC_LOG_SERIOUS, "DPD: Putting connection \"%s\" into %%trap", c->name); + if (c->kind == CK_INSTANCE) + delete_connection(c, TRUE); break; case DPD_ACTION_CLEAR: /* dpdaction=clear - Wipe the SA & eroute - everything */ - loglog(RC_LOG_SERIOUS, "DPD: Clearing connection"); + loglog(RC_LOG_SERIOUS, "DPD: Clearing connection \"%s\"", c->name); unroute_connection(c); + if (c->kind == CK_INSTANCE) + delete_connection(c, TRUE); break; case DPD_ACTION_RESTART: /* dpdaction=restart - Restart connection, * except if roadwarrior connection */ - loglog(RC_LOG_SERIOUS, "DPD: Restarting connection"); + loglog(RC_LOG_SERIOUS, "DPD: Restarting connection \"%s\"", c->name); unroute_connection(c); - initiate_connection(c->name, NULL_FD); + + /* caching the connection name before deletion */ + strncpy(cname, c->name, BUF_LEN); + + if (c->kind == CK_INSTANCE) + delete_connection(c, TRUE); + initiate_connection(cname, NULL_FD); break; default: loglog(RC_LOG_SERIOUS, "DPD: unknown action"); diff --git a/src/pluto/state.c b/src/pluto/state.c index 273038f89..d1587a1a5 100644 --- a/src/pluto/state.c +++ b/src/pluto/state.c @@ -464,12 +464,7 @@ delete_states_by_connection(struct connection *c, bool relations) passert(sr->routing != RT_ROUTED_TUNNEL); sr = sr->next; } - - if (ck == CK_INSTANCE) - { - c->kind = ck; - delete_connection(c, relations); - } + c->kind = ck; } /* Walk through the state table, and delete each state whose phase 1 (IKE) @@ -506,6 +501,8 @@ delete_states_by_peer(ip_address *peer) , peerstr , c->name); delete_states_by_connection(c, TRUE); + if (c->kind == CK_INSTANCE) + delete_connection(c, TRUE); break; /* can only delete it once */ } } |