Skip to content

Instantly share code, notes, and snippets.

@leiless
Last active October 20, 2023 07:16
Show Gist options
  • Save leiless/59c05535fbaf1bce0593235e4d50f40d to your computer and use it in GitHub Desktop.
Save leiless/59c05535fbaf1bce0593235e4d50f40d to your computer and use it in GitHub Desktop.
[macOS] CSR get active config programatically
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
typedef uint32_t csr_config_t;
/* Those two functions are syscall */
/**
* Get active CSR config mask
* @return zero if success
* -1 if failed to get(errno will be set)
* @errno EINVAL, EFAULT if `csr_config_t *` is invalid
* @see xnu/bsd/kern/kern_csr.c
*/
extern int csr_get_active_config(csr_config_t *);
/**
* Check if given CSR mask is allowed
* @return 0 if given mask is allowed
* -1 if inactive(errno will be set)
* @errno EPERM if given mask is either invalid or disallowed
* @see xnu/bsd/kern/kern_csr.c
*/
extern int csr_check(csr_config_t);
/* CSR configuration flags */
#define CSR_ALLOW_UNTRUSTED_KEXTS (1 << 0)
#define CSR_ALLOW_UNRESTRICTED_FS (1 << 1)
#define CSR_ALLOW_TASK_FOR_PID (1 << 2)
#define CSR_ALLOW_KERNEL_DEBUGGER (1 << 3)
#define CSR_ALLOW_APPLE_INTERNAL (1 << 4)
#define CSR_ALLOW_DESTRUCTIVE_DTRACE (1 << 5) /* name deprecated */
#define CSR_ALLOW_UNRESTRICTED_DTRACE (1 << 5)
#define CSR_ALLOW_UNRESTRICTED_NVRAM (1 << 6)
#define CSR_ALLOW_DEVICE_CONFIGURATION (1 << 7)
#define CSR_ALLOW_ANY_RECOVERY_OS (1 << 8)
#define CSR_ALLOW_UNAPPROVED_KEXTS (1 << 9)
#define CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE (1 << 10)
#define CSR_ALLOW_UNAUTHENTICATED_ROOT (1 << 11) // macOS 11+
#define CSR_VALID_FLAGS (CSR_ALLOW_UNTRUSTED_KEXTS | \
CSR_ALLOW_UNRESTRICTED_FS | \
CSR_ALLOW_TASK_FOR_PID | \
CSR_ALLOW_KERNEL_DEBUGGER | \
CSR_ALLOW_APPLE_INTERNAL | \
CSR_ALLOW_UNRESTRICTED_DTRACE | \
CSR_ALLOW_UNRESTRICTED_NVRAM | \
CSR_ALLOW_DEVICE_CONFIGURATION | \
CSR_ALLOW_ANY_RECOVERY_OS | \
CSR_ALLOW_UNAPPROVED_KEXTS | \
CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE | \
CSR_ALLOW_UNAUTHENTICATED_ROOT)
static const char *mask_str[] = {
"CSR_ALLOW_UNTRUSTED_KEXTS",
"CSR_ALLOW_UNRESTRICTED_FS",
"CSR_ALLOW_TASK_FOR_PID",
"CSR_ALLOW_KERNEL_DEBUGGER",
"CSR_ALLOW_APPLE_INTERNAL",
"CSR_ALLOW_UNRESTRICTED_DTRACE",
"CSR_ALLOW_UNRESTRICTED_NVRAM",
"CSR_ALLOW_DEVICE_CONFIGURATION",
"CSR_ALLOW_ANY_RECOVERY_OS",
"CSR_ALLOW_UNAPPROVED_KEXTS",
"CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE",
"CSR_ALLOW_UNAUTHENTICATED_ROOT",
};
int main(void)
{
csr_config_t csr;
(void) csr_get_active_config(&csr);
printf("csr config: %#x\n\n", csr);
size_t i, n = sizeof(mask_str) / sizeof(*mask_str);
for (i = 0; i < n; i++) {
if (csr_check(1 << i) == 0) {
printf("%36s: yes\n", mask_str[i]);
} else {
printf("%36s: (%d %s)\n", mask_str[i], errno, strerror(errno));
}
}
return 0;
}
@leiless
Copy link
Author

leiless commented Aug 11, 2019

$ nvram -x csr-active-config
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>csr-active-config</key>
	<data>
	dwIAAA==
	</data>
</dict>
</plist>

Data type csr_config_t , aka uint32_t

@leiless
Copy link
Author

leiless commented Feb 26, 2021

Store csr_config_t in little endian

$ echo dwIAAA== | base64 -d | hexdump
0000000 77 02 00 00
0000004

$ echo EQAAAA== | base64 -d | hexdump
0000000 11 00 00 00
0000004

@leiless
Copy link
Author

leiless commented Feb 26, 2021

Sample output

Note that csr_check(0) always success(i.e. return zero)

# In recovery mode
$ csrutil enable --without kext

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.4
BuildVersion:	19E224g

$ nvram -x csr-active-config | grep -E '\s<data>$' -A1 | tail -1 | base64 -d | hexdump
0000000 11 00 00 00
0000004

$ csrutil status
System Integrity Protection status: unknown (Custom Configuration).

Configuration:
	Apple Internal: disabled
	Kext Signing: disabled
	Filesystem Protections: enabled
	Debugging Restrictions: enabled
	DTrace Restrictions: enabled
	NVRAM Protections: enabled
	BaseSystem Verification: enabled

This is an unsupported configuration, likely to break in the future and leave your machine in an unknown state.

