Skip to content

Commit

Permalink
BootManagement: Add csrutil EFI tool and Toogle SIP boot option
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebeaton committed May 28, 2021
1 parent acd3217 commit eb5cc3e
Show file tree
Hide file tree
Showing 32 changed files with 801 additions and 214 deletions.
306 changes: 306 additions & 0 deletions Application/CsrUtil/CsrUtil.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
/** @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/OcBootManagementLib.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", CSR_APPLE_DISABLE_SIP_DEFAULT);
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", CSR_APPLE_DISABLE_SIP_DEFAULT);
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;
CHAR16 **OldArgv;
UINT32 CsrConfig;
UINT32 Attributes;

Status = GetArguments (&Argc, &Argv);

if (EFI_ERROR (Status)) {
Print (L"GetArguments - %r\n", Status);
return Status;
}

OldArgv = Argv;
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 = CSR_APPLE_DISABLE_SIP_DEFAULT;
} 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 = CSR_APPLE_DISABLE_SIP_DEFAULT;
} 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 (OldArgv != Argv) {
//
// Pause if detect called as tool
//
WaitForKeyPress (L"Press any key to continue...");
}

return EFI_SUCCESS;
}
39 changes: 39 additions & 0 deletions Application/CsrUtil/CsrUtil.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## @file
# Basic reimplementation of SIP aspects of csrutil.
#
# Copyright (C) 2021, Mike Beaton. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-3-Clause
##


[Defines]
INF_VERSION = 0x00010005
BASE_NAME = CsrUtil
FILE_GUID = 6760D9B7-C556-4C3D-B599-B0444A469BC3
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain

#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE

#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#

[Sources]
CsrUtil.c

[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OpenCorePkg/OpenCorePkg.dec

[LibraryClasses]
OcBootManagementLib
UefiBootServicesTableLib
UefiApplicationEntryPoint
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ OpenCore Changelog
- Added Hyper-V device path expansion to allow setting default boot volume
- Added `Apple` variant of `GopPassThrough` to handle only `AppleFramebufferInfo` handles
- Fixed further kernel patches not being processed if a patch was skipped due to arch mismatch
- Added optional Toggle SIP system boot menu option
- Added `CsrUtil.efi` tool, similar to Apple `csrutil`
- Removed support for `<TOOLPATH>.lbl`/`.l2x` pre-drawn entry labels
- Fixed previous text not cleared before console mode tools and entries in OpenCanopy

#### v0.6.9
- Fixed out-of-sync cursor movement rectangle when loading e.g. CrScreenshotDxe
Expand Down
Binary file modified Docs/Configuration.pdf
Binary file not shown.
Loading

0 comments on commit eb5cc3e

Please sign in to comment.