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