/** @file\r
The file defined some common structures used for communicating between SMM variable module and SMM variable wrapper module.\r
\r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials are licensed and made available under \r
the terms and conditions of the BSD License that accompanies this distribution. \r
The full text of the license may be found at\r
///\r
typedef struct {\r
EFI_GUID Guid;\r
- UINTN NameSize;\r
+ UINTN NameSize; // Return name buffer size\r
CHAR16 Name[1];\r
} SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME;\r
\r
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
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
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