MdeModulePkg Variable: Update GetNextVariableName to follow UEFI 2.7

"The size must be large enough to fit input string supplied in
VariableName buffer" is added in the description for VariableNameSize.
And two cases of EFI_INVALID_PARAMETER are added.
1. The input values of VariableName and VendorGuid are not a name and
   GUID of an existing variable.
2. Null-terminator is not found in the first VariableNameSize bytes of
   the input VariableName buffer.

This patch is to update code to follow them.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Star Zeng 2017-06-22 17:30:39 +08:00
parent 6ca2bfa5e8
commit 6f817f9b8b
5 changed files with 123 additions and 31 deletions

View File

@ -3,7 +3,7 @@
Emulation Variable services operate on the runtime volatile memory. Emulation Variable services operate on the runtime volatile memory.
The nonvolatile variable space doesn't exist. The nonvolatile variable space doesn't exist.
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -1233,7 +1233,8 @@ Done:
This code Finds the Next available variable. This code Finds the Next available variable.
@param VariableNameSize Size of the variable. @param VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input
string supplied in VariableName buffer.
@param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName(). @param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable. On output, returns the Null-terminated Unicode string of the current variable.
@param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName(). @param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
@ -1242,9 +1243,13 @@ Done:
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The next variable was not found. @retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_BUFFER_TOO_SMALL VariableNameSize is too small for the result. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
VariableNameSize has been updated with the size needed to complete the request. VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL. @retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/ **/
EFI_STATUS EFI_STATUS
@ -1259,16 +1264,42 @@ EmuGetNextVariableName (
VARIABLE_POINTER_TRACK Variable; VARIABLE_POINTER_TRACK Variable;
UINTN VarNameSize; UINTN VarNameSize;
EFI_STATUS Status; EFI_STATUS Status;
UINTN MaxLen;
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) { if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
//
// Calculate the possible maximum length of name string, including the Null terminator.
//
MaxLen = *VariableNameSize / sizeof (CHAR16);
if ((MaxLen == 0) || (StrnLenS (VariableName, MaxLen) == MaxLen)) {
//
// Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer,
// follow spec to return EFI_INVALID_PARAMETER.
//
return EFI_INVALID_PARAMETER;
}
AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);
Status = FindVariable (VariableName, VendorGuid, &Variable, Global); Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
//
// For VariableName is an empty string, FindVariable() will try to find and return
// the first qualified variable, and if FindVariable() returns error (EFI_NOT_FOUND)
// as no any variable is found, still go to return the error (EFI_NOT_FOUND).
//
if (VariableName[0] != 0) {
//
// For VariableName is not an empty string, and FindVariable() returns error as
// VariableName and VendorGuid are not a name and GUID of an existing variable,
// there is no way to get next variable, follow spec to return EFI_INVALID_PARAMETER.
//
Status = EFI_INVALID_PARAMETER;
}
goto Done; goto Done;
} }

View File

