OvmfPkg/PlatformDxe: Handle all requests in ExtractConfig and RouteConfig
Per the UEFI specification, if the Request argument in EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig() is NULL or does not contain any request elements, the implementation should return all of the settings being abstracted for the particular ConfigHdr reference. The current implementation returns EFI_INVALID_PARAMETER if Request is NULL or does not contain any request elements. Instead, construct a new ConfigRequest to handle these cases per the specification. In addition, per the UEFI specification, if the Configuration argument in EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig() has a ConfigHdr that specifies a non-existing target, the implementation should return EFI_NOT_FOUND. The current implementation returns EFI_INVALID_PARAMETER if Configuration has a non-existing target in ConfigHdr. Instead, perform a check and return EFI_NOT_FOUND in this case. Signed-off-by: Dimitrije Pavlov <Dimitrije.Pavlov@arm.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
		
				
					committed by
					
						![mergify[bot]](/avatar/e3df20cd7a67969c41a65f03bea54961?size=40) mergify[bot]
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							165b5bcd68
						
					
				
				
					commit
					aefcc91805
				
			| @@ -108,6 +108,11 @@ STATIC EFI_EVENT  mGopEvent; | |||||||
| // | // | ||||||
| STATIC VOID  *mGopTracker; | STATIC VOID  *mGopTracker; | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // The driver image handle, used to obtain the device path for <ConfigHdr>. | ||||||
|  | // | ||||||
|  | STATIC EFI_HANDLE  mImageHandle; | ||||||
|  |  | ||||||
| // | // | ||||||
| // Cache the resolutions we get from the GOP. | // Cache the resolutions we get from the GOP. | ||||||
| // | // | ||||||
| @@ -229,6 +234,10 @@ ExtractConfig ( | |||||||
| { | { | ||||||
|   MAIN_FORM_STATE  MainFormState; |   MAIN_FORM_STATE  MainFormState; | ||||||
|   EFI_STATUS       Status; |   EFI_STATUS       Status; | ||||||
|  |   EFI_STRING       ConfigRequestHdr; | ||||||
|  |   EFI_STRING       ConfigRequest; | ||||||
|  |   UINTN            Size; | ||||||
|  |   BOOLEAN          AllocatedRequest; | ||||||
|  |  | ||||||
|   DEBUG ((DEBUG_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request)); |   DEBUG ((DEBUG_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request)); | ||||||
|  |  | ||||||
| @@ -236,18 +245,73 @@ ExtractConfig ( | |||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   ConfigRequestHdr = NULL; | ||||||
|  |   ConfigRequest    = NULL; | ||||||
|  |   Size             = 0; | ||||||
|  |   AllocatedRequest = FALSE; | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Check if <ConfigHdr> matches the GUID and name | ||||||
|  |   // | ||||||
|  |   *Progress = Request; | ||||||
|  |   if ((Request != NULL) && | ||||||
|  |       !HiiIsConfigHdrMatch ( | ||||||
|  |          Request, | ||||||
|  |          &gOvmfPlatformConfigGuid, | ||||||
|  |          mVariableName | ||||||
|  |          ) | ||||||
|  |       ) | ||||||
|  |   { | ||||||
|  |     return EFI_NOT_FOUND; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Status = PlatformConfigToFormState (&MainFormState); |   Status = PlatformConfigToFormState (&MainFormState); | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     *Progress = Request; |  | ||||||
|     return Status; |     return Status; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { | ||||||
|  |     // | ||||||
|  |     // Request has no <RequestElement>, so construct full request string. | ||||||
|  |     // Allocate and fill a buffer large enough to hold <ConfigHdr> | ||||||
|  |     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a | ||||||
|  |     // null terminator. | ||||||
|  |     // | ||||||
|  |     ConfigRequestHdr = HiiConstructConfigHdr ( | ||||||
|  |                          &gOvmfPlatformConfigGuid, | ||||||
|  |                          mVariableName, | ||||||
|  |                          mImageHandle | ||||||
|  |                          ); | ||||||
|  |     if (ConfigRequestHdr == NULL) { | ||||||
|  |       return EFI_OUT_OF_RESOURCES; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); | ||||||
|  |     ConfigRequest    = AllocateZeroPool (Size); | ||||||
|  |     AllocatedRequest = TRUE; | ||||||
|  |     if (ConfigRequest == NULL) { | ||||||
|  |       FreePool (ConfigRequestHdr); | ||||||
|  |       return EFI_OUT_OF_RESOURCES; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     UnicodeSPrint ( | ||||||
|  |       ConfigRequest, | ||||||
|  |       Size, | ||||||
|  |       L"%s&OFFSET=0&WIDTH=%016LX", | ||||||
|  |       ConfigRequestHdr, | ||||||
|  |       sizeof MainFormState | ||||||
|  |       ); | ||||||
|  |     FreePool (ConfigRequestHdr); | ||||||
|  |   } else { | ||||||
|  |     ConfigRequest = Request; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // Answer the textual request keying off the binary form state. |   // Answer the textual request keying off the binary form state. | ||||||
|   // |   // | ||||||
|   Status = gHiiConfigRouting->BlockToConfig ( |   Status = gHiiConfigRouting->BlockToConfig ( | ||||||
|                                 gHiiConfigRouting, |                                 gHiiConfigRouting, | ||||||
|                                 Request, |                                 ConfigRequest, | ||||||
|                                 (VOID *)&MainFormState, |                                 (VOID *)&MainFormState, | ||||||
|                                 sizeof MainFormState, |                                 sizeof MainFormState, | ||||||
|                                 Results, |                                 Results, | ||||||
| @@ -265,6 +329,33 @@ ExtractConfig ( | |||||||
|     DEBUG ((DEBUG_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results)); |     DEBUG ((DEBUG_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // If we used a newly allocated ConfigRequest, update Progress to point to | ||||||
|  |   // original Request instead of ConfigRequest. | ||||||
|  |   // | ||||||
|  |   if (Request == NULL) { | ||||||
|  |     *Progress = NULL; | ||||||
|  |   } else if (StrStr (Request, L"OFFSET") == NULL) { | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       // | ||||||
|  |       // Since we constructed ConfigRequest, failure can only occur if there | ||||||
|  |       // is not enough memory. In this case, we point Progress to the first | ||||||
|  |       // character of Request. | ||||||
|  |       // | ||||||
|  |       *Progress = Request; | ||||||
|  |     } else { | ||||||
|  |       // | ||||||
|  |       // In case of success, we point Progress to the null terminator of | ||||||
|  |       // Request. | ||||||
|  |       // | ||||||
|  |       *Progress = Request + StrLen (Request); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (AllocatedRequest) { | ||||||
|  |     FreePool (ConfigRequest); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   return Status; |   return Status; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -348,6 +439,21 @@ RouteConfig ( | |||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Check if <ConfigHdr> matches the GUID and name | ||||||
|  |   // | ||||||
|  |   *Progress = Configuration; | ||||||
|  |   if ((Configuration != NULL) && | ||||||
|  |       !HiiIsConfigHdrMatch ( | ||||||
|  |          Configuration, | ||||||
|  |          &gOvmfPlatformConfigGuid, | ||||||
|  |          mVariableName | ||||||
|  |          ) | ||||||
|  |       ) | ||||||
|  |   { | ||||||
|  |     return EFI_NOT_FOUND; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // the "read" step in RMW |   // the "read" step in RMW | ||||||
|   // |   // | ||||||
| @@ -866,6 +972,11 @@ PlatformInit ( | |||||||
|     return Status; |     return Status; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Save the driver image handle. | ||||||
|  |   // | ||||||
|  |   mImageHandle = ImageHandle; | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // Publish the HII package list to HII Database. |   // Publish the HII package list to HII Database. | ||||||
|   // |   // | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ | |||||||
| // | // | ||||||
| // Name of the UEFI variable that we use for persistent storage. | // Name of the UEFI variable that we use for persistent storage. | ||||||
| // | // | ||||||
| STATIC CHAR16  mVariableName[] = L"PlatformConfig"; | CHAR16  mVariableName[] = L"PlatformConfig"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   Serialize and persistently save platform configuration. |   Serialize and persistently save platform configuration. | ||||||
|   | |||||||
| @@ -50,4 +50,6 @@ PlatformConfigLoad ( | |||||||
| #define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION  BIT0 | #define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION  BIT0 | ||||||
| #define PLATFORM_CONFIG_F_DOWNGRADE            BIT63 | #define PLATFORM_CONFIG_F_DOWNGRADE            BIT63 | ||||||
|  |  | ||||||
|  | extern CHAR16  mVariableName[]; | ||||||
|  |  | ||||||
| #endif // _PLATFORM_CONFIG_H_ | #endif // _PLATFORM_CONFIG_H_ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user