mac_syscalls.c revision 165591
1232950Stheraven/*-
2232950Stheraven * Copyright (c) 1999-2002, 2006 Robert N. M. Watson
3232950Stheraven * Copyright (c) 2001 Ilmar S. Habibulin
4232950Stheraven * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5232950Stheraven * Copyright (c) 2005-2006 SPARTA, Inc.
6232950Stheraven * All rights reserved.
7232950Stheraven *
8232950Stheraven * This software was developed by Robert Watson and Ilmar Habibulin for the
9232950Stheraven * TrustedBSD Project.
10232950Stheraven *
11232950Stheraven * This software was developed for the FreeBSD Project in part by Network
12232950Stheraven * Associates Laboratories, the Security Research Division of Network
13232950Stheraven * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
14232950Stheraven * as part of the DARPA CHATS research program.
15232950Stheraven *
16232950Stheraven * This software was enhanced by SPARTA ISSO under SPAWAR contract
17232950Stheraven * N66001-04-C-6019 ("SEFOS").
18232950Stheraven *
19232950Stheraven * Redistribution and use in source and binary forms, with or without
20232950Stheraven * modification, are permitted provided that the following conditions
21232950Stheraven * are met:
22232950Stheraven * 1. Redistributions of source code must retain the above copyright
23232950Stheraven *    notice, this list of conditions and the following disclaimer.
24232950Stheraven * 2. Redistributions in binary form must reproduce the above copyright
25232950Stheraven *    notice, this list of conditions and the following disclaimer in the
26232950Stheraven *    documentation and/or other materials provided with the distribution.
27227825Stheraven *
28227825Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29227825Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30227825Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31227825Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32227825Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33227825Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34227825Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35227825Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36227825Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37227825Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38227825Stheraven * SUCH DAMAGE.
39227825Stheraven */
40227825Stheraven
41227825Stheraven#include <sys/cdefs.h>
42227825Stheraven__FBSDID("$FreeBSD: head/sys/security/mac/mac_syscalls.c 165591 2006-12-28 21:07:45Z rwatson $");
43227825Stheraven
44227825Stheraven#include "opt_mac.h"
45227825Stheraven
46227825Stheraven#include <sys/param.h>
47227825Stheraven#include <sys/kernel.h>
48227825Stheraven#include <sys/lock.h>
49227825Stheraven#include <sys/malloc.h>
50227825Stheraven#include <sys/mutex.h>
51227825Stheraven#include <sys/mac.h>
52227825Stheraven#include <sys/proc.h>
53227825Stheraven#include <sys/systm.h>
54227825Stheraven#include <sys/sysproto.h>
55227825Stheraven#include <sys/sysent.h>
56227825Stheraven#include <sys/vnode.h>
57227825Stheraven#include <sys/mount.h>
58227825Stheraven#include <sys/file.h>
59227825Stheraven#include <sys/namei.h>
60227825Stheraven#include <sys/socket.h>
61227825Stheraven#include <sys/pipe.h>
62227825Stheraven#include <sys/socketvar.h>
63227825Stheraven
64227825Stheraven#include <security/mac/mac_framework.h>
65227825Stheraven#include <security/mac/mac_internal.h>
66227825Stheraven#include <security/mac/mac_policy.h>
67227825Stheraven
68#ifdef MAC
69
70/*
71 * MPSAFE
72 */
73int
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 */
125int
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 */
161int
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
222out:
223	mac_cred_label_free(intlabel);
224	return (error);
225}
226
227/*
228 * MPSAFE
229 */
230int
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
310out:
311	free(buffer, M_MACTEMP);
312	free(elements, M_MACTEMP);
313	return (error);
314}
315
316/*
317 * MPSAFE
318 */
319int
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
362out:
363	free(buffer, M_MACTEMP);
364	free(elements, M_MACTEMP);
365
366	return (error);
367}
368
369/*
370 * MPSAFE
371 */
372int
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
415out:
416	free(buffer, M_MACTEMP);
417	free(elements, M_MACTEMP);
418
419	return (error);
420}
421
422/*
423 * MPSAFE
424 */
425int
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);
512out:
513	free(buffer, M_MACTEMP);
514	return (error);
515}
516
517/*
518 * MPSAFE
519 */
520int
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);
566out:
567	mac_vnode_label_free(intlabel);
568	return (error);
569}
570
571/*
572 * MPSAFE
573 */
574int
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);
620out:
621	mac_vnode_label_free(intlabel);
622	return (error);
623}
624
625/*
626 * MPSAFE
627 */
628int
629mac_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	}
660out:
661	return (error);
662}
663
664#else /* !MAC */
665
666int
667__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
668{
669
670	return (ENOSYS);
671}
672
673int
674__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
675{
676
677	return (ENOSYS);
678}
679
680int
681__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
682{
683
684	return (ENOSYS);
685}
686
687int
688__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
689{
690
691	return (ENOSYS);
692}
693
694int
695__mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
696{
697
698	return (ENOSYS);
699}
700
701int
702__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
703{
704
705	return (ENOSYS);
706}
707
708int
709__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
710{
711
712	return (ENOSYS);
713}
714
715int
716__mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
717{
718
719	return (ENOSYS);
720}
721
722int
723__mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
724{
725
726	return (ENOSYS);
727}
728
729int
730mac_syscall(struct thread *td, struct mac_syscall_args *uap)
731{
732
733	return (ENOSYS);
734}
735
736#endif /* !MAC */
737