return FALSE;\r
}\r
\r
+/**\r
+ This function check if the address refered by Buffer and Length is valid.\r
+\r
+ @param Buffer the buffer address to be checked.\r
+ @param Length the buffer length to be checked.\r
+\r
+ @retval TRUE this address is valid.\r
+ @retval FALSE this address is NOT valid.\r
+**/\r
+BOOLEAN\r
+InternalIsAddressValid (\r
+ IN UINTN Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ if (Buffer > (MAX_ADDRESS - Length)) {\r
+ //\r
+ // Overflow happen\r
+ //\r
+ return FALSE;\r
+ }\r
+ if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)Buffer, (UINT64)Length)) {\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
\r
/**\r
Initializes a basic mutual exclusion lock.\r
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;\r
VARIABLE_INFO_ENTRY *VariableInfo;\r
UINTN InfoSize;\r
+ UINTN NameBufferSize;\r
\r
//\r
// If input is invalid, stop processing this SMI\r
return EFI_SUCCESS;\r
}\r
\r
- if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, *CommBufferSize)) {\r
- DEBUG ((EFI_D_ERROR, "SMM communication buffer size is in SMRAM!\n"));\r
+ if (!InternalIsAddressValid ((UINTN)CommBuffer, *CommBufferSize)) {\r
+ DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM or overflow!\n"));\r
return EFI_SUCCESS;\r
}\r
\r
switch (SmmVariableFunctionHeader->Function) {\r
case SMM_VARIABLE_FUNCTION_GET_VARIABLE:\r
SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+ if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
+ ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
+ //\r
+ // Prevent InfoSize overflow happen\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) \r
+ SmmVariableHeader->DataSize + SmmVariableHeader->NameSize;\r
\r
goto EXIT;\r
}\r
\r
+ if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') {\r
+ //\r
+ // Make sure VariableName is A Null-terminated string.\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
+\r
Status = VariableServiceGetVariable (\r
SmmVariableHeader->Name,\r
&SmmVariableHeader->Guid,\r
\r
case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:\r
GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) SmmVariableFunctionHeader->Data;\r
+ if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {\r
+ //\r
+ // Prevent InfoSize overflow happen\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + GetNextVariableName->NameSize;\r
\r
//\r
goto EXIT;\r
}\r
\r
+ NameBufferSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE - OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);\r
+ if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') {\r
+ //\r
+ // Make sure input VariableName is A Null-terminated string.\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
+\r
Status = VariableServiceGetNextVariableName (\r
&GetNextVariableName->NameSize,\r
GetNextVariableName->Name,\r
\r
case SMM_VARIABLE_FUNCTION_SET_VARIABLE:\r
SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;\r
+ if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||\r
+ ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) {\r
+ //\r
+ // Prevent InfoSize overflow happen\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)\r
+ SmmVariableHeader->DataSize + SmmVariableHeader->NameSize;\r
\r
goto EXIT;\r
}\r
\r
+ if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') {\r
+ //\r
+ // Make sure VariableName is A Null-terminated string.\r
+ //\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto EXIT;\r
+ }\r
+\r
Status = VariableServiceSetVariable (\r
SmmVariableHeader->Name,\r
&SmmVariableHeader->Guid,\r
//\r
\r
if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {\r
- DEBUG ((EFI_D_ERROR, "SMM communication buffer size is in SMRAM!\n"));\r
+ DEBUG ((EFI_D_ERROR, "SMM communication buffer in SMRAM!\n"));\r
Status = EFI_ACCESS_DENIED;\r
goto EXIT;\r
} \r