OcBootManagementLib: Rework filesystem scan policy

This commit is contained in:
vit9696 2019-06-18 11:20:27 +03:00
parent b2f858b7e5
commit c8545a2564
6 changed files with 98 additions and 71 deletions

View File

@ -91,6 +91,11 @@ typedef struct OC_BOOT_ENTRY_ {
**/
#define OC_SCAN_ALLOW_FS_HFS BIT9
/**
Allow scanning ESP filesystems.
**/
#define OC_SCAN_ALLOW_FS_ESP BIT10
/**
Allow scanning SATA devices.
**/
@ -144,7 +149,7 @@ typedef struct OC_BOOT_ENTRY_ {
All device bits used by OC_SCAN_DEVICE_LOCK.
**/
#define OC_SCAN_FILE_SYSTEM_BITS ( \
OC_SCAN_ALLOW_FS_APFS | OC_SCAN_ALLOW_FS_HFS)
OC_SCAN_ALLOW_FS_APFS | OC_SCAN_ALLOW_FS_HFS | OC_SCAN_ALLOW_FS_ESP)
/**
By default allow booting from APFS from internal drives.
@ -356,7 +361,6 @@ OcFreeBootEntries (
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] Policy Scan policy.
@param[in] Handle Device handle (with EfiSimpleFileSystem protocol).
@param[in] SimpleFs Simple file system protocol of the device handle.
@param[out] BootEntry Resulting boot entry.
@param[out] AlternateBootEntry Resulting alternate boot entry (e.g. recovery).
@param[in] IsLoadHandle OpenCore load handle, try skipping OC entry.
@ -370,7 +374,6 @@ OcFillBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN UINT32 Policy,
IN EFI_HANDLE Handle,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs,
OUT OC_BOOT_ENTRY *BootEntry,
OUT OC_BOOT_ENTRY *AlternateBootEntry OPTIONAL,
IN BOOLEAN IsLoadHandle
@ -446,7 +449,7 @@ OcLoadBootEntry (
@retval EFI_SUCCESS Hibernation mode was found and activated.
**/
EFI_STATUS
ActivateHibernateWake (
OcActivateHibernateWake (
IN UINT32 HibernateMask
);
@ -462,4 +465,30 @@ OcRunSimpleBootPicker (
IN OC_PICKER_CONTEXT *Context
);
/**
Get device scan policy type.
@param[in] Handle Device/partition handle.
@param[out] External Check whether device is external.
@retval required policy or 0 on mismatch.
**/
UINT32
OcGetDevicePolicyType (
IN EFI_HANDLE Handle,
OUT BOOLEAN *External OPTIONAL
);
/**
Get file system scan policy type.
@param[in] Handle Partition handle.
@retval required policy or 0 on mismatch.
**/
UINT32
OcGetFileSystemPolicyType (
IN EFI_HANDLE Handle
);
#endif // OC_BOOT_MANAGEMENT_LIB_H

View File

@ -238,6 +238,7 @@ OcOpenFileByDevicePath (
@param[in] HdDevicePath The Device Path of the partition.
@retval device handle or NULL
**/
EFI_HANDLE
OcPartitionGetDiskHandle (
@ -249,6 +250,7 @@ OcPartitionGetDiskHandle (
@param[in] DiskDevicePath The Device Path of the disk to scan.
@retval device path or NULL
**/
EFI_DEVICE_PATH_PROTOCOL *
OcDiskFindSystemPartitionPath (
@ -256,10 +258,12 @@ OcDiskFindSystemPartitionPath (
);
/**
Retrieve the partition's GPT information, if applicable
Retrieve the partition's GPT information, if applicable.
Calls to this function undergo internal lazy caching.
@param[in] FsHandle The device handle of the partition to retrieve info of.
@retval partition entry or NULL
**/
CONST EFI_PARTITION_ENTRY *
OcGetGptPartitionEntry (

View File

@ -30,10 +30,9 @@ typedef struct {
EFI_HANDLE BlockIoHandle;
} INTERNAL_DMG_LOAD_CONTEXT;
EFI_STATUS
RETURN_STATUS
InternalCheckScanPolicy (
IN EFI_HANDLE Handle,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs,
IN UINT32 Policy,
OUT BOOLEAN *External OPTIONAL
);

View File

@ -297,7 +297,6 @@ OcFillBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN UINT32 Policy,
IN EFI_HANDLE Handle,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs,
OUT OC_BOOT_ENTRY *BootEntry,
OUT OC_BOOT_ENTRY *AlternateBootEntry OPTIONAL,
IN BOOLEAN IsLoadHandle
@ -313,7 +312,7 @@ OcFillBootEntry (
Count = 0;
Status = InternalCheckScanPolicy (Handle, SimpleFs, Policy, &BootEntry->IsExternal);
Status = InternalCheckScanPolicy (Handle, Policy, &BootEntry->IsExternal);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCB: Skipping handle %p due to scan policy %x\n", Handle, Policy));
return 0;
@ -448,7 +447,6 @@ OcScanForBootEntries (
BootPolicy,
Context->ScanPolicy,
Handles[Index],
SimpleFs,
&Entries[EntryIndex],
&Entries[EntryIndex+1],
Context->ExcludeHandle == Handles[Index]
@ -536,7 +534,7 @@ OcScanForBootEntries (
}
EFI_STATUS
ActivateHibernateWake (
OcActivateHibernateWake (
IN UINT32 HibernateMask
)
{

View File

@ -51,7 +51,11 @@
gAppleBlessedOsxFolderInfoGuid ## SOMETIMES_CONSUMES
gEfiFileInfoGuid ## SOMETIMES_CONSUMES
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES
gEfiPartTypeSystemPartGuid ## SOMETIMES_CONSUMES
gAppleApfsPartitionTypeGuid ## SOMETIMES_CONSUMES
gAppleBootVariableGuid ## SOMETIMES_CONSUMES
gAppleHfsPartitionTypeGuid ## SOMETIMES_CONSUMES
gAppleHfsBootPartitionTypeGuid ## SOMETIMES_CONSUMES
gAppleLegacyLoadAppFileGuid ## SOMETIMES_CONSUMES
[Protocols]

View File

@ -16,7 +16,9 @@
#include <Guid/AppleApfsInfo.h>
#include <Guid/AppleBless.h>
#include <Guid/AppleHfsInfo.h>
#include <Guid/AppleVariable.h>
#include <Guid/Gpt.h>
#include <Guid/FileInfo.h>
#include <Guid/GlobalVariable.h>
#include <Guid/OcVariables.h>
@ -26,15 +28,17 @@
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/SimpleTextOut.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcFileLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
STATIC
UINT32
InternalGetRequestedPolicyType (
OcGetDevicePolicyType (
IN EFI_HANDLE Handle,
OUT BOOLEAN *External OPTIONAL
)
@ -106,77 +110,66 @@ InternalGetRequestedPolicyType (
return 0;
}
EFI_STATUS
UINT32
OcGetFileSystemPolicyType (
IN EFI_HANDLE Handle
)
{
CONST EFI_PARTITION_ENTRY *PartitionEntry;
PartitionEntry = OcGetGptPartitionEntry (Handle);
if (PartitionEntry == NULL) {
DEBUG ((DEBUG_INFO, "OCB: missing partition info for %p\n", Handle));
return 0;
}
if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleApfsPartitionTypeGuid)) {
return OC_SCAN_ALLOW_FS_APFS;
}
if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) {
return OC_SCAN_ALLOW_FS_ESP;
}
//
// Unsure whether these two should be separate, likely not.
//
if (CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleHfsPartitionTypeGuid)
|| CompareGuid (&PartitionEntry->PartitionTypeGUID, &gAppleHfsBootPartitionTypeGuid)) {
return OC_SCAN_ALLOW_FS_HFS;
}
return 0;
}
RETURN_STATUS
InternalCheckScanPolicy (
IN EFI_HANDLE Handle,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs,
IN UINT32 Policy,
OUT BOOLEAN *External OPTIONAL
)
{
EFI_STATUS Status;
EFI_FILE_PROTOCOL *Root;
UINTN BufferSize;
UINT32 RequestedPolicy;
UINT32 DevicePolicy;
UINT32 FileSystemPolicy;
RequestedPolicy = InternalGetRequestedPolicyType (Handle, External);
if ((Policy & OC_SCAN_DEVICE_LOCK) != 0 && (Policy & RequestedPolicy) == 0) {
//
// Always request policy type due to external checks.
//
DevicePolicy = OcGetDevicePolicyType (Handle, External);
if ((Policy & OC_SCAN_DEVICE_LOCK) != 0 && (Policy & DevicePolicy) == 0) {
DEBUG ((DEBUG_INFO, "OCB: invalid device policy (%u/%u) for %p\n", DevicePolicy, Policy, Handle));
return EFI_SECURITY_VIOLATION;
}
Status = EFI_SUCCESS;
if ((Policy & OC_SCAN_FILE_SYSTEM_LOCK) != 0) {
Status = SimpleFs->OpenVolume (SimpleFs, &Root);
FileSystemPolicy = OcGetFileSystemPolicyType (Handle);
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_SECURITY_VIOLATION;
//
// FIXME: We cannot use EfiPartitionInfo protocol, as it is not
// widely available, and when it is, it is not guaranteed to be spec compliant.
// For this reason we would really like to implement ApplePartitionInfo protocol,
// but currently it is not a priority.
//
if ((Policy & OC_SCAN_ALLOW_FS_APFS) != 0 && EFI_ERROR (Status)) {
BufferSize = 0;
Status = Root->GetInfo (Root, &gAppleApfsVolumeInfoGuid, &BufferSize, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = EFI_SUCCESS;
}
}
//
// FIXME: This is even worse but works for testing the concept purposes.
// Current logic is blessed but not APFS.
//
if ((Policy & OC_SCAN_ALLOW_FS_HFS) != 0 && EFI_ERROR (Status)) {
BufferSize = 0;
Status = Root->GetInfo (Root, &gAppleApfsVolumeInfoGuid, &BufferSize, NULL);
if (Status != EFI_BUFFER_TOO_SMALL) {
BufferSize = 0;
Status = Root->GetInfo (Root, &gAppleBlessedSystemFileInfoGuid, &BufferSize, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = EFI_SUCCESS;
} else {
BufferSize = 0;
Status = Root->GetInfo (Root, &gAppleBlessedSystemFolderInfoGuid, &BufferSize, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = EFI_SUCCESS;
}
}
}
}
Root->Close (Root);
if (EFI_ERROR (Status)) {
return Status;
if ((Policy & FileSystemPolicy) == 0) {
DEBUG ((DEBUG_INFO, "OCB: invalid file system policy (%u/%u) for %p\n", FileSystemPolicy, Policy, Handle));
return EFI_SECURITY_VIOLATION;
}
}
return EFI_SUCCESS;
return RETURN_SUCCESS;
}