1 /* 2 * Copyright (c) 1999-2005 Apple Computer, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/filedesc.h> 34 #include <sys/ipc.h> 35 #include <sys/mount.h> 36 #include <sys/proc.h> 37 #include <sys/socket.h> 38 #include <sys/socketvar.h> 39 #include <sys/protosw.h> 40 #include <sys/domain.h> 41 #include <sys/systm.h> 42 #include <sys/un.h> 43 #include <sys/vnode.h> 44 45 #include <netinet/in.h> 46 #include <netinet/in_pcb.h> 47 48 #include <security/audit/audit.h> 49 #include <security/audit/audit_private.h> 50 51 /* 52 * Calls to manipulate elements of the audit record structure from system 53 * call code. Macro wrappers will prevent this functions from being 54 * entered if auditing is disabled, avoiding the function call cost. We 55 * check the thread audit record pointer anyway, as the audit condition 56 * could change, and pre-selection may not have allocated an audit 57 * record for this event. 58 * 59 * XXXAUDIT: Should we assert, in each case, that this field of the record 60 * hasn't already been filled in? 61 */ 62 void 63 audit_arg_addr(void * addr) 64 { 65 struct kaudit_record *ar; 66 67 ar = currecord(); 68 if (ar == NULL) 69 return; 70 71 ar->k_ar.ar_arg_addr = addr; 72 ARG_SET_VALID(ar, ARG_ADDR); 73 } 74 75 void 76 audit_arg_exit(int status, int retval) 77 { 78 struct kaudit_record *ar; 79 80 ar = currecord(); 81 if (ar == NULL) 82 return; 83 84 ar->k_ar.ar_arg_exitstatus = status; 85 ar->k_ar.ar_arg_exitretval = retval; 86 ARG_SET_VALID(ar, ARG_EXIT); 87 } 88 89 void 90 audit_arg_len(int len) 91 { 92 struct kaudit_record *ar; 93 94 ar = currecord(); 95 if (ar == NULL) 96 return; 97 98 ar->k_ar.ar_arg_len = len; 99 ARG_SET_VALID(ar, ARG_LEN); 100 } 101 102 void 103 audit_arg_fd(int fd) 104 { 105 struct kaudit_record *ar; 106 107 ar = currecord(); 108 if (ar == NULL) 109 return; 110 111 ar->k_ar.ar_arg_fd = fd; 112 ARG_SET_VALID(ar, ARG_FD); 113 } 114 115 void 116 audit_arg_fflags(int fflags) 117 { 118 struct kaudit_record *ar; 119 120 ar = currecord(); 121 if (ar == NULL) 122 return; 123 124 ar->k_ar.ar_arg_fflags = fflags; 125 ARG_SET_VALID(ar, ARG_FFLAGS); 126 } 127 128 void 129 audit_arg_gid(gid_t gid) 130 { 131 struct kaudit_record *ar; 132 133 ar = currecord(); 134 if (ar == NULL) 135 return; 136 137 ar->k_ar.ar_arg_gid = gid; 138 ARG_SET_VALID(ar, ARG_GID); 139 } 140 141 void 142 audit_arg_uid(uid_t uid) 143 { 144 struct kaudit_record *ar; 145 146 ar = currecord(); 147 if (ar == NULL) 148 return; 149 150 ar->k_ar.ar_arg_uid = uid; 151 ARG_SET_VALID(ar, ARG_UID); 152 } 153 154 void 155 audit_arg_egid(gid_t egid) 156 { 157 struct kaudit_record *ar; 158 159 ar = currecord(); 160 if (ar == NULL) 161 return; 162 163 ar->k_ar.ar_arg_egid = egid; 164 ARG_SET_VALID(ar, ARG_EGID); 165 } 166 167 void 168 audit_arg_euid(uid_t euid) 169 { 170 struct kaudit_record *ar; 171 172 ar = currecord(); 173 if (ar == NULL) 174 return; 175 176 ar->k_ar.ar_arg_euid = euid; 177 ARG_SET_VALID(ar, ARG_EUID); 178 } 179 180 void 181 audit_arg_rgid(gid_t rgid) 182 { 183 struct kaudit_record *ar; 184 185 ar = currecord(); 186 if (ar == NULL) 187 return; 188 189 ar->k_ar.ar_arg_rgid = rgid; 190 ARG_SET_VALID(ar, ARG_RGID); 191 } 192 193 void 194 audit_arg_ruid(uid_t ruid) 195 { 196 struct kaudit_record *ar; 197 198 ar = currecord(); 199 if (ar == NULL) 200 return; 201 202 ar->k_ar.ar_arg_ruid = ruid; 203 ARG_SET_VALID(ar, ARG_RUID); 204 } 205 206 void 207 audit_arg_sgid(gid_t sgid) 208 { 209 struct kaudit_record *ar; 210 211 ar = currecord(); 212 if (ar == NULL) 213 return; 214 215 ar->k_ar.ar_arg_sgid = sgid; 216 ARG_SET_VALID(ar, ARG_SGID); 217 } 218 219 void 220 audit_arg_suid(uid_t suid) 221 { 222 struct kaudit_record *ar; 223 224 ar = currecord(); 225 if (ar == NULL) 226 return; 227 228 ar->k_ar.ar_arg_suid = suid; 229 ARG_SET_VALID(ar, ARG_SUID); 230 } 231 232 void 233 audit_arg_groupset(gid_t *gidset, u_int gidset_size) 234 { 235 int i; 236 struct kaudit_record *ar; 237 238 ar = currecord(); 239 if (ar == NULL) 240 return; 241 242 for (i = 0; i < gidset_size; i++) 243 ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 244 ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 245 ARG_SET_VALID(ar, ARG_GROUPSET); 246 } 247 248 void 249 audit_arg_login(char *login) 250 { 251 struct kaudit_record *ar; 252 253 ar = currecord(); 254 if (ar == NULL) 255 return; 256 257 strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 258 ARG_SET_VALID(ar, ARG_LOGIN); 259 } 260 261 void 262 audit_arg_ctlname(int *name, int namelen) 263 { 264 struct kaudit_record *ar; 265 266 ar = currecord(); 267 if (ar == NULL) 268 return; 269 270 bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 271 ar->k_ar.ar_arg_len = namelen; 272 ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 273 } 274 275 void 276 audit_arg_mask(int mask) 277 { 278 struct kaudit_record *ar; 279 280 ar = currecord(); 281 if (ar == NULL) 282 return; 283 284 ar->k_ar.ar_arg_mask = mask; 285 ARG_SET_VALID(ar, ARG_MASK); 286 } 287 288 void 289 audit_arg_mode(mode_t mode) 290 { 291 struct kaudit_record *ar; 292 293 ar = currecord(); 294 if (ar == NULL) 295 return; 296 297 ar->k_ar.ar_arg_mode = mode; 298 ARG_SET_VALID(ar, ARG_MODE); 299 } 300 301 void 302 audit_arg_dev(int dev) 303 { 304 struct kaudit_record *ar; 305 306 ar = currecord(); 307 if (ar == NULL) 308 return; 309 310 ar->k_ar.ar_arg_dev = dev; 311 ARG_SET_VALID(ar, ARG_DEV); 312 } 313 314 void 315 audit_arg_value(long value) 316 { 317 struct kaudit_record *ar; 318 319 ar = currecord(); 320 if (ar == NULL) 321 return; 322 323 ar->k_ar.ar_arg_value = value; 324 ARG_SET_VALID(ar, ARG_VALUE); 325 } 326 327 void 328 audit_arg_owner(uid_t uid, gid_t gid) 329 { 330 struct kaudit_record *ar; 331 332 ar = currecord(); 333 if (ar == NULL) 334 return; 335 336 ar->k_ar.ar_arg_uid = uid; 337 ar->k_ar.ar_arg_gid = gid; 338 ARG_SET_VALID(ar, ARG_UID | ARG_GID); 339 } 340 341 void 342 audit_arg_pid(pid_t pid) 343 { 344 struct kaudit_record *ar; 345 346 ar = currecord(); 347 if (ar == NULL) 348 return; 349 350 ar->k_ar.ar_arg_pid = pid; 351 ARG_SET_VALID(ar, ARG_PID); 352 } 353 354 void 355 audit_arg_process(struct proc *p) 356 { 357 struct kaudit_record *ar; 358 359 ar = currecord(); 360 if ((ar == NULL) || (p == NULL)) 361 return; 362 363 /* 364 * XXXAUDIT: PROC_LOCK_ASSERT(p); 365 */ 366 ar->k_ar.ar_arg_auid = p->p_au->ai_auid; 367 ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid; 368 ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0]; 369 ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid; 370 ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid; 371 ar->k_ar.ar_arg_asid = p->p_au->ai_asid; 372 ar->k_ar.ar_arg_termid = p->p_au->ai_termid; 373 ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 374 ARG_RGID | ARG_ASID | ARG_TERMID | ARG_PROCESS); 375 } 376 377 void 378 audit_arg_signum(u_int signum) 379 { 380 struct kaudit_record *ar; 381 382 ar = currecord(); 383 if (ar == NULL) 384 return; 385 386 ar->k_ar.ar_arg_signum = signum; 387 ARG_SET_VALID(ar, ARG_SIGNUM); 388 } 389 390 void 391 audit_arg_socket(int sodomain, int sotype, int soprotocol) 392 { 393 struct kaudit_record *ar; 394 395 ar = currecord(); 396 if (ar == NULL) 397 return; 398 399 ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 400 ar->k_ar.ar_arg_sockinfo.so_type = sotype; 401 ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 402 ARG_SET_VALID(ar, ARG_SOCKINFO); 403 } 404 405 /* 406 * XXXAUDIT: Argument here should be 'sa' not 'so'. Caller is responsible 407 * for synchronizing access to the source of the address. 408 */ 409 void 410 audit_arg_sockaddr(struct thread *td, struct sockaddr *so) 411 { 412 struct kaudit_record *ar; 413 414 ar = currecord(); 415 if (ar == NULL || td == NULL || so == NULL) 416 return; 417 418 bcopy(so, &ar->k_ar.ar_arg_sockaddr, sizeof(ar->k_ar.ar_arg_sockaddr)); 419 switch (so->sa_family) { 420 case AF_INET: 421 ARG_SET_VALID(ar, ARG_SADDRINET); 422 break; 423 424 case AF_INET6: 425 ARG_SET_VALID(ar, ARG_SADDRINET6); 426 break; 427 428 case AF_UNIX: 429 audit_arg_upath(td, ((struct sockaddr_un *)so)->sun_path, 430 ARG_UPATH1); 431 ARG_SET_VALID(ar, ARG_SADDRUNIX); 432 break; 433 /* XXXAUDIT: default:? */ 434 } 435 } 436 437 void 438 audit_arg_auid(uid_t auid) 439 { 440 struct kaudit_record *ar; 441 442 ar = currecord(); 443 if (ar == NULL) 444 return; 445 446 ar->k_ar.ar_arg_auid = auid; 447 ARG_SET_VALID(ar, ARG_AUID); 448 } 449 450 void 451 audit_arg_auditinfo(struct auditinfo *au_info) 452 { 453 struct kaudit_record *ar; 454 455 ar = currecord(); 456 if (ar == NULL) 457 return; 458 459 ar->k_ar.ar_arg_auid = au_info->ai_auid; 460 ar->k_ar.ar_arg_asid = au_info->ai_asid; 461 ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 462 ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 463 ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 464 ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 465 ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 466 } 467 468 void 469 audit_arg_text(char *text) 470 { 471 struct kaudit_record *ar; 472 473 ar = currecord(); 474 if (ar == NULL) 475 return; 476 477 /* 478 * XXXAUDIT: Why do we accept a possibly NULL string here? 479 */ 480 /* Invalidate the text string */ 481 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 482 if (text == NULL) 483 return; 484 485 if (ar->k_ar.ar_arg_text == NULL) 486 ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 487 M_WAITOK); 488 489 strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 490 ARG_SET_VALID(ar, ARG_TEXT); 491 } 492 493 void 494 audit_arg_cmd(int cmd) 495 { 496 struct kaudit_record *ar; 497 498 ar = currecord(); 499 if (ar == NULL) 500 return; 501 502 ar->k_ar.ar_arg_cmd = cmd; 503 ARG_SET_VALID(ar, ARG_CMD); 504 } 505 506 void 507 audit_arg_svipc_cmd(int cmd) 508 { 509 struct kaudit_record *ar; 510 511 ar = currecord(); 512 if (ar == NULL) 513 return; 514 515 ar->k_ar.ar_arg_svipc_cmd = cmd; 516 ARG_SET_VALID(ar, ARG_SVIPC_CMD); 517 } 518 519 void 520 audit_arg_svipc_perm(struct ipc_perm *perm) 521 { 522 struct kaudit_record *ar; 523 524 ar = currecord(); 525 if (ar == NULL) 526 return; 527 528 bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 529 sizeof(ar->k_ar.ar_arg_svipc_perm)); 530 ARG_SET_VALID(ar, ARG_SVIPC_PERM); 531 } 532 533 void 534 audit_arg_svipc_id(int id) 535 { 536 struct kaudit_record *ar; 537 538 ar = currecord(); 539 if (ar == NULL) 540 return; 541 542 ar->k_ar.ar_arg_svipc_id = id; 543 ARG_SET_VALID(ar, ARG_SVIPC_ID); 544 } 545 546 void 547 audit_arg_svipc_addr(void * addr) 548 { 549 struct kaudit_record *ar; 550 551 ar = currecord(); 552 if (ar == NULL) 553 return; 554 555 ar->k_ar.ar_arg_svipc_addr = addr; 556 ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 557 } 558 559 void 560 audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 561 { 562 struct kaudit_record *ar; 563 564 ar = currecord(); 565 if (ar == NULL) 566 return; 567 568 ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 569 ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 570 ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 571 ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 572 } 573 574 void 575 audit_arg_auditon(union auditon_udata *udata) 576 { 577 struct kaudit_record *ar; 578 579 ar = currecord(); 580 if (ar == NULL) 581 return; 582 583 bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 584 sizeof(ar->k_ar.ar_arg_auditon)); 585 ARG_SET_VALID(ar, ARG_AUDITON); 586 } 587 588 /* 589 * Audit information about a file, either the file's vnode info, or its 590 * socket address info. 591 */ 592 void 593 audit_arg_file(struct proc *p, struct file *fp) 594 { 595 struct kaudit_record *ar; 596 struct socket *so; 597 struct inpcb *pcb; 598 struct vnode *vp; 599 int vfslocked; 600 601 /* 602 * XXXAUDIT: Why is the (ar == NULL) test only in the socket case? 603 */ 604 switch (fp->f_type) { 605 case DTYPE_VNODE: 606 case DTYPE_FIFO: 607 /* 608 * XXXAUDIT: Only possibly to record as first vnode? 609 */ 610 vp = fp->f_vnode; 611 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 612 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); 613 audit_arg_vnode(vp, ARG_VNODE1); 614 VOP_UNLOCK(vp, 0, curthread); 615 VFS_UNLOCK_GIANT(vfslocked); 616 break; 617 618 case DTYPE_SOCKET: 619 ar = currecord(); 620 if (ar == NULL) 621 return; 622 623 /* 624 * XXXAUDIT: Socket locking? Inpcb locking? 625 */ 626 so = (struct socket *)fp->f_data; 627 if (INP_CHECK_SOCKAF(so, PF_INET)) { 628 if (so->so_pcb == NULL) 629 return; 630 ar->k_ar.ar_arg_sockinfo.so_type = 631 so->so_type; 632 ar->k_ar.ar_arg_sockinfo.so_domain = 633 INP_SOCKAF(so); 634 ar->k_ar.ar_arg_sockinfo.so_protocol = 635 so->so_proto->pr_protocol; 636 pcb = (struct inpcb *)so->so_pcb; 637 ar->k_ar.ar_arg_sockinfo.so_raddr = 638 pcb->inp_faddr.s_addr; 639 ar->k_ar.ar_arg_sockinfo.so_laddr = 640 pcb->inp_laddr.s_addr; 641 ar->k_ar.ar_arg_sockinfo.so_rport = 642 pcb->inp_fport; 643 ar->k_ar.ar_arg_sockinfo.so_lport = 644 pcb->inp_lport; 645 ARG_SET_VALID(ar, ARG_SOCKINFO); 646 } 647 break; 648 649 default: 650 /* XXXAUDIT: else? */ 651 break; 652 } 653 654 } 655 656 /* 657 * Store a path as given by the user process for auditing into the audit 658 * record stored on the user thread. This function will allocate the memory to 659 * store the path info if not already available. This memory will be 660 * freed when the audit record is freed. 661 * 662 * XXXAUDIT: Possibly assert that the memory isn't already allocated? 663 */ 664 void 665 audit_arg_upath(struct thread *td, char *upath, u_int64_t flag) 666 { 667 struct kaudit_record *ar; 668 char **pathp; 669 670 if (td == NULL || upath == NULL) 671 return; /* nothing to do! */ 672 673 /* 674 * XXXAUDIT: Witness warning for possible sleep here? 675 */ 676 KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2), 677 ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 678 KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2), 679 ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 680 681 ar = currecord(); 682 if (ar == NULL) 683 return; 684 685 if (flag == ARG_UPATH1) 686 pathp = &ar->k_ar.ar_arg_upath1; 687 else 688 pathp = &ar->k_ar.ar_arg_upath2; 689 690 if (*pathp == NULL) 691 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 692 693 canon_path(td, upath, *pathp); 694 695 ARG_SET_VALID(ar, flag); 696 } 697 698 /* 699 * Function to save the path and vnode attr information into the audit 700 * record. 701 * 702 * It is assumed that the caller will hold any vnode locks necessary to 703 * perform a VOP_GETATTR() on the passed vnode. 704 * 705 * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but 706 * always provides access to the generation number as we need that 707 * to construct the BSM file ID. 708 * XXX: We should accept the process argument from the caller, since 709 * it's very likely they already have a reference. 710 * XXX: Error handling in this function is poor. 711 * 712 * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 713 */ 714 void 715 audit_arg_vnode(struct vnode *vp, u_int64_t flags) 716 { 717 struct kaudit_record *ar; 718 struct vattr vattr; 719 int error; 720 struct vnode_au_info *vnp; 721 struct thread *td; 722 723 /* 724 * XXXAUDIT: Why is vp possibly NULL here? 725 */ 726 if (vp == NULL) 727 return; 728 729 /* 730 * Assume that if the caller is calling audit_arg_vnode() on a 731 * non-MPSAFE vnode, then it will have acquired Giant. 732 */ 733 VFS_ASSERT_GIANT(vp->v_mount); 734 ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 735 736 ar = currecord(); 737 if (ar == NULL) /* This will be the case for unaudited system calls */ 738 return; 739 740 /* 741 * XXXAUDIT: KASSERT argument validity instead? 742 * 743 * XXXAUDIT: The below clears, and then resets the flags for valid 744 * arguments. Ideally, either the new vnode is used, or the old one 745 * would be. 746 */ 747 if ((flags & (ARG_VNODE1 | ARG_VNODE2)) == 0) 748 return; 749 750 td = curthread; 751 752 if (flags & ARG_VNODE1) { 753 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1); 754 vnp = &ar->k_ar.ar_arg_vnode1; 755 } else { 756 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2); 757 vnp = &ar->k_ar.ar_arg_vnode2; 758 } 759 760 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td); 761 if (error) { 762 /* XXX: How to handle this case? */ 763 return; 764 } 765 766 vnp->vn_mode = vattr.va_mode; 767 vnp->vn_uid = vattr.va_uid; 768 vnp->vn_gid = vattr.va_gid; 769 vnp->vn_dev = vattr.va_rdev; 770 vnp->vn_fsid = vattr.va_fsid; 771 vnp->vn_fileid = vattr.va_fileid; 772 vnp->vn_gen = vattr.va_gen; 773 if (flags & ARG_VNODE1) 774 ARG_SET_VALID(ar, ARG_VNODE1); 775 else 776 ARG_SET_VALID(ar, ARG_VNODE2); 777 } 778 779 /* 780 * The close() system call uses it's own audit call to capture the 781 * path/vnode information because those pieces are not easily obtained 782 * within the system call itself. 783 */ 784 void 785 audit_sysclose(struct thread *td, int fd) 786 { 787 struct vnode *vp; 788 struct file *fp; 789 int vfslocked; 790 791 audit_arg_fd(fd); 792 793 if (getvnode(td->td_proc->p_fd, fd, &fp) != 0) 794 return; 795 796 vp = fp->f_vnode; 797 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 798 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 799 audit_arg_vnode(vp, ARG_VNODE1); 800 VOP_UNLOCK(vp, 0, td); 801 VFS_UNLOCK_GIANT(vfslocked); 802 fdrop(fp, td); 803 } 804