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 return (EINVAL); 261 vp = fp->f_vnode; 262 intlabel = mac_vnode_label_alloc(); 263 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 264 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 265 mac_vnode_copy_label(vp->v_label, intlabel); 266 VOP_UNLOCK(vp, 0); 267 VFS_UNLOCK_GIANT(vfslocked); 268 error = mac_vnode_externalize_label(intlabel, elements, 269 buffer, mac.m_buflen); 270 mac_vnode_label_free(intlabel); 271 break; 272 273 case DTYPE_PIPE: 274 if (!(mac_labeled & MPC_OBJECT_PIPE)) 275 return (EINVAL); 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 return (EINVAL); 289 so = fp->f_data; 290 intlabel = mac_socket_label_alloc(M_WAITOK); 291 SOCK_LOCK(so); 292 mac_socket_copy_label(so->so_label, intlabel); 293 SOCK_UNLOCK(so); 294 error = mac_socket_externalize_label(intlabel, elements, 295 buffer, mac.m_buflen); 296 mac_socket_label_free(intlabel); 297 break; 298 299 default: 300 error = EINVAL; 301 } 302 fdrop(fp, td); 303 if (error == 0) 304 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 305 306 out: 307 free(buffer, M_MACTEMP); 308 free(elements, M_MACTEMP); 309 return (error); 310 } 311 312 int 313 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 314 { 315 char *elements, *buffer; 316 struct nameidata nd; 317 struct label *intlabel; 318 struct mac mac; 319 int vfslocked, error; 320 321 if (!(mac_labeled & MPC_OBJECT_VNODE)) 322 return (EINVAL); 323 324 error = copyin(uap->mac_p, &mac, sizeof(mac)); 325 if (error) 326 return (error); 327 328 error = mac_check_structmac_consistent(&mac); 329 if (error) 330 return (error); 331 332 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 333 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 334 if (error) { 335 free(elements, M_MACTEMP); 336 return (error); 337 } 338 339 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 340 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, 341 uap->path_p, td); 342 error = namei(&nd); 343 if (error) 344 goto out; 345 346 intlabel = mac_vnode_label_alloc(); 347 vfslocked = NDHASGIANT(&nd); 348 mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 349 error = mac_vnode_externalize_label(intlabel, elements, buffer, 350 mac.m_buflen); 351 352 NDFREE(&nd, 0); 353 VFS_UNLOCK_GIANT(vfslocked); 354 mac_vnode_label_free(intlabel); 355 if (error == 0) 356 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 357 358 out: 359 free(buffer, M_MACTEMP); 360 free(elements, M_MACTEMP); 361 362 return (error); 363 } 364 365 int 366 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 367 { 368 char *elements, *buffer; 369 struct nameidata nd; 370 struct label *intlabel; 371 struct mac mac; 372 int vfslocked, error; 373 374 if (!(mac_labeled & MPC_OBJECT_VNODE)) 375 return (EINVAL); 376 377 error = copyin(uap->mac_p, &mac, sizeof(mac)); 378 if (error) 379 return (error); 380 381 error = mac_check_structmac_consistent(&mac); 382 if (error) 383 return (error); 384 385 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 386 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 387 if (error) { 388 free(elements, M_MACTEMP); 389 return (error); 390 } 391 392 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 393 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 394 uap->path_p, td); 395 error = namei(&nd); 396 if (error) 397 goto out; 398 399 intlabel = mac_vnode_label_alloc(); 400 vfslocked = NDHASGIANT(&nd); 401 mac_vnode_copy_label(nd.ni_vp->v_label, intlabel); 402 error = mac_vnode_externalize_label(intlabel, elements, buffer, 403 mac.m_buflen); 404 NDFREE(&nd, 0); 405 VFS_UNLOCK_GIANT(vfslocked); 406 mac_vnode_label_free(intlabel); 407 408 if (error == 0) 409 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 410 411 out: 412 free(buffer, M_MACTEMP); 413 free(elements, M_MACTEMP); 414 415 return (error); 416 } 417 418 int 419 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 420 { 421 struct label *intlabel; 422 struct pipe *pipe; 423 struct socket *so; 424 struct file *fp; 425 struct mount *mp; 426 struct vnode *vp; 427 struct mac mac; 428 char *buffer; 429 int error, vfslocked; 430 431 error = copyin(uap->mac_p, &mac, sizeof(mac)); 432 if (error) 433 return (error); 434 435 error = mac_check_structmac_consistent(&mac); 436 if (error) 437 return (error); 438 439 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 440 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 441 if (error) { 442 free(buffer, M_MACTEMP); 443 return (error); 444 } 445 446 error = fget(td, uap->fd, CAP_MAC_SET, &fp); 447 if (error) 448 goto out; 449 450 switch (fp->f_type) { 451 case DTYPE_FIFO: 452 case DTYPE_VNODE: 453 if (!(mac_labeled & MPC_OBJECT_VNODE)) 454 return (EINVAL); 455 intlabel = mac_vnode_label_alloc(); 456 error = mac_vnode_internalize_label(intlabel, buffer); 457 if (error) { 458 mac_vnode_label_free(intlabel); 459 break; 460 } 461 vp = fp->f_vnode; 462 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 463 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 464 if (error != 0) { 465 VFS_UNLOCK_GIANT(vfslocked); 466 mac_vnode_label_free(intlabel); 467 break; 468 } 469 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 470 error = vn_setlabel(vp, intlabel, td->td_ucred); 471 VOP_UNLOCK(vp, 0); 472 vn_finished_write(mp); 473 VFS_UNLOCK_GIANT(vfslocked); 474 mac_vnode_label_free(intlabel); 475 break; 476 477 case DTYPE_PIPE: 478 if (!(mac_labeled & MPC_OBJECT_PIPE)) 479 return (EINVAL); 480 intlabel = mac_pipe_label_alloc(); 481 error = mac_pipe_internalize_label(intlabel, buffer); 482 if (error == 0) { 483 pipe = fp->f_data; 484 PIPE_LOCK(pipe); 485 error = mac_pipe_label_set(td->td_ucred, 486 pipe->pipe_pair, intlabel); 487 PIPE_UNLOCK(pipe); 488 } 489 mac_pipe_label_free(intlabel); 490 break; 491 492 case DTYPE_SOCKET: 493 if (!(mac_labeled & MPC_OBJECT_SOCKET)) 494 return (EINVAL); 495 intlabel = mac_socket_label_alloc(M_WAITOK); 496 error = mac_socket_internalize_label(intlabel, buffer); 497 if (error == 0) { 498 so = fp->f_data; 499 error = mac_socket_label_set(td->td_ucred, so, 500 intlabel); 501 } 502 mac_socket_label_free(intlabel); 503 break; 504 505 default: 506 error = EINVAL; 507 } 508 fdrop(fp, td); 509 out: 510 free(buffer, M_MACTEMP); 511 return (error); 512 } 513 514 int 515 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 516 { 517 struct label *intlabel; 518 struct nameidata nd; 519 struct mount *mp; 520 struct mac mac; 521 char *buffer; 522 int vfslocked, error; 523 524 if (!(mac_labeled & MPC_OBJECT_VNODE)) 525 return (EINVAL); 526 527 error = copyin(uap->mac_p, &mac, sizeof(mac)); 528 if (error) 529 return (error); 530 531 error = mac_check_structmac_consistent(&mac); 532 if (error) 533 return (error); 534 535 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 536 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 537 if (error) { 538 free(buffer, M_MACTEMP); 539 return (error); 540 } 541 542 intlabel = mac_vnode_label_alloc(); 543 error = mac_vnode_internalize_label(intlabel, buffer); 544 free(buffer, M_MACTEMP); 545 if (error) 546 goto out; 547 548 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, 549 uap->path_p, td); 550 error = namei(&nd); 551 vfslocked = NDHASGIANT(&nd); 552 if (error == 0) { 553 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 554 if (error == 0) { 555 error = vn_setlabel(nd.ni_vp, intlabel, 556 td->td_ucred); 557 vn_finished_write(mp); 558 } 559 } 560 561 NDFREE(&nd, 0); 562 VFS_UNLOCK_GIANT(vfslocked); 563 out: 564 mac_vnode_label_free(intlabel); 565 return (error); 566 } 567 568 int 569 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 570 { 571 struct label *intlabel; 572 struct nameidata nd; 573 struct mount *mp; 574 struct mac mac; 575 char *buffer; 576 int vfslocked, error; 577 578 if (!(mac_labeled & MPC_OBJECT_VNODE)) 579 return (EINVAL); 580 581 error = copyin(uap->mac_p, &mac, sizeof(mac)); 582 if (error) 583 return (error); 584 585 error = mac_check_structmac_consistent(&mac); 586 if (error) 587 return (error); 588 589 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 590 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 591 if (error) { 592 free(buffer, M_MACTEMP); 593 return (error); 594 } 595 596 intlabel = mac_vnode_label_alloc(); 597 error = mac_vnode_internalize_label(intlabel, buffer); 598 free(buffer, M_MACTEMP); 599 if (error) 600 goto out; 601 602 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, 603 uap->path_p, td); 604 error = namei(&nd); 605 vfslocked = NDHASGIANT(&nd); 606 if (error == 0) { 607 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 608 if (error == 0) { 609 error = vn_setlabel(nd.ni_vp, intlabel, 610 td->td_ucred); 611 vn_finished_write(mp); 612 } 613 } 614 615 NDFREE(&nd, 0); 616 VFS_UNLOCK_GIANT(vfslocked); 617 out: 618 mac_vnode_label_free(intlabel); 619 return (error); 620 } 621 622 int 623 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap) 624 { 625 struct mac_policy_conf *mpc; 626 char target[MAC_MAX_POLICY_NAME]; 627 int error; 628 629 error = copyinstr(uap->policy, target, sizeof(target), NULL); 630 if (error) 631 return (error); 632 633 error = ENOSYS; 634 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 635 if (strcmp(mpc->mpc_name, target) == 0 && 636 mpc->mpc_ops->mpo_syscall != NULL) { 637 error = mpc->mpc_ops->mpo_syscall(td, 638 uap->call, uap->arg); 639 goto out; 640 } 641 } 642 643 if (!LIST_EMPTY(&mac_policy_list)) { 644 mac_policy_slock_sleep(); 645 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 646 if (strcmp(mpc->mpc_name, target) == 0 && 647 mpc->mpc_ops->mpo_syscall != NULL) { 648 error = mpc->mpc_ops->mpo_syscall(td, 649 uap->call, uap->arg); 650 break; 651 } 652 } 653 mac_policy_sunlock_sleep(); 654 } 655 out: 656 return (error); 657 } 658 659 #else /* !MAC */ 660 661 int 662 sys___mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 663 { 664 665 return (ENOSYS); 666 } 667 668 int 669 sys___mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 670 { 671 672 return (ENOSYS); 673 } 674 675 int 676 sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 677 { 678 679 return (ENOSYS); 680 } 681 682 int 683 sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 684 { 685 686 return (ENOSYS); 687 } 688 689 int 690 sys___mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 691 { 692 693 return (ENOSYS); 694 } 695 696 int 697 sys___mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 698 { 699 700 return (ENOSYS); 701 } 702 703 int 704 sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 705 { 706 707 return (ENOSYS); 708 } 709 710 int 711 sys___mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 712 { 713 714 return (ENOSYS); 715 } 716 717 int 718 sys___mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 719 { 720 721 return (ENOSYS); 722 } 723 724 int 725 sys_mac_syscall(struct thread *td, struct mac_syscall_args *uap) 726 { 727 728 return (ENOSYS); 729 } 730 731 #endif /* !MAC */ 732