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