X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FLibrary%2FDxeDeferImageLoadLib%2FDxeDeferImageLoadLib.c;fp=SecurityPkg%2FLibrary%2FDxeDeferImageLoadLib%2FDxeDeferImageLoadLib.c;h=0000000000000000000000000000000000000000;hp=a6a3fe3cfc68627253010bd211bd03bc67e785ab;hb=d31666211873086c058285f4a4f1933bc3c3428c;hpb=fda8482df707dd4f3880e5060979f8df86b86e12 diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c deleted file mode 100644 index a6a3fe3cfc..0000000000 --- a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c +++ /dev/null @@ -1,927 +0,0 @@ -/** @file - Implement defer image load services for user identification in UEFI2.2. - -Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "DxeDeferImageLoadLib.h" - -// -// Handle for the Deferred Image Load Protocol instance produced by this driver. -// -EFI_HANDLE mDeferredImageHandle = NULL; -BOOLEAN mIsProtocolInstalled = FALSE; -EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL; -DEFERRED_IMAGE_TABLE mDeferredImage = { - 0, // Deferred image count - NULL // The deferred image info -}; - -EFI_DEFERRED_IMAGE_LOAD_PROTOCOL gDeferredImageLoad = { - GetDefferedImageInfo -}; - -/** - Get the image type. - - @param[in] File This is a pointer to the device path of the file - that is being dispatched. - - @return UINT32 Image Type - -**/ -UINT32 -GetFileType ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *File - ) -{ - EFI_STATUS Status; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - - // - // First check to see if File is from a Firmware Volume - // - DeviceHandle = NULL; - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File; - Status = gBS->LocateDevicePath ( - &gEfiFirmwareVolume2ProtocolGuid, - &TempDevicePath, - &DeviceHandle - ); - if (!EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - DeviceHandle, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - NULL, - NULL, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - return IMAGE_FROM_FV; - } - } - - // - // Next check to see if File is from a Block I/O device - // - DeviceHandle = NULL; - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File; - Status = gBS->LocateDevicePath ( - &gEfiBlockIoProtocolGuid, - &TempDevicePath, - &DeviceHandle - ); - if (!EFI_ERROR (Status)) { - BlockIo = NULL; - Status = gBS->OpenProtocol ( - DeviceHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status) && BlockIo != NULL) { - if (BlockIo->Media != NULL) { - if (BlockIo->Media->RemovableMedia) { - // - // Block I/O is present and specifies the media is removable - // - return IMAGE_FROM_REMOVABLE_MEDIA; - } else { - // - // Block I/O is present and specifies the media is not removable - // - return IMAGE_FROM_FIXED_MEDIA; - } - } - } - } - - // - // File is not in a Firmware Volume or on a Block I/O device, so check to see if - // the device path supports the Simple File System Protocol. - // - DeviceHandle = NULL; - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File; - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - &TempDevicePath, - &DeviceHandle - ); - if (!EFI_ERROR (Status)) { - // - // Simple File System is present without Block I/O, so assume media is fixed. - // - return IMAGE_FROM_FIXED_MEDIA; - } - - // - // File is not from an FV, Block I/O or Simple File System, so the only options - // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC. - // - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File; - while (!IsDevicePathEndType (TempDevicePath)) { - switch (DevicePathType (TempDevicePath)) { - - case MEDIA_DEVICE_PATH: - if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) { - return IMAGE_FROM_OPTION_ROM; - } - break; - - case MESSAGING_DEVICE_PATH: - if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) { - return IMAGE_FROM_REMOVABLE_MEDIA; - } - break; - - default: - break; - } - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - return IMAGE_UNKNOWN; -} - - -/** - Get current user's access right. - - @param[out] AccessControl Points to the user's access control data, the - caller should free data buffer. - @param[in] AccessType The type of user access control. - - @retval EFI_SUCCESS Get current user access control successfully - @retval others Fail to get current user access control - -**/ -EFI_STATUS -GetAccessControl ( - OUT EFI_USER_INFO_ACCESS_CONTROL **AccessControl, - IN UINT32 AccessType - ) -{ - EFI_STATUS Status; - EFI_USER_INFO_HANDLE UserInfo; - EFI_USER_INFO *Info; - UINTN InfoSize; - EFI_USER_INFO_ACCESS_CONTROL *Access; - EFI_USER_PROFILE_HANDLE CurrentUser; - UINTN CheckLen; - EFI_USER_MANAGER_PROTOCOL *UserManager; - - CurrentUser = NULL; - Status = gBS->LocateProtocol ( - &gEfiUserManagerProtocolGuid, - NULL, - (VOID **) &UserManager - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Get current user access information. - // - UserManager->Current (UserManager, &CurrentUser); - - UserInfo = NULL; - Info = NULL; - InfoSize = 0; - while (TRUE) { - // - // Get next user information. - // - Status = UserManager->GetNextInfo (UserManager, CurrentUser, &UserInfo); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = UserManager->GetInfo ( - UserManager, - CurrentUser, - UserInfo, - Info, - &InfoSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - if (Info != NULL) { - FreePool (Info); - } - Info = AllocateZeroPool (InfoSize); - ASSERT (Info != NULL); - Status = UserManager->GetInfo ( - UserManager, - CurrentUser, - UserInfo, - Info, - &InfoSize - ); - } - - if (EFI_ERROR (Status)) { - break; - } - - ASSERT (Info != NULL); - if (Info->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD) { - continue; - } - - // - // Get specified access information. - // - CheckLen = 0; - while (CheckLen < Info->InfoSize - sizeof (EFI_USER_INFO)) { - Access = (EFI_USER_INFO_ACCESS_CONTROL *) ((UINT8 *) (Info + 1) + CheckLen); - if (Access->Type == AccessType) { - *AccessControl = AllocateZeroPool (Access->Size); - ASSERT (*AccessControl != NULL); - CopyMem (*AccessControl, Access, Access->Size); - FreePool (Info); - return EFI_SUCCESS; - } - CheckLen += Access->Size; - } - } - - if (Info != NULL) { - FreePool (Info); - } - return EFI_NOT_FOUND; -} - -/** - Get file name from device path. - - The file name may contain one or more device path node. Save the file name in a - buffer if file name is found. The caller is responsible to free the buffer. - - @param[in] DevicePath A pointer to a device path. - @param[out] FileName The callee allocated buffer to save the file name if file name is found. - @param[out] FileNameOffset The offset of file name in device path if file name is found. - - @retval UINTN The file name length. 0 means file name is not found. - -**/ -UINTN -GetFileName ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT8 **FileName, - OUT UINTN *FileNameOffset - ) -{ - UINTN Length; - EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RootDevicePath; - CHAR8 *NodeStr; - UINTN NodeStrLength; - CHAR16 LastNodeChar; - CHAR16 FirstNodeChar; - - // - // Get the length of DevicePath before file name. - // - Length = 0; - RootDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; - while (!IsDevicePathEnd (RootDevicePath)) { - if ((DevicePathType(RootDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType(RootDevicePath) == MEDIA_FILEPATH_DP)) { - break; - } - Length += DevicePathNodeLength (RootDevicePath); - RootDevicePath = NextDevicePathNode (RootDevicePath); - } - - *FileNameOffset = Length; - if (Length == 0) { - return 0; - } - - // - // Get the file name length. - // - Length = 0; - TmpDevicePath = RootDevicePath; - while (!IsDevicePathEnd (TmpDevicePath)) { - if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) { - break; - } - Length += DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); - TmpDevicePath = NextDevicePathNode (TmpDevicePath); - } - if (Length == 0) { - return 0; - } - - *FileName = AllocateZeroPool (Length); - ASSERT (*FileName != NULL); - - // - // Copy the file name to the buffer. - // - Length = 0; - LastNodeChar = '\\'; - TmpDevicePath = RootDevicePath; - while (!IsDevicePathEnd (TmpDevicePath)) { - if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) { - break; - } - - FirstNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *)((UINT8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL))); - NodeStr = (CHAR8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL); - NodeStrLength = DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL) - sizeof(CHAR16); - - if ((FirstNodeChar == '\\') && (LastNodeChar == '\\')) { - // - // Skip separator "\" when there are two separators. - // - NodeStr += sizeof (CHAR16); - NodeStrLength -= sizeof (CHAR16); - } else if ((FirstNodeChar != '\\') && (LastNodeChar != '\\')) { - // - // Add separator "\" when there is no separator. - // - WriteUnaligned16 ((UINT16 *)(*FileName + Length), '\\'); - Length += sizeof (CHAR16); - } - CopyMem (*FileName + Length, NodeStr, NodeStrLength); - Length += NodeStrLength; - - LastNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *) (NodeStr + NodeStrLength - sizeof(CHAR16))); - TmpDevicePath = NextDevicePathNode (TmpDevicePath); - } - - return Length; -} - - -/** - Check whether the DevicePath2 is identical with DevicePath1, or identical with - DevicePath1's child device path. - - If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device - path, then TRUE returned. Otherwise, FALSE is returned. - - If DevicePath1 is NULL, then ASSERT(). - If DevicePath2 is NULL, then ASSERT(). - - @param[in] DevicePath1 A pointer to a device path. - @param[in] DevicePath2 A pointer to a device path. - - @retval TRUE Two device paths are identical , or DevicePath2 is - DevicePath1's child device path. - @retval FALSE Two device paths are not identical, and DevicePath2 - is not DevicePath1's child device path. - -**/ -BOOLEAN -CheckDevicePath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ) -{ - UINTN DevicePathSize; - UINTN FileNameSize1; - UINTN FileNameSize2; - UINT8 *FileName1; - UINT8 *FileName2; - UINTN FileNameOffset1; - UINTN FileNameOffset2; - BOOLEAN DevicePathEqual; - - FileName1 = NULL; - FileName2 = NULL; - DevicePathEqual = TRUE; - - ASSERT (DevicePath1 != NULL); - ASSERT (DevicePath2 != NULL); - if (IsDevicePathEnd (DevicePath1)) { - return FALSE; - } - - // - // The file name may contain one or more device path node. - // To compare the file name, copy file name to a buffer and compare the buffer. - // - FileNameSize1 = GetFileName (DevicePath1, &FileName1, &FileNameOffset1); - if (FileNameSize1 != 0) { - FileNameSize2 = GetFileName (DevicePath2, &FileName2, &FileNameOffset2); - if (FileNameOffset1 != FileNameOffset2) { - DevicePathEqual = FALSE; - goto Done; - } - if (CompareMem (DevicePath1, DevicePath2, FileNameOffset1) != 0) { - DevicePathEqual = FALSE; - goto Done; - } - if (FileNameSize1 > FileNameSize2) { - DevicePathEqual = FALSE; - goto Done; - } - if (CompareMem (FileName1, FileName2, FileNameSize1) != 0) { - DevicePathEqual = FALSE; - goto Done; - } - DevicePathEqual = TRUE; - goto Done; - } - - DevicePathSize = GetDevicePathSize (DevicePath1); - if (DevicePathSize > GetDevicePathSize (DevicePath2)) { - return FALSE; - } - - // - // Exclude the end of device path node. - // - DevicePathSize -= sizeof (EFI_DEVICE_PATH_PROTOCOL); - if (CompareMem (DevicePath1, DevicePath2, DevicePathSize) != 0) { - DevicePathEqual = FALSE; - } - -Done: - if (FileName1 != NULL) { - FreePool (FileName1); - } - if (FileName2 != NULL) { - FreePool (FileName2); - } - return DevicePathEqual; -} - - -/** - Check whether the image pointed to by DevicePath is in the device path list - specified by AccessType. - - @param[in] DevicePath Points to device path. - @param[in] AccessType The type of user access control. - - @retval TRUE The DevicePath is in the specified List. - @retval FALSE The DevicePath is not in the specified List. - -**/ -BOOLEAN -IsDevicePathInList ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT32 AccessType - ) -{ - EFI_STATUS Status; - EFI_USER_INFO_ACCESS_CONTROL *Access; - EFI_DEVICE_PATH_PROTOCOL *Path; - UINTN OffSet; - - Status = GetAccessControl (&Access, AccessType); - if (EFI_ERROR (Status)) { - return FALSE; - } - - OffSet = 0; - while (OffSet < Access->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL)) { - Path = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(Access + 1) + OffSet); - if (CheckDevicePath (Path, DevicePath)) { - // - // The device path is found in list. - // - FreePool (Access); - return TRUE; - } - OffSet += GetDevicePathSize (Path); - } - - FreePool (Access); - return FALSE; -} - - -/** - Check whether the image pointed to by DevicePath is permitted to load. - - @param[in] DevicePath Points to device path - - @retval TRUE The image pointed by DevicePath is permitted to load. - @retval FALSE The image pointed by DevicePath is forbidden to load. - -**/ -BOOLEAN -VerifyDevicePath ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_PERMIT_LOAD)) { - // - // This access control overrides any restrictions put in place by the - // EFI_USER_INFO_ACCESS_FORBID_LOAD record. - // - return TRUE; - } - - if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_FORBID_LOAD)) { - // - // The device path is found in the forbidden list. - // - return FALSE; - } - - return TRUE; -} - - -/** - Check the image pointed by DevicePath is a boot option or not. - - @param[in] DevicePath Points to device path. - - @retval TRUE The image pointed by DevicePath is a boot option. - @retval FALSE The image pointed by DevicePath is not a boot option. - -**/ -BOOLEAN -IsBootOption ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_STATUS Status; - UINT16 *BootOrderList; - UINTN BootOrderListSize; - UINTN Index; - CHAR16 StrTemp[20]; - UINT8 *OptionBuffer; - UINT8 *OptionPtr; - EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; - - // - // Get BootOrder - // - BootOrderListSize = 0; - BootOrderList = NULL; - Status = gRT->GetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - NULL, - &BootOrderListSize, - NULL - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - BootOrderList = AllocateZeroPool (BootOrderListSize); - ASSERT (BootOrderList != NULL); - Status = gRT->GetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - NULL, - &BootOrderListSize, - BootOrderList - ); - } - - if (EFI_ERROR (Status)) { - // - // No Boot option - // - return FALSE; - } - - OptionBuffer = NULL; - for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) { - // - // Try to find the DevicePath in BootOption - // - UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index); - GetEfiGlobalVariable2 (StrTemp, (VOID**)&OptionBuffer, NULL); - if (OptionBuffer == NULL) { - continue; - } - - // - // Check whether the image is forbidden. - // - - OptionPtr = OptionBuffer; - // - // Skip attribute. - // - OptionPtr += sizeof (UINT32); - - // - // Skip device path length. - // - OptionPtr += sizeof (UINT16); - - // - // Skip descript string - // - OptionPtr += StrSize ((UINT16 *) OptionPtr); - - // - // Now OptionPtr points to Device Path. - // - OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) OptionPtr; - - if (CheckDevicePath (DevicePath, OptionDevicePath)) { - FreePool (OptionBuffer); - OptionBuffer = NULL; - return TRUE; - } - FreePool (OptionBuffer); - OptionBuffer = NULL; - } - - if (BootOrderList != NULL) { - FreePool (BootOrderList); - } - - return FALSE; -} - - -/** - Add the image info to a deferred image list. - - @param[in] ImageDevicePath A pointer to the device path of a image. - @param[in] Image Points to the first byte of the image, or NULL if the - image is not available. - @param[in] ImageSize The size of the image, or 0 if the image is not available. - -**/ -VOID -PutDefferedImageInfo ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath, - IN VOID *Image, - IN UINTN ImageSize - ) -{ - DEFERRED_IMAGE_INFO *CurImageInfo; - UINTN PathSize; - - // - // Expand memory for the new deferred image. - // - if (mDeferredImage.Count == 0) { - mDeferredImage.ImageInfo = AllocatePool (sizeof (DEFERRED_IMAGE_INFO)); - ASSERT (mDeferredImage.ImageInfo != NULL); - } else { - CurImageInfo = AllocatePool ((mDeferredImage.Count + 1) * sizeof (DEFERRED_IMAGE_INFO)); - ASSERT (CurImageInfo != NULL); - - CopyMem ( - CurImageInfo, - mDeferredImage.ImageInfo, - mDeferredImage.Count * sizeof (DEFERRED_IMAGE_INFO) - ); - FreePool (mDeferredImage.ImageInfo); - mDeferredImage.ImageInfo = CurImageInfo; - } - mDeferredImage.Count++; - - // - // Save the deferred image information. - // - CurImageInfo = &mDeferredImage.ImageInfo[mDeferredImage.Count - 1]; - PathSize = GetDevicePathSize (ImageDevicePath); - CurImageInfo->ImageDevicePath = AllocateZeroPool (PathSize); - ASSERT (CurImageInfo->ImageDevicePath != NULL); - CopyMem (CurImageInfo->ImageDevicePath, ImageDevicePath, PathSize); - - CurImageInfo->Image = Image; - CurImageInfo->ImageSize = ImageSize; - CurImageInfo->BootOption = IsBootOption (ImageDevicePath); -} - - -/** - Returns information about a deferred image. - - This function returns information about a single deferred image. The deferred images are - numbered consecutively, starting with 0. If there is no image which corresponds to - ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by - iteratively calling this function until EFI_NOT_FOUND is returned. - Image may be NULL and ImageSize set to 0 if the decision to defer execution was made - because of the location of the executable image, rather than its actual contents. - - @param[in] This Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL. - @param[in] ImageIndex Zero-based index of the deferred index. - @param[out] ImageDevicePath On return, points to a pointer to the device path of the image. - The device path should not be freed by the caller. - @param[out] Image On return, points to the first byte of the image or NULL if the - image is not available. The image should not be freed by the caller - unless LoadImage() has been successfully called. - @param[out] ImageSize On return, the size of the image, or 0 if the image is not available. - @param[out] BootOption On return, points to TRUE if the image was intended as a boot option - or FALSE if it was not intended as a boot option. - - @retval EFI_SUCCESS Image information returned successfully. - @retval EFI_NOT_FOUND ImageIndex does not refer to a valid image. - @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or - BootOption is NULL. - -**/ -EFI_STATUS -EFIAPI -GetDefferedImageInfo ( - IN EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *This, - IN UINTN ImageIndex, - OUT EFI_DEVICE_PATH_PROTOCOL **ImageDevicePath, - OUT VOID **Image, - OUT UINTN *ImageSize, - OUT BOOLEAN *BootOption - ) -{ - DEFERRED_IMAGE_INFO *ReqImageInfo; - - // - // Check the parameter. - // - - if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((ImageDevicePath == NULL) || (BootOption == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (ImageIndex >= mDeferredImage.Count) { - return EFI_NOT_FOUND; - } - - // - // Get the request deferred image. - // - ReqImageInfo = &mDeferredImage.ImageInfo[ImageIndex]; - - *ImageDevicePath = ReqImageInfo->ImageDevicePath; - *Image = ReqImageInfo->Image; - *ImageSize = ReqImageInfo->ImageSize; - *BootOption = ReqImageInfo->BootOption; - - return EFI_SUCCESS; -} - - -/** - Provides the service of deferring image load based on platform policy control, - and installs Deferred Image Load Protocol. - - @param[in] AuthenticationStatus This is the authentication status returned from the - security measurement services for the input file. - @param[in] File This is a pointer to the device path of the file that - is being dispatched. This will optionally be used for - logging. - @param[in] FileBuffer File buffer matches the input file device path. - @param[in] FileSize Size of File buffer matches the input file device path. - @param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service. - - @retval EFI_SUCCESS FileBuffer is NULL and current user has permission to start - UEFI device drivers on the device path specified by DevicePath. - @retval EFI_SUCCESS The file specified by DevicePath and non-NULL - FileBuffer did authenticate, and the platform policy dictates - that the DXE Foundation may use the file. - @retval EFI_SECURITY_VIOLATION FileBuffer is NULL and the user has no - permission to start UEFI device drivers on the device path specified - by DevicePath. - @retval EFI_SECURITY_VIOLATION FileBuffer is not NULL and the user has no permission to load - drivers from the device path specified by DevicePath. The - image has been added into the list of the deferred images. - @retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not - authenticate, and the platform policy dictates that the DXE - Foundation many not use File. - -**/ -EFI_STATUS -EFIAPI -DxeDeferImageLoadHandler ( - IN UINT32 AuthenticationStatus, - IN CONST EFI_DEVICE_PATH_PROTOCOL *File, - IN VOID *FileBuffer, - IN UINTN FileSize, - IN BOOLEAN BootPolicy - ) -{ - EFI_STATUS Status; - EFI_USER_PROFILE_HANDLE CurrentUser; - UINT32 Policy; - UINT32 FileType; - - // - // Ignore if File is NULL. - // - if (File == NULL) { - return EFI_SUCCESS; - } - - // - // Check whether user has a logon. - // - CurrentUser = NULL; - if (mUserManager != NULL) { - mUserManager->Current (mUserManager, &CurrentUser); - if (CurrentUser != NULL) { - // - // The user is logon; verify the FilePath by current user access policy. - // - if (!VerifyDevicePath (File)) { - DEBUG ((EFI_D_ERROR, "[Security] The image is forbidden to load!\n")); - return EFI_SECURITY_VIOLATION; - } - return EFI_SUCCESS; - } - } - - // - // Still no user logon. - // Check the file type and get policy setting. - // - FileType = GetFileType (File); - Policy = PcdGet32 (PcdDeferImageLoadPolicy); - if ((Policy & FileType) == FileType) { - // - // This file type is secure to load. - // - return EFI_SUCCESS; - } - - DEBUG ((EFI_D_INFO, "[Security] No user identified, the image is deferred to load!\n")); - PutDefferedImageInfo (File, FileBuffer, FileSize); - - // - // Install the Deferred Image Load Protocol onto a new handle. - // - if (!mIsProtocolInstalled) { - Status = gBS->InstallMultipleProtocolInterfaces ( - &mDeferredImageHandle, - &gEfiDeferredImageLoadProtocolGuid, - &gDeferredImageLoad, - NULL - ); - ASSERT_EFI_ERROR (Status); - mIsProtocolInstalled = TRUE; - } - - return EFI_ACCESS_DENIED; -} - -/** - Locate user manager protocol when user manager is installed. - - @param[in] Event The Event that is being processed, not used. - @param[in] Context Event Context, not used. - -**/ -VOID -EFIAPI -FindUserManagerProtocol ( - IN EFI_EVENT Event, - IN VOID* Context - ) -{ - gBS->LocateProtocol ( - &gEfiUserManagerProtocolGuid, - NULL, - (VOID **) &mUserManager - ); - -} - - -/** - Register security handler for deferred image load. - - @param[in] ImageHandle ImageHandle of the loaded driver. - @param[in] SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCCESS The handlers were registered successfully. -**/ -EFI_STATUS -EFIAPI -DxeDeferImageLoadLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - VOID *Registration; - - // - // Register user manager notification function. - // - EfiCreateProtocolNotifyEvent ( - &gEfiUserManagerProtocolGuid, - TPL_CALLBACK, - FindUserManagerProtocol, - NULL, - &Registration - ); - - return RegisterSecurity2Handler ( - DxeDeferImageLoadHandler, - EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD - ); -} - -