child-rekey: Prevent crash if peer rekeys a Child SA twice before sending a delete
Some (Windows) peers have been seen to initiate a second rekeying for the same Child SA. Presumably, this happens if a rekey request from us for the same old Child SA arrives while it waits for the response to its first rekey request. Once we receive the delete for the old SA, we conclude the rekeying with the second replacement. However, the first replacement remained linked to the old SA. So this change prevents a crash once the peer sends a delete for that first replacement (which it seems to do after about 5 minutes). References strongswan/strongswan#2944 Closes strongswan/strongswan#2945
This commit is contained in:
@@ -400,7 +400,7 @@ METHOD(task_t, build_r, status_t,
|
||||
{
|
||||
notify_payload_t *notify;
|
||||
child_cfg_t *config;
|
||||
child_sa_t *child_sa;
|
||||
child_sa_t *child_sa, *old_replacement;
|
||||
child_sa_state_t state = CHILD_INSTALLED;
|
||||
uint32_t reqid;
|
||||
bool followup_sent = FALSE;
|
||||
@@ -470,6 +470,13 @@ METHOD(task_t, build_r, status_t,
|
||||
if (child_sa && child_sa->get_state(child_sa) == CHILD_INSTALLED)
|
||||
{
|
||||
this->child_sa->set_state(this->child_sa, CHILD_REKEYED);
|
||||
/* we've seen peers sending multiple rekey requests (probably a bug in
|
||||
* their collision handling), so make sure we unlink any previous SA */
|
||||
old_replacement = this->child_sa->get_rekey_sa(this->child_sa);
|
||||
if (old_replacement)
|
||||
{
|
||||
old_replacement->set_rekey_sa(old_replacement, NULL);
|
||||
}
|
||||
/* link the SAs to handle possible collisions */
|
||||
this->child_sa->set_rekey_sa(this->child_sa, child_sa);
|
||||
child_sa->set_rekey_sa(child_sa, this->child_sa);
|
||||
|
||||
Reference in New Issue
Block a user