From 56251c669f0f13d2ffc226cfd3a3d8c5f8269e7a Mon Sep 17 00:00:00 2001 From: czhang46 Date: Mon, 22 Apr 2013 08:52:58 +0000 Subject: Fix potential overflow for SetVariable interface Signed-off-by: Chao Zhang Reviewed-by : Guo Dong Reviewed-by : Siyuan Fu git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14305 6f19259b-4bc3-4df7-8a09-765794883524 --- .../VariableAuthenticated/EsalVariableDxeSal/Variable.c | 16 +++++++++++----- SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c | 13 +++++++++---- .../RuntimeDxe/VariableSmmRuntimeDxe.c | 9 ++++++++- 3 files changed, 28 insertions(+), 10 deletions(-) (limited to 'SecurityPkg') diff --git a/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c b/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c index d0269c9da7..e098c81df3 100644 --- a/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c +++ b/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c @@ -1,7 +1,7 @@ /** @file The implementation of Extended SAL variable services. -Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2013, 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 which accompanies this distribution. The full text of the license may be found at @@ -2591,6 +2591,14 @@ EsalSetVariable ( PayloadSize = DataSize; } + + if ((UINTN)(~0) - PayloadSize < StrSize(VariableName)){ + // + // Prevent whole variable size overflow + // + return EFI_INVALID_PARAMETER; + } + VariableGlobal = &Global->VariableGlobal[VirtualMode]; Instance = Global->FvbInstance; @@ -2599,8 +2607,7 @@ EsalSetVariable ( // For variable for hardware error record, the size of the VariableName, including the Unicode Null // in bytes plus the DataSize is limited to maximum size of PcdGet32(PcdMaxHardwareErrorVariableSize) bytes. // - if ((PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize)) || - (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize))) { + if (StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) { return EFI_INVALID_PARAMETER; } // @@ -2616,8 +2623,7 @@ EsalSetVariable ( // For variable not for hardware error record, the size of the VariableName, including the // Unicode Null in bytes plus the DataSize is limited to maximum size of PcdGet32(PcdMaxVariableSize) bytes. // - if ((PayloadSize > PcdGet32(PcdMaxVariableSize)) || - (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxVariableSize))) { + if (StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) { return EFI_INVALID_PARAMETER; } } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 1595c8c206..ebe04b50f5 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -2664,14 +2664,20 @@ VariableServiceSetVariable ( PayloadSize = DataSize; } + if ((UINTN)(~0) - PayloadSize < StrSize(VariableName)){ + // + // Prevent whole variable size overflow + // + return EFI_INVALID_PARAMETER; + } + // // The size of the VariableName, including the Unicode Null in bytes plus // the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize) // bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others. // if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { - if ((PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize)) || - (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize))) { + if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) { return EFI_INVALID_PARAMETER; } if (!IsHwErrRecVariable(VariableName, VendorGuid)) { @@ -2682,8 +2688,7 @@ VariableServiceSetVariable ( // The size of the VariableName, including the Unicode Null in bytes plus // the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes. // - if ((PayloadSize > PcdGet32 (PcdMaxVariableSize)) || - (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize))) { + if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) { return EFI_INVALID_PARAMETER; } } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c index 9f750d6780..5a02b77d53 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -442,8 +442,15 @@ RuntimeServiceSetVariable ( return EFI_INVALID_PARAMETER; } + if ((UINTN)(~0) - StrSize (VariableName) < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + DataSize) { + // + // Prevent PayloadSize overflow + // + return EFI_INVALID_PARAMETER; + } + AcquireLockOnlyAtBootTime(&mVariableServicesLock); - + // // Init the communicate buffer. The buffer data size is: // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize. -- cgit v1.2.3