#include <pexpert/pexpert.h>
#include <sys/csr.h>
#include <sys/errno.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/types.h>
static int csr_allow_all = 0;
void
csr_init(void)
{
boot_args *args = (boot_args *)PE_state.bootArgs;
if (args->flags & kBootArgsFlagCSRBoot) {
csr_allow_all = 1;
}
}
int
csr_get_active_config(csr_config_t *config)
{
boot_args *args = (boot_args *)PE_state.bootArgs;
if (args->flags & kBootArgsFlagCSRActiveConfig) {
*config = args->csrActiveConfig & CSR_VALID_FLAGS;
} else {
*config = 0;
}
return 0;
}
int
csr_check(csr_config_t mask)
{
boot_args *args = (boot_args *)PE_state.bootArgs;
if (mask & CSR_ALLOW_DEVICE_CONFIGURATION)
return (args->flags & kBootArgsFlagCSRConfigMode) ? 0 : EPERM;
csr_config_t config;
int ret = csr_get_active_config(&config);
if (ret) {
return ret;
}
if ((config & (CSR_ALLOW_UNTRUSTED_KEXTS|CSR_ALLOW_APPLE_INTERNAL)) != 0)
config |= CSR_ALLOW_KERNEL_DEBUGGER;
ret = ((config & mask) == mask) ? 0 : EPERM;
if (ret == EPERM) {
if (csr_allow_all && (mask & CSR_ALWAYS_ENFORCED_FLAGS) == 0)
ret = 0;
}
return ret;
}
int syscall_csr_check(struct csrctl_args *args);
int syscall_csr_get_active_config(struct csrctl_args *args);
int
syscall_csr_check(struct csrctl_args *args)
{
csr_config_t mask = 0;
int error = 0;
if (args->useraddr == 0 || args->usersize != sizeof(mask))
return EINVAL;
error = copyin(args->useraddr, &mask, sizeof(mask));
if (error)
return error;
return csr_check(mask);
}
int
syscall_csr_get_active_config(struct csrctl_args *args)
{
csr_config_t config = 0;
int error = 0;
if (args->useraddr == 0 || args->usersize != sizeof(config))
return EINVAL;
error = csr_get_active_config(&config);
if (error)
return error;
return copyout(&config, args->useraddr, sizeof(config));
}
int
csrctl(__unused proc_t p, struct csrctl_args *args, __unused int32_t *retval)
{
switch (args->op) {
case CSR_SYSCALL_CHECK:
return syscall_csr_check(args);
case CSR_SYSCALL_GET_ACTIVE_CONFIG:
return syscall_csr_get_active_config(args);
default:
return ENOSYS;
}
}