X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FVariable%2FRuntimeDxe%2FVariable.c;h=263221105bac2d788b4dd51f9894ec25c8c8862d;hp=d68dfbe648ce570bf614f717f251e44c0293075b;hb=1b79547a919616901a5437dd7047e2472de4946b;hpb=03877377e32646bedfac0e8ff8ca4689d64f06d0 diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index d68dfbe648..263221105b 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -1765,6 +1765,7 @@ CheckRemainingSpaceForConsistencyInternal ( // // No enough space for Variable[Index]. // + VA_END (Args); return FALSE; } // @@ -3133,8 +3134,11 @@ VariableServiceSetVariable ( // // Check for reserverd bit in variable attribute. + // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated but we still allow + // the delete operation of common authenticated variable at user physical presence. + // So leave EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute check to AuthVariableLib // - if ((Attributes & (~EFI_VARIABLE_ATTRIBUTES_MASK)) != 0) { + if ((Attributes & (~(EFI_VARIABLE_ATTRIBUTES_MASK | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS))) != 0) { return EFI_INVALID_PARAMETER; } @@ -3142,7 +3146,11 @@ VariableServiceSetVariable ( // Make sure if runtime bit is set, boot service bit is set also. // if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { - return EFI_INVALID_PARAMETER; + if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { + return EFI_UNSUPPORTED; + } else { + return EFI_INVALID_PARAMETER; + } } else if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) { if (!mVariableModuleGlobal->VariableGlobal.AuthSupport) { // @@ -3165,15 +3173,16 @@ VariableServiceSetVariable ( // if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { - return EFI_INVALID_PARAMETER; + return EFI_UNSUPPORTED; } if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) { - if (DataSize < AUTHINFO_SIZE) { - // - // Try to write Authenticated Variable without AuthInfo. - // - return EFI_SECURITY_VIOLATION; + // + // If DataSize == AUTHINFO_SIZE and then PayloadSize is 0. + // Maybe it's the delete operation of common authenticated variable at user physical presence. + // + if (DataSize != AUTHINFO_SIZE) { + return EFI_UNSUPPORTED; } PayloadSize = DataSize - AUTHINFO_SIZE; } else if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { @@ -3519,6 +3528,13 @@ VariableServiceQueryVariableInfo ( return EFI_INVALID_PARAMETER; } + if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { + // + // Deprecated attribute, make this check as highest priority. + // + return EFI_UNSUPPORTED; + } + if ((Attributes & EFI_VARIABLE_ATTRIBUTES_MASK) == 0) { // // Make sure the Attributes combination is supported by the platform. @@ -4020,7 +4036,105 @@ VariableWriteServiceInitialize ( return Status; } +/** + Convert normal variable storage to the allocated auth variable storage. + + @param[in] NormalVarStorage Pointer to the normal variable storage header + + @retval the allocated auth variable storage +**/ +VOID * +ConvertNormalVarStorageToAuthVarStorage ( + VARIABLE_STORE_HEADER *NormalVarStorage + ) +{ + VARIABLE_HEADER *StartPtr; + UINT8 *NextPtr; + VARIABLE_HEADER *EndPtr; + UINTN AuthVarStroageSize; + AUTHENTICATED_VARIABLE_HEADER *AuthStartPtr; + VARIABLE_STORE_HEADER *AuthVarStorage; + + AuthVarStroageSize = sizeof (VARIABLE_STORE_HEADER); + // + // Set AuthFormat as FALSE for normal variable storage + // + mVariableModuleGlobal->VariableGlobal.AuthFormat = FALSE; + + // + // Calculate Auth Variable Storage Size + // + StartPtr = GetStartPointer (NormalVarStorage); + EndPtr = GetEndPointer (NormalVarStorage); + while (StartPtr < EndPtr) { + if (StartPtr->State == VAR_ADDED) { + AuthVarStroageSize = HEADER_ALIGN (AuthVarStroageSize); + AuthVarStroageSize += sizeof (AUTHENTICATED_VARIABLE_HEADER); + AuthVarStroageSize += StartPtr->NameSize + GET_PAD_SIZE (StartPtr->NameSize); + AuthVarStroageSize += StartPtr->DataSize + GET_PAD_SIZE (StartPtr->DataSize); + } + StartPtr = GetNextVariablePtr (StartPtr); + } + + // + // Allocate Runtime memory for Auth Variable Storage + // + AuthVarStorage = AllocateRuntimeZeroPool (AuthVarStroageSize); + ASSERT (AuthVarStorage != NULL); + if (AuthVarStorage == NULL) { + return NULL; + } + + // + // Copy Variable from Normal storage to Auth storage + // + StartPtr = GetStartPointer (NormalVarStorage); + EndPtr = GetEndPointer (NormalVarStorage); + AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) GetStartPointer (AuthVarStorage); + while (StartPtr < EndPtr) { + if (StartPtr->State == VAR_ADDED) { + AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (AuthStartPtr); + // + // Copy Variable Header + // + AuthStartPtr->StartId = StartPtr->StartId; + AuthStartPtr->State = StartPtr->State; + AuthStartPtr->Attributes = StartPtr->Attributes; + AuthStartPtr->NameSize = StartPtr->NameSize; + AuthStartPtr->DataSize = StartPtr->DataSize; + CopyGuid (&AuthStartPtr->VendorGuid, &StartPtr->VendorGuid); + // + // Copy Variable Name + // + NextPtr = (UINT8 *) (AuthStartPtr + 1); + CopyMem (NextPtr, GetVariableNamePtr (StartPtr), AuthStartPtr->NameSize); + // + // Copy Variable Data + // + NextPtr = NextPtr + AuthStartPtr->NameSize + GET_PAD_SIZE (AuthStartPtr->NameSize); + CopyMem (NextPtr, GetVariableDataPtr (StartPtr), AuthStartPtr->DataSize); + // + // Go to next variable + // + AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) (NextPtr + AuthStartPtr->DataSize + GET_PAD_SIZE (AuthStartPtr->DataSize)); + } + StartPtr = GetNextVariablePtr (StartPtr); + } + // + // Update Auth Storage Header + // + AuthVarStorage->Format = NormalVarStorage->Format; + AuthVarStorage->State = NormalVarStorage->State; + AuthVarStorage->Size = (UINT32)((UINTN)AuthStartPtr - (UINTN)AuthVarStorage); + CopyGuid (&AuthVarStorage->Signature, &gEfiAuthenticatedVariableGuid); + ASSERT (AuthVarStorage->Size <= AuthVarStroageSize); + // + // Restore AuthFormat + // + mVariableModuleGlobal->VariableGlobal.AuthFormat = TRUE; + return AuthVarStorage; +} /** Initializes variable store area for non-volatile and volatile variable. @@ -4041,6 +4155,7 @@ VariableCommonInitialize ( EFI_HOB_GUID_TYPE *GuidHob; EFI_GUID *VariableGuid; EFI_FIRMWARE_VOLUME_HEADER *NvFvHeader; + BOOLEAN IsNormalVariableHob; // // Allocate runtime memory for variable driver global structure. @@ -4082,12 +4197,24 @@ VariableCommonInitialize ( // // Get HOB variable store. // + IsNormalVariableHob = FALSE; GuidHob = GetFirstGuidHob (VariableGuid); + if (GuidHob == NULL && VariableGuid == &gEfiAuthenticatedVariableGuid) { + // + // Try getting it from normal variable HOB + // + GuidHob = GetFirstGuidHob (&gEfiVariableGuid); + IsNormalVariableHob = TRUE; + } if (GuidHob != NULL) { VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob); VariableStoreLength = GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE); if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) { - mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader); + if (IsNormalVariableHob == FALSE) { + mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader); + } else { + mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) ConvertNormalVarStorageToAuthVarStorage ((VOID *) VariableStoreHeader); + } if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) { FreePool (NvFvHeader); FreePool (mVariableModuleGlobal);