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