1 /*- 2 * Copyright (c) 1999-2005 Apple 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 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 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/filedesc.h> 35 #include <sys/capsicum.h> 36 #include <sys/ipc.h> 37 #include <sys/mount.h> 38 #include <sys/proc.h> 39 #include <sys/socket.h> 40 #include <sys/socketvar.h> 41 #include <sys/protosw.h> 42 #include <sys/domain.h> 43 #include <sys/sbuf.h> 44 #include <sys/systm.h> 45 #include <sys/un.h> 46 #include <sys/vnode.h> 47 48 #include <netinet/in.h> 49 #include <netinet/in_pcb.h> 50 51 #include <security/audit/audit.h> 52 #include <security/audit/audit_private.h> 53 54 /* 55 * Calls to manipulate elements of the audit record structure from system 56 * call code. Macro wrappers will prevent this functions from being entered 57 * if auditing is disabled, avoiding the function call cost. We check the 58 * thread audit record pointer anyway, as the audit condition could change, 59 * and pre-selection may not have allocated an audit record for this event. 60 * 61 * XXXAUDIT: Should we assert, in each case, that this field of the record 62 * hasn't already been filled in? 63 */ 64 void 65 audit_arg_addr(void *addr) 66 { 67 struct kaudit_record *ar; 68 69 ar = currecord(); 70 if (ar == NULL) 71 return; 72 73 ar->k_ar.ar_arg_addr = addr; 74 ARG_SET_VALID(ar, ARG_ADDR); 75 } 76 77 void 78 audit_arg_exit(int status, int retval) 79 { 80 struct kaudit_record *ar; 81 82 ar = currecord(); 83 if (ar == NULL) 84 return; 85 86 ar->k_ar.ar_arg_exitstatus = status; 87 ar->k_ar.ar_arg_exitretval = retval; 88 ARG_SET_VALID(ar, ARG_EXIT); 89 } 90 91 void 92 audit_arg_len(int len) 93 { 94 struct kaudit_record *ar; 95 96 ar = currecord(); 97 if (ar == NULL) 98 return; 99 100 ar->k_ar.ar_arg_len = len; 101 ARG_SET_VALID(ar, ARG_LEN); 102 } 103 104 void 105 audit_arg_atfd1(int atfd) 106 { 107 struct kaudit_record *ar; 108 109 ar = currecord(); 110 if (ar == NULL) 111 return; 112 113 ar->k_ar.ar_arg_atfd1 = atfd; 114 ARG_SET_VALID(ar, ARG_ATFD1); 115 } 116 117 void 118 audit_arg_atfd2(int atfd) 119 { 120 struct kaudit_record *ar; 121 122 ar = currecord(); 123 if (ar == NULL) 124 return; 125 126 ar->k_ar.ar_arg_atfd2 = atfd; 127 ARG_SET_VALID(ar, ARG_ATFD2); 128 } 129 130 void 131 audit_arg_fd(int fd) 132 { 133 struct kaudit_record *ar; 134 135 ar = currecord(); 136 if (ar == NULL) 137 return; 138 139 ar->k_ar.ar_arg_fd = fd; 140 ARG_SET_VALID(ar, ARG_FD); 141 } 142 143 void 144 audit_arg_fflags(int fflags) 145 { 146 struct kaudit_record *ar; 147 148 ar = currecord(); 149 if (ar == NULL) 150 return; 151 152 ar->k_ar.ar_arg_fflags = fflags; 153 ARG_SET_VALID(ar, ARG_FFLAGS); 154 } 155 156 void 157 audit_arg_gid(gid_t gid) 158 { 159 struct kaudit_record *ar; 160 161 ar = currecord(); 162 if (ar == NULL) 163 return; 164 165 ar->k_ar.ar_arg_gid = gid; 166 ARG_SET_VALID(ar, ARG_GID); 167 } 168 169 void 170 audit_arg_uid(uid_t uid) 171 { 172 struct kaudit_record *ar; 173 174 ar = currecord(); 175 if (ar == NULL) 176 return; 177 178 ar->k_ar.ar_arg_uid = uid; 179 ARG_SET_VALID(ar, ARG_UID); 180 } 181 182 void 183 audit_arg_egid(gid_t egid) 184 { 185 struct kaudit_record *ar; 186 187 ar = currecord(); 188 if (ar == NULL) 189 return; 190 191 ar->k_ar.ar_arg_egid = egid; 192 ARG_SET_VALID(ar, ARG_EGID); 193 } 194 195 void 196 audit_arg_euid(uid_t euid) 197 { 198 struct kaudit_record *ar; 199 200 ar = currecord(); 201 if (ar == NULL) 202 return; 203 204 ar->k_ar.ar_arg_euid = euid; 205 ARG_SET_VALID(ar, ARG_EUID); 206 } 207 208 void 209 audit_arg_rgid(gid_t rgid) 210 { 211 struct kaudit_record *ar; 212 213 ar = currecord(); 214 if (ar == NULL) 215 return; 216 217 ar->k_ar.ar_arg_rgid = rgid; 218 ARG_SET_VALID(ar, ARG_RGID); 219 } 220 221 void 222 audit_arg_ruid(uid_t ruid) 223 { 224 struct kaudit_record *ar; 225 226 ar = currecord(); 227 if (ar == NULL) 228 return; 229 230 ar->k_ar.ar_arg_ruid = ruid; 231 ARG_SET_VALID(ar, ARG_RUID); 232 } 233 234 void 235 audit_arg_sgid(gid_t sgid) 236 { 237 struct kaudit_record *ar; 238 239 ar = currecord(); 240 if (ar == NULL) 241 return; 242 243 ar->k_ar.ar_arg_sgid = sgid; 244 ARG_SET_VALID(ar, ARG_SGID); 245 } 246 247 void 248 audit_arg_suid(uid_t suid) 249 { 250 struct kaudit_record *ar; 251 252 ar = currecord(); 253 if (ar == NULL) 254 return; 255 256 ar->k_ar.ar_arg_suid = suid; 257 ARG_SET_VALID(ar, ARG_SUID); 258 } 259 260 void 261 audit_arg_groupset(gid_t *gidset, u_int gidset_size) 262 { 263 u_int i; 264 struct kaudit_record *ar; 265 266 KASSERT(gidset_size <= ngroups_max + 1, 267 ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)")); 268 269 ar = currecord(); 270 if (ar == NULL) 271 return; 272 273 if (ar->k_ar.ar_arg_groups.gidset == NULL) 274 ar->k_ar.ar_arg_groups.gidset = malloc( 275 sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK); 276 277 for (i = 0; i < gidset_size; i++) 278 ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 279 ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 280 ARG_SET_VALID(ar, ARG_GROUPSET); 281 } 282 283 void 284 audit_arg_login(char *login) 285 { 286 struct kaudit_record *ar; 287 288 ar = currecord(); 289 if (ar == NULL) 290 return; 291 292 strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 293 ARG_SET_VALID(ar, ARG_LOGIN); 294 } 295 296 void 297 audit_arg_ctlname(int *name, int namelen) 298 { 299 struct kaudit_record *ar; 300 301 ar = currecord(); 302 if (ar == NULL) 303 return; 304 305 bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 306 ar->k_ar.ar_arg_len = namelen; 307 ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 308 } 309 310 void 311 audit_arg_mask(int mask) 312 { 313 struct kaudit_record *ar; 314 315 ar = currecord(); 316 if (ar == NULL) 317 return; 318 319 ar->k_ar.ar_arg_mask = mask; 320 ARG_SET_VALID(ar, ARG_MASK); 321 } 322 323 void 324 audit_arg_mode(mode_t mode) 325 { 326 struct kaudit_record *ar; 327 328 ar = currecord(); 329 if (ar == NULL) 330 return; 331 332 ar->k_ar.ar_arg_mode = mode; 333 ARG_SET_VALID(ar, ARG_MODE); 334 } 335 336 void 337 audit_arg_dev(int dev) 338 { 339 struct kaudit_record *ar; 340 341 ar = currecord(); 342 if (ar == NULL) 343 return; 344 345 ar->k_ar.ar_arg_dev = dev; 346 ARG_SET_VALID(ar, ARG_DEV); 347 } 348 349 void 350 audit_arg_value(long value) 351 { 352 struct kaudit_record *ar; 353 354 ar = currecord(); 355 if (ar == NULL) 356 return; 357 358 ar->k_ar.ar_arg_value = value; 359 ARG_SET_VALID(ar, ARG_VALUE); 360 } 361 362 void 363 audit_arg_owner(uid_t uid, gid_t gid) 364 { 365 struct kaudit_record *ar; 366 367 ar = currecord(); 368 if (ar == NULL) 369 return; 370 371 ar->k_ar.ar_arg_uid = uid; 372 ar->k_ar.ar_arg_gid = gid; 373 ARG_SET_VALID(ar, ARG_UID | ARG_GID); 374 } 375 376 void 377 audit_arg_pid(pid_t pid) 378 { 379 struct kaudit_record *ar; 380 381 ar = currecord(); 382 if (ar == NULL) 383 return; 384 385 ar->k_ar.ar_arg_pid = pid; 386 ARG_SET_VALID(ar, ARG_PID); 387 } 388 389 void 390 audit_arg_process(struct proc *p) 391 { 392 struct kaudit_record *ar; 393 struct ucred *cred; 394 395 KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 396 397 PROC_LOCK_ASSERT(p, MA_OWNED); 398 399 ar = currecord(); 400 if (ar == NULL) 401 return; 402 403 cred = p->p_ucred; 404 ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; 405 ar->k_ar.ar_arg_euid = cred->cr_uid; 406 ar->k_ar.ar_arg_egid = cred->cr_groups[0]; 407 ar->k_ar.ar_arg_ruid = cred->cr_ruid; 408 ar->k_ar.ar_arg_rgid = cred->cr_rgid; 409 ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; 410 ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; 411 ar->k_ar.ar_arg_pid = p->p_pid; 412 ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 413 ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 414 } 415 416 void 417 audit_arg_signum(u_int signum) 418 { 419 struct kaudit_record *ar; 420 421 ar = currecord(); 422 if (ar == NULL) 423 return; 424 425 ar->k_ar.ar_arg_signum = signum; 426 ARG_SET_VALID(ar, ARG_SIGNUM); 427 } 428 429 void 430 audit_arg_socket(int sodomain, int sotype, int soprotocol) 431 { 432 struct kaudit_record *ar; 433 434 ar = currecord(); 435 if (ar == NULL) 436 return; 437 438 ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 439 ar->k_ar.ar_arg_sockinfo.so_type = sotype; 440 ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 441 ARG_SET_VALID(ar, ARG_SOCKINFO); 442 } 443 444 void 445 audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa) 446 { 447 struct kaudit_record *ar; 448 449 KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL")); 450 KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 451 452 ar = currecord(); 453 if (ar == NULL) 454 return; 455 456 bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 457 switch (sa->sa_family) { 458 case AF_INET: 459 ARG_SET_VALID(ar, ARG_SADDRINET); 460 break; 461 462 case AF_INET6: 463 ARG_SET_VALID(ar, ARG_SADDRINET6); 464 break; 465 466 case AF_UNIX: 467 if (dirfd != AT_FDCWD) 468 audit_arg_atfd1(dirfd); 469 audit_arg_upath1(td, dirfd, 470 ((struct sockaddr_un *)sa)->sun_path); 471 ARG_SET_VALID(ar, ARG_SADDRUNIX); 472 break; 473 /* XXXAUDIT: default:? */ 474 } 475 } 476 477 void 478 audit_arg_auid(uid_t auid) 479 { 480 struct kaudit_record *ar; 481 482 ar = currecord(); 483 if (ar == NULL) 484 return; 485 486 ar->k_ar.ar_arg_auid = auid; 487 ARG_SET_VALID(ar, ARG_AUID); 488 } 489 490 void 491 audit_arg_auditinfo(struct auditinfo *au_info) 492 { 493 struct kaudit_record *ar; 494 495 ar = currecord(); 496 if (ar == NULL) 497 return; 498 499 ar->k_ar.ar_arg_auid = au_info->ai_auid; 500 ar->k_ar.ar_arg_asid = au_info->ai_asid; 501 ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 502 ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 503 ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 504 ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 505 ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 506 } 507 508 void 509 audit_arg_auditinfo_addr(struct auditinfo_addr *au_info) 510 { 511 struct kaudit_record *ar; 512 513 ar = currecord(); 514 if (ar == NULL) 515 return; 516 517 ar->k_ar.ar_arg_auid = au_info->ai_auid; 518 ar->k_ar.ar_arg_asid = au_info->ai_asid; 519 ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 520 ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 521 ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; 522 ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; 523 ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; 524 ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; 525 ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; 526 ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; 527 ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); 528 } 529 530 void 531 audit_arg_text(char *text) 532 { 533 struct kaudit_record *ar; 534 535 KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 536 537 ar = currecord(); 538 if (ar == NULL) 539 return; 540 541 /* Invalidate the text string */ 542 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 543 544 if (ar->k_ar.ar_arg_text == NULL) 545 ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 546 M_WAITOK); 547 548 strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 549 ARG_SET_VALID(ar, ARG_TEXT); 550 } 551 552 void 553 audit_arg_cmd(int cmd) 554 { 555 struct kaudit_record *ar; 556 557 ar = currecord(); 558 if (ar == NULL) 559 return; 560 561 ar->k_ar.ar_arg_cmd = cmd; 562 ARG_SET_VALID(ar, ARG_CMD); 563 } 564 565 void 566 audit_arg_svipc_cmd(int cmd) 567 { 568 struct kaudit_record *ar; 569 570 ar = currecord(); 571 if (ar == NULL) 572 return; 573 574 ar->k_ar.ar_arg_svipc_cmd = cmd; 575 ARG_SET_VALID(ar, ARG_SVIPC_CMD); 576 } 577 578 void 579 audit_arg_svipc_perm(struct ipc_perm *perm) 580 { 581 struct kaudit_record *ar; 582 583 ar = currecord(); 584 if (ar == NULL) 585 return; 586 587 bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 588 sizeof(ar->k_ar.ar_arg_svipc_perm)); 589 ARG_SET_VALID(ar, ARG_SVIPC_PERM); 590 } 591 592 void 593 audit_arg_svipc_id(int id) 594 { 595 struct kaudit_record *ar; 596 597 ar = currecord(); 598 if (ar == NULL) 599 return; 600 601 ar->k_ar.ar_arg_svipc_id = id; 602 ARG_SET_VALID(ar, ARG_SVIPC_ID); 603 } 604 605 void 606 audit_arg_svipc_addr(void * addr) 607 { 608 struct kaudit_record *ar; 609 610 ar = currecord(); 611 if (ar == NULL) 612 return; 613 614 ar->k_ar.ar_arg_svipc_addr = addr; 615 ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 616 } 617 618 void 619 audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 620 { 621 struct kaudit_record *ar; 622 623 ar = currecord(); 624 if (ar == NULL) 625 return; 626 627 ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 628 ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 629 ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 630 ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 631 } 632 633 void 634 audit_arg_auditon(union auditon_udata *udata) 635 { 636 struct kaudit_record *ar; 637 638 ar = currecord(); 639 if (ar == NULL) 640 return; 641 642 bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 643 sizeof(ar->k_ar.ar_arg_auditon)); 644 ARG_SET_VALID(ar, ARG_AUDITON); 645 } 646 647 /* 648 * Audit information about a file, either the file's vnode info, or its 649 * socket address info. 650 */ 651 void 652 audit_arg_file(struct proc *p, struct file *fp) 653 { 654 struct kaudit_record *ar; 655 struct socket *so; 656 struct inpcb *pcb; 657 struct vnode *vp; 658 659 ar = currecord(); 660 if (ar == NULL) 661 return; 662 663 switch (fp->f_type) { 664 case DTYPE_VNODE: 665 case DTYPE_FIFO: 666 /* 667 * XXXAUDIT: Only possibly to record as first vnode? 668 */ 669 vp = fp->f_vnode; 670 vn_lock(vp, LK_SHARED | LK_RETRY); 671 audit_arg_vnode1(vp); 672 VOP_UNLOCK(vp, 0); 673 break; 674 675 case DTYPE_SOCKET: 676 so = (struct socket *)fp->f_data; 677 if (INP_CHECK_SOCKAF(so, PF_INET)) { 678 SOCK_LOCK(so); 679 ar->k_ar.ar_arg_sockinfo.so_type = 680 so->so_type; 681 ar->k_ar.ar_arg_sockinfo.so_domain = 682 INP_SOCKAF(so); 683 ar->k_ar.ar_arg_sockinfo.so_protocol = 684 so->so_proto->pr_protocol; 685 SOCK_UNLOCK(so); 686 pcb = (struct inpcb *)so->so_pcb; 687 INP_RLOCK(pcb); 688 ar->k_ar.ar_arg_sockinfo.so_raddr = 689 pcb->inp_faddr.s_addr; 690 ar->k_ar.ar_arg_sockinfo.so_laddr = 691 pcb->inp_laddr.s_addr; 692 ar->k_ar.ar_arg_sockinfo.so_rport = 693 pcb->inp_fport; 694 ar->k_ar.ar_arg_sockinfo.so_lport = 695 pcb->inp_lport; 696 INP_RUNLOCK(pcb); 697 ARG_SET_VALID(ar, ARG_SOCKINFO); 698 } 699 break; 700 701 default: 702 /* XXXAUDIT: else? */ 703 break; 704 } 705 } 706 707 /* 708 * Store a path as given by the user process for auditing into the audit 709 * record stored on the user thread. This function will allocate the memory 710 * to store the path info if not already available. This memory will be 711 * freed when the audit record is freed. 712 */ 713 static void 714 audit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp) 715 { 716 717 if (*pathp == NULL) 718 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 719 audit_canon_path(td, dirfd, upath, *pathp); 720 } 721 722 void 723 audit_arg_upath1(struct thread *td, int dirfd, char *upath) 724 { 725 struct kaudit_record *ar; 726 727 ar = currecord(); 728 if (ar == NULL) 729 return; 730 731 audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1); 732 ARG_SET_VALID(ar, ARG_UPATH1); 733 } 734 735 void 736 audit_arg_upath2(struct thread *td, int dirfd, char *upath) 737 { 738 struct kaudit_record *ar; 739 740 ar = currecord(); 741 if (ar == NULL) 742 return; 743 744 audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2); 745 ARG_SET_VALID(ar, ARG_UPATH2); 746 } 747 748 /* 749 * Function to save the path and vnode attr information into the audit 750 * record. 751 * 752 * It is assumed that the caller will hold any vnode locks necessary to 753 * perform a VOP_GETATTR() on the passed vnode. 754 * 755 * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always 756 * provides access to the generation number as we need that to construct the 757 * BSM file ID. 758 * 759 * XXX: We should accept the process argument from the caller, since it's 760 * very likely they already have a reference. 761 * 762 * XXX: Error handling in this function is poor. 763 * 764 * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 765 */ 766 static int 767 audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp) 768 { 769 struct vattr vattr; 770 int error; 771 772 ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 773 774 error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 775 if (error) { 776 /* XXX: How to handle this case? */ 777 return (error); 778 } 779 780 vnp->vn_mode = vattr.va_mode; 781 vnp->vn_uid = vattr.va_uid; 782 vnp->vn_gid = vattr.va_gid; 783 vnp->vn_dev = vattr.va_rdev; 784 vnp->vn_fsid = vattr.va_fsid; 785 vnp->vn_fileid = vattr.va_fileid; 786 vnp->vn_gen = vattr.va_gen; 787 return (0); 788 } 789 790 void 791 audit_arg_vnode1(struct vnode *vp) 792 { 793 struct kaudit_record *ar; 794 int error; 795 796 ar = currecord(); 797 if (ar == NULL) 798 return; 799 800 ARG_CLEAR_VALID(ar, ARG_VNODE1); 801 error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1); 802 if (error == 0) 803 ARG_SET_VALID(ar, ARG_VNODE1); 804 } 805 806 void 807 audit_arg_vnode2(struct vnode *vp) 808 { 809 struct kaudit_record *ar; 810 int error; 811 812 ar = currecord(); 813 if (ar == NULL) 814 return; 815 816 ARG_CLEAR_VALID(ar, ARG_VNODE2); 817 error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2); 818 if (error == 0) 819 ARG_SET_VALID(ar, ARG_VNODE2); 820 } 821 822 /* 823 * Audit the argument strings passed to exec. 824 */ 825 void 826 audit_arg_argv(char *argv, int argc, int length) 827 { 828 struct kaudit_record *ar; 829 830 if (audit_argv == 0) 831 return; 832 833 ar = currecord(); 834 if (ar == NULL) 835 return; 836 837 ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 838 bcopy(argv, ar->k_ar.ar_arg_argv, length); 839 ar->k_ar.ar_arg_argc = argc; 840 ARG_SET_VALID(ar, ARG_ARGV); 841 } 842 843 /* 844 * Audit the environment strings passed to exec. 845 */ 846 void 847 audit_arg_envv(char *envv, int envc, int length) 848 { 849 struct kaudit_record *ar; 850 851 if (audit_arge == 0) 852 return; 853 854 ar = currecord(); 855 if (ar == NULL) 856 return; 857 858 ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 859 bcopy(envv, ar->k_ar.ar_arg_envv, length); 860 ar->k_ar.ar_arg_envc = envc; 861 ARG_SET_VALID(ar, ARG_ENVV); 862 } 863 864 void 865 audit_arg_rights(cap_rights_t *rightsp) 866 { 867 struct kaudit_record *ar; 868 869 ar = currecord(); 870 if (ar == NULL) 871 return; 872 873 ar->k_ar.ar_arg_rights = *rightsp; 874 ARG_SET_VALID(ar, ARG_RIGHTS); 875 } 876 877 void 878 audit_arg_fcntl_rights(uint32_t fcntlrights) 879 { 880 struct kaudit_record *ar; 881 882 ar = currecord(); 883 if (ar == NULL) 884 return; 885 886 ar->k_ar.ar_arg_fcntl_rights = fcntlrights; 887 ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS); 888 } 889 890 /* 891 * The close() system call uses it's own audit call to capture the path/vnode 892 * information because those pieces are not easily obtained within the system 893 * call itself. 894 */ 895 void 896 audit_sysclose(struct thread *td, int fd) 897 { 898 cap_rights_t rights; 899 struct kaudit_record *ar; 900 struct vnode *vp; 901 struct file *fp; 902 903 KASSERT(td != NULL, ("audit_sysclose: td == NULL")); 904 905 ar = currecord(); 906 if (ar == NULL) 907 return; 908 909 audit_arg_fd(fd); 910 911 if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0) 912 return; 913 914 vp = fp->f_vnode; 915 vn_lock(vp, LK_SHARED | LK_RETRY); 916 audit_arg_vnode1(vp); 917 VOP_UNLOCK(vp, 0); 918 fdrop(fp, td); 919 } 920