mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
263 lines
9.2 KiB
C
263 lines
9.2 KiB
C
/** @file
|
|
Copyright (C) 2018, vit9696. All rights reserved.
|
|
Copyright (C) 2020, PMheart. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#include "ocvalidate.h"
|
|
#include "OcValidateLib.h"
|
|
|
|
#include <Library/OcBootManagementLib.h>
|
|
#include <Library/OcConfigurationLib.h>
|
|
#include <Protocol/OcLog.h>
|
|
|
|
/**
|
|
Validate if SecureBootModel has allowed value.
|
|
|
|
@param[in] SecureBootModel SecureBootModel retrieved from user config.
|
|
|
|
@retval TRUE If SecureBootModel is valid.
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
ValidateSecureBootModel (
|
|
IN CONST CHAR8 *SecureBootModel
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
CONST CHAR8 *AllowedSecureBootModel[] = {
|
|
"Default", "Disabled",
|
|
"j137", "j680", "j132", "j174", "j140k",
|
|
"j780", "j213", "j140a", "j152f", "j160",
|
|
"j230k", "j214k", "j223", "j215", "j185", "j185f",
|
|
"x86legacy"
|
|
};
|
|
|
|
for (Index = 0; Index < ARRAY_SIZE (AllowedSecureBootModel); ++Index) {
|
|
if (AsciiStrCmp (SecureBootModel, AllowedSecureBootModel[Index]) == 0) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
UINT32
|
|
CheckMisc (
|
|
IN OC_GLOBAL_CONFIG *Config
|
|
)
|
|
{
|
|
UINT32 ErrorCount;
|
|
UINT32 Index;
|
|
OC_MISC_CONFIG *UserMisc;
|
|
OC_UEFI_CONFIG *UserUefi;
|
|
UINT32 ConsoleAttributes;
|
|
CONST CHAR8 *HibernateMode;
|
|
UINT32 PickerAttributes;
|
|
CONST CHAR8 *PickerMode;
|
|
UINT64 DisplayLevel;
|
|
UINT64 AllowedDisplayLevel;
|
|
UINT64 HaltLevel;
|
|
UINT64 AllowedHaltLevel;
|
|
UINT32 Target;
|
|
CONST CHAR8 *BootProtect;
|
|
BOOLEAN IsRequestBootVarRoutingEnabled;
|
|
CONST CHAR8 *AsciiDmgLoading;
|
|
UINT32 ExposeSensitiveData;
|
|
CONST CHAR8 *AsciiVault;
|
|
UINT32 ScanPolicy;
|
|
UINT32 AllowedScanPolicy;
|
|
CONST CHAR8 *SecureBootModel;
|
|
CONST CHAR8 *Arguments;
|
|
CONST CHAR8 *Comment;
|
|
CONST CHAR8 *AsciiName;
|
|
CONST CHAR16 *UnicodeName;
|
|
CONST CHAR8 *Path;
|
|
|
|
DEBUG ((DEBUG_VERBOSE, "config loaded into Misc checker!\n"));
|
|
|
|
ErrorCount = 0;
|
|
UserMisc = &Config->Misc;
|
|
UserUefi = &Config->Uefi;
|
|
ConsoleAttributes = UserMisc->Boot.ConsoleAttributes;
|
|
HibernateMode = OC_BLOB_GET (&UserMisc->Boot.HibernateMode);
|
|
PickerAttributes = UserMisc->Boot.PickerAttributes;
|
|
PickerMode = OC_BLOB_GET (&UserMisc->Boot.PickerMode);
|
|
DisplayLevel = UserMisc->Debug.DisplayLevel;
|
|
AllowedDisplayLevel = DEBUG_WARN | DEBUG_INFO | DEBUG_VERBOSE | DEBUG_ERROR;
|
|
HaltLevel = DisplayLevel;
|
|
AllowedHaltLevel = AllowedDisplayLevel;
|
|
Target = UserMisc->Debug.Target;
|
|
BootProtect = OC_BLOB_GET (&UserMisc->Security.BootProtect);
|
|
IsRequestBootVarRoutingEnabled = UserUefi->Quirks.RequestBootVarRouting;
|
|
AsciiDmgLoading = OC_BLOB_GET (&UserMisc->Security.DmgLoading);
|
|
ExposeSensitiveData = UserMisc->Security.ExposeSensitiveData;
|
|
AsciiVault = OC_BLOB_GET (&UserMisc->Security.Vault);
|
|
ScanPolicy = UserMisc->Security.ScanPolicy;
|
|
AllowedScanPolicy = OC_SCAN_FILE_SYSTEM_LOCK | OC_SCAN_DEVICE_LOCK | OC_SCAN_DEVICE_BITS | OC_SCAN_FILE_SYSTEM_BITS;
|
|
SecureBootModel = OC_BLOB_GET (&UserMisc->Security.SecureBootModel);
|
|
|
|
if ((ConsoleAttributes & ~0x7FU) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Boot->ConsoleAttributes has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if (AsciiStrCmp (HibernateMode, "None") != 0
|
|
&& AsciiStrCmp (HibernateMode, "Auto") != 0
|
|
&& AsciiStrCmp (HibernateMode, "RTC") != 0
|
|
&& AsciiStrCmp (HibernateMode, "NVRAM") != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Boot->HibernateMode is borked (Can only be None, Auto, RTC, or NVRAM)!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if ((PickerAttributes & ~OC_ATTR_ALL_BITS) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Boot->PickerAttributes is has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
//
|
|
// FIXME: Is OpenCanopy.efi mandatory if set to External? Or is this just a suggestion?
|
|
//
|
|
if (AsciiStrCmp (PickerMode, "Builtin") != 0
|
|
&& AsciiStrCmp (PickerMode, "External") != 0
|
|
&& AsciiStrCmp (PickerMode, "Apple") != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Boot->PickerMode is borked (Can only be Builtin, External, or Apple)!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
//
|
|
// FIXME: Check whether DisplayLevel only supports values within AllowedDisplayLevel, or all possible levels in DebugLib.h?
|
|
//
|
|
if ((DisplayLevel & ~AllowedDisplayLevel) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Debug->DisplayLevel is has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
if ((HaltLevel & ~AllowedHaltLevel) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->HaltLevel has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if ((Target & ~OC_LOG_ALL_BITS) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Debug->Target has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
//
|
|
// TODO: Check requirements of Security->AuthRestart.
|
|
//
|
|
|
|
if (AsciiStrCmp (BootProtect, "None") != 0
|
|
&& AsciiStrCmp (BootProtect, "Bootstrap") != 0
|
|
&& AsciiStrCmp (BootProtect, "BootstrapShort") != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->BootProtect is borked (Can only be None, Bootstrap, or BootstrapShort)!\n"));
|
|
++ErrorCount;
|
|
} else if (AsciiStrCmp (BootProtect, "Bootstrap") == 0
|
|
|| AsciiStrCmp (BootProtect, "BootstrapShort") == 0) {
|
|
if (!IsRequestBootVarRoutingEnabled) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->BootProtect is set to %a which requires UEFI->Quirks->RequestBootVarRouting to be enabled!\n", BootProtect));
|
|
++ErrorCount;
|
|
}
|
|
//
|
|
// NOTE: RequestBootVarRouting requires OpenRuntime.efi, which will be checked in UEFI checker.
|
|
//
|
|
}
|
|
|
|
if (AsciiStrCmp (AsciiDmgLoading, "Disabled") != 0
|
|
&& AsciiStrCmp (AsciiDmgLoading, "Signed") != 0
|
|
&& AsciiStrCmp (AsciiDmgLoading, "Any") != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->DmgLoading is borked (Can only be Disabled, Signed, or Any)!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if ((ExposeSensitiveData & ~OCS_EXPOSE_ALL_BITS) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->ExposeSensitiveData has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if (AsciiStrCmp (AsciiVault, "Optional") != 0
|
|
&& AsciiStrCmp (AsciiVault, "Basic") != 0
|
|
&& AsciiStrCmp (AsciiVault, "Secure") != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->Vault is borked (Can only be Optional, Basic, or Secure)!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
//
|
|
// ScanPolicy can be zero (failsafe value).
|
|
//
|
|
if (ScanPolicy != 0) {
|
|
if ((ScanPolicy & ~AllowedScanPolicy) != 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->ScanPolicy has unknown bits set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if ((ScanPolicy & OC_SCAN_FILE_SYSTEM_BITS) != 0 && (ScanPolicy & OC_SCAN_FILE_SYSTEM_LOCK) == 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->ScanPolicy requests scanning filesystem, but OC_SCAN_FILE_SYSTEM_LOCK (bit 0) is not set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
if ((ScanPolicy & OC_SCAN_DEVICE_BITS) != 0 && (ScanPolicy & OC_SCAN_DEVICE_LOCK) == 0) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->ScanPolicy requests scanning devices, but OC_SCAN_DEVICE_LOCK (bit 1) is not set!\n"));
|
|
++ErrorCount;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate SecureBootModel.
|
|
//
|
|
if (!ValidateSecureBootModel (SecureBootModel)) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Security->SecureBootModel is borked!\n"));
|
|
++ErrorCount;
|
|
}
|
|
|
|
for (Index = 0; Index < UserMisc->Entries.Count; ++Index) {
|
|
Arguments = OC_BLOB_GET (&UserMisc->Entries.Values[Index]->Arguments);
|
|
Comment = OC_BLOB_GET (&UserMisc->Entries.Values[Index]->Comment);
|
|
AsciiName = OC_BLOB_GET (&UserMisc->Entries.Values[Index]->Name);
|
|
Path = OC_BLOB_GET (&UserMisc->Entries.Values[Index]->Path);
|
|
|
|
//
|
|
// Sanitise strings.
|
|
//
|
|
// NOTE: As Arguments takes identical requirements of Comment,
|
|
// we use Comment sanitiser here.
|
|
//
|
|
if (!AsciiCommentIsLegal (Arguments)) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Entries[%u]->Arguments contains illegal character!\n", Index));
|
|
++ErrorCount;
|
|
}
|
|
if (!AsciiCommentIsLegal (Comment)) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Entries[%u]->Comment contains illegal character!\n", Index));
|
|
++ErrorCount;
|
|
}
|
|
|
|
UnicodeName = AsciiStrCopyToUnicode (AsciiName, 0);
|
|
if (UnicodeName != NULL) {
|
|
if (!UnicodeIsFilteredString (UnicodeName, TRUE)) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Entries[%u]->Name contains illegal character!\n", Index));
|
|
++ErrorCount;
|
|
}
|
|
|
|
FreePool ((VOID *) UnicodeName);
|
|
}
|
|
|
|
//
|
|
// FIXME: Properly sanitise Path.
|
|
//
|
|
if (!AsciiCommentIsLegal (Path)) {
|
|
DEBUG ((DEBUG_WARN, "Misc->Entries[%u]->Path contains illegal character!\n", Index));
|
|
++ErrorCount;
|
|
}
|
|
}
|
|
|
|
return ReportError (__func__, ErrorCount);
|
|
}
|