xref: /freebsd/sys/security/mac/mac_syscalls.c (revision c243e4902be8df1e643c76b5f18b68bb77cc5268)
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 __FBSDID("$FreeBSD$");
47 
48 #include "opt_mac.h"
49 
50 #include <sys/param.h>
51 #include <sys/capability.h>
52 #include <sys/fcntl.h>
53 #include <sys/kernel.h>
54 #include <sys/lock.h>
55 #include <sys/malloc.h>
56 #include <sys/mutex.h>
57 #include <sys/mac.h>
58 #include <sys/proc.h>
59 #include <sys/systm.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysproto.h>
62 #include <sys/sysent.h>
63 #include <sys/vnode.h>
64 #include <sys/mount.h>
65 #include <sys/file.h>
66 #include <sys/namei.h>
67 #include <sys/socket.h>
68 #include <sys/pipe.h>
69 #include <sys/socketvar.h>
70 
71 #include <security/mac/mac_framework.h>
72 #include <security/mac/mac_internal.h>
73 #include <security/mac/mac_policy.h>
74 
75 #ifdef MAC
76 
77 FEATURE(security_mac, "Mandatory Access Control Framework support");
78 
79 int
80 sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
81 {
82 	char *elements, *buffer;
83 	struct mac mac;
84 	struct proc *tproc;
85 	struct ucred *tcred;
86 	int error;
87 
88 	error = copyin(uap->mac_p, &mac, sizeof(mac));
89 	if (error)
90 		return (error);
91 
92 	error = mac_check_structmac_consistent(&mac);
93 	if (error)
94 		return (error);
95 
96 	tproc = pfind(uap->pid);
97 	if (tproc == NULL)
98 		return (ESRCH);
99 
100 	tcred = NULL;				/* Satisfy gcc. */
101 	error = p_cansee(td, tproc);
102 	if (error == 0)
103 		tcred = crhold(tproc->p_ucred);
104 	PROC_UNLOCK(tproc);
105 	if (error)
106 		return (error);
107 
108 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
109 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
110 	if (error) {
111 		free(elements, M_MACTEMP);
112 		crfree(tcred);
113 		return (error);
114 	}
115 
116 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
117 	error = mac_cred_externalize_label(tcred->cr_label, elements,
118 	    buffer, mac.m_buflen);
119 	if (error == 0)
120 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
121 
122 	free(buffer, M_MACTEMP);
123 	free(elements, M_MACTEMP);
124 	crfree(tcred);
125 	return (error);
126 }
127 
128 int
129 sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
130 {
131 	char *elements, *buffer;
132 	struct mac mac;
133 	int error;
134 
135 	error = copyin(uap->mac_p, &mac, sizeof(mac));
136 	if (error)
137 		return (error);
138 
139 	error = mac_check_structmac_consistent(&mac);
140 	if (error)
141 		return (error);
142 
143 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
144 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
145 	if (error) {
146 		free(elements, M_MACTEMP);
147 		return (error);
148 	}
149 
150 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
151 	error = mac_cred_externalize_label(td->td_ucred->cr_label,
152 	    elements, buffer, mac.m_buflen);
153 	if (error == 0)
154 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
155 
156 	free(buffer, M_MACTEMP);
157 	free(elements, M_MACTEMP);
158 	return (error);
159 }
160 
161 int
162 sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
163 {
164 	struct ucred *newcred, *oldcred;
165 	struct label *intlabel;
166 	struct proc *p;
167 	struct mac mac;
168 	char *buffer;
169 	int error;
170 
171 	if (!(mac_labeled & MPC_OBJECT_CRED))
172 		return (EINVAL);
173 
174 	error = copyin(uap->mac_p, &mac, sizeof(mac));
175 	if (error)
176 		return (error);
177 
178 	error = mac_check_structmac_consistent(&mac);
179 	if (error)
180 		return (error);
181 
182 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
183 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
184 	if (error) {
185 		free(buffer, M_MACTEMP);
186 		return (error);
187 	}
188 
189 	intlabel = mac_cred_label_alloc();
190 	error = mac_cred_internalize_label(intlabel, buffer);
191 	free(buffer, M_MACTEMP);
192 	if (error)
193 		goto out;
194 
195 	newcred = crget();
196 
197 	p = td->td_proc;
198 	PROC_LOCK(p);
199 	oldcred = p->p_ucred;
200 
201 	error = mac_cred_check_relabel(oldcred, intlabel);
202 	if (error) {
203 		PROC_UNLOCK(p);
204 		crfree(newcred);
205 		goto out;
206 	}
207 
208 	setsugid(p);
209 	crcopy(newcred, oldcred);
210 	mac_cred_relabel(newcred, intlabel);
211 	p->p_ucred = newcred;
212 
213 	PROC_UNLOCK(p);
214 	crfree(oldcred);
215 	mac_proc_vm_revoke(td);
216 
217 out:
218 	mac_cred_label_free(intlabel);
219 	return (error);
220 }
221 
222 int
223 sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
224 {
225 	char *elements, *buffer;
226 	struct label *intlabel;
227 	struct file *fp;
228 	struct mac mac;
229 	struct vnode *vp;
230 	struct pipe *pipe;
231 	struct socket *so;
232 	short label_type;
233 	int vfslocked, error;
234 
235 	error = copyin(uap->mac_p, &mac, sizeof(mac));
236 	if (error)
237 		return (error);
238 
239 	error = mac_check_structmac_consistent(&mac);
240 	if (error)
241 		return (error);
242 
243 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
244 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
245 	if (error) {
246 		free(elements, M_MACTEMP);
247 		return (error);
248 	}
249 
250 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
251 	error = fget(td, uap->fd, CAP_MAC_GET, &fp);
252 	if (error)
253 		goto out;
254 
255 	label_type = fp->f_type;
256 	switch (fp->f_type) {
257 	case DTYPE_FIFO:
258 	case DTYPE_VNODE:
259 		if (!(mac_labeled & MPC_OBJECT_VNODE)) {
260 			error = EINVAL;
261 			goto out_fdrop;
262 		}
263 		vp = fp->f_vnode;
264 		intlabel = mac_vnode_label_alloc();
265 		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
266 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
267 		mac_vnode_copy_label(vp->v_label, intlabel);
268 		VOP_UNLOCK(vp, 0);
269 		VFS_UNLOCK_GIANT(vfslocked);
270 		error = mac_vnode_externalize_label(intlabel, elements,
271 		    buffer, mac.m_buflen);
272 		mac_vnode_label_free(intlabel);
273 		break;
274 
275 	case DTYPE_PIPE:
276 		if (!(mac_labeled & MPC_OBJECT_PIPE)) {
277 			error = EINVAL;
278 			goto out_fdrop;
279 		}
280 		pipe = fp->f_data;
281 		intlabel = mac_pipe_label_alloc();
282 		PIPE_LOCK(pipe);
283 		mac_pipe_copy_label(pipe->pipe_pair->pp_label, intlabel);
284 		PIPE_UNLOCK(pipe);
285 		error = mac_pipe_externalize_label(intlabel, elements,
286 		    buffer, mac.m_buflen);
287 		mac_pipe_label_free(intlabel);
288 		break;
289 
290 	case DTYPE_SOCKET:
291 		if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
292 			error = EINVAL;
293 			goto out_fdrop;
294 		}
295 		so = fp->f_data;
296 		intlabel = mac_socket_label_alloc(M_WAITOK);
297 		SOCK_LOCK(so);
298 		mac_socket_copy_label(so->so_label, intlabel);
299 		SOCK_UNLOCK(so);
300 		error = mac_socket_externalize_label(intlabel, elements,
301 		    buffer, mac.m_buflen);
302 		mac_socket_label_free(intlabel);
303 		break;
304 
305 	default:
306 		error = EINVAL;
307 	}
308 	if (error == 0)
309 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
310 out_fdrop:
311 	fdrop(fp, td);
312 out:
313 	free(buffer, M_MACTEMP);
314 	free(elements, M_MACTEMP);
315 	return (error);
316 }
317 
318 int
319 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
320 {
321 	char *elements, *buffer;
322 	struct nameidata nd;
323 	struct label *intlabel;
324 	struct mac mac;
325 	int vfslocked, error;
326 
327 	if (!(mac_labeled & MPC_OBJECT_VNODE))
328 		return (EINVAL);
329 
330 	error = copyin(uap->mac_p, &mac, sizeof(mac));
331 	if (error)
332 		return (error);
333 
334 	error = mac_check_structmac_consistent(&mac);
335 	if (error)
336 		return (error);
337 
338 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
339 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
340 	if (error) {
341 		free(elements, M_MACTEMP);
342 		return (error);
343 	}
344 
345 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
346 	NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE,
347 	    uap->path_p, td);
348 	error = namei(&nd);
349 	if (error)
350 		goto out;
351 
352 	intlabel = mac_vnode_label_alloc();
353 	vfslocked = NDHASGIANT(&nd);
354 	mac_vnode_copy_label(nd.ni_vp->v_label, intlabel);
355 	error = mac_vnode_externalize_label(intlabel, elements, buffer,
356 	    mac.m_buflen);
357 
358 	NDFREE(&nd, 0);
359 	VFS_UNLOCK_GIANT(vfslocked);
360 	mac_vnode_label_free(intlabel);
361 	if (error == 0)
362 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
363 
364 out:
365 	free(buffer, M_MACTEMP);
366 	free(elements, M_MACTEMP);
367 
368 	return (error);
369 }
370 
371 int
372 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
373 {
374 	char *elements, *buffer;
375 	struct nameidata nd;
376 	struct label *intlabel;
377 	struct mac mac;
378 	int vfslocked, error;
379 
380 	if (!(mac_labeled & MPC_OBJECT_VNODE))
381 		return (EINVAL);
382 
383 	error = copyin(uap->mac_p, &mac, sizeof(mac));
384 	if (error)
385 		return (error);
386 
387 	error = mac_check_structmac_consistent(&mac);
388 	if (error)
389 		return (error);
390 
391 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
392 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
393 	if (error) {
394 		free(elements, M_MACTEMP);
395 		return (error);
396 	}
397 
398 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
399 	NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
400 	    uap->path_p, td);
401 	error = namei(&nd);
402 	if (error)
403 		goto out;
404 
405 	intlabel = mac_vnode_label_alloc();
406 	vfslocked = NDHASGIANT(&nd);
407 	mac_vnode_copy_label(nd.ni_vp->v_label, intlabel);
408 	error = mac_vnode_externalize_label(intlabel, elements, buffer,
409 	    mac.m_buflen);
410 	NDFREE(&nd, 0);
411 	VFS_UNLOCK_GIANT(vfslocked);
412 	mac_vnode_label_free(intlabel);
413 
414 	if (error == 0)
415 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
416 
417 out:
418 	free(buffer, M_MACTEMP);
419 	free(elements, M_MACTEMP);
420 
421 	return (error);
422 }
423 
424 int
425 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
426 {
427 	struct label *intlabel;
428 	struct pipe *pipe;
429 	struct socket *so;
430 	struct file *fp;
431 	struct mount *mp;
432 	struct vnode *vp;
433 	struct mac mac;
434 	char *buffer;
435 	int error, vfslocked;
436 
437 	error = copyin(uap->mac_p, &mac, sizeof(mac));
438 	if (error)
439 		return (error);
440 
441 	error = mac_check_structmac_consistent(&mac);
442 	if (error)
443 		return (error);
444 
445 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
446 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
447 	if (error) {
448 		free(buffer, M_MACTEMP);
449 		return (error);
450 	}
451 
452 	error = fget(td, uap->fd, CAP_MAC_SET, &fp);
453 	if (error)
454 		goto out;
455 
456 	switch (fp->f_type) {
457 	case DTYPE_FIFO:
458 	case DTYPE_VNODE:
459 		if (!(mac_labeled & MPC_OBJECT_VNODE)) {
460 			error = EINVAL;
461 			goto out_fdrop;
462 		}
463 		intlabel = mac_vnode_label_alloc();
464 		error = mac_vnode_internalize_label(intlabel, buffer);
465 		if (error) {
466 			mac_vnode_label_free(intlabel);
467 			break;
468 		}
469 		vp = fp->f_vnode;
470 		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
471 		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
472 		if (error != 0) {
473 			VFS_UNLOCK_GIANT(vfslocked);
474 			mac_vnode_label_free(intlabel);
475 			break;
476 		}
477 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
478 		error = vn_setlabel(vp, intlabel, td->td_ucred);
479 		VOP_UNLOCK(vp, 0);
480 		vn_finished_write(mp);
481 		VFS_UNLOCK_GIANT(vfslocked);
482 		mac_vnode_label_free(intlabel);
483 		break;
484 
485 	case DTYPE_PIPE:
486 		if (!(mac_labeled & MPC_OBJECT_PIPE)) {
487 			error = EINVAL;
488 			goto out_fdrop;
489 		}
490 		intlabel = mac_pipe_label_alloc();
491 		error = mac_pipe_internalize_label(intlabel, buffer);
492 		if (error == 0) {
493 			pipe = fp->f_data;
494 			PIPE_LOCK(pipe);
495 			error = mac_pipe_label_set(td->td_ucred,
496 			    pipe->pipe_pair, intlabel);
497 			PIPE_UNLOCK(pipe);
498 		}
499 		mac_pipe_label_free(intlabel);
500 		break;
501 
502 	case DTYPE_SOCKET:
503 		if (!(mac_labeled & MPC_OBJECT_SOCKET)) {
504 			error = EINVAL;
505 			goto out_fdrop;
506 		}
507 		intlabel = mac_socket_label_alloc(M_WAITOK);
508 		error = mac_socket_internalize_label(intlabel, buffer);
509 		if (error == 0) {
510 			so = fp->f_data;
511 			error = mac_socket_label_set(td->td_ucred, so,
512 			    intlabel);
513 		}
514 		mac_socket_label_free(intlabel);
515 		break;
516 
517 	default:
518 		error = EINVAL;
519 	}
520 out_fdrop:
521 	fdrop(fp, td);
522 out:
523 	free(buffer, M_MACTEMP);
524 	return (error);
525 }
526 
527 int
528 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
529 {
530 	struct label *intlabel;
531 	struct nameidata nd;
532 	struct mount *mp;
533 	struct mac mac;
534 	char *buffer;
535 	int vfslocked, error;
536 
537 	if (!(mac_labeled & MPC_OBJECT_VNODE))
538 		return (EINVAL);
539 
540 	error = copyin(uap->mac_p, &mac, sizeof(mac));
541 	if (error)
542 		return (error);
543 
544 	error = mac_check_structmac_consistent(&mac);
545 	if (error)
546 		return (error);
547 
548 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
549 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
550 	if (error) {
551 		free(buffer, M_MACTEMP);
552 		return (error);
553 	}
554 
555 	intlabel = mac_vnode_label_alloc();
556 	error = mac_vnode_internalize_label(intlabel, buffer);
557 	free(buffer, M_MACTEMP);
558 	if (error)
559 		goto out;
560 
561 	NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE,
562 	    uap->path_p, td);
563 	error = namei(&nd);
564 	vfslocked = NDHASGIANT(&nd);
565 	if (error == 0) {
566 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
567 		if (error == 0) {
568 			error = vn_setlabel(nd.ni_vp, intlabel,
569 			    td->td_ucred);
570 			vn_finished_write(mp);
571 		}
572 	}
573 
574 	NDFREE(&nd, 0);
575 	VFS_UNLOCK_GIANT(vfslocked);
576 out:
577 	mac_vnode_label_free(intlabel);
578 	return (error);
579 }
580 
581 int
582 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
583 {
584 	struct label *intlabel;
585 	struct nameidata nd;
586 	struct mount *mp;
587 	struct mac mac;
588 	char *buffer;
589 	int vfslocked, error;
590 
591 	if (!(mac_labeled & MPC_OBJECT_VNODE))
592 		return (EINVAL);
593 
594 	error = copyin(uap->mac_p, &mac, sizeof(mac));
595 	if (error)
596 		return (error);
597 
598 	error = mac_check_structmac_consistent(&mac);
599 	if (error)
600 		return (error);
601 
602 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
603 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
604 	if (error) {
605 		free(buffer, M_MACTEMP);
606 		return (error);
607 	}
608 
609 	intlabel = mac_vnode_label_alloc();
610 	error = mac_vnode_internalize_label(intlabel, buffer);
611 	free(buffer, M_MACTEMP);
612 	if (error)
613 		goto out;
614 
615 	NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
616 	    uap->path_p, td);
617 	error = namei(&nd);
618 	vfslocked = NDHASGIANT(&nd);
619 	if (error == 0) {
620 		error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
621 		if (error == 0) {
622 			error = vn_setlabel(nd.ni_vp, intlabel,
623 			    td->td_ucred);
624 			vn_finished_write(mp);
625 		}
626 	}
627 
628 	NDFREE(&nd, 0);
629 	VFS_UNLOCK_GIANT(vfslocked);
630 out:
631 	mac_vnode_label_free(intlabel);
632 	return (error);
633 }
634 
635 int
636 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
637 {
638 	struct mac_policy_conf *mpc;
639 	char target[MAC_MAX_POLICY_NAME];
640 	int error;
641 
642 	error = copyinstr(uap->policy, target, sizeof(target), NULL);
643 	if (error)
644 		return (error);
645 
646 	error = ENOSYS;
647 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
648 		if (strcmp(mpc->mpc_name, target) == 0 &&
649 		    mpc->mpc_ops->mpo_syscall != NULL) {
650 			error = mpc->mpc_ops->mpo_syscall(td,
651 			    uap->call, uap->arg);
652 			goto out;
653 		}
654 	}
655 
656 	if (!LIST_EMPTY(&mac_policy_list)) {
657 		mac_policy_slock_sleep();
658 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
659 			if (strcmp(mpc->mpc_name, target) == 0 &&
660 			    mpc->mpc_ops->mpo_syscall != NULL) {
661 				error = mpc->mpc_ops->mpo_syscall(td,
662 				    uap->call, uap->arg);
663 				break;
664 			}
665 		}
666 		mac_policy_sunlock_sleep();
667 	}
668 out:
669 	return (error);
670 }
671 
672 #else /* !MAC */
673 
674 int
675 sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
676 {
677 
678 	return (ENOSYS);
679 }
680 
681 int
682 sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
683 {
684 
685 	return (ENOSYS);
686 }
687 
688 int
689 sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
690 {
691 
692 	return (ENOSYS);
693 }
694 
695 int
696 sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
697 {
698 
699 	return (ENOSYS);
700 }
701 
702 int
703 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
704 {
705 
706 	return (ENOSYS);
707 }
708 
709 int
710 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
711 {
712 
713 	return (ENOSYS);
714 }
715 
716 int
717 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
718 {
719 
720 	return (ENOSYS);
721 }
722 
723 int
724 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
725 {
726 
727 	return (ENOSYS);
728 }
729 
730 int
731 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
732 {
733 
734 	return (ENOSYS);
735 }
736 
737 int
738 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap)
739 {
740 
741 	return (ENOSYS);
742 }
743 
744 #endif /* !MAC */
745