Coverage Report

Created: 2026-04-09 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/SockFuzzer/third_party/xnu/security/mac_internal.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2007 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
/*-
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.
35
 *
36
 * This software was developed by Robert Watson and Ilmar Habibulin for the
37
 * TrustedBSD Project.
38
 *
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.
43
 *
44
 * Redistribution and use in source and binary forms, with or without
45
 * modification, are permitted provided that the following conditions
46
 * are met:
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.
52
 *
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
63
 * SUCH DAMAGE.
64
 *
65
 */
66
67
#ifndef _SECURITY_MAC_INTERNAL_H_
68
#define _SECURITY_MAC_INTERNAL_H_
69
70
#ifndef PRIVATE
71
#warning "MAC policy is not KPI, see Technical Q&A QA1574, this header will be removed in next version"
72
#endif
73
74
#include <string.h>
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>
84
#include <sys/lock.h>
85
#include <sys/malloc.h>
86
#include <sys/sbuf.h>
87
#include <sys/proc.h>
88
#include <sys/systm.h>
89
#include <sys/socket.h>
90
#include <sys/socketvar.h>
91
#include <sys/vnode.h>
92
93
/*
94
 * MAC Framework sysctl namespace.
95
 */
96
97
SYSCTL_DECL(_security);
98
SYSCTL_DECL(_security_mac);
99
100
extern int mac_late;
101
102
struct mac_policy_list_element {
103
  struct mac_policy_conf *mpc;
104
};
105
106
struct mac_policy_list {
107
  u_int                           numloaded;
108
  u_int                           max;
109
  u_int                           maxindex;
110
  u_int                           staticmax;
111
  u_int                           chunks;
112
  u_int                           freehint;
113
  struct mac_policy_list_element  *entries;
114
};
115
116
typedef struct mac_policy_list mac_policy_list_t;
117
118
119
/*
120
 * Policy that has registered with the framework for a specific
121
 * label namespace name.
122
 */
123
struct mac_label_listener {
124
  mac_policy_handle_t             mll_handle;
125
  LIST_ENTRY(mac_label_listener)  mll_list;
126
};
127
128
LIST_HEAD(mac_label_listeners_t, mac_label_listener);
129
130
/*
131
 * Type of list used to manage label namespace names.
132
 */
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;
137
};
138
139
LIST_HEAD(mac_label_element_list_t, mac_label_element);
140
141
/*
142
 * MAC Framework global variables.
143
 */
144
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;
147
148
extern struct mac_policy_list mac_policy_list;
149
150
/*
151
 * global flags to control whether a MACF subsystem is configured
152
 * at all in the system.
153
 */
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;
166
167
extern unsigned int mac_label_vnodes;
168
extern unsigned int mac_vnode_label_count;
169
170
static bool mac_proc_check_enforce(proc_t p);
171
172
static __inline__ bool
173
mac_proc_check_enforce(proc_t p)
174
0
{
175
0
#if CONFIG_MACF
176
0
  // Don't apply policies to the kernel itself.
177
0
  return p != kernproc;
178
0
#else
179
0
#pragma unused(p)
180
0
  return false;
181
0
#endif // CONFIG_MACF
182
0
}
183
184
static bool mac_cred_check_enforce(kauth_cred_t cred);
185
186
static __inline__ bool
187
mac_cred_check_enforce(kauth_cred_t cred)
188
0
{
189
0
#if CONFIG_MACF
190
0
  return cred != proc_ucred(kernproc);
191
0
#else
192
0
#pragma unused(p)
193
0
  return false;
194
0
#endif // CONFIG_MACF
195
0
}
196
197
/*
198
 * MAC Framework infrastructure functions.
199
 */
200
201
int mac_error_select(int error1, int error2);
202
203
void  mac_policy_list_busy(void);
204
int   mac_policy_list_conditional_busy(void);
205
void  mac_policy_list_unbusy(void);
206
207
void           mac_labelzone_init(void);
208
struct label  *mac_labelzone_alloc(int flags);
209
void           mac_labelzone_free(struct label *label);
210
211
void  mac_label_init(struct label *label);
212
void  mac_label_destroy(struct label *label);
213
#if KERNEL
214
int   mac_check_structmac_consistent(struct user_mac *mac);
215
#else
216
int   mac_check_structmac_consistent(struct mac *mac);
217
#endif
218
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);
221
222
int mac_cred_label_internalize(struct label *label, char *string);
223
int mac_vnode_label_internalize(struct label *label, char *string);
224
225
/*
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
229
 * of the caller.
230
 */
231
0
#define MAC_CHECK(check, args...) do {                                  \
232
0
  struct mac_policy_conf *mpc;                                    \
233
0
  u_int i;                                                        \
234
0
                                                                        \
235
0
  error = 0;                                                      \
