From aefcc91805fd69e4aad4bc08a9f708db11cae5f0 Mon Sep 17 00:00:00 2001 From: Dimitrije Pavlov Date: Thu, 18 Aug 2022 14:58:42 -0500 Subject: [PATCH] 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 Reviewed-by: Ard Biesheuvel --- OvmfPkg/PlatformDxe/Platform.c | 115 ++++++++++++++++++++++++++- OvmfPkg/PlatformDxe/PlatformConfig.c | 2 +- OvmfPkg/PlatformDxe/PlatformConfig.h | 2 + 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/PlatformDxe/Platform.c b/OvmfPkg/PlatformDxe/Platform.c index 4d432f18df..ac31fafbdc 100644 --- a/OvmfPkg/PlatformDxe/Platform.c +++ b/OvmfPkg/PlatformDxe/Platform.c @@ -108,6 +108,11 @@ STATIC EFI_EVENT mGopEvent; // STATIC VOID *mGopTracker; +// +// The driver image handle, used to obtain the device path for . +// +STATIC EFI_HANDLE mImageHandle; + // // Cache the resolutions we get from the GOP. // @@ -229,6 +234,10 @@ ExtractConfig ( { MAIN_FORM_STATE MainFormState; EFI_STATUS Status; + EFI_STRING ConfigRequestHdr; + EFI_STRING ConfigRequest; + UINTN Size; + BOOLEAN AllocatedRequest; DEBUG ((DEBUG_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request)); @@ -236,18 +245,73 @@ ExtractConfig ( return EFI_INVALID_PARAMETER; } + ConfigRequestHdr = NULL; + ConfigRequest = NULL; + Size = 0; + AllocatedRequest = FALSE; + + // + // Check if matches the GUID and name + // + *Progress = Request; + if ((Request != NULL) && + !HiiIsConfigHdrMatch ( + Request, + &gOvmfPlatformConfigGuid, + mVariableName + ) + ) + { + return EFI_NOT_FOUND; + } + Status = PlatformConfigToFormState (&MainFormState); if (EFI_ERROR (Status)) { - *Progress = Request; return Status; } + if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { + // + // Request has no , so construct full request string. + // Allocate and fill a buffer large enough to hold + // 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. // Status = gHiiConfigRouting->BlockToConfig ( gHiiConfigRouting, - Request, + ConfigRequest, (VOID *)&MainFormState, sizeof MainFormState, Results, @@ -265,6 +329,33 @@ ExtractConfig ( 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; } @@ -348,6 +439,21 @@ RouteConfig ( return EFI_INVALID_PARAMETER; } + // + // Check if matches the GUID and name + // + *Progress = Configuration; + if ((Configuration != NULL) && + !HiiIsConfigHdrMatch ( + Configuration, + &gOvmfPlatformConfigGuid, + mVariableName + ) + ) + { + return EFI_NOT_FOUND; + } + // // the "read" step in RMW // @@ -866,6 +972,11 @@ PlatformInit ( return Status; } + // + // Save the driver image handle. + // + mImageHandle = ImageHandle; + // // Publish the HII package list to HII Database. // diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.c b/OvmfPkg/PlatformDxe/PlatformConfig.c index e202ac5b47..f5ac2d0609 100644 --- a/OvmfPkg/PlatformDxe/PlatformConfig.c +++ b/OvmfPkg/PlatformDxe/PlatformConfig.c @@ -21,7 +21,7 @@ // // 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. diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.h b/OvmfPkg/PlatformDxe/PlatformConfig.h index 902c9b2ce0..5d9b457b1b 100644 --- a/OvmfPkg/PlatformDxe/PlatformConfig.h +++ b/OvmfPkg/PlatformDxe/PlatformConfig.h @@ -50,4 +50,6 @@ PlatformConfigLoad ( #define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0 #define PLATFORM_CONFIG_F_DOWNGRADE BIT63 +extern CHAR16 mVariableName[]; + #endif // _PLATFORM_CONFIG_H_ -- 2.39.2