fixed a use-after-free bug in dpd_timeout()

This commit is contained in:
Andreas Steffen
2009-03-10 21:13:18 +00:00
parent c587052624
commit 4e14ed7d59
3 changed files with 20 additions and 10 deletions
+2
View File
@@ -2995,6 +2995,8 @@ terminate_connection(const char *nm)
c->policy &= ~POLICY_UP; c->policy &= ~POLICY_UP;
flush_pending_by_connection(c); flush_pending_by_connection(c);
delete_states_by_connection(c, FALSE); delete_states_by_connection(c, FALSE);
if (c->kind == CK_INSTANCE)
delete_connection(c, FALSE);
reset_cur_connection(); reset_cur_connection();
} }
c = n; c = n;
+15 -4
View File
@@ -5592,6 +5592,7 @@ dpd_timeout(struct state *st)
struct state *newest_phase1_st; struct state *newest_phase1_st;
struct connection *c = st->st_connection; struct connection *c = st->st_connection;
int action = st->st_connection->dpd_action; int action = st->st_connection->dpd_action;
char cname[BUF_LEN];
passert(action == DPD_ACTION_HOLD passert(action == DPD_ACTION_HOLD
|| action == DPD_ACTION_CLEAR || action == DPD_ACTION_CLEAR
@@ -5622,20 +5623,30 @@ dpd_timeout(struct state *st)
* leak traffic. Also, being in %trap means new packets will * leak traffic. Also, being in %trap means new packets will
* force an initiation of the conn again. * 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; break;
case DPD_ACTION_CLEAR: case DPD_ACTION_CLEAR:
/* dpdaction=clear - Wipe the SA & eroute - everything */ /* 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); unroute_connection(c);
if (c->kind == CK_INSTANCE)
delete_connection(c, TRUE);
break; break;
case DPD_ACTION_RESTART: case DPD_ACTION_RESTART:
/* dpdaction=restart - Restart connection, /* dpdaction=restart - Restart connection,
* except if roadwarrior 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); 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; break;
default: default:
loglog(RC_LOG_SERIOUS, "DPD: unknown action"); loglog(RC_LOG_SERIOUS, "DPD: unknown action");
+3 -6
View File
@@ -464,12 +464,7 @@ delete_states_by_connection(struct connection *c, bool relations)
passert(sr->routing != RT_ROUTED_TUNNEL); passert(sr->routing != RT_ROUTED_TUNNEL);
sr = sr->next; sr = sr->next;
} }
c->kind = ck;
if (ck == CK_INSTANCE)
{
c->kind = ck;
delete_connection(c, relations);
}
} }
/* Walk through the state table, and delete each state whose phase 1 (IKE) /* 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 , peerstr
, c->name); , c->name);
delete_states_by_connection(c, TRUE); delete_states_by_connection(c, TRUE);
if (c->kind == CK_INSTANCE)
delete_connection(c, TRUE);
break; /* can only delete it once */ break; /* can only delete it once */
} }
} }