summaryrefslogtreecommitdiffstats
path: root/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
diff options
context:
space:
mode:
authorEric Dong <eric.dong@intel.com>2018-07-31 13:13:20 +0800
committerEric Dong <eric.dong@intel.com>2018-08-01 19:11:00 +0800
commit87acb6e298e718250dd8b741b6888a3a54c7cb5a (patch)
tree742f329d651d9f289f770c07b71f5cbe64e78df7 /SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
parentc4c7fb388e7f86fa98417a706bb495fb3c3c910b (diff)
downloadedk2-87acb6e298e718250dd8b741b6888a3a54c7cb5a.tar.gz
edk2-87acb6e298e718250dd8b741b6888a3a54c7cb5a.tar.bz2
edk2-87acb6e298e718250dd8b741b6888a3a54c7cb5a.zip
SecurityPkg OpalPasswordSupportLib: Add check to avoid potential buffer overflow.
Current code not check the CommunicationBuffer size before use it. Attacker can read beyond the end of the (untrusted) commbuffer into controlled memory. Attacker can get access outside of valid SMM memory regions. This patch add check before use it. bugz: https://bugzilla.tianocore.org/show_bug.cgi?id=198 Cc: Yao Jiewen <jiewen.yao@intel.com> Cc: Wu Hao <hao.a.wu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Yao Jiewen <jiewen.yao@intel.com>
Diffstat (limited to 'SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c')
-rw-r--r--SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c b/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
index 837582359e..e377e9ca79 100644
--- a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
+++ b/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
@@ -14,8 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "OpalPasswordSupportNotify.h"
-#define OPAL_PASSWORD_MAX_LENGTH 32
-
LIST_ENTRY mDeviceList = INITIALIZE_LIST_HEAD_VARIABLE (mDeviceList);
BOOLEAN gInSmm = FALSE;
EFI_GUID gOpalPasswordNotifyProtocolGuid = OPAL_PASSWORD_NOTIFY_PROTOCOL_GUID;
@@ -663,34 +661,53 @@ SmmOpalPasswordHandler (
EFI_STATUS Status;
OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;
UINTN TempCommBufferSize;
- UINT8 *NewPassword;
- UINT8 PasswordLength;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN RemainedDevicePathSize;
+ OPAL_COMM_DEVICE_LIST *DeviceBuffer;
if (CommBuffer == NULL || CommBufferSize == NULL) {
return EFI_SUCCESS;
}
+ Status = EFI_SUCCESS;
+ DeviceBuffer = NULL;
+
TempCommBufferSize = *CommBufferSize;
if (TempCommBufferSize < OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data)) {
return EFI_SUCCESS;
}
-
- Status = EFI_SUCCESS;
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)CommBuffer;
-
- DevicePath = &((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->OpalDevicePath;
- PasswordLength = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->PasswordLength;
- NewPassword = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->Password;
+ SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)CommBuffer;
switch (SmmFunctionHeader->Function) {
case SMM_FUNCTION_SET_OPAL_PASSWORD:
- if (OpalPasswordIsFullZero (NewPassword) || PasswordLength == 0) {
- Status = EFI_INVALID_PARAMETER;
- goto EXIT;
- }
+ if (TempCommBufferSize <= OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data) + OFFSET_OF (OPAL_COMM_DEVICE_LIST, OpalDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ DeviceBuffer = AllocateCopyPool (TempCommBufferSize - OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data), SmmFunctionHeader->Data);
+ if (DeviceBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
- Status = OpalSavePasswordToSmm (DevicePath, NewPassword, PasswordLength);
+ //
+ // Validate the DevicePath.
+ //
+ RemainedDevicePathSize = TempCommBufferSize - OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data)
+ - OFFSET_OF (OPAL_COMM_DEVICE_LIST, OpalDevicePath);
+ if (!IsDevicePathValid(&DeviceBuffer->OpalDevicePath, RemainedDevicePathSize) ||
+ (RemainedDevicePathSize != GetDevicePathSize (&DeviceBuffer->OpalDevicePath))) {
+ Status = EFI_SUCCESS;
+ goto EXIT;
+ }
+
+ if (OpalPasswordIsFullZero (DeviceBuffer->Password) ||
+ DeviceBuffer->PasswordLength == 0 ||
+ DeviceBuffer->PasswordLength > OPAL_PASSWORD_MAX_LENGTH) {
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT;
+ }
+
+ Status = OpalSavePasswordToSmm (&DeviceBuffer->OpalDevicePath, DeviceBuffer->Password, DeviceBuffer->PasswordLength);
break;
default:
@@ -701,6 +718,10 @@ SmmOpalPasswordHandler (
EXIT:
SmmFunctionHeader->ReturnStatus = Status;
+ if (DeviceBuffer != NULL) {
+ FreePool (DeviceBuffer);
+ }
+
//
// Return EFI_SUCCESS cause only one handler can be trigged.
// so return EFI_WARN_INTERRUPT_SOURCE_PENDING to make all handler can be trigged.