$ gcc -Wall csr.c -ocsr
$ ./csr
csr config: 0x1

           CSR_ALLOW_UNTRUSTED_KEXTS: yes
           CSR_ALLOW_UNRESTRICTED_FS: (1 Operation not permitted)
              CSR_ALLOW_TASK_FOR_PID: (1 Operation not permitted)
           CSR_ALLOW_KERNEL_DEBUGGER: yes
            CSR_ALLOW_APPLE_INTERNAL: (1 Operation not permitted)
       CSR_ALLOW_UNRESTRICTED_DTRACE: (1 Operation not permitted)
        CSR_ALLOW_UNRESTRICTED_NVRAM: (1 Operation not permitted)
      CSR_ALLOW_DEVICE_CONFIGURATION: (1 Operation not permitted)
           CSR_ALLOW_ANY_RECOVERY_OS: (1 Operation not permitted)
          CSR_ALLOW_UNAPPROVED_KEXTS: (1 Operation not permitted)
CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE: (1 Operation not permitted)
      CSR_ALLOW_UNAUTHENTICATED_ROOT: (1 Operation not permitted)

see:
http://xr.anadoxin.org/source2/xref/macos-11.0.1-bigsur/xnu-7195.50.7.100.1/bsd/kern/kern_csr.c#csr_get_active_config
http://xr.anadoxin.org/source2/xref/macos-11.0.1-bigsur/xnu-7195.50.7.100.1/bsd/kern/kern_csr.c#csr_check

http://xr.anadoxin.org/source2/xref/macos-10.15.6-catalina/xnu-6153.141.1/bsd/kern/kern_csr.c#csr_get_active_config
http://xr.anadoxin.org/source2/xref/macos-10.15.6-catalina/xnu-6153.141.1/bsd/kern/kern_csr.c#csr_check

@leiless
Copy link
Author

leiless commented Feb 26, 2021

Note the difference between Apple Internal: disabled and CSR_ALLOW_APPLE_INTERNAL: (1 Operation not permitted)

                            puts("enabled (Custom Configuration).\n");
                            puts("Configuration:");
                            rsi = "disabled";
                            if ((var_B4 & 0x10) != 0x0) {
                                    rsi = "enabled";
                            }
                            printf("\tApple Internal: %s\n", rsi);

...

                                    rsi = *(rbx + objc_cls_ref_NSMutableArray);
                                    rdx = "enabled";
                                    if ((var_B4 & *(int32_t *)(rbx + 0x1000032a0)) != 0x0) {
                                            rdx = "disabled";
                                    }
                                    printf("\t%s: %s\n", rsi, rdx);

Detail:
https://gist.github.com/leiless/7ee62d6589397f3bca4a1830d5405cbb#file-csrutil_entrypoint-c-L45-L49
https://gist.github.com/leiless/7ee62d6589397f3bca4a1830d5405cbb#file-csrutil_entrypoint-c-L52-L57

@leiless
Copy link
Author

leiless commented Feb 26, 2021

# In recovery mode
$ csrutil disable

$ nvram -x csr-active-config | grep -E '\s<data>$' -A1 | tail -1 | base64 -d | hexdump
0000000 77 00 00 00
0000004

$ csrutil status
System Integrity Protection status: disabled.

$ ./csr
csr config: 0x67

           CSR_ALLOW_UNTRUSTED_KEXTS: yes
           CSR_ALLOW_UNRESTRICTED_FS: yes
              CSR_ALLOW_TASK_FOR_PID: yes
           CSR_ALLOW_KERNEL_DEBUGGER: yes
            CSR_ALLOW_APPLE_INTERNAL: (1 Operation not permitted)
       CSR_ALLOW_UNRESTRICTED_DTRACE: yes
        CSR_ALLOW_UNRESTRICTED_NVRAM: yes
      CSR_ALLOW_DEVICE_CONFIGURATION: (1 Operation not permitted)
           CSR_ALLOW_ANY_RECOVERY_OS: (1 Operation not permitted)
          CSR_ALLOW_UNAPPROVED_KEXTS: (1 Operation not permitted)
CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE: (1 Operation not permitted)
      CSR_ALLOW_UNAUTHENTICATED_ROOT: (1 Operation not permitted)

@leiless
Copy link
Author

leiless commented Feb 26, 2021

# In recovery mode
$ csrutil enable

$ nvram -x csr-active-config | grep -E '\s<data>$' -A1 | tail -1 | base64 -d | hexdump
0000000 10 00 00 00
0000004

$ csrutil status
System Integrity Protection status: enabled.

$ ./csr
csr config: 0

           CSR_ALLOW_UNTRUSTED_KEXTS: (1 Operation not permitted)
           CSR_ALLOW_UNRESTRICTED_FS: (1 Operation not permitted)
              CSR_ALLOW_TASK_FOR_PID: (1 Operation not permitted)
           CSR_ALLOW_KERNEL_DEBUGGER: (1 Operation not permitted)
            CSR_ALLOW_APPLE_INTERNAL: (1 Operation not permitted)
       CSR_ALLOW_UNRESTRICTED_DTRACE: (1 Operation not permitted)
        CSR_ALLOW_UNRESTRICTED_NVRAM: (1 Operation not permitted)
      CSR_ALLOW_DEVICE_CONFIGURATION: (1 Operation not permitted)
           CSR_ALLOW_ANY_RECOVERY_OS: (1 Operation not permitted)
          CSR_ALLOW_UNAPPROVED_KEXTS: (1 Operation not permitted)
CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE: (1 Operation not permitted)
      CSR_ALLOW_UNAUTHENTICATED_ROOT: (1 Operation not permitted)

@leiless
Copy link
Author

leiless commented Mar 1, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment