EFI_STATUS Status;\r
UINTN PayloadSize;\r
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;\r
+ UINTN SmmCommBufPayloadSize;\r
\r
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (*VariableNameSize >= mVariableBufferSize) {\r
- //\r
- // VariableNameSize may be near MAX_ADDRESS incorrectly, this can cause the computed PayLoadSize to\r
- // overflow to a small value and pass the check in InitCommunicateBuffer().\r
- // To protect against this vulnerability, return EFI_INVALID_PARAMETER if VariableNameSize is >= mVariableBufferSize.\r
- // And there will be further check to ensure the total size is also not > mVariableBufferSize.\r
- //\r
+ //\r
+ // SMM Communication Buffer max payload size\r
+ //\r
+ SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);\r
+\r
+ //\r
+ // If input string exceeds SMM payload limit. Return failure\r
+ //\r
+ if (StrSize (VariableName) > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// Init the communicate buffer. The buffer data size is:\r
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.\r
//\r
- PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + *VariableNameSize; \r
+ if (*VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+ //\r
+ // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size\r
+ //\r
+ *VariableNameSize = SmmCommBufPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+ }\r
+ //\r
+ // Payload should be Guid + NameSize + MAX of Input & Output buffer\r
+ //\r
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + MAX (*VariableNameSize, StrSize (VariableName));\r
+\r
+\r
Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
ASSERT (SmmGetNextVariableName != NULL);\r
\r
+ //\r
+ // SMM comm buffer->NameSize is buffer size for return string\r
+ //\r
SmmGetNextVariableName->NameSize = *VariableNameSize;\r
+\r
CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid);\r
- CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize);\r
+ //\r
+ // Copy whole string\r
+ //\r
+ CopyMem (SmmGetNextVariableName->Name, VariableName, StrSize (VariableName));\r
\r
//\r
// Send data to SMM\r