1 /*-
2 * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5 * Copyright (c) 2005-2006 SPARTA, Inc.
6 * Copyright (c) 2008 Apple Inc.
7 * All rights reserved.
8 *
9 * This software was developed by Robert Watson and Ilmar Habibulin for the
10 * TrustedBSD Project.
11 *
12 * This software was developed for the FreeBSD Project in part by Network
13 * Associates Laboratories, the Security Research Division of Network
14 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
15 * as part of the DARPA CHATS research program.
16 *
17 * This software was enhanced by SPARTA ISSO under SPAWAR contract
18 * N66001-04-C-6019 ("SEFOS").
19 *
20 * This software was developed at the University of Cambridge Computer
21 * Laboratory with support from a grant from Google, Inc.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * SUCH DAMAGE.
43 */
44
45 #include <sys/cdefs.h>
46 #include "opt_mac.h"
47
48 #include <sys/param.h>
49 #include <sys/abi_compat.h>
50 #include <sys/capsicum.h>
51 #include <sys/fcntl.h>
52 #include <sys/kernel.h>
53 #include <sys/lock.h>
54 #include <sys/malloc.h>
55 #include <sys/mutex.h>
56 #include <sys/mac.h>
57 #include <sys/proc.h>
58 #include <sys/systm.h>
59 #include <sys/sysctl.h>
60 #include <sys/sysproto.h>
61 #include <sys/vnode.h>
62 #include <sys/mount.h>
63 #include <sys/file.h>
64 #include <sys/namei.h>
65 #include <sys/socket.h>
66 #include <sys/pipe.h>
67 #include <sys/socketvar.h>
68
69 #include <security/mac/mac_framework.h>
70 #include <security/mac/mac_internal.h>
71 #include <security/mac/mac_policy.h>
72 #include <security/mac/mac_syscalls.h>
73
74 #ifdef MAC
75
76 FEATURE(security_mac, "Mandatory Access Control Framework support");
77
78 static int kern___mac_get_path(struct thread *td, const char *path_p,
79 struct mac *mac_p, int follow);
80 static int kern___mac_set_path(struct thread *td, const char *path_p,
81 struct mac *mac_p, int follow);
82
83 #ifdef COMPAT_FREEBSD32
84 struct mac32 {
85 uint32_t m_buflen; /* size_t */
86 uint32_t m_string; /* char * */
87 };
88 #endif
89
90 /*
91 * Copyin a 'struct mac', including the string pointed to by 'm_string'.
92 *
93 * On success (0 returned), fills '*mac', whose associated storage must be freed
94 * after use by calling free_copied_label() (which see). On success, 'u_string'
95 * if not NULL is filled with the userspace address for 'u_mac->m_string'.
96 */
97 static int
mac_label_copyin_impl(const void * const u_mac,struct mac * const mac,char ** const u_string,bool is_32bit)98 mac_label_copyin_impl(const void *const u_mac, struct mac *const mac,
99 char **const u_string, bool is_32bit)
100 {
101 char *buffer;
102 int error;
103
104 #ifdef COMPAT_FREEBSD32
105 if (is_32bit) {
106 struct mac32 mac32;
107
108 error = copyin(u_mac, &mac32, sizeof(mac32));
109 if (error != 0)
110 return (error);
111
112 CP(mac32, *mac, m_buflen);
113 PTRIN_CP(mac32, *mac, m_string);
114 } else
115 #endif
116 {
117 error = copyin(u_mac, mac, sizeof(*mac));
118 if (error != 0)
119 return (error);
120 }
121
122 error = mac_check_structmac_consistent(mac);
123 if (error != 0)
124 return (error);
125
126 /* 'm_buflen' not too big checked by function call above. */
127 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
128 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
129 if (error != 0) {
130 free(buffer, M_MACTEMP);
131 return (error);
132 }
133
134 MPASS(error == 0);
135 if (u_string != NULL)
136 *u_string = mac->m_string;
137 mac->m_string = buffer;
138 return (0);
139 }
140
141 int
mac_label_copyin(const struct mac * const u_mac,struct mac * const mac,char ** const u_string)142 mac_label_copyin(const struct mac *const u_mac, struct mac *const mac,
143 char **const u_string)
144 {
145 return (mac_label_copyin_impl(u_mac, mac, u_string, false));
146 }
147
148 void
free_copied_label(const struct mac * const mac)149 free_copied_label(const struct mac *const mac)
150 {
151 free(mac->m_string, M_MACTEMP);
152 }
153
154 #ifdef COMPAT_FREEBSD32
155 int
mac_label_copyin32(const struct mac32 * const u_mac,struct mac * const mac,char ** const u_string)156 mac_label_copyin32(const struct mac32 *const u_mac,
157 struct mac *const mac, char **const u_string)
158 {
159 return (mac_label_copyin_impl(u_mac, mac, u_string, true));
160 }
161 #endif
162
163 int
sys___mac_get_pid(struct thread * td,struct __mac_get_pid_args * uap)164 sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
165 {
166 char *buffer, *u_buffer;
167 struct mac mac;
168 struct proc *tproc;
169 struct ucred *tcred;
170 int error;
171
172 error = mac_label_copyin(uap->mac_p, &mac, &u_buffer);
173 if (error)
174 return (error);
175
176 tproc = pfind(uap->pid);
177 if (tproc == NULL) {
178 error = ESRCH;
179 goto free_mac_and_exit;
180 }
181
182 tcred = NULL; /* Satisfy gcc. */
183 error = p_cansee(td, tproc);
184 if (error == 0)
185 tcred = crhold(tproc->p_ucred);
186 PROC_UNLOCK(tproc);
187 if (error)
188 goto free_mac_and_exit;
189
190 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
191 error = mac_cred_externalize_label(tcred->cr_label, mac.m_string,
192 buffer, mac.m_buflen);
193 if (error == 0)
194 error = copyout(buffer, u_buffer, strlen(buffer)+1);
195 free(buffer, M_MACTEMP);
196 crfree(tcred);
197
198 free_mac_and_exit:
199 free_copied_label(&mac);
200 return (error);
201 }
202
203 int
sys___mac_get_proc(struct thread * td,struct __mac_get_proc_args * uap)204 sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
205 {
206 char *buffer, *u_buffer;
207 struct mac mac;
208 int error;
209
210 error = mac_label_copyin(uap->mac_p, &mac, &u_buffer);
211 if (error)
212 return (error);
213
214 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
215 error = mac_cred_externalize_label(td->td_ucred->cr_label,
216 mac.m_string, buffer, mac.m_buflen);
217 if (error == 0)
218 error = copyout(buffer, u_buffer, strlen(buffer)+1);
219
220 free(buffer, M_MACTEMP);
221 free_copied_label(&mac);
222 return (error);
223 }
224
225 /*
226 * Performs preparation (including allocations) for mac_set_proc().
227 *
228 * No lock should be held while calling this function. On success,
229 * mac_set_proc_finish() must be called to free the data associated to
230 * 'mac_set_proc_data', even if mac_set_proc_core() fails. 'mac_set_proc_data'
231 * is not set in case of error, and is set to a non-NULL value on success.
232 */
233 int
mac_set_proc_prepare(struct thread * const td,const struct mac * const mac,void ** const mac_set_proc_data)234 mac_set_proc_prepare(struct thread *const td, const struct mac *const mac,
235 void **const mac_set_proc_data)
236 {
237 struct label *intlabel;
238 int error;
239
240 PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
241
242 if (!(mac_labeled & MPC_OBJECT_CRED))
243 return (EINVAL);
244
245 intlabel = mac_cred_label_alloc();
246 error = mac_cred_internalize_label(intlabel, mac->m_string);
247 if (error) {
248 mac_cred_label_free(intlabel);
249 return (error);
250 }
251
252 *mac_set_proc_data = intlabel;
253 return (0);
254 }
255
256 /*
257 * Actually sets the MAC label on 'newcred'.
258 *
259 * The current process' lock *must* be held. This function only sets the label
260 * on 'newcred', but does not put 'newcred' in place on the current process'
261 * (consequently, it also does not call setsugid()). 'mac_set_proc_data' must
262 * be the pointer returned by mac_set_proc_prepare(). If called, this function
263 * must be so between a successful call to mac_set_proc_prepare() and
264 * mac_set_proc_finish(), but calling it is not mandatory (e.g., if some other
265 * error occured under the process lock that obsoletes setting the MAC label).
266 */
267 int
mac_set_proc_core(struct thread * const td,struct ucred * const newcred,void * const mac_set_proc_data)268 mac_set_proc_core(struct thread *const td, struct ucred *const newcred,
269 void *const mac_set_proc_data)
270 {
271 struct label *const intlabel = mac_set_proc_data;
272 struct proc *const p = td->td_proc;
273 int error;
274
275 MPASS(td == curthread);
276 PROC_LOCK_ASSERT(p, MA_OWNED);
277
278 error = mac_cred_check_relabel(p->p_ucred, intlabel);
279 if (error)
280 return (error);
281
282 mac_cred_relabel(newcred, intlabel);
283 return (0);
284 }
285
286 /*
287 * Performs mac_set_proc() last operations, without the process lock.
288 *
289 * 'proc_label_set' indicates whether the label was actually set by a call to
290 * mac_set_proc_core() that succeeded. 'mac_set_proc_data' must be the pointer
291 * returned by mac_set_proc_prepare(), and its associated data will be freed.
292 */
293 void
mac_set_proc_finish(struct thread * const td,bool proc_label_set,void * const mac_set_proc_data)294 mac_set_proc_finish(struct thread *const td, bool proc_label_set,
295 void *const mac_set_proc_data)
296 {
297 struct label *const intlabel = mac_set_proc_data;
298
299 PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
300
301 if (proc_label_set)
302 mac_proc_vm_revoke(td);
303 mac_cred_label_free(intlabel);
304 }
305
306 int
sys___mac_set_proc(struct thread * td,struct __mac_set_proc_args * uap)307 sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
308 {
309 struct ucred *newcred, *oldcred;
310 void *intlabel;
311 struct proc *const p = td->td_proc;
312 struct mac mac;
313 int error;
314
315 error = mac_label_copyin(uap->mac_p, &mac, NULL);
316 if (error)
317 return (error);
318
319 error = mac_set_proc_prepare(td, &mac, &intlabel);
320 if (error)
321 goto free_label;
322
323 newcred = crget();
324
325 PROC_LOCK(p);
326 oldcred = p->p_ucred;
327 crcopy(newcred, oldcred);
328
329 error = mac_set_proc_core(td, newcred, intlabel);
330 if (error) {
331 PROC_UNLOCK(p);
332 crfree(newcred);
333 goto finish;
334 }
335
336 setsugid(p);
337 proc_set_cred(p, newcred);
338 PROC_UNLOCK(p);
339
340 crfree(oldcred);
341 finish:
342 mac_set_proc_finish(td, error == 0, intlabel);
343 free_label:
344 free_copied_label(&mac);
345 return (error);
346 }
347
348 int
sys___mac_get_fd(struct thread * td,struct __mac_get_fd_args * uap)349 sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
350 {
351 char *u_buffer, *buffer;
352 struct label *intlabel;
353 struct file *fp;
354 struct mac mac;
355 struct vnode *vp;
356 struct pipe *pipe;
357 struct socket *so;
358 cap_rights_t rights;
359 int error;
360
361 error = mac_label_copyin(uap->mac_p, &mac, &u_buffer);
362 if (error)
363 return (error);
364
365 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
366 error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_MAC_GET),
367 &fp);
368 if (error)
369 goto out;
370
371 switch (fp->f_type) {
372 case DTYPE_FIFO:
373 case DTYPE_VNODE:
374 if (!(mac_labeled & MPC_OBJECT_VNODE)) {
375 error = EINVAL;
376 goto out_fdrop;
377 }
378 vp = fp->f_vnode;
379 intlabel = mac_vnode_label_alloc();
380 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
381 mac_vnode_copy_label(vp->v_label, intlabel);
382 VOP_UNLOCK(vp);
383 error = mac_vnode_externalize_label(intlabel, mac.m_string,
384 buffer, mac.m_buflen);
385 mac_vnode_label_free(intlabel);
386 break;
387
388 case DTYPE_PIPE:
389 if (!(mac_labeled & MPC_OBJECT_PIPE)) {
390 error = EINVAL;
391 goto out_fdrop;
392 }
393 pipe = fp->f_data;
394 intlabel = mac_pipe_label_alloc();
395 PIPE_LOCK(pipe);
396 mac_pipe_copy_label(pipe->pipe_pair->pp_label, intlabel);
397 PIPE_UNLOCK(pipe);
398 error = mac_pipe_externalize_label(intlabel, mac.m_string,
399 buffer, mac.m_buflen);
400 mac_pipe_label_free(intlabel);
401 break;
402
403 case DTYPE_SOCKET:
404 if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
405 error = EINVAL;
406 goto out_fdrop;
407 }
408 so = fp->f_data;
409 intlabel = mac_socket_label_alloc(M_WAITOK);
410 SOCK_LOCK(so);
411 mac_socket_copy_label(so->so_label, intlabel);
412 SOCK_UNLOCK(so);
413 error = mac_socket_externalize_label(intlabel, mac.m_string,
414 buffer, mac.m_buflen);
415 mac_socket_label_free(intlabel);
416 break;
417
418 default:
419 error = EINVAL;
420 }
421 if (error == 0)
422 error = copyout(buffer, u_buffer, strlen(buffer)+1);
423 out_fdrop:
424 fdrop(fp, td);
425 out:
426 free(buffer, M_MACTEMP);
427 free_copied_label(&mac);
428 return (error);
429 }
430
431 int
sys___mac_get_file(struct thread * td,struct __mac_get_file_args * uap)432 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
433 {
434
435 return (kern___mac_get_path(td, uap->path_p, uap->mac_p, FOLLOW));
436 }
437
438 int
sys___mac_get_link(struct thread * td,struct __mac_get_link_args * uap)439 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
440 {
441
442 return (kern___mac_get_path(td, uap->path_p, uap->mac_p, NOFOLLOW));
443 }
444
445 static int
kern___mac_get_path(struct thread * td,const char * path_p,struct mac * mac_p,int follow)446 kern___mac_get_path(struct thread *td, const char *path_p, struct mac *mac_p,
447 int follow)
448 {
449 char *u_buffer, *buffer;
450 struct nameidata nd;
451 struct label *intlabel;
452 struct mac mac;
453 int error;
454
455 if (!(mac_labeled & MPC_OBJECT_VNODE))
456 return (EINVAL);
457
458 error = mac_label_copyin(mac_p, &mac, &u_buffer);
459 if (error)
460 return (error);
461
462 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
463 NDINIT(&nd, LOOKUP, LOCKLEAF | follow, UIO_USERSPACE, path_p);
464 error = namei(&nd);
465 if (error)
466 goto out;
467
468 intlabel = mac_vnode_label_alloc();
469 mac_vnode_copy_label(nd.ni_vp->v_label, intlabel);
470 error = mac_vnode_externalize_label(intlabel, mac.m_string, buffer,
471 mac.m_buflen);
472 vput(nd.ni_vp);
473 NDFREE_PNBUF(&nd);
474 mac_vnode_label_free(intlabel);
475
476 if (error == 0)
477 error = copyout(buffer, u_buffer, strlen(buffer)+1);
478
479 out:
480 free(buffer, M_MACTEMP);
481 free_copied_label(&mac);
482
483 return (error);
484 }
485
486 int
sys___mac_set_fd(struct thread * td,struct __mac_set_fd_args * uap)487 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
488 {
489 struct label *intlabel;
490 struct pipe *pipe;
491 struct socket *so;
492 struct file *fp;
493 struct mount *mp;
494 struct vnode *vp;
495 struct mac mac;
496 cap_rights_t rights;
497 int error;
498
499 error = mac_label_copyin(uap->mac_p, &mac, NULL);
500 if (error)
501 return (error);
502
503 error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_MAC_SET),
504 &fp);
505 if (error)
506 goto out;
507
508 switch (fp->f_type) {
509 case DTYPE_FIFO:
510 case DTYPE_VNODE:
511 if (!(mac_labeled & MPC_OBJECT_VNODE)) {
512 error = EINVAL;
513 goto out_fdrop;
514 }
515 intlabel = mac_vnode_label_alloc();
516 error = mac_vnode_internalize_label(intlabel, mac.m_string);
517 if (error) {
518 mac_vnode_label_free(intlabel);
519 break;
520 }
521 vp = fp->f_vnode;
522 error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH);
523 if (error != 0) {
524 mac_vnode_label_free(intlabel);
525 break;
526 }
527 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
528 error = vn_setlabel(vp, intlabel, td->td_ucred);
529 VOP_UNLOCK(vp);
530 vn_finished_write(mp);
531 mac_vnode_label_free(intlabel);
532 break;
533
534 case DTYPE_PIPE:
535 if (!(mac_labeled & MPC_OBJECT_PIPE)) {
536 error = EINVAL;
537 goto out_fdrop;
538 }
539 intlabel = mac_pipe_label_alloc();
540 error = mac_pipe_internalize_label(intlabel, mac.m_string);
541 if (error == 0) {
542 pipe = fp->f_data;
543 PIPE_LOCK(pipe);
544 error = mac_pipe_label_set(td->td_ucred,
545 pipe->pipe_pair, intlabel);
546 PIPE_UNLOCK(pipe);
547 }
548 mac_pipe_label_free(intlabel);
549 break;
550
551 case DTYPE_SOCKET:
552 if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
553 error = EINVAL;
554 goto out_fdrop;
555 }
556 intlabel = mac_socket_label_alloc(M_WAITOK);
557 error = mac_socket_internalize_label(intlabel, mac.m_string);
558 if (error == 0) {
559 so = fp->f_data;
560 error = mac_socket_label_set(td->td_ucred, so,
561 intlabel);
562 }
563 mac_socket_label_free(intlabel);
564 break;
565
566 default:
567 error = EINVAL;
568 }
569 out_fdrop:
570 fdrop(fp, td);
571 out:
572 free_copied_label(&mac);
573 return (error);
574 }
575
576 int
sys___mac_set_file(struct thread * td,struct __mac_set_file_args * uap)577 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
578 {
579
580 return (kern___mac_set_path(td, uap->path_p, uap->mac_p, FOLLOW));
581 }
582
583 int
sys___mac_set_link(struct thread * td,struct __mac_set_link_args * uap)584 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
585 {
586
587 return (kern___mac_set_path(td, uap->path_p, uap->mac_p, NOFOLLOW));
588 }
589
590 static int
kern___mac_set_path(struct thread * td,const char * path_p,struct mac * mac_p,int follow)591 kern___mac_set_path(struct thread *td, const char *path_p, struct mac *mac_p,
592 int follow)
593 {
594 struct label *intlabel;
595 struct nameidata nd;
596 struct mount *mp;
597 struct mac mac;
598 int error;
599
600 if (!(mac_labeled & MPC_OBJECT_VNODE))
601 return (EINVAL);
602
603 error = mac_label_copyin(mac_p, &mac, NULL);
604 if (error)
605 return (error);
606
607 intlabel = mac_vnode_label_alloc();
608 error = mac_vnode_internalize_label(intlabel, mac.m_string);
609 free_copied_label(&mac);
610 if (error)
611 goto out;
612
613 NDINIT(&nd, LOOKUP, LOCKLEAF | follow, UIO_USERSPACE, path_p);
614 error = namei(&nd);
615 if (error == 0) {
616 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | V_PCATCH);
617 if (error == 0) {
618 error = vn_setlabel(nd.ni_vp, intlabel,
619 td->td_ucred);
620 vn_finished_write(mp);
621 }
622 vput(nd.ni_vp);
623 NDFREE_PNBUF(&nd);
624 }
625 out:
626 mac_vnode_label_free(intlabel);
627 return (error);
628 }
629
630 int
sys_mac_syscall(struct thread * td,struct mac_syscall_args * uap)631 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
632 {
633 struct mac_policy_conf *mpc;
634 char target[MAC_MAX_POLICY_NAME];
635 int error;
636
637 error = copyinstr(uap->policy, target, sizeof(target), NULL);
638 if (error)
639 return (error);
640
641 error = ENOSYS;
642 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
643 if (strcmp(mpc->mpc_name, target) == 0 &&
644 mpc->mpc_ops->mpo_syscall != NULL) {
645 error = mpc->mpc_ops->mpo_syscall(td,
646 uap->call, uap->arg);
647 goto out;
648 }
649 }
650
651 if (!LIST_EMPTY(&mac_policy_list)) {
652 mac_policy_slock_sleep();
653 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
654 if (strcmp(mpc->mpc_name, target) == 0 &&
655 mpc->mpc_ops->mpo_syscall != NULL) {
656 error = mpc->mpc_ops->mpo_syscall(td,
657 uap->call, uap->arg);
658 break;
659 }
660 }
661 mac_policy_sunlock_sleep();
662 }
663 out:
664 return (error);
665 }
666
667 #else /* !MAC */
668
669 int
sys___mac_get_pid(struct thread * td,struct __mac_get_pid_args * uap)670 sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
671 {
672
673 return (ENOSYS);
674 }
675
676 int
sys___mac_get_proc(struct thread * td,struct __mac_get_proc_args * uap)677 sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
678 {
679
680 return (ENOSYS);
681 }
682
683 int
sys___mac_set_proc(struct thread * td,struct __mac_set_proc_args * uap)684 sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
685 {
686
687 return (ENOSYS);
688 }
689
690 int
sys___mac_get_fd(struct thread * td,struct __mac_get_fd_args * uap)691 sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
692 {
693
694 return (ENOSYS);
695 }
696
697 int
sys___mac_get_file(struct thread * td,struct __mac_get_file_args * uap)698 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
699 {
700
701 return (ENOSYS);
702 }
703
704 int
sys___mac_get_link(struct thread * td,struct __mac_get_link_args * uap)705 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
706 {
707
708 return (ENOSYS);
709 }
710
711 int
sys___mac_set_fd(struct thread * td,struct __mac_set_fd_args * uap)712 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
713 {
714
715 return (ENOSYS);
716 }
717
718 int
sys___mac_set_file(struct thread * td,struct __mac_set_file_args * uap)719 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
720 {
721
722 return (ENOSYS);
723 }
724
725 int
sys___mac_set_link(struct thread * td,struct __mac_set_link_args * uap)726 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
727 {
728
729 return (ENOSYS);
730 }
731
732 int
sys_mac_syscall(struct thread * td,struct mac_syscall_args * uap)733 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
734 {
735
736 return (ENOSYS);
737 }
738
739 #endif /* !MAC */
740