aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-03-10 21:13:18 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-03-10 21:13:18 +0000
commit4e14ed7d5988837eeb94032fe124a1b85520ec03 (patch)
treeffc6833aecfde74251dbf03c47ecec9e89375595
parentc587052624be4219d869e38f45b9f00a4db3b4e9 (diff)
downloadstrongswan-4e14ed7d5988837eeb94032fe124a1b85520ec03.tar.bz2
strongswan-4e14ed7d5988837eeb94032fe124a1b85520ec03.tar.xz
fixed a use-after-free bug in dpd_timeout()
-rw-r--r--src/pluto/connections.c2
-rw-r--r--src/pluto/ipsec_doi.c19
-rw-r--r--src/pluto/state.c9
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 */
}
}