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