From 3588bb3529537b2f840f4aa5dd57d65fbfef455d Mon Sep 17 00:00:00 2001 From: lzeng14 Date: Mon, 8 Apr 2013 06:56:08 +0000 Subject: If DataSize or VariableNameSize is near MAX_ADDRESS, this can cause the computed PayLoadSize to overflow to a small value and pass the check in InitCommunicateBuffer(). To protect against this vulnerability, check DataSize and VariableNameSize to make sure PayloadSize doesn't overflow. Signed-off-by: Star Zeng Reviewed-by: Ruiyu Ni git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14252 6f19259b-4bc3-4df7-8a09-765794883524 --- .../VariableAuthenticated/RuntimeDxe/Variable.c | 5 ++++ .../RuntimeDxe/VariableSmmRuntimeDxe.c | 30 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'SecurityPkg') diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 10915e45b0..1595c8c206 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -3223,6 +3223,11 @@ VariableCommonInitialize ( } ASSERT(VariableStoreHeader->Size == VariableStoreLength); + // + // The max variable or hardware error variable size should be < variable store size. + // + ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) < VariableStoreLength); + // // Parse non-volatile variable data and get last variable offset. // diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c index a785476ff3..103a12914a 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -214,6 +214,16 @@ RuntimeServiceGetVariable ( return EFI_INVALID_PARAMETER; } + if (*DataSize >= mVariableBufferSize) { + // + // DataSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to + // overflow to a small value and pass the check in InitCommunicateBuffer(). + // To protect against this vulnerability, return EFI_INVALID_PARAMETER if DataSize is >= mVariableBufferSize. + // And there will be further check to ensure the total size is also not > mVariableBufferSize. + // + return EFI_INVALID_PARAMETER; + } + AcquireLockOnlyAtBootTime(&mVariableServicesLock); // @@ -291,6 +301,16 @@ RuntimeServiceGetNextVariableName ( return EFI_INVALID_PARAMETER; } + if (*VariableNameSize >= mVariableBufferSize) { + // + // VariableNameSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to + // overflow to a small value and pass the check in InitCommunicateBuffer(). + // To protect against this vulnerability, return EFI_INVALID_PARAMETER if VariableNameSize is >= mVariableBufferSize. + // And there will be further check to ensure the total size is also not > mVariableBufferSize. + // + return EFI_INVALID_PARAMETER; + } + AcquireLockOnlyAtBootTime(&mVariableServicesLock); // @@ -374,6 +394,16 @@ RuntimeServiceSetVariable ( return EFI_INVALID_PARAMETER; } + if (DataSize >= mVariableBufferSize) { + // + // DataSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to + // overflow to a small value and pass the check in InitCommunicateBuffer(). + // To protect against this vulnerability, return EFI_INVALID_PARAMETER if DataSize is >= mVariableBufferSize. + // And there will be further check to ensure the total size is also not > mVariableBufferSize. + // + return EFI_INVALID_PARAMETER; + } + AcquireLockOnlyAtBootTime(&mVariableServicesLock); // -- cgit v1.2.3