1/* 2 * Copyright (c) 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <pexpert/pexpert.h> 30#include <sys/csr.h> 31#include <sys/errno.h> 32#include <sys/sysproto.h> 33#include <sys/systm.h> 34#include <sys/types.h> 35 36/* allow everything by default? */ 37/* XXX: set this to 0 later: <rdar://problem/16040413> */ 38static int csr_allow_all = 1; 39 40/* allow everything if CSR_ALLOW_APPLE_INTERNAL is set */ 41static int csr_allow_internal = 1; 42 43/* Current boot-arg policy: 44 * rootless=0 45 * csr_allow_all = 1 46 * rootless=1 47 * csr_allow_all = 0 48 * csr_allow_internal = 0 49 * 50 * After <rdar://problem/16239861>: 51 * rootless=0 52 * no effect 53 * rootless=1 54 * csr_allow_internal = 0 55 * 56 * Enforcement policy: 57 * =============================== 58 * | csr_allow_internal 59 * | 0 1 60 * =============================== 61 * csr_ 0 | always customer 62 * allow_ | 63 * all 1 | never never 64 * =============================== 65 * NB: "customer" means enforce when 66 * CSR_ALLOW_APPLE_INTERNAL not set */ 67 68void 69csr_init(void) 70{ 71 boot_args *args = (boot_args *)PE_state.bootArgs; 72 if (args->flags & kBootArgsFlagCSRBoot) { 73 /* special booter; allow everything */ 74 csr_allow_all = 1; 75 } 76 77 int rootless_boot_arg; 78 if (PE_parse_boot_argn("rootless", &rootless_boot_arg, sizeof(rootless_boot_arg))) { 79 /* XXX: set csr_allow_all to boot arg value for now 80 * (to be removed by <rdar://problem/16239861>) */ 81 csr_allow_all = !rootless_boot_arg; 82 /* if rootless=1, do not allow everything when CSR_ALLOW_APPLE_INTERNAL is set */ 83 csr_allow_internal &= !rootless_boot_arg; 84 } 85} 86 87int 88csrctl(__unused proc_t p, struct csrctl_args *uap, __unused int32_t *retval) 89{ 90 int error = 0; 91 92 if (uap->useraddr == 0) 93 return EINVAL; 94 if (uap->usersize != sizeof(csr_config_t)) 95 return EINVAL; 96 97 switch (uap->op) { 98 case CSR_OP_CHECK: 99 { 100 csr_config_t mask; 101 error = copyin(uap->useraddr, &mask, sizeof(csr_config_t)); 102 103 if (error) 104 return error; 105 106 error = csr_check(mask); 107 break; 108 } 109 110 case CSR_OP_GET_ACTIVE_CONFIG: 111 case CSR_OP_GET_PENDING_CONFIG: /* fall through */ 112 { 113 csr_config_t config = 0; 114 if (uap->op == CSR_OP_GET_ACTIVE_CONFIG) 115 error = csr_get_active_config(&config); 116 else 117 error = csr_get_pending_config(&config); 118 119 if (error) 120 return error; 121 122 error = copyout(&config, uap->useraddr, sizeof(csr_config_t)); 123 break; 124 } 125 126 default: 127 error = EINVAL; 128 break; 129 } 130 131 return error; 132} 133 134int 135csr_get_active_config(csr_config_t *config) 136{ 137 boot_args *args = (boot_args *)PE_state.bootArgs; 138 if (args->flags & kBootArgsFlagCSRActiveConfig) { 139 *config = args->csrActiveConfig & CSR_VALID_FLAGS; 140 } else { 141 /* XXX: change to 0 when <rdar://problem/16239698> is in the build */ 142 *config = CSR_ALLOW_APPLE_INTERNAL; 143 } 144 145 return 0; 146} 147 148int 149csr_get_pending_config(csr_config_t *config) 150{ 151 boot_args *args = (boot_args *)PE_state.bootArgs; 152 if (args->flags & kBootArgsFlagCSRPendingConfig) { 153 *config = args->csrPendingConfig & CSR_VALID_FLAGS; 154 return 0; 155 } else { 156 return ENOENT; 157 } 158} 159 160int 161csr_check(csr_config_t mask) 162{ 163 if (csr_allow_all) { 164 return 0; 165 } 166 167 csr_config_t config; 168 int error = csr_get_active_config(&config); 169 if (error) { 170 return error; 171 } 172 173 if (csr_allow_internal && (config & CSR_ALLOW_APPLE_INTERNAL)) { 174 return 0; 175 } 176 177 if (mask == 0) { 178 /* pass 0 to check if Rootless enforcement is active */ 179 return -1; 180 } 181 182 error = (config & mask) ? 0 : EPERM; 183 return error; 184} 185 186void 187csr_set_allow_all(int value) 188{ 189 csr_allow_all = !!value; // force value to 0 or 1 190} 191