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 --- .../Universal/Variable/RuntimeDxe/Variable.c | 5 ++++ .../Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 30 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index 8f10425ebb..956c1f2ae1 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -2755,6 +2755,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/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 2a59ac16f9..2fca25981a 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -198,6 +198,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); // @@ -275,6 +285,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); // @@ -355,6 +375,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