diff options
4 files changed, 70 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index 8f10425..956c1f2 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -2756,6 +2756,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.
//
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 2a59ac1..2fca259 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);
//
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 10915e4..1595c8c 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -3224,6 +3224,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.
//
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c index a785476..103a129 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);
//
|