1/*- 2 * Copyright (c) 1999-2009 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/* 31 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 32 * support for mandatory and extensible security protections. This notice 33 * is included in support of clause 2.2 (b) of the Apple Public License, 34 * Version 2.0. 35 */ 36 37#include <sys/param.h> 38#include <sys/fcntl.h> 39#include <sys/kernel.h> 40#include <sys/lock.h> 41#include <sys/namei.h> 42#include <sys/proc_internal.h> 43#include <sys/kauth.h> 44#include <sys/queue.h> 45#include <sys/systm.h> 46#include <sys/time.h> 47#include <sys/ucred.h> 48#include <sys/uio.h> 49#include <sys/unistd.h> 50#include <sys/file_internal.h> 51#include <sys/vnode_internal.h> 52#include <sys/user.h> 53#include <sys/syscall.h> 54#include <sys/malloc.h> 55#include <sys/un.h> 56#include <sys/sysent.h> 57#include <sys/sysproto.h> 58#include <sys/vfs_context.h> 59#include <sys/domain.h> 60#include <sys/protosw.h> 61#include <sys/socketvar.h> 62 63#include <bsm/audit.h> 64#include <bsm/audit_internal.h> 65#include <bsm/audit_kevents.h> 66 67#include <security/audit/audit.h> 68#include <security/audit/audit_bsd.h> 69#include <security/audit/audit_private.h> 70 71#include <mach/host_priv.h> 72#include <mach/host_special_ports.h> 73#include <mach/audit_triggers_server.h> 74 75#include <kern/host.h> 76#include <kern/kalloc.h> 77#include <kern/zalloc.h> 78#include <kern/lock.h> 79#include <kern/wait_queue.h> 80#include <kern/sched_prim.h> 81 82#if CONFIG_MACF 83#include <bsm/audit_record.h> 84#include <security/mac.h> 85#include <security/mac_framework.h> 86#include <security/mac_policy.h> 87extern zone_t audit_mac_label_zone; 88#endif 89 90#include <net/route.h> 91 92#include <netinet/in.h> 93#include <netinet/in_pcb.h> 94 95#if CONFIG_AUDIT 96/* 97 * Calls to manipulate elements of the audit record structure from system 98 * call code. Macro wrappers will prevent this functions from being entered 99 * if auditing is disabled, avoiding the function call cost. We check the 100 * thread audit record pointer anyway, as the audit condition could change, 101 * and pre-selection may not have allocated an audit record for this event. 102 * 103 * XXXAUDIT: Should we assert, in each case, that this field of the record 104 * hasn't already been filled in? 105 */ 106void 107audit_arg_addr(struct kaudit_record *ar, user_addr_t addr) 108{ 109 struct proc *p = current_proc(); 110 111 ar->k_ar.ar_arg_addr = addr; 112 113 /* 114 * If the process is 64-bit then flag the address as such. 115 */ 116 if (proc_is64bit(p)) 117 ARG_SET_VALID(ar, ARG_ADDR64); 118 else 119 ARG_SET_VALID(ar, ARG_ADDR32); 120} 121 122void 123audit_arg_exit(struct kaudit_record *ar, int status, int retval) 124{ 125 126 ar->k_ar.ar_arg_exitstatus = status; 127 ar->k_ar.ar_arg_exitretval = retval; 128 ARG_SET_VALID(ar, ARG_EXIT); 129} 130 131void 132audit_arg_len(struct kaudit_record *ar, user_size_t len) 133{ 134 135 ar->k_ar.ar_arg_len = len; 136 ARG_SET_VALID(ar, ARG_LEN); 137} 138 139void 140audit_arg_fd(struct kaudit_record *ar, int fd) 141{ 142 143 ar->k_ar.ar_arg_fd = fd; 144 ARG_SET_VALID(ar, ARG_FD); 145} 146 147void 148audit_arg_fflags(struct kaudit_record *ar, int fflags) 149{ 150 151 ar->k_ar.ar_arg_fflags = fflags; 152 ARG_SET_VALID(ar, ARG_FFLAGS); 153} 154 155void 156audit_arg_gid(struct kaudit_record *ar, gid_t gid) 157{ 158 159 ar->k_ar.ar_arg_gid = gid; 160 ARG_SET_VALID(ar, ARG_GID); 161} 162 163void 164audit_arg_uid(struct kaudit_record *ar, uid_t uid) 165{ 166 167 ar->k_ar.ar_arg_uid = uid; 168 ARG_SET_VALID(ar, ARG_UID); 169} 170 171void 172audit_arg_egid(struct kaudit_record *ar, gid_t egid) 173{ 174 175 ar->k_ar.ar_arg_egid = egid; 176 ARG_SET_VALID(ar, ARG_EGID); 177} 178 179void 180audit_arg_euid(struct kaudit_record *ar, uid_t euid) 181{ 182 183 ar->k_ar.ar_arg_euid = euid; 184 ARG_SET_VALID(ar, ARG_EUID); 185} 186 187void 188audit_arg_rgid(struct kaudit_record *ar, gid_t rgid) 189{ 190 191 ar->k_ar.ar_arg_rgid = rgid; 192 ARG_SET_VALID(ar, ARG_RGID); 193} 194 195void 196audit_arg_ruid(struct kaudit_record *ar, uid_t ruid) 197{ 198 199 ar->k_ar.ar_arg_ruid = ruid; 200 ARG_SET_VALID(ar, ARG_RUID); 201} 202 203void 204audit_arg_sgid(struct kaudit_record *ar, gid_t sgid) 205{ 206 207 ar->k_ar.ar_arg_sgid = sgid; 208 ARG_SET_VALID(ar, ARG_SGID); 209} 210 211void 212audit_arg_suid(struct kaudit_record *ar, uid_t suid) 213{ 214 215 ar->k_ar.ar_arg_suid = suid; 216 ARG_SET_VALID(ar, ARG_SUID); 217} 218 219void 220audit_arg_groupset(struct kaudit_record *ar, gid_t *gidset, u_int gidset_size) 221{ 222 u_int i; 223 224 for (i = 0; i < gidset_size; i++) 225 ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 226 ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 227 ARG_SET_VALID(ar, ARG_GROUPSET); 228} 229 230void 231audit_arg_login(struct kaudit_record *ar, char *login) 232{ 233 234 strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 235 ARG_SET_VALID(ar, ARG_LOGIN); 236} 237 238void 239audit_arg_ctlname(struct kaudit_record *ar, int *name, int namelen) 240{ 241 242 bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 243 ar->k_ar.ar_arg_len = namelen; 244 ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 245} 246 247void 248audit_arg_mask(struct kaudit_record *ar, int mask) 249{ 250 251 ar->k_ar.ar_arg_mask = mask; 252 ARG_SET_VALID(ar, ARG_MASK); 253} 254 255void 256audit_arg_mode(struct kaudit_record *ar, mode_t mode) 257{ 258 259 ar->k_ar.ar_arg_mode = mode; 260 ARG_SET_VALID(ar, ARG_MODE); 261} 262 263void 264audit_arg_value32(struct kaudit_record *ar, uint32_t value32) 265{ 266 267 ar->k_ar.ar_arg_value32 = value32; 268 ARG_SET_VALID(ar, ARG_VALUE32); 269} 270 271void 272audit_arg_value64(struct kaudit_record *ar, uint64_t value64) 273{ 274 275 ar->k_ar.ar_arg_value64 = value64; 276 ARG_SET_VALID(ar, ARG_VALUE64); 277} 278 279void 280audit_arg_owner(struct kaudit_record *ar, uid_t uid, gid_t gid) 281{ 282 283 ar->k_ar.ar_arg_uid = uid; 284 ar->k_ar.ar_arg_gid = gid; 285 ARG_SET_VALID(ar, ARG_UID | ARG_GID); 286} 287 288void 289audit_arg_pid(struct kaudit_record *ar, pid_t pid) 290{ 291 292 ar->k_ar.ar_arg_pid = pid; 293 ARG_SET_VALID(ar, ARG_PID); 294} 295 296void 297audit_arg_process(struct kaudit_record *ar, proc_t p) 298{ 299 kauth_cred_t my_cred; 300 301 KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 302 303 if ( p == NULL) 304 return; 305 306 my_cred = kauth_cred_proc_ref(p); 307 ar->k_ar.ar_arg_auid = my_cred->cr_audit.as_aia_p->ai_auid; 308 ar->k_ar.ar_arg_asid = my_cred->cr_audit.as_aia_p->ai_asid; 309 bcopy(&my_cred->cr_audit.as_aia_p->ai_termid, 310 &ar->k_ar.ar_arg_termid_addr, sizeof(au_tid_addr_t)); 311 ar->k_ar.ar_arg_euid = kauth_cred_getuid(my_cred); 312 ar->k_ar.ar_arg_egid = kauth_cred_getgid(my_cred); 313 ar->k_ar.ar_arg_ruid = kauth_cred_getruid(my_cred); 314 ar->k_ar.ar_arg_rgid = kauth_cred_getrgid(my_cred); 315 kauth_cred_unref(&my_cred); 316 ar->k_ar.ar_arg_pid = p->p_pid; 317 ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 318 ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 319} 320 321void 322audit_arg_signum(struct kaudit_record *ar, u_int signum) 323{ 324 325 ar->k_ar.ar_arg_signum = signum; 326 ARG_SET_VALID(ar, ARG_SIGNUM); 327} 328 329void 330audit_arg_socket(struct kaudit_record *ar, int sodomain, int sotype, 331 int soprotocol) 332{ 333 334 ar->k_ar.ar_arg_sockinfo.sai_domain = sodomain; 335 ar->k_ar.ar_arg_sockinfo.sai_type = sotype; 336 ar->k_ar.ar_arg_sockinfo.sai_protocol = soprotocol; 337 ARG_SET_VALID(ar, ARG_SOCKINFO); 338} 339 340/* 341 * Note that the current working directory vp must be supplied at the audit 342 * call site to permit per thread current working directories, and that it 343 * must take a upath starting with '/' into account for chroot if the path 344 * is absolute. This results in the real (non-chroot) path being recorded 345 * in the audit record. 346 */ 347void 348audit_arg_sockaddr(struct kaudit_record *ar, struct vnode *cwd_vp, 349 struct sockaddr *sa) 350{ 351 int slen; 352 struct sockaddr_un *sun; 353 char path[SOCK_MAXADDRLEN - offsetof(struct sockaddr_un, sun_path) + 1]; 354 355 KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 356 357 if (cwd_vp == NULL || sa == NULL) 358 return; 359 360 bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 361 switch (sa->sa_family) { 362 case AF_INET: 363 ARG_SET_VALID(ar, ARG_SADDRINET); 364 break; 365 366 case AF_INET6: 367 ARG_SET_VALID(ar, ARG_SADDRINET6); 368 break; 369 370 case AF_UNIX: 371 sun = (struct sockaddr_un *)sa; 372 slen = sun->sun_len - offsetof(struct sockaddr_un, sun_path); 373 374 if (slen >= 0) { 375 /* 376 * Make sure the path is NULL-terminated 377 */ 378 if (sun->sun_path[slen] != 0) { 379 bcopy(sun->sun_path, path, slen); 380 path[slen] = 0; 381 audit_arg_upath(ar, cwd_vp, path, ARG_UPATH1); 382 } else { 383 audit_arg_upath(ar, cwd_vp, sun->sun_path, 384 ARG_UPATH1); 385 } 386 } 387 ARG_SET_VALID(ar, ARG_SADDRUNIX); 388 break; 389 /* XXXAUDIT: default:? */ 390 } 391} 392 393void 394audit_arg_auid(struct kaudit_record *ar, uid_t auid) 395{ 396 397 ar->k_ar.ar_arg_auid = auid; 398 ARG_SET_VALID(ar, ARG_AUID); 399} 400 401void 402audit_arg_auditinfo(struct kaudit_record *ar, struct auditinfo *au_info) 403{ 404 405 ar->k_ar.ar_arg_auid = au_info->ai_auid; 406 ar->k_ar.ar_arg_asid = au_info->ai_asid; 407 ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 408 ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 409 ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 410 ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 411 ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 412} 413 414void 415audit_arg_auditinfo_addr(struct kaudit_record *ar, 416 struct auditinfo_addr *au_info) 417{ 418 419 ar->k_ar.ar_arg_auid = au_info->ai_auid; 420 ar->k_ar.ar_arg_asid = au_info->ai_asid; 421 ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 422 ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 423 ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; 424 ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; 425 ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; 426 ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; 427 ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; 428 ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; 429 ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); 430} 431 432void 433audit_arg_text(struct kaudit_record *ar, char *text) 434{ 435 436 KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 437 438 /* Invalidate the text string */ 439 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 440 if (text == NULL) 441 return; 442 443 if (ar->k_ar.ar_arg_text == NULL) 444 ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 445 M_WAITOK); 446 447 strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 448 ARG_SET_VALID(ar, ARG_TEXT); 449} 450 451void 452audit_arg_opaque(struct kaudit_record *ar, void *data, size_t size) 453{ 454 455 KASSERT(data != NULL, ("audit_arg_opaque: data == NULL")); 456 KASSERT(size <= UINT16_MAX, ("audit_arg_opaque: size > UINT16_MAX")); 457 458 if (data == NULL || size > UINT16_MAX) 459 return; 460 461 if (ar->k_ar.ar_arg_opaque == NULL) 462 ar->k_ar.ar_arg_opaque = malloc(size, M_AUDITDATA, M_WAITOK); 463 else 464 return; 465 466 memcpy(ar->k_ar.ar_arg_opaque, data, size); 467 ar->k_ar.ar_arg_opq_size = (u_int16_t) size; 468 ARG_SET_VALID(ar, ARG_OPAQUE); 469} 470 471void 472audit_arg_data(struct kaudit_record *ar, void *data, size_t size, size_t number) 473{ 474 size_t sz; 475 476 KASSERT(data != NULL, ("audit_arg_data: data == NULL")); 477 KASSERT(size >= AUR_BYTE_SIZE && size <= AUR_INT64_SIZE, 478 ("audit_arg_data: size < AUR_BYTE_SIZE or size > AUR_INT64_SIZE")); 479 KASSERT(number <= UINT8_MAX, 480 ("audit_arg_data: number > UINT8_MAX")); 481 482 if (data == NULL || size < AUR_BYTE_SIZE || size > AUR_INT64_SIZE || 483 number > UINT8_MAX) 484 return; 485 486 sz = size * number; 487 488 if (ar->k_ar.ar_arg_data == NULL) 489 ar->k_ar.ar_arg_data = malloc(sz, M_AUDITDATA, M_WAITOK); 490 else 491 return; 492 493 memcpy(ar->k_ar.ar_arg_data, data, sz); 494 495 switch(size) { 496 case AUR_BYTE_SIZE: 497 ar->k_ar.ar_arg_data_type = AUR_BYTE; 498 break; 499 500 case AUR_SHORT_SIZE: 501 ar->k_ar.ar_arg_data_type = AUR_SHORT; 502 break; 503 504 case AUR_INT32_SIZE: 505 ar->k_ar.ar_arg_data_type = AUR_INT32; 506 break; 507 508 case AUR_INT64_SIZE: 509 ar->k_ar.ar_arg_data_type = AUR_INT64; 510 break; 511 512 default: 513 free(ar->k_ar.ar_arg_data, M_AUDITDATA); 514 ar->k_ar.ar_arg_data = NULL; 515 return; 516 } 517 518 ar->k_ar.ar_arg_data_count = (u_char)number; 519 520 ARG_SET_VALID(ar, ARG_DATA); 521} 522 523void 524audit_arg_cmd(struct kaudit_record *ar, int cmd) 525{ 526 527 ar->k_ar.ar_arg_cmd = cmd; 528 ARG_SET_VALID(ar, ARG_CMD); 529} 530 531void 532audit_arg_svipc_cmd(struct kaudit_record *ar, int cmd) 533{ 534 535 ar->k_ar.ar_arg_svipc_cmd = cmd; 536 ARG_SET_VALID(ar, ARG_SVIPC_CMD); 537} 538 539void 540audit_arg_svipc_perm(struct kaudit_record *ar, struct ipc_perm *perm) 541{ 542 543 bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 544 sizeof(ar->k_ar.ar_arg_svipc_perm)); 545 ARG_SET_VALID(ar, ARG_SVIPC_PERM); 546} 547 548void 549audit_arg_svipc_id(struct kaudit_record *ar, int id) 550{ 551 552 ar->k_ar.ar_arg_svipc_id = id; 553 ARG_SET_VALID(ar, ARG_SVIPC_ID); 554} 555 556void 557audit_arg_svipc_addr(struct kaudit_record *ar, user_addr_t addr) 558{ 559 560 ar->k_ar.ar_arg_svipc_addr = addr; 561 ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 562} 563 564void 565audit_arg_posix_ipc_perm(struct kaudit_record *ar, uid_t uid, gid_t gid, 566 mode_t mode) 567{ 568 569 ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 570 ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 571 ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 572 ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 573} 574 575void 576audit_arg_auditon(struct kaudit_record *ar, union auditon_udata *udata) 577{ 578 579 bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 580 sizeof(ar->k_ar.ar_arg_auditon)); 581 ARG_SET_VALID(ar, ARG_AUDITON); 582} 583 584/* 585 * Audit information about a file, either the file's vnode info, or its 586 * socket address info. 587 */ 588void 589audit_arg_file(struct kaudit_record *ar, __unused proc_t p, 590 struct fileproc *fp) 591{ 592 struct socket *so; 593 struct inpcb *pcb; 594 struct sockaddr_in *sin; 595 struct sockaddr_in6 *sin6; 596 597 switch (fp->f_fglob->fg_type) { 598 case DTYPE_VNODE: 599 /* case DTYPE_FIFO: */ 600 audit_arg_vnpath_withref(ar, 601 (struct vnode *)fp->f_fglob->fg_data, ARG_VNODE1); 602 break; 603 604 case DTYPE_SOCKET: 605 so = (struct socket *)fp->f_fglob->fg_data; 606 if (INP_CHECK_SOCKAF(so, PF_INET)) { 607 if (so->so_pcb == NULL) 608 break; 609 ar->k_ar.ar_arg_sockinfo.sai_type = 610 so->so_type; 611 ar->k_ar.ar_arg_sockinfo.sai_domain = 612 INP_SOCKAF(so); 613 ar->k_ar.ar_arg_sockinfo.sai_protocol = 614 so->so_proto->pr_protocol; 615 pcb = (struct inpcb *)so->so_pcb; 616 sin = (struct sockaddr_in *) 617 &ar->k_ar.ar_arg_sockinfo.sai_faddr; 618 sin->sin_addr.s_addr = pcb->inp_faddr.s_addr; 619 sin->sin_port = pcb->inp_fport; 620 sin = (struct sockaddr_in *) 621 &ar->k_ar.ar_arg_sockinfo.sai_laddr; 622 sin->sin_addr.s_addr = pcb->inp_laddr.s_addr; 623 sin->sin_port = pcb->inp_lport; 624 ARG_SET_VALID(ar, ARG_SOCKINFO); 625 } 626 if (INP_CHECK_SOCKAF(so, PF_INET6)) { 627 if (so->so_pcb == NULL) 628 break; 629 ar->k_ar.ar_arg_sockinfo.sai_type = 630 so->so_type; 631 ar->k_ar.ar_arg_sockinfo.sai_domain = 632 INP_SOCKAF(so); 633 ar->k_ar.ar_arg_sockinfo.sai_protocol = 634 so->so_proto->pr_protocol; 635 pcb = (struct inpcb *)so->so_pcb; 636 sin6 = (struct sockaddr_in6 *) 637 &ar->k_ar.ar_arg_sockinfo.sai_faddr; 638 sin6->sin6_addr = pcb->in6p_faddr; 639 sin6->sin6_port = pcb->in6p_fport; 640 sin6 = (struct sockaddr_in6 *) 641 &ar->k_ar.ar_arg_sockinfo.sai_laddr; 642 sin6->sin6_addr = pcb->in6p_laddr; 643 sin6->sin6_port = pcb->in6p_lport; 644 ARG_SET_VALID(ar, ARG_SOCKINFO); 645 } 646 break; 647 648 default: 649 /* XXXAUDIT: else? */ 650 break; 651 } 652} 653 654/* 655 * Store a path as given by the user process for auditing into the audit 656 * record stored on the user thread. This function will allocate the memory 657 * to store the path info if not already available. This memory will be 658 * freed when the audit record is freed. 659 * 660 * Note that the current working directory vp must be supplied at the audit call 661 * site to permit per thread current working directories, and that it must take 662 * a upath starting with '/' into account for chroot if the path is absolute. 663 * This results in the real (non-chroot) path being recorded in the audit 664 * record. 665 * 666 * XXXAUDIT: Possibly assert that the memory isn't already allocated? 667 */ 668void 669audit_arg_upath(struct kaudit_record *ar, struct vnode *cwd_vp, char *upath, u_int64_t flag) 670{ 671 char **pathp; 672 673 KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL")); 674 KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2), 675 ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 676 KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2), 677 ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 678 679 if (flag == ARG_UPATH1) 680 pathp = &ar->k_ar.ar_arg_upath1; 681 else 682 pathp = &ar->k_ar.ar_arg_upath2; 683 684 if (*pathp == NULL) 685 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 686 else 687 return; 688 689 if (audit_canon_path(cwd_vp, upath, *pathp) == 0) 690 ARG_SET_VALID(ar, flag); 691 else { 692 free(*pathp, M_AUDITPATH); 693 *pathp = NULL; 694 } 695} 696 697/* 698 * Function to save the path and vnode attr information into the audit 699 * record. 700 * 701 * It is assumed that the caller will hold any vnode locks necessary to 702 * perform a VNOP_GETATTR() on the passed vnode. 703 * 704 * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always 705 * provides access to the generation number as we need that to construct the 706 * BSM file ID. 707 * 708 * XXX: We should accept the process argument from the caller, since it's 709 * very likely they already have a reference. 710 * 711 * XXX: Error handling in this function is poor. 712 * 713 * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 714 */ 715void 716audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) 717{ 718 struct vnode_attr va; 719 int error; 720 int len; 721 char **pathp; 722 struct vnode_au_info *vnp; 723 proc_t p; 724#if CONFIG_MACF 725 char **vnode_mac_labelp; 726 struct mac mac; 727#endif 728 729 KASSERT(vp != NULL, ("audit_arg_vnpath: vp == NULL")); 730 KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2), 731 ("audit_arg_vnpath: flags != ARG_VNODE[1,2]")); 732 733 p = current_proc(); 734 735 /* 736 * XXXAUDIT: The below clears, and then resets the flags for valid 737 * arguments. Ideally, either the new vnode is used, or the old one 738 * would be. 739 */ 740 if (flags & ARG_VNODE1) { 741 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_KPATH1); 742 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1); 743 pathp = &ar->k_ar.ar_arg_kpath1; 744 vnp = &ar->k_ar.ar_arg_vnode1; 745#if CONFIG_MACF 746 vnode_mac_labelp = &ar->k_ar.ar_vnode1_mac_labels; 747#endif 748 } else { 749 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_KPATH2); 750 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2); 751 pathp = &ar->k_ar.ar_arg_kpath2; 752 vnp = &ar->k_ar.ar_arg_vnode2; 753#if CONFIG_MACF 754 vnode_mac_labelp = &ar->k_ar.ar_vnode2_mac_labels; 755#endif 756 } 757 758 if (*pathp == NULL) 759 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 760 else 761 return; 762 763 /* 764 * If vn_getpath() succeeds, place it in a string buffer 765 * attached to the audit record, and set a flag indicating 766 * it is present. 767 */ 768 len = MAXPATHLEN; 769 if (vn_getpath(vp, *pathp, &len) == 0) { 770 if (flags & ARG_VNODE1) 771 ARG_SET_VALID(ar, ARG_KPATH1); 772 else 773 ARG_SET_VALID(ar, ARG_KPATH2); 774 } else { 775 free(*pathp, M_AUDITPATH); 776 *pathp = NULL; 777 } 778 779 VATTR_INIT(&va); 780 VATTR_WANTED(&va, va_mode); 781 VATTR_WANTED(&va, va_uid); 782 VATTR_WANTED(&va, va_gid); 783 VATTR_WANTED(&va, va_rdev); 784 VATTR_WANTED(&va, va_fsid); 785 VATTR_WANTED(&va, va_fileid); 786 VATTR_WANTED(&va, va_gen); 787 error = vnode_getattr(vp, &va, vfs_context_current()); 788 if (error) { 789 /* XXX: How to handle this case? */ 790 return; 791 } 792 793#if CONFIG_MACF 794 if (*vnode_mac_labelp == NULL && (vp->v_lflag & VL_LABELED) == VL_LABELED) { 795 *vnode_mac_labelp = (char *)zalloc(audit_mac_label_zone); 796 if (*vnode_mac_labelp != NULL) { 797 mac.m_buflen = MAC_AUDIT_LABEL_LEN; 798 mac.m_string = *vnode_mac_labelp; 799 mac_vnode_label_externalize_audit(vp, &mac); 800 } 801 } 802#endif 803 804 /* 805 * XXX do we want to fall back here when these aren't supported? 806 */ 807 vnp->vn_mode = va.va_mode; 808 vnp->vn_uid = va.va_uid; 809 vnp->vn_gid = va.va_gid; 810 vnp->vn_dev = va.va_rdev; 811 vnp->vn_fsid = va.va_fsid; 812 vnp->vn_fileid = (u_int32_t)va.va_fileid; 813 vnp->vn_gen = va.va_gen; 814 if (flags & ARG_VNODE1) 815 ARG_SET_VALID(ar, ARG_VNODE1); 816 else 817 ARG_SET_VALID(ar, ARG_VNODE2); 818} 819 820void 821audit_arg_vnpath_withref(struct kaudit_record *ar, struct vnode *vp, u_int64_t flags) 822{ 823 if (vp == NULL || vnode_getwithref(vp)) 824 return; 825 audit_arg_vnpath(ar, vp, flags); 826 (void)vnode_put(vp); 827} 828 829void 830audit_arg_mach_port1(struct kaudit_record *ar, mach_port_name_t port) 831{ 832 833 ar->k_ar.ar_arg_mach_port1 = port; 834 ARG_SET_VALID(ar, ARG_MACHPORT1); 835} 836 837void 838audit_arg_mach_port2(struct kaudit_record *ar, mach_port_name_t port) 839{ 840 841 ar->k_ar.ar_arg_mach_port2 = port; 842 ARG_SET_VALID(ar, ARG_MACHPORT2); 843} 844 845 846/* 847 * Audit the argument strings passed to exec. 848 */ 849void 850audit_arg_argv(struct kaudit_record *ar, char *argv, int argc, int length) 851{ 852 853 if (audit_argv == 0 || argc == 0) 854 return; 855 856 if (ar->k_ar.ar_arg_argv == NULL) 857 ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 858 bcopy(argv, ar->k_ar.ar_arg_argv, length); 859 ar->k_ar.ar_arg_argc = argc; 860 ARG_SET_VALID(ar, ARG_ARGV); 861} 862 863/* 864 * Audit the environment strings passed to exec. 865 */ 866void 867audit_arg_envv(struct kaudit_record *ar, char *envv, int envc, int length) 868{ 869 870 if (audit_arge == 0 || envc == 0) 871 return; 872 873 if (ar->k_ar.ar_arg_envv == NULL) 874 ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 875 bcopy(envv, ar->k_ar.ar_arg_envv, length); 876 ar->k_ar.ar_arg_envc = envc; 877 ARG_SET_VALID(ar, ARG_ENVV); 878} 879 880/* 881 * The close() system call uses it's own audit call to capture the path/vnode 882 * information because those pieces are not easily obtained within the system 883 * call itself. 884 */ 885void 886audit_sysclose(struct kaudit_record *ar, proc_t p, int fd) 887{ 888 struct fileproc *fp; 889 struct vnode *vp; 890 891 KASSERT(p != NULL, ("audit_sysclose: p == NULL")); 892 893 audit_arg_fd(ar, fd); 894 895 if (fp_getfvp(p, fd, &fp, &vp) != 0) 896 return; 897 898 audit_arg_vnpath_withref(ar, (struct vnode *)fp->f_fglob->fg_data, 899 ARG_VNODE1); 900 fp_drop(p, fd, fp, 0); 901} 902 903#endif /* CONFIG_AUDIT */ 904