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