From: Jiaxin Wu Date: Mon, 18 Jan 2016 01:59:16 +0000 (+0000) Subject: NetworkPkg: Fix IpSec SPD and SAD mapping issue when SPD is updated X-Git-Tag: edk2-stable201903~8043 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=4991eeffcd86e1dc0bf2b15655b986b932551854 NetworkPkg: Fix IpSec SPD and SAD mapping issue when SPD is updated The current implementation doesn't handle the relationship between SPD and SAD well, which may introduce some security and connection issue after SPD updated. For SPD SetData policy: A) When delete the existed SPD entry, its related SAs also should be removed from its Sas list(SadEntry->BySpd). If the SA entry is established by IKE, we can remove it from global SAD list(SadEntry->List) and then free it directly since its SpdEntry will be freed later. B) SPD SetData operation should do some setting date validity-check. For example, whether the SaId specified by setting Data is valid. If the setting date is invalid, EFI_INVALID_PARAMETER should be returned. Cc: Ye Ting Cc: Fu Siyuan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu Reviewed-by: Ye Ting Reviewed-by: Fu Siyuan git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19652 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/NetworkPkg/IpSecDxe/IpSecConfigImpl.c b/NetworkPkg/IpSecDxe/IpSecConfigImpl.c index 8c7724c7da..e1b24e4355 100644 --- a/NetworkPkg/IpSecDxe/IpSecConfigImpl.c +++ b/NetworkPkg/IpSecDxe/IpSecConfigImpl.c @@ -1,7 +1,7 @@ /** @file The implementation of IPSEC_CONFIG_PROTOCOL. - Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -211,7 +211,7 @@ CompareSpdSelector ( } // - // Compare the all LocalAddress fields in the two Spdselectors. + // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors. // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return // TRUE. @@ -372,7 +372,7 @@ IsSubSpdSelector ( } // - // Compare the all LocalAddress fields in the two Spdselectors. + // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors. // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return // TRUE. @@ -429,9 +429,9 @@ IsSubSpdSelector ( } // - // Compare the all LocalAddress fields in the two Spdselectors. - // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare - // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return + // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors. + // First, SpdSel1->LocalAddress to SpdSel2->RemoteAddress && Compare + // SpdSel1->RemoteAddress to SpdSel2->LocalAddress. If all match, return // TRUE. // for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) { @@ -1018,6 +1018,8 @@ UnfixPadEntry ( mode is Tunnel, and its tunnel option is NULL. - The Action of Data is protected and its policy mode is not Tunnel and it tunnel option is not NULL. + - SadEntry requied to be set into new SpdEntry's Sas has + been found but it is invalid. @retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated. @retval EFI_SUCCESS The specified configuration data was obtained successfully. @@ -1039,6 +1041,7 @@ SetSpdEntry ( LIST_ENTRY *Entry; LIST_ENTRY *Entry2; LIST_ENTRY *NextEntry; + LIST_ENTRY *NextEntry2; IPSEC_SPD_ENTRY *SpdEntry; IPSEC_SAD_ENTRY *SadEntry; UINTN SpdEntrySize; @@ -1097,11 +1100,22 @@ SetSpdEntry ( SpdSas = &SpdEntry->Data->Sas; // - // TODO: Deleted the related SAs. + // Remove the related SAs from Sas(SadEntry->BySpd). If the SA entry is established by + // IKE, remove from mConfigData list(SadEntry->List) and then free it directly since its + // SpdEntry will be freed later. // - NET_LIST_FOR_EACH (Entry2, SpdSas) { - SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2); - SadEntry->Data->SpdEntry = NULL; + NET_LIST_FOR_EACH_SAFE (Entry2, NextEntry2, SpdSas) { + SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2); + + if (SadEntry->Data->SpdEntry != NULL) { + RemoveEntryList (&SadEntry->BySpd); + SadEntry->Data->SpdEntry = NULL; + } + + if (!(SadEntry->Data->ManualSet)) { + RemoveEntryList (&SadEntry->List); + FreePool (SadEntry); + } } // @@ -1194,20 +1208,30 @@ SetSpdEntry ( NET_LIST_FOR_EACH (Entry, SadList) { SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry); - for (Index = 0; Index < SpdData->SaIdCount; Index++) { - - if (CompareSaId ( - (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index], - (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id - )) { - if (SadEntry->Data->SpdEntry != NULL) { - RemoveEntryList (&SadEntry->BySpd); + for (Index = 0; Index < SpdData->SaIdCount; Index++) { + if (CompareSaId ( + (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index], + (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id + )) { + // + // Check whether the found SadEntry is vaild. + // + if (IsSubSpdSelector ( + (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector, + (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector + )) { + if (SadEntry->Data->SpdEntry != NULL) { + RemoveEntryList (&SadEntry->BySpd); + } + InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd); + SadEntry->Data->SpdEntry = SpdEntry; + } else { + return EFI_INVALID_PARAMETER; + } } - InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd); - SadEntry->Data->SpdEntry = SpdEntry; - } - } + } } + // // Insert the new SPD entry. //