236
0
  for (i = 0; i < mac_policy_list.staticmax; i++) {               \
237
0
          mpc = mac_policy_list.entries[i].mpc;                   \
238
0
          if (mpc == NULL)                                        \
239
0
                  continue;                                       \
240
0
                                                                        \
241
0
          if (mpc->mpc_ops->mpo_ ## check != NULL)                \
242
0
                  error = mac_error_select(                       \
243
0
                      mpc->mpc_ops->mpo_ ## check (args),         \
244
0
                      error);                                     \
245
0
  }                                                               \
246
0
  if (mac_policy_list_conditional_busy() != 0) {                  \
247
0
          for (; i <= mac_policy_list.maxindex; i++) {            \
248
0
                  mpc = mac_policy_list.entries[i].mpc;           \
249
0
                  if (mpc == NULL)                                \
250
0
                          continue;                               \
251
0
                                                                        \
252
0
                  if (mpc->mpc_ops->mpo_ ## check != NULL)        \
253
0
                          error = mac_error_select(               \
254
0
                              mpc->mpc_ops->mpo_ ## check (args), \
255
0
                              error);                             \
256
0
          }                                                       \
257
0
          mac_policy_list_unbusy();                               \
258
0
  }                                                               \
259
0
} while (0)
260
261
/*
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.
267
 */
268
#define MAC_GRANT(check, args...) do {                                  \
269
  struct mac_policy_conf *mpc;                                    \
270
  u_int i;                                                        \
271
                                                                        \
272
  error = EPERM;                                                  \
273
  for (i = 0; i < mac_policy_list.staticmax; i++) {               \
274
          mpc = mac_policy_list.entries[i].mpc;                   \
275
          if (mpc == NULL)                                        \
276
                  continue;                                       \
277
                                                                        \
278
          if (mpc->mpc_ops->mpo_ ## check != NULL) {              \
279
                  if (mpc->mpc_ops->mpo_ ## check (args) == 0)    \
280
                          error = 0;                              \
281
          }                                                       \
282
  }                                                               \
283
  if (mac_policy_list_conditional_busy() != 0) {                  \
284
          for (; i <= mac_policy_list.maxindex; i++) {            \
285
                  mpc = mac_policy_list.entries[i].mpc;           \
286
                  if (mpc == NULL)                                \
287
                          continue;                               \
288
                                                                        \
289
                  if (mpc->mpc_ops->mpo_ ## check != NULL) {      \
290
                          if (mpc->mpc_ops->mpo_ ## check (args)  \
291
                              == 0)                               \
292
                                  error = 0;                      \
293
                  }                                               \
294
          }                                                       \
295
          mac_policy_list_unbusy();                               \
296
  }                                                               \
297
} while (0)
298
299
/*
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.
306
 */
307
#define MAC_BOOLEAN(operation, composition, args...) do {               \
308
  struct mac_policy_conf *mpc;                                    \
309
  u_int i;                                                        \
310
                                                                        \
311
  for (i = 0; i < mac_policy_list.staticmax; i++) {               \
312
          mpc = mac_policy_list.entries[i].mpc;                   \
313
          if (mpc == NULL)                                        \
314
                  continue;                                       \
315
                                                                        \
316
          if (mpc->mpc_ops->mpo_ ## operation != NULL)            \
317
                  result = result composition                     \
318
                      mpc->mpc_ops->mpo_ ## operation             \
319
                      (args);                                     \
320
  }                                                               \
321
  if (mac_policy_list_conditional_busy() != 0) {                  \
322
          for (; i <= mac_policy_list.maxindex; i++) {            \
323
                  mpc = mac_policy_list.entries[i].mpc;           \
324
                  if (mpc == NULL)                                \
325
                          continue;                               \
326
                                                                        \
327
                  if (mpc->mpc_ops->mpo_ ## operation != NULL)    \
328
                          result = result composition             \
329
                              mpc->mpc_ops->mpo_ ## operation     \
330
                              (args);                             \
331
          }                                                       \
332
          mac_policy_list_unbusy();                               \
333
  }                                                               \
334
} while (0)
335
336
#define MAC_INTERNALIZE(obj, label, instring)                           \
337
  mac_internalize(offsetof(struct mac_policy_ops, mpo_ ## obj ## _label_internalize), label, instring)
338
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)
341
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)
344
345
/*
346
 * MAC_PERFORM performs the designated operation by walking the policy
347
 * module list and invoking that operation for each policy.
348
 */
349
#define MAC_PERFORM(operation, args...) do {                            \
350
  struct mac_policy_conf *mpc;                                    \
351
  u_int i;                                                        \
352
                                                                        \
353
  for (i = 0; i < mac_policy_list.staticmax; i++) {               \
354
          mpc = mac_policy_list.entries[i].mpc;                   \
355
          if (mpc == NULL)                                        \
356
                  continue;                                       \
357
                                                                        \
358
          if (mpc->mpc_ops->mpo_ ## operation != NULL)            \
359
                  mpc->mpc_ops->mpo_ ## operation (args);         \
360
  }                                                               \
361
  if (mac_policy_list_conditional_busy() != 0) {                  \
362
          for (; i <= mac_policy_list.maxindex; i++) {            \
363
                  mpc = mac_policy_list.entries[i].mpc;           \
364
                  if (mpc == NULL)                                \
365
                          continue;                               \
366
                                                                        \
367
                  if (mpc->mpc_ops->mpo_ ## operation != NULL)    \
368
                          mpc->mpc_ops->mpo_ ## operation (args); \
369
          }                                                       \
370
          mac_policy_list_unbusy();                               \
371
  }                                                               \
372
} while (0)
373
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;
384
385
void mac_policy_addto_labellist(const mac_policy_handle_t, int);
386
void mac_policy_removefrom_labellist(const mac_policy_handle_t);
387
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,
391
    char *elementlist);
392
#endif  /* !_SECURITY_MAC_INTERNAL_H_ */