2  * Copyright (c) 2007 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  30  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 
  31  * Copyright (c) 2001 Ilmar S. Habibulin 
  32  * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc. 
  33  * Copyright (c) 2005 SPARTA, Inc. 
  34  * All rights reserved. 
  36  * This software was developed by Robert Watson and Ilmar Habibulin for the 
  39  * This software was developed for the FreeBSD Project in part by Network 
  40  * Associates Laboratories, the Security Research Division of Network 
  41  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 
  42  * as part of the DARPA CHATS research program. 
  44  * Redistribution and use in source and binary forms, with or without 
  45  * modification, are permitted provided that the following conditions 
  47  * 1. Redistributions of source code must retain the above copyright 
  48  *    notice, this list of conditions and the following disclaimer. 
  49  * 2. Redistributions in binary form must reproduce the above copyright 
  50  *    notice, this list of conditions and the following disclaimer in the 
  51  *    documentation and/or other materials provided with the distribution. 
  53  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 
  54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
  57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  67 #ifndef _SECURITY_MAC_INTERNAL_H_ 
  68 #define _SECURITY_MAC_INTERNAL_H_ 
  71 #warning "MAC policy is not KPI, see Technical Q&A QA1574, this header will be removed in next version" 
  75 #include <sys/param.h> 
  76 #include <sys/queue.h> 
  77 #include <security/mac.h> 
  78 #include <security/mac_framework.h> 
  79 #include <security/mac_policy.h> 
  80 #include <security/mac_data.h> 
  81 #include <sys/sysctl.h> 
  82 #include <kern/locks.h> 
  83 #include <sys/kernel.h> 
  85 #include <sys/malloc.h> 
  88 #include <sys/systm.h> 
  89 #include <sys/socket.h> 
  90 #include <sys/socketvar.h> 
  91 #include <sys/vnode.h> 
  94  * MAC Framework sysctl namespace. 
  97 SYSCTL_DECL(_security
); 
  98 SYSCTL_DECL(_security_mac
); 
 102 struct mac_policy_list_element 
{ 
 103         struct mac_policy_conf 
*mpc
; 
 106 struct mac_policy_list 
{ 
 113         struct mac_policy_list_element  
*entries
; 
 116 typedef struct mac_policy_list mac_policy_list_t
; 
 120  * Policy that has registered with the framework for a specific 
 121  * label namespace name. 
 123 struct mac_label_listener 
{ 
 124         mac_policy_handle_t             mll_handle
; 
 125         LIST_ENTRY(mac_label_listener
)  mll_list
; 
 128 LIST_HEAD(mac_label_listeners_t
, mac_label_listener
); 
 131  * Type of list used to manage label namespace names. 
 133 struct mac_label_element 
{ 
 134         char                            mle_name
[MAC_MAX_LABEL_ELEMENT_NAME
]; 
 135         struct mac_label_listeners_t    mle_listeners
; 
 136         LIST_ENTRY(mac_label_element
)   mle_list
; 
 139 LIST_HEAD(mac_label_element_list_t
, mac_label_element
); 
 142  * MAC Framework global variables. 
 145 extern struct mac_label_element_list_t mac_label_element_list
; 
 146 extern struct mac_label_element_list_t mac_static_label_element_list
; 
 148 extern struct mac_policy_list mac_policy_list
; 
 151  * global flags to control whether a MACF subsystem is configured 
 152  * at all in the system. 
 154 extern unsigned int mac_device_enforce
; 
 155 extern unsigned int mac_pipe_enforce
; 
 156 extern unsigned int mac_posixsem_enforce
; 
 157 extern unsigned int mac_posixshm_enforce
; 
 158 extern unsigned int mac_proc_enforce
; 
 159 extern unsigned int mac_socket_enforce
; 
 160 extern unsigned int mac_system_enforce
; 
 161 extern unsigned int mac_sysvmsg_enforce
; 
 162 extern unsigned int mac_sysvsem_enforce
; 
 163 extern unsigned int mac_sysvshm_enforce
; 
 164 extern unsigned int mac_vm_enforce
; 
 165 extern unsigned int mac_vnode_enforce
; 
 167 extern unsigned int mac_label_vnodes
; 
 168 extern unsigned int mac_vnode_label_count
; 
 170 static bool mac_proc_check_enforce(proc_t p
); 
 172 static __inline__ 
bool 
 173 mac_proc_check_enforce(proc_t p
) 
 176         // Don't apply policies to the kernel itself. 
 177         return p 
!= kernproc
; 
 181 #endif // CONFIG_MACF 
 184 static bool mac_cred_check_enforce(kauth_cred_t cred
); 
 186 static __inline__ 
bool 
 187 mac_cred_check_enforce(kauth_cred_t cred
) 
 190         return cred 
!= proc_ucred(kernproc
); 
 194 #endif // CONFIG_MACF 
 198  * MAC Framework infrastructure functions. 
 201 int mac_error_select(int error1
, int error2
); 
 203 void  mac_policy_list_busy(void); 
 204 int   mac_policy_list_conditional_busy(void); 
 205 void  mac_policy_list_unbusy(void); 
 207 void           mac_labelzone_init(void); 
 208 struct label  
*mac_labelzone_alloc(int flags
); 
 209 void           mac_labelzone_free(struct label 
*label
); 
 211 void  mac_label_init(struct label 
*label
); 
 212 void  mac_label_destroy(struct label 
*label
); 
 214 int   mac_check_structmac_consistent(struct user_mac 
*mac
); 
 216 int   mac_check_structmac_consistent(struct mac 
*mac
); 
 219 int mac_cred_label_externalize(struct label 
*, char *e
, char *out
, size_t olen
, int flags
); 
 220 int mac_vnode_label_externalize(struct label 
*, char *e
, char *out
, size_t olen
, int flags
); 
 222 int mac_cred_label_internalize(struct label 
*label
, char *string
); 
 223 int mac_vnode_label_internalize(struct label 
*label
, char *string
); 
 226  * MAC_CHECK performs the designated check by walking the policy 
 227  * module list and checking with each as to how it feels about the 
 228  * request.  Note that it returns its value via 'error' in the scope 
 231 #define MAC_CHECK(check, args...) do {                                  \ 
 232         struct mac_policy_conf *mpc;                                    \ 
 236         for (i = 0; i < mac_policy_list.staticmax; i++) {               \ 
 237                 mpc = mac_policy_list.entries[i].mpc;                   \ 
 241                 if (mpc->mpc_ops->mpo_ ## check != NULL)                \ 
 242                         error = mac_error_select(                       \ 
 243                             mpc->mpc_ops->mpo_ ## check (args),         \ 
 246         if (mac_policy_list_conditional_busy() != 0) {                  \ 
 247                 for (; i <= mac_policy_list.maxindex; i++) {            \ 
 248                         mpc = mac_policy_list.entries[i].mpc;           \ 
 252                         if (mpc->mpc_ops->mpo_ ## check != NULL)        \ 
 253                                 error = mac_error_select(               \ 
 254                                     mpc->mpc_ops->mpo_ ## check (args), \ 
 257                 mac_policy_list_unbusy();                               \ 
 262  * MAC_GRANT performs the designated check by walking the policy 
 263  * module list and checking with each as to how it feels about the 
 264  * request.  Unlike MAC_CHECK, it grants if any policies return '0', 
 265  * and otherwise returns EPERM.  Note that it returns its value via 
 266  * 'error' in the scope of the caller. 
 268 #define MAC_GRANT(check, args...) do {                                  \ 
 269         struct mac_policy_conf *mpc;                                    \ 
 273         for (i = 0; i < mac_policy_list.staticmax; i++) {               \ 
 274                 mpc = mac_policy_list.entries[i].mpc;                   \ 
 278                 if (mpc->mpc_ops->mpo_ ## check != NULL) {              \ 
 279                         if (mpc->mpc_ops->mpo_ ## check (args) == 0)    \ 
 283         if (mac_policy_list_conditional_busy() != 0) {                  \ 
 284                 for (; i <= mac_policy_list.maxindex; i++) {            \ 
 285                         mpc = mac_policy_list.entries[i].mpc;           \ 
 289                         if (mpc->mpc_ops->mpo_ ## check != NULL) {      \ 
 290                                 if (mpc->mpc_ops->mpo_ ## check (args)  \ 
 295                 mac_policy_list_unbusy();                               \ 
 300  * MAC_BOOLEAN performs the designated boolean composition by walking 
 301  * the module list, invoking each instance of the operation, and 
 302  * combining the results using the passed C operator.  Note that it 
 303  * returns its value via 'result' in the scope of the caller, which 
 304  * should be initialized by the caller in a meaningful way to get 
 305  * a meaningful result. 
 307 #define MAC_BOOLEAN(operation, composition, args...) do {               \ 
 308         struct mac_policy_conf *mpc;                                    \ 
 311         for (i = 0; i < mac_policy_list.staticmax; i++) {               \ 
 312                 mpc = mac_policy_list.entries[i].mpc;                   \ 
 316                 if (mpc->mpc_ops->mpo_ ## operation != NULL)            \ 
 317                         result = result composition                     \ 
 318                             mpc->mpc_ops->mpo_ ## operation             \ 
 321         if (mac_policy_list_conditional_busy() != 0) {                  \ 
 322                 for (; i <= mac_policy_list.maxindex; i++) {            \ 
 323                         mpc = mac_policy_list.entries[i].mpc;           \ 
 327                         if (mpc->mpc_ops->mpo_ ## operation != NULL)    \ 
 328                                 result = result composition             \ 
 329                                     mpc->mpc_ops->mpo_ ## operation     \ 
 332                 mac_policy_list_unbusy();                               \ 
 336 #define MAC_INTERNALIZE(obj, label, instring)                           \ 
 337         mac_internalize(offsetof(struct mac_policy_ops, mpo_ ## obj ## _label_internalize), label, instring) 
 339 #define MAC_EXTERNALIZE(obj, label, elementlist, outbuf, outbuflen)     \ 
 340         mac_externalize(offsetof(struct mac_policy_ops, mpo_ ## obj ## _label_externalize), label, elementlist, outbuf, outbuflen) 
 342 #define MAC_EXTERNALIZE_AUDIT(obj, label, outbuf, outbuflen)    \ 
 343         mac_externalize(offsetof(struct mac_policy_ops, mpo_ ## obj ## _label_externalize_audit), label, "*", outbuf, outbuflen) 
 346  * MAC_PERFORM performs the designated operation by walking the policy 
 347  * module list and invoking that operation for each policy. 
 349 #define MAC_PERFORM(operation, args...) do {                            \ 
 350         struct mac_policy_conf *mpc;                                    \ 
 353         for (i = 0; i < mac_policy_list.staticmax; i++) {               \ 
 354                 mpc = mac_policy_list.entries[i].mpc;                   \ 
 358                 if (mpc->mpc_ops->mpo_ ## operation != NULL)            \ 
 359                         mpc->mpc_ops->mpo_ ## operation (args);         \ 
 361         if (mac_policy_list_conditional_busy() != 0) {                  \ 
 362                 for (; i <= mac_policy_list.maxindex; i++) {            \ 
 363                         mpc = mac_policy_list.entries[i].mpc;           \ 
 367                         if (mpc->mpc_ops->mpo_ ## operation != NULL)    \ 
 368                                 mpc->mpc_ops->mpo_ ## operation (args); \ 
 370                 mac_policy_list_unbusy();                               \ 
 374 struct __mac_get_pid_args
; 
 375 struct __mac_get_proc_args
; 
 376 struct __mac_set_proc_args
; 
 377 struct __mac_get_lcid_args
; 
 378 struct __mac_get_fd_args
; 
 379 struct __mac_get_file_args
; 
 380 struct __mac_get_link_args
; 
 381 struct __mac_set_fd_args
; 
 382 struct __mac_set_file_args
; 
 383 struct __mac_syscall_args
; 
 385 void mac_policy_addto_labellist(const mac_policy_handle_t
, int); 
 386 void mac_policy_removefrom_labellist(const mac_policy_handle_t
); 
 388 int mac_externalize(size_t mpo_externalize_off
, struct label 
*label
, 
 389     const char *elementlist
, char *outbuf
, size_t outbuflen
); 
 390 int mac_internalize(size_t mpo_internalize_off
, struct label 
*label
, 
 392 #endif  /* !_SECURITY_MAC_INTERNAL_H_ */