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