@ -60,14 +60,22 @@ RuntimeServiceGetVariable (
This code Finds the Next available variable. This code Finds the Next available variable.
@param VariableNameSize Size of the variable name @param VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input
@param VariableName Pointer to variable name string supplied in VariableName buffer.
@param VendorGuid Variable Vendor Guid @param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable.
@param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
On output, returns the VendorGuid of the current variable.
@return EFI_INVALID_PARAMETER Invalid parameter @retval EFI_SUCCESS The function completed successfully.
@return EFI_SUCCESS Find the specified variable @retval EFI_NOT_FOUND The next variable was not found.
@return EFI_NOT_FOUND Not found @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/ **/
EFI_STATUS EFI_STATUS

View File

@ -3,7 +3,7 @@
The internal header file includes the common header files, defines The internal header file includes the common header files, defines
internal structure and functions used by EmuVariable module. internal structure and functions used by EmuVariable module.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -173,7 +173,8 @@ EmuGetVariable (
This code finds the next available variable. This code finds the next available variable.
@param VariableNameSize Size of the variable. @param VariableNameSize The size of the VariableName buffer. The size must be large enough to fit input
string supplied in VariableName buffer.
@param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName(). @param VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable. On output, returns the Null-terminated Unicode string of the current variable.
@param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName(). @param VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
@ -182,9 +183,13 @@ EmuGetVariable (
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The next variable was not found. @retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_BUFFER_TOO_SMALL VariableNameSize is too small for the result. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
VariableNameSize has been updated with the size needed to complete the request. VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL. @retval EFI_INVALID_PARAMETER VariableNameSize or VariableName or VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/ **/
EFI_STATUS EFI_STATUS

View File

@ -2905,8 +2905,11 @@ Done:
@param[in] VendorGuid Variable Vendor Guid. @param[in] VendorGuid Variable Vendor Guid.
@param[out] VariablePtr Pointer to variable header address. @param[out] VariablePtr Pointer to variable header address.
@return EFI_SUCCESS Find the specified variable. @retval EFI_SUCCESS The function completed successfully.
@return EFI_NOT_FOUND Not found. @retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
**/ **/
EFI_STATUS EFI_STATUS
@ -2926,6 +2929,19 @@ VariableServiceGetNextVariableInternal (
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
//
// For VariableName is an empty string, FindVariable() will try to find and return
// the first qualified variable, and if FindVariable() returns error (EFI_NOT_FOUND)
// as no any variable is found, still go to return the error (EFI_NOT_FOUND).
//
if (VariableName[0] != 0) {
//
// For VariableName is not an empty string, and FindVariable() returns error as
// VariableName and VendorGuid are not a name and GUID of an existing variable,
// there is no way to get next variable, follow spec to return EFI_INVALID_PARAMETER.
//
Status = EFI_INVALID_PARAMETER;
}
goto Done; goto Done;
} }
@ -3046,14 +3062,22 @@ Done:
Caution: This function may receive untrusted input. Caution: This function may receive untrusted input.
This function may be invoked in SMM mode. This function will do basic validation, before parse the data. This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
@param VariableNameSize Size of the variable name. @param VariableNameSize The size of the VariableName buffer. The size must be large
enough to fit input string supplied in VariableName buffer.
@param VariableName Pointer to variable name. @param VariableName Pointer to variable name.
@param VendorGuid Variable Vendor Guid. @param VendorGuid Variable Vendor Guid.
@return EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_SUCCESS The function completed successfully.
@return EFI_SUCCESS Find the specified variable. @retval EFI_NOT_FOUND The next variable was not found.
@return EFI_NOT_FOUND Not found. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result. VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
@retval EFI_INVALID_PARAMETER VariableName is NULL.
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/ **/
EFI_STATUS EFI_STATUS
@ -3065,6 +3089,7 @@ VariableServiceGetNextVariableName (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN MaxLen;
UINTN VarNameSize; UINTN VarNameSize;
VARIABLE_HEADER *VariablePtr; VARIABLE_HEADER *VariablePtr;
@ -3072,6 +3097,18 @@ VariableServiceGetNextVariableName (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
//
// Calculate the possible maximum length of name string, including the Null terminator.
//
MaxLen = *VariableNameSize / sizeof (CHAR16);
if ((MaxLen == 0) || (StrnLenS (VariableName, MaxLen) == MaxLen)) {
//
// Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer,
// follow spec to return EFI_INVALID_PARAMETER.
//
return EFI_INVALID_PARAMETER;
}
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
Status = VariableServiceGetNextVariableInternal (VariableName, VendorGuid, &VariablePtr); Status = VariableServiceGetNextVariableInternal (VariableName, VendorGuid, &VariablePtr);

View File

@ -543,8 +543,11 @@ VariableServiceGetVariable (
@param[in] VendorGuid Variable Vendor Guid. @param[in] VendorGuid Variable Vendor Guid.
@param[out] VariablePtr Pointer to variable header address. @param[out] VariablePtr Pointer to variable header address.
@return EFI_SUCCESS Find the specified variable. @retval EFI_SUCCESS The function completed successfully.
@return EFI_NOT_FOUND Not found. @retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
**/ **/
EFI_STATUS EFI_STATUS
@ -562,14 +565,22 @@ VariableServiceGetNextVariableInternal (
Caution: This function may receive untrusted input. Caution: This function may receive untrusted input.
This function may be invoked in SMM mode. This function will do basic validation, before parse the data. This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
@param VariableNameSize Size of the variable name. @param VariableNameSize The size of the VariableName buffer. The size must be large
enough to fit input string supplied in VariableName buffer.
@param VariableName Pointer to variable name. @param VariableName Pointer to variable name.
@param VendorGuid Variable Vendor Guid. @param VendorGuid Variable Vendor Guid.
@return EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_SUCCESS The function completed successfully.
@return EFI_SUCCESS Find the specified variable. @retval EFI_NOT_FOUND The next variable was not found.
@return EFI_NOT_FOUND Not found. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result. VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
@retval EFI_INVALID_PARAMETER VariableName is NULL.
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
GUID of an existing variable.
@retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of
the input VariableName buffer.
**/ **/
EFI_STATUS EFI_STATUS