mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
310 lines
7.3 KiB
C
310 lines
7.3 KiB
C
/** @file
|
|
Basic reimplementation of SIP aspects of csrutil.
|
|
|
|
Copyright (c) 2021, Mike Beaton. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-3-Clause
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/OcDebugLogLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/OcVariableLib.h>
|
|
#include <Library/UefiApplicationEntryPoint.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <IndustryStandard/AppleCsrConfig.h>
|
|
#include <Guid/AppleVariable.h>
|
|
|
|
// #define PRINT_ARGUMENTS
|
|
|
|
#define MAX_FIRST_ARG_LEN 15
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SplitArguments (
|
|
UINTN *Argc,
|
|
CHAR16 ***Argv
|
|
)
|
|
{
|
|
CHAR16 *Space;
|
|
|
|
STATIC CHAR16 *NewArgs[3];
|
|
STATIC CHAR16 FirstArg[MAX_FIRST_ARG_LEN + 1];
|
|
|
|
if (*Argc != 2) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Space = StrStr ((*Argv)[1], L" ");
|
|
if (Space == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (Space - (*Argv)[1] > MAX_FIRST_ARG_LEN) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
StrnCpyS (FirstArg, ARRAY_SIZE (FirstArg), (*Argv)[1], Space - (*Argv)[1]);
|
|
|
|
NewArgs[0] = L"Self";
|
|
NewArgs[1] = FirstArg;
|
|
NewArgs[2] = ++Space;
|
|
|
|
*Argc = 3;
|
|
*Argv = NewArgs;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
#ifdef PRINT_ARGUMENTS
|
|
STATIC
|
|
VOID
|
|
PrintArguments (
|
|
UINTN Argc,
|
|
CHAR16 **Argv
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < Argc; ++Index) {
|
|
Print (L"%u: %s\n", Index, Argv[Index]);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
STATIC
|
|
VOID
|
|
PrintUsage (
|
|
VOID
|
|
)
|
|
{
|
|
Print (L"usage: csrutil <command> [<csr-value>]\n");
|
|
Print (L"Modify the System Integrity Protection configuration.\n");
|
|
Print (L"Available commands:\n");
|
|
Print (L"\n");
|
|
Print (L" clear\n");
|
|
Print (L" Clear the existing configuration.\n");
|
|
Print (L" disable [<csr-value>]\n");
|
|
Print (L" Disable the protection on the machine (use default 0x%x or csr value).\n", OC_CSR_DISABLE_FLAGS);
|
|
Print (L" enable [<csr-value>]\n");
|
|
Print (L" Enable the protection on the machine (use 0 or other legal csr value).\n");
|
|
Print (L" toggle [<csr-value>]\n");
|
|
Print (L" Toggle the protection on the machine (use default 0x%x or csr value).\n", OC_CSR_DISABLE_FLAGS);
|
|
Print (L" status\n");
|
|
Print (L" Display the current configuration.\n");
|
|
Print (L"\n");
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UefiMain (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS OldStatus;
|
|
EFI_STATUS Status;
|
|
UINTN Data;
|
|
CHAR16 *EndPtr;
|
|
UINTN Argc;
|
|
CHAR16 **Argv;
|
|
UINT32 CsrConfig;
|
|
UINT32 Attributes;
|
|
|
|
Status = GetArguments (&Argc, &Argv);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
Print (L"GetArguments - %r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Status = SplitArguments (&Argc, &Argv);
|
|
|
|
#ifdef PRINT_ARGUMENTS
|
|
if (!EFI_ERROR (Status)) {
|
|
PrintArguments (Argc, Argv);
|
|
}
|
|
|
|
#endif
|
|
|
|
if (EFI_ERROR (Status) || (Argc < 2)) {
|
|
PrintUsage ();
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (Argc > 2) {
|
|
Data = 0;
|
|
if (OcUnicodeStartsWith (Argv[2], L"0x", TRUE)) {
|
|
Status = StrHexToUintnS (Argv[2], &EndPtr, &Data);
|
|
} else {
|
|
Status = StrDecimalToUintnS (Argv[2], &EndPtr, &Data);
|
|
}
|
|
|
|
if (!EFI_ERROR (Status) && ((EndPtr != &Argv[2][StrLen (Argv[2])]) || ((Data & MAX_UINT32) != Data))) {
|
|
Status = EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
PrintUsage ();
|
|
return Status;
|
|
}
|
|
|
|
if ((Argc == 2) && (StrCmp (Argv[1], L"status") == 0)) {
|
|
//
|
|
// Status
|
|
//
|
|
Print (L"System Integrity Protection status: ");
|
|
} else {
|
|
//
|
|
// When changing status, use existing attributes where present
|
|
// (e.g. keep changes made while WriteFlash=false as volatile only)
|
|
//
|
|
Status = OcGetSip (&CsrConfig, &Attributes);
|
|
|
|
if ((Status != EFI_NOT_FOUND) && EFI_ERROR (Status)) {
|
|
Print (L"Error getting SIP status - %r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
if (Status == EFI_NOT_FOUND) {
|
|
Attributes = CSR_APPLE_SIP_NVRAM_NV_ATTR;
|
|
} else {
|
|
//
|
|
// We are finding other bits set on Apl, specifically 0x80000000,
|
|
// so only consider relevant bits.
|
|
//
|
|
Attributes &= CSR_APPLE_SIP_NVRAM_NV_ATTR;
|
|
}
|
|
|
|
if ((Argc == 2) && (StrCmp (Argv[1], L"clear") == 0)) {
|
|
//
|
|
// Clear
|
|
//
|
|
OldStatus = Status;
|
|
|
|
Status = OcSetSip (NULL, Attributes);
|
|
|
|
if (EFI_ERROR (Status) && !((OldStatus == EFI_NOT_FOUND) && (Status == EFI_NOT_FOUND))) {
|
|
Print (L"Error clearing SIP - r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Print (L"Successfully cleared system integrity configuration: ");
|
|
} else if ((Argc <= 3) && (StrCmp (Argv[1], L"disable") == 0)) {
|
|
//
|
|
// Disable; allow anything except valid enable values
|
|
//
|
|
if (Argc == 2) {
|
|
CsrConfig = OC_CSR_DISABLE_FLAGS;
|
|
} else {
|
|
if ((Data & ~CSR_ALLOW_APPLE_INTERNAL) == 0) {
|
|
Print (L"Illegal value for %s\n", L"disable");
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
CsrConfig = (UINT32)Data;
|
|
}
|
|
|
|
Status = OcSetSip (&CsrConfig, Attributes);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
Print (L"Error disabling SIP - r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Print (L"System Integrity Protection is ");
|
|
} else if ((Argc <= 3) && (StrCmp (Argv[1], L"enable") == 0)) {
|
|
//
|
|
// Enable; allow user-specified Apple internal (which reports as enabled) or zero only
|
|
//
|
|
if (Argc == 2) {
|
|
CsrConfig = 0;
|
|
} else {
|
|
if ((Data & ~CSR_ALLOW_APPLE_INTERNAL) != 0) {
|
|
Print (L"Illegal value for %s\n", L"enable");
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
CsrConfig = (UINT32)Data;
|
|
}
|
|
|
|
Status = OcSetSip (&CsrConfig, Attributes);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
Print (L"Error enabling SIP - r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Print (L"System Integrity Protection is ");
|
|
} else if ((Argc <= 3) && (StrCmp (Argv[1], L"toggle") == 0)) {
|
|
//
|
|
// Toggle; allow anything except valid enable values
|
|
//
|
|
if (Argc == 2) {
|
|
CsrConfig = OC_CSR_DISABLE_FLAGS;
|
|
} else {
|
|
if ((Data & ~CSR_ALLOW_APPLE_INTERNAL) == 0) {
|
|
Print (L"Illegal value for %s\n", L"toggle");
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
CsrConfig = (UINT32)Data;
|
|
}
|
|
|
|
Status = OcToggleSip (CsrConfig);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
Print (L"Error toggling SIP - r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Print (L"System Integrity Protection value was toggled to ");
|
|
} else {
|
|
//
|
|
// Unsupported
|
|
//
|
|
PrintUsage ();
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add result
|
|
//
|
|
Status = OcGetSip (&CsrConfig, &Attributes);
|
|
|
|
if ((Status != EFI_NOT_FOUND) && EFI_ERROR (Status)) {
|
|
Print (L"error getting SIP status - %r\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
if (Status != EFI_NOT_FOUND) {
|
|
Attributes &= CSR_APPLE_SIP_NVRAM_NV_ATTR;
|
|
}
|
|
|
|
Print (L"%sd (", OcIsSipEnabled (Status, CsrConfig) ? L"enable" : L"disable");
|
|
if (Status == EFI_NOT_FOUND) {
|
|
Print (L"nvram var not set");
|
|
} else {
|
|
Print (L"0x%x", CsrConfig);
|
|
if ((Attributes & ~EFI_VARIABLE_NON_VOLATILE) != CSR_APPLE_SIP_NVRAM_ATTR) {
|
|
Print (L", UNKNOWN: 0x%x", Attributes);
|
|
} else if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
|
|
Print (L", volatile");
|
|
}
|
|
}
|
|
|
|
Print (L")\n");
|
|
|
|
if (StrCmp (Argv[0], L"Self") == 0) {
|
|
//
|
|
// Pause if detect called as tool
|
|
//
|
|
WaitForKeyPress (L"Press any key to continue...");
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|