mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
297 lines
7.9 KiB
C
297 lines
7.9 KiB
C
/** @file
|
|
Boot entry protocol implementation of Toggle SIP boot picker entry.
|
|
|
|
Copyright (c) 2022, Mike Beaton. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-3-Clause
|
|
**/
|
|
|
|
#include <Guid/AppleVariable.h>
|
|
#include <IndustryStandard/AppleCsrConfig.h>
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcVariableLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
|
#include <Protocol/OcBootEntry.h>
|
|
|
|
#define OC_MENU_TOGGLE_SIP "Toggle SIP (%a)"
|
|
#define OC_MENU_TOGGLE_SIP_SHOW_CSR "Toggle SIP (0x%X:%a)"
|
|
#define OC_MENU_TOGGLE_SIP_MAX_SIZE (\
|
|
sizeof(OC_MENU_TOGGLE_SIP_SHOW_CSR) \
|
|
+ sizeof(UINT32) * 2 * sizeof (CHAR8) - L_STR_LEN("%X") \
|
|
+ L_STR_LEN("Disabled") - L_STR_LEN("%a"))
|
|
|
|
STATIC UINT32 mCsrUserConfig;
|
|
STATIC UINT32 mCsrNextConfig;
|
|
STATIC UINT32 mAttributes;
|
|
STATIC BOOLEAN mShowCsr;
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SystemActionSetSip (
|
|
IN OUT OC_PICKER_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN IsEnabled;
|
|
UINT32 CsrActiveConfig;
|
|
|
|
Status = OcSetSip (&mCsrNextConfig, mAttributes);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "BEP: OcSetSip (0x%X, 0x%X) failed! - %r\n", mCsrNextConfig, mAttributes, Status));
|
|
return Status;
|
|
}
|
|
|
|
Status = OcGetSip (&CsrActiveConfig, &mAttributes);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "BEP: OcGetSip (0x%X, 0x%X) failed! - %r\n", mCsrNextConfig, mAttributes, Status));
|
|
return Status;
|
|
}
|
|
|
|
IsEnabled = OcIsSipEnabled (Status, CsrActiveConfig);
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"BEP: SystemActionSetSip csr-active-config=0x%X (SIP %a) - %r\n",
|
|
CsrActiveConfig,
|
|
(IsEnabled ? "enabled" : "disabled"),
|
|
Status
|
|
));
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC OC_PICKER_ENTRY mToggleSipBootEntries[1] = {
|
|
{
|
|
.Id = "toggle_sip",
|
|
.Name = NULL, ///< overridden in set up
|
|
.Path = NULL,
|
|
.Arguments = NULL,
|
|
.Flavour = NULL, ///< overridden in set up
|
|
.Auxiliary = TRUE,
|
|
.Tool = FALSE,
|
|
.TextMode = FALSE,
|
|
.RealPath = FALSE,
|
|
.SystemAction = SystemActionSetSip,
|
|
.AudioBasePath = NULL, ///< overridden in set up
|
|
.AudioBaseType = OC_VOICE_OVER_AUDIO_BASE_TYPE_OPEN_CORE
|
|
}
|
|
};
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ToggleSipGetBootEntries (
|
|
IN OUT OC_PICKER_CONTEXT *PickerContext,
|
|
IN CONST EFI_HANDLE Device OPTIONAL,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 CsrActiveConfig;
|
|
BOOLEAN IsEnabled;
|
|
CHAR8 *Name;
|
|
|
|
//
|
|
// Custom entries only.
|
|
//
|
|
if (Device != NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Configure current action.
|
|
//
|
|
Status = OcGetSip (&CsrActiveConfig, &mAttributes);
|
|
if (!EFI_ERROR (Status) || (Status == EFI_NOT_FOUND)) {
|
|
IsEnabled = OcIsSipEnabled (Status, CsrActiveConfig);
|
|
|
|
//
|
|
// Same logic as in CsrUtil.efi to determine attributes to use
|
|
// (specifically keep same V or NV setting as existing value, if any).
|
|
//
|
|
if (Status == EFI_NOT_FOUND) {
|
|
//
|
|
// TODO: We may want to upgrade Boot Entry Protocol again, so that
|
|
// this line is able to access and respect OC WriteFlash setting?
|
|
//
|
|
mAttributes = CSR_APPLE_SIP_NVRAM_NV_ATTR;
|
|
CsrActiveConfig = 0;
|
|
} else {
|
|
//
|
|
// We are finding other bits set on Apl, specifically 0x80000000,
|
|
// so only consider relevant bits.
|
|
//
|
|
mAttributes &= CSR_APPLE_SIP_NVRAM_NV_ATTR;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "BEP: ToggleSip failed to read csr-active-config, aborting! - %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
Name = AllocatePool (OC_MENU_TOGGLE_SIP_MAX_SIZE);
|
|
if (Name == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
if (mShowCsr) {
|
|
Status = OcAsciiSafeSPrint (
|
|
Name,
|
|
OC_MENU_TOGGLE_SIP_MAX_SIZE,
|
|
OC_MENU_TOGGLE_SIP_SHOW_CSR,
|
|
CsrActiveConfig,
|
|
IsEnabled ? "Enabled" : "Disabled"
|
|
);
|
|
} else {
|
|
Status = OcAsciiSafeSPrint (
|
|
Name,
|
|
OC_MENU_TOGGLE_SIP_MAX_SIZE,
|
|
OC_MENU_TOGGLE_SIP,
|
|
IsEnabled ? "Enabled" : "Disabled"
|
|
);
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ASSERT (FALSE);
|
|
FreePool (Name);
|
|
return EFI_ABORTED;
|
|
}
|
|
|
|
mToggleSipBootEntries[0].Name = Name;
|
|
if (IsEnabled) {
|
|
mToggleSipBootEntries[0].Flavour = OC_FLAVOUR_TOGGLE_SIP_ENABLED;
|
|
mToggleSipBootEntries[0].AudioBasePath = OC_VOICE_OVER_AUDIO_FILE_SIP_IS_ENABLED;
|
|
mCsrNextConfig = mCsrUserConfig;
|
|
} else {
|
|
mToggleSipBootEntries[0].Flavour = OC_FLAVOUR_TOGGLE_SIP_DISABLED;
|
|
mToggleSipBootEntries[0].AudioBasePath = OC_VOICE_OVER_AUDIO_FILE_SIP_IS_DISABLED;
|
|
mCsrNextConfig = 0;
|
|
}
|
|
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"BEP: Toggle SIP entry, currently %a, will change 0x%X->0x%X%a\n",
|
|
(IsEnabled ? "enabled" : "disabled"),
|
|
CsrActiveConfig,
|
|
mCsrNextConfig,
|
|
((mAttributes & EFI_VARIABLE_NON_VOLATILE) == 0 ? " (volatile)" : "")
|
|
));
|
|
|
|
*Entries = mToggleSipBootEntries;
|
|
*NumEntries = ARRAY_SIZE (mToggleSipBootEntries);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
ToggleSipFreeBootEntries (
|
|
IN OC_PICKER_ENTRY **Entries,
|
|
IN UINTN NumEntries
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
if (NumEntries == 0) {
|
|
return;
|
|
}
|
|
|
|
ASSERT (NumEntries == 1);
|
|
ASSERT (Entries != NULL);
|
|
|
|
for (Index = 0; Index < NumEntries; Index++) {
|
|
if (Entries[Index]->Name != NULL) {
|
|
FreePool ((VOID *)Entries[Index]->Name); ///< Discard const
|
|
}
|
|
}
|
|
}
|
|
|
|
STATIC
|
|
OC_BOOT_ENTRY_PROTOCOL
|
|
mToggleSipBootEntryProtocol = {
|
|
OC_BOOT_ENTRY_PROTOCOL_REVISION,
|
|
ToggleSipGetBootEntries,
|
|
ToggleSipFreeBootEntries
|
|
};
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UefiMain (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
OC_FLEX_ARRAY *ParsedLoadOptions;
|
|
CHAR16 *Option;
|
|
UINTN Index;
|
|
UINTN Data;
|
|
BOOLEAN HasUserCsr;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
ImageHandle,
|
|
&gEfiLoadedImageProtocolGuid,
|
|
(VOID **)&LoadedImage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = OcParseLoadOptions (LoadedImage, &ParsedLoadOptions);
|
|
HasUserCsr = FALSE;
|
|
if (!EFI_ERROR (Status)) {
|
|
for (Index = 0; Index < ParsedLoadOptions->Count; Index++) {
|
|
Option = OcParsedVarsItemAt (ParsedLoadOptions, Index)->Unicode.Name;
|
|
if (Option[0] != L'-') {
|
|
if (OcUnicodeStartsWith (Option, L"0x", TRUE)) {
|
|
Status = StrHexToUintnS (Option, NULL, &Data);
|
|
} else {
|
|
Status = StrDecimalToUintnS (Option, NULL, &Data);
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "BEP: ToggleSip cannot parse %s - %r\n", Option, Status));
|
|
HasUserCsr = FALSE;
|
|
} else {
|
|
HasUserCsr = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
mShowCsr = OcHasParsedVar (ParsedLoadOptions, L"--show-csr", OcStringFormatUnicode);
|
|
|
|
OcFlexArrayFree (&ParsedLoadOptions);
|
|
} else {
|
|
ASSERT (ParsedLoadOptions == NULL);
|
|
|
|
if (Status != EFI_NOT_FOUND) {
|
|
return Status;
|
|
}
|
|
|
|
mShowCsr = FALSE;
|
|
}
|
|
|
|
if (HasUserCsr) {
|
|
mCsrUserConfig = (UINT32)Data;
|
|
if (OcIsSipEnabled (EFI_SUCCESS, mCsrUserConfig)) {
|
|
DEBUG ((DEBUG_WARN, "BEP: Specified value 0x%X will not disable SIP!\n", mCsrUserConfig));
|
|
}
|
|
} else {
|
|
mCsrUserConfig = OC_CSR_DISABLE_FLAGS; ///< Defaults.
|
|
}
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&ImageHandle,
|
|
&gOcBootEntryProtocolGuid,
|
|
&mToggleSipBootEntryProtocol,
|
|
NULL
|
|
);
|
|
return Status;
|
|
}
|