1181053Srwatson/*- 2180701Srwatson * Copyright (c) 1999-2005 Apple Inc. 3155192Srwatson * All rights reserved. 4155192Srwatson * 5155192Srwatson * Redistribution and use in source and binary forms, with or without 6155192Srwatson * modification, are permitted provided that the following conditions 7155192Srwatson * are met: 8155192Srwatson * 1. Redistributions of source code must retain the above copyright 9155192Srwatson * notice, this list of conditions and the following disclaimer. 10155192Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11155192Srwatson * notice, this list of conditions and the following disclaimer in the 12155192Srwatson * documentation and/or other materials provided with the distribution. 13180701Srwatson * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14155192Srwatson * its contributors may be used to endorse or promote products derived 15155192Srwatson * from this software without specific prior written permission. 16155192Srwatson * 17155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27155192Srwatson * POSSIBILITY OF SUCH DAMAGE. 28155192Srwatson */ 29155192Srwatson 30178186Srwatson#include <sys/cdefs.h> 31178186Srwatson__FBSDID("$FreeBSD$"); 32178186Srwatson 33155192Srwatson#include <sys/param.h> 34155192Srwatson#include <sys/filedesc.h> 35155192Srwatson#include <sys/ipc.h> 36155192Srwatson#include <sys/mount.h> 37155192Srwatson#include <sys/proc.h> 38155192Srwatson#include <sys/socket.h> 39155192Srwatson#include <sys/socketvar.h> 40155192Srwatson#include <sys/protosw.h> 41155192Srwatson#include <sys/domain.h> 42159277Srwatson#include <sys/sbuf.h> 43155192Srwatson#include <sys/systm.h> 44155192Srwatson#include <sys/un.h> 45155192Srwatson#include <sys/vnode.h> 46155192Srwatson 47155192Srwatson#include <netinet/in.h> 48155192Srwatson#include <netinet/in_pcb.h> 49155192Srwatson 50155192Srwatson#include <security/audit/audit.h> 51155192Srwatson#include <security/audit/audit_private.h> 52155192Srwatson 53155192Srwatson/* 54155192Srwatson * Calls to manipulate elements of the audit record structure from system 55170196Srwatson * call code. Macro wrappers will prevent this functions from being entered 56170196Srwatson * if auditing is disabled, avoiding the function call cost. We check the 57170196Srwatson * thread audit record pointer anyway, as the audit condition could change, 58170196Srwatson * and pre-selection may not have allocated an audit record for this event. 59155192Srwatson * 60155192Srwatson * XXXAUDIT: Should we assert, in each case, that this field of the record 61155192Srwatson * hasn't already been filled in? 62155192Srwatson */ 63155192Srwatsonvoid 64170585Srwatsonaudit_arg_addr(void *addr) 65155192Srwatson{ 66155192Srwatson struct kaudit_record *ar; 67155192Srwatson 68155192Srwatson ar = currecord(); 69155192Srwatson if (ar == NULL) 70155192Srwatson return; 71155192Srwatson 72155192Srwatson ar->k_ar.ar_arg_addr = addr; 73155192Srwatson ARG_SET_VALID(ar, ARG_ADDR); 74155192Srwatson} 75155192Srwatson 76155192Srwatsonvoid 77155192Srwatsonaudit_arg_exit(int status, int retval) 78155192Srwatson{ 79155192Srwatson struct kaudit_record *ar; 80155192Srwatson 81155192Srwatson ar = currecord(); 82155192Srwatson if (ar == NULL) 83155192Srwatson return; 84155192Srwatson 85155192Srwatson ar->k_ar.ar_arg_exitstatus = status; 86155192Srwatson ar->k_ar.ar_arg_exitretval = retval; 87155192Srwatson ARG_SET_VALID(ar, ARG_EXIT); 88155192Srwatson} 89155192Srwatson 90155192Srwatsonvoid 91155192Srwatsonaudit_arg_len(int len) 92155192Srwatson{ 93155192Srwatson struct kaudit_record *ar; 94155192Srwatson 95155192Srwatson ar = currecord(); 96155192Srwatson if (ar == NULL) 97155192Srwatson return; 98155192Srwatson 99155192Srwatson ar->k_ar.ar_arg_len = len; 100155192Srwatson ARG_SET_VALID(ar, ARG_LEN); 101155192Srwatson} 102155192Srwatson 103155192Srwatsonvoid 104195925Srwatsonaudit_arg_atfd1(int atfd) 105195925Srwatson{ 106195925Srwatson struct kaudit_record *ar; 107195925Srwatson 108195925Srwatson ar = currecord(); 109195925Srwatson if (ar == NULL) 110195925Srwatson return; 111195925Srwatson 112195925Srwatson ar->k_ar.ar_arg_atfd1 = atfd; 113195925Srwatson ARG_SET_VALID(ar, ARG_ATFD1); 114195925Srwatson} 115195925Srwatson 116195925Srwatsonvoid 117195925Srwatsonaudit_arg_atfd2(int atfd) 118195925Srwatson{ 119195925Srwatson struct kaudit_record *ar; 120195925Srwatson 121195925Srwatson ar = currecord(); 122195925Srwatson if (ar == NULL) 123195925Srwatson return; 124195925Srwatson 125195925Srwatson ar->k_ar.ar_arg_atfd2 = atfd; 126195925Srwatson ARG_SET_VALID(ar, ARG_ATFD2); 127195925Srwatson} 128195925Srwatson 129195925Srwatsonvoid 130155192Srwatsonaudit_arg_fd(int fd) 131155192Srwatson{ 132155192Srwatson struct kaudit_record *ar; 133155192Srwatson 134155192Srwatson ar = currecord(); 135155192Srwatson if (ar == NULL) 136155192Srwatson return; 137155192Srwatson 138155192Srwatson ar->k_ar.ar_arg_fd = fd; 139155192Srwatson ARG_SET_VALID(ar, ARG_FD); 140155192Srwatson} 141155192Srwatson 142155192Srwatsonvoid 143155192Srwatsonaudit_arg_fflags(int fflags) 144155192Srwatson{ 145155192Srwatson struct kaudit_record *ar; 146155192Srwatson 147155192Srwatson ar = currecord(); 148155192Srwatson if (ar == NULL) 149155192Srwatson return; 150155192Srwatson 151155192Srwatson ar->k_ar.ar_arg_fflags = fflags; 152155192Srwatson ARG_SET_VALID(ar, ARG_FFLAGS); 153155192Srwatson} 154155192Srwatson 155155192Srwatsonvoid 156155192Srwatsonaudit_arg_gid(gid_t gid) 157155192Srwatson{ 158155192Srwatson struct kaudit_record *ar; 159155192Srwatson 160155192Srwatson ar = currecord(); 161155192Srwatson if (ar == NULL) 162155192Srwatson return; 163155192Srwatson 164155192Srwatson ar->k_ar.ar_arg_gid = gid; 165155192Srwatson ARG_SET_VALID(ar, ARG_GID); 166155192Srwatson} 167155192Srwatson 168155192Srwatsonvoid 169155192Srwatsonaudit_arg_uid(uid_t uid) 170155192Srwatson{ 171155192Srwatson struct kaudit_record *ar; 172155192Srwatson 173155192Srwatson ar = currecord(); 174155192Srwatson if (ar == NULL) 175155192Srwatson return; 176155192Srwatson 177155192Srwatson ar->k_ar.ar_arg_uid = uid; 178155192Srwatson ARG_SET_VALID(ar, ARG_UID); 179155192Srwatson} 180155192Srwatson 181155192Srwatsonvoid 182155192Srwatsonaudit_arg_egid(gid_t egid) 183155192Srwatson{ 184155192Srwatson struct kaudit_record *ar; 185155192Srwatson 186155192Srwatson ar = currecord(); 187155192Srwatson if (ar == NULL) 188155192Srwatson return; 189155192Srwatson 190155192Srwatson ar->k_ar.ar_arg_egid = egid; 191155192Srwatson ARG_SET_VALID(ar, ARG_EGID); 192155192Srwatson} 193155192Srwatson 194155192Srwatsonvoid 195155192Srwatsonaudit_arg_euid(uid_t euid) 196155192Srwatson{ 197155192Srwatson struct kaudit_record *ar; 198155192Srwatson 199155192Srwatson ar = currecord(); 200155192Srwatson if (ar == NULL) 201155192Srwatson return; 202155192Srwatson 203155192Srwatson ar->k_ar.ar_arg_euid = euid; 204155192Srwatson ARG_SET_VALID(ar, ARG_EUID); 205155192Srwatson} 206155192Srwatson 207155192Srwatsonvoid 208155192Srwatsonaudit_arg_rgid(gid_t rgid) 209155192Srwatson{ 210155192Srwatson struct kaudit_record *ar; 211155192Srwatson 212155192Srwatson ar = currecord(); 213155192Srwatson if (ar == NULL) 214155192Srwatson return; 215155192Srwatson 216155192Srwatson ar->k_ar.ar_arg_rgid = rgid; 217155192Srwatson ARG_SET_VALID(ar, ARG_RGID); 218155192Srwatson} 219155192Srwatson 220155192Srwatsonvoid 221155192Srwatsonaudit_arg_ruid(uid_t ruid) 222155192Srwatson{ 223155192Srwatson struct kaudit_record *ar; 224155192Srwatson 225155192Srwatson ar = currecord(); 226155192Srwatson if (ar == NULL) 227155192Srwatson return; 228155192Srwatson 229155192Srwatson ar->k_ar.ar_arg_ruid = ruid; 230155192Srwatson ARG_SET_VALID(ar, ARG_RUID); 231155192Srwatson} 232155192Srwatson 233155192Srwatsonvoid 234155192Srwatsonaudit_arg_sgid(gid_t sgid) 235155192Srwatson{ 236155192Srwatson struct kaudit_record *ar; 237155192Srwatson 238155192Srwatson ar = currecord(); 239155192Srwatson if (ar == NULL) 240155192Srwatson return; 241155192Srwatson 242155192Srwatson ar->k_ar.ar_arg_sgid = sgid; 243155192Srwatson ARG_SET_VALID(ar, ARG_SGID); 244155192Srwatson} 245155192Srwatson 246155192Srwatsonvoid 247155192Srwatsonaudit_arg_suid(uid_t suid) 248155192Srwatson{ 249155192Srwatson struct kaudit_record *ar; 250155192Srwatson 251155192Srwatson ar = currecord(); 252155192Srwatson if (ar == NULL) 253155192Srwatson return; 254155192Srwatson 255155192Srwatson ar->k_ar.ar_arg_suid = suid; 256155192Srwatson ARG_SET_VALID(ar, ARG_SUID); 257155192Srwatson} 258155192Srwatson 259155192Srwatsonvoid 260155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size) 261155192Srwatson{ 262180699Srwatson u_int i; 263155192Srwatson struct kaudit_record *ar; 264155192Srwatson 265202143Sbrooks KASSERT(gidset_size <= ngroups_max + 1, 266202143Sbrooks ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)")); 267195177Ssson 268155192Srwatson ar = currecord(); 269155192Srwatson if (ar == NULL) 270155192Srwatson return; 271155192Srwatson 272195177Ssson if (ar->k_ar.ar_arg_groups.gidset == NULL) 273195177Ssson ar->k_ar.ar_arg_groups.gidset = malloc( 274195177Ssson sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK); 275195177Ssson 276155192Srwatson for (i = 0; i < gidset_size; i++) 277155192Srwatson ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 278155192Srwatson ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 279155192Srwatson ARG_SET_VALID(ar, ARG_GROUPSET); 280155192Srwatson} 281155192Srwatson 282155192Srwatsonvoid 283155192Srwatsonaudit_arg_login(char *login) 284155192Srwatson{ 285155192Srwatson struct kaudit_record *ar; 286155192Srwatson 287155192Srwatson ar = currecord(); 288155192Srwatson if (ar == NULL) 289155192Srwatson return; 290155192Srwatson 291155192Srwatson strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 292155192Srwatson ARG_SET_VALID(ar, ARG_LOGIN); 293155192Srwatson} 294155192Srwatson 295155192Srwatsonvoid 296155192Srwatsonaudit_arg_ctlname(int *name, int namelen) 297155192Srwatson{ 298155192Srwatson struct kaudit_record *ar; 299155192Srwatson 300155192Srwatson ar = currecord(); 301155192Srwatson if (ar == NULL) 302155192Srwatson return; 303155192Srwatson 304155192Srwatson bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 305155192Srwatson ar->k_ar.ar_arg_len = namelen; 306155192Srwatson ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 307155192Srwatson} 308155192Srwatson 309155192Srwatsonvoid 310155192Srwatsonaudit_arg_mask(int mask) 311155192Srwatson{ 312155192Srwatson struct kaudit_record *ar; 313155192Srwatson 314155192Srwatson ar = currecord(); 315155192Srwatson if (ar == NULL) 316155192Srwatson return; 317155192Srwatson 318155192Srwatson ar->k_ar.ar_arg_mask = mask; 319155192Srwatson ARG_SET_VALID(ar, ARG_MASK); 320155192Srwatson} 321155192Srwatson 322155192Srwatsonvoid 323155192Srwatsonaudit_arg_mode(mode_t mode) 324155192Srwatson{ 325155192Srwatson struct kaudit_record *ar; 326155192Srwatson 327155192Srwatson ar = currecord(); 328155192Srwatson if (ar == NULL) 329155192Srwatson return; 330155192Srwatson 331155192Srwatson ar->k_ar.ar_arg_mode = mode; 332155192Srwatson ARG_SET_VALID(ar, ARG_MODE); 333155192Srwatson} 334155192Srwatson 335155192Srwatsonvoid 336155192Srwatsonaudit_arg_dev(int dev) 337155192Srwatson{ 338155192Srwatson struct kaudit_record *ar; 339155192Srwatson 340155192Srwatson ar = currecord(); 341155192Srwatson if (ar == NULL) 342155192Srwatson return; 343155192Srwatson 344155192Srwatson ar->k_ar.ar_arg_dev = dev; 345155192Srwatson ARG_SET_VALID(ar, ARG_DEV); 346155192Srwatson} 347155192Srwatson 348155192Srwatsonvoid 349155192Srwatsonaudit_arg_value(long value) 350155192Srwatson{ 351155192Srwatson struct kaudit_record *ar; 352155192Srwatson 353155192Srwatson ar = currecord(); 354155192Srwatson if (ar == NULL) 355155192Srwatson return; 356155192Srwatson 357155192Srwatson ar->k_ar.ar_arg_value = value; 358155192Srwatson ARG_SET_VALID(ar, ARG_VALUE); 359155192Srwatson} 360155192Srwatson 361155192Srwatsonvoid 362155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid) 363155192Srwatson{ 364155192Srwatson struct kaudit_record *ar; 365155192Srwatson 366155192Srwatson ar = currecord(); 367155192Srwatson if (ar == NULL) 368155192Srwatson return; 369155192Srwatson 370155192Srwatson ar->k_ar.ar_arg_uid = uid; 371155192Srwatson ar->k_ar.ar_arg_gid = gid; 372155192Srwatson ARG_SET_VALID(ar, ARG_UID | ARG_GID); 373155192Srwatson} 374155192Srwatson 375155192Srwatsonvoid 376155192Srwatsonaudit_arg_pid(pid_t pid) 377155192Srwatson{ 378155192Srwatson struct kaudit_record *ar; 379155192Srwatson 380155192Srwatson ar = currecord(); 381155192Srwatson if (ar == NULL) 382155192Srwatson return; 383155192Srwatson 384155192Srwatson ar->k_ar.ar_arg_pid = pid; 385155192Srwatson ARG_SET_VALID(ar, ARG_PID); 386155192Srwatson} 387155192Srwatson 388155192Srwatsonvoid 389155192Srwatsonaudit_arg_process(struct proc *p) 390155192Srwatson{ 391155192Srwatson struct kaudit_record *ar; 392184948Srwatson struct ucred *cred; 393155192Srwatson 394160086Srwatson KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 395160086Srwatson 396160086Srwatson PROC_LOCK_ASSERT(p, MA_OWNED); 397160086Srwatson 398155192Srwatson ar = currecord(); 399160086Srwatson if (ar == NULL) 400155192Srwatson return; 401155192Srwatson 402184948Srwatson cred = p->p_ucred; 403184948Srwatson ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; 404184948Srwatson ar->k_ar.ar_arg_euid = cred->cr_uid; 405184948Srwatson ar->k_ar.ar_arg_egid = cred->cr_groups[0]; 406184948Srwatson ar->k_ar.ar_arg_ruid = cred->cr_ruid; 407184948Srwatson ar->k_ar.ar_arg_rgid = cred->cr_rgid; 408184948Srwatson ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; 409184948Srwatson ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; 410159277Srwatson ar->k_ar.ar_arg_pid = p->p_pid; 411155192Srwatson ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 412168688Scsjp ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 413155192Srwatson} 414155192Srwatson 415155192Srwatsonvoid 416155192Srwatsonaudit_arg_signum(u_int signum) 417155192Srwatson{ 418155192Srwatson struct kaudit_record *ar; 419155192Srwatson 420155192Srwatson ar = currecord(); 421155192Srwatson if (ar == NULL) 422155192Srwatson return; 423155192Srwatson 424155192Srwatson ar->k_ar.ar_arg_signum = signum; 425155192Srwatson ARG_SET_VALID(ar, ARG_SIGNUM); 426155192Srwatson} 427155192Srwatson 428155192Srwatsonvoid 429155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol) 430155192Srwatson{ 431155192Srwatson struct kaudit_record *ar; 432156889Srwatson 433155192Srwatson ar = currecord(); 434155192Srwatson if (ar == NULL) 435155192Srwatson return; 436155192Srwatson 437155192Srwatson ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 438155192Srwatson ar->k_ar.ar_arg_sockinfo.so_type = sotype; 439155192Srwatson ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 440155192Srwatson ARG_SET_VALID(ar, ARG_SOCKINFO); 441155192Srwatson} 442155192Srwatson 443155192Srwatsonvoid 444247667Spjdaudit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa) 445155192Srwatson{ 446155192Srwatson struct kaudit_record *ar; 447155192Srwatson 448160086Srwatson KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL")); 449160086Srwatson KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 450160086Srwatson 451155192Srwatson ar = currecord(); 452160086Srwatson if (ar == NULL) 453155192Srwatson return; 454155192Srwatson 455164011Scsjp bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 456160086Srwatson switch (sa->sa_family) { 457155192Srwatson case AF_INET: 458155192Srwatson ARG_SET_VALID(ar, ARG_SADDRINET); 459155192Srwatson break; 460155192Srwatson 461155192Srwatson case AF_INET6: 462155192Srwatson ARG_SET_VALID(ar, ARG_SADDRINET6); 463155192Srwatson break; 464155192Srwatson 465155192Srwatson case AF_UNIX: 466247667Spjd if (dirfd != AT_FDCWD) 467247667Spjd audit_arg_atfd1(dirfd); 468247667Spjd audit_arg_upath1(td, dirfd, 469243726Spjd ((struct sockaddr_un *)sa)->sun_path); 470155192Srwatson ARG_SET_VALID(ar, ARG_SADDRUNIX); 471155192Srwatson break; 472155192Srwatson /* XXXAUDIT: default:? */ 473155192Srwatson } 474155192Srwatson} 475155192Srwatson 476155192Srwatsonvoid 477155192Srwatsonaudit_arg_auid(uid_t auid) 478155192Srwatson{ 479155192Srwatson struct kaudit_record *ar; 480155192Srwatson 481155192Srwatson ar = currecord(); 482155192Srwatson if (ar == NULL) 483155192Srwatson return; 484155192Srwatson 485155192Srwatson ar->k_ar.ar_arg_auid = auid; 486155192Srwatson ARG_SET_VALID(ar, ARG_AUID); 487155192Srwatson} 488155192Srwatson 489155192Srwatsonvoid 490155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info) 491155192Srwatson{ 492155192Srwatson struct kaudit_record *ar; 493155192Srwatson 494155192Srwatson ar = currecord(); 495155192Srwatson if (ar == NULL) 496155192Srwatson return; 497155192Srwatson 498155192Srwatson ar->k_ar.ar_arg_auid = au_info->ai_auid; 499155192Srwatson ar->k_ar.ar_arg_asid = au_info->ai_asid; 500155192Srwatson ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 501155192Srwatson ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 502155192Srwatson ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 503155192Srwatson ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 504155192Srwatson ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 505155192Srwatson} 506155192Srwatson 507155192Srwatsonvoid 508171066Scsjpaudit_arg_auditinfo_addr(struct auditinfo_addr *au_info) 509171066Scsjp{ 510171066Scsjp struct kaudit_record *ar; 511171066Scsjp 512171066Scsjp ar = currecord(); 513171066Scsjp if (ar == NULL) 514171066Scsjp return; 515171066Scsjp 516171066Scsjp ar->k_ar.ar_arg_auid = au_info->ai_auid; 517171066Scsjp ar->k_ar.ar_arg_asid = au_info->ai_asid; 518171066Scsjp ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 519171066Scsjp ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 520171066Scsjp ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; 521171066Scsjp ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; 522171066Scsjp ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; 523171066Scsjp ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; 524171066Scsjp ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; 525171066Scsjp ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; 526171066Scsjp ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); 527171066Scsjp} 528171066Scsjp 529171066Scsjpvoid 530155192Srwatsonaudit_arg_text(char *text) 531155192Srwatson{ 532155192Srwatson struct kaudit_record *ar; 533155192Srwatson 534160086Srwatson KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 535160086Srwatson 536155192Srwatson ar = currecord(); 537155192Srwatson if (ar == NULL) 538155192Srwatson return; 539155192Srwatson 540155192Srwatson /* Invalidate the text string */ 541155192Srwatson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 542155192Srwatson 543155192Srwatson if (ar->k_ar.ar_arg_text == NULL) 544155192Srwatson ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 545155192Srwatson M_WAITOK); 546155192Srwatson 547155192Srwatson strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 548155192Srwatson ARG_SET_VALID(ar, ARG_TEXT); 549155192Srwatson} 550155192Srwatson 551155192Srwatsonvoid 552155192Srwatsonaudit_arg_cmd(int cmd) 553155192Srwatson{ 554155192Srwatson struct kaudit_record *ar; 555155192Srwatson 556155192Srwatson ar = currecord(); 557155192Srwatson if (ar == NULL) 558155192Srwatson return; 559155192Srwatson 560155192Srwatson ar->k_ar.ar_arg_cmd = cmd; 561155192Srwatson ARG_SET_VALID(ar, ARG_CMD); 562155192Srwatson} 563155192Srwatson 564155192Srwatsonvoid 565155192Srwatsonaudit_arg_svipc_cmd(int cmd) 566155192Srwatson{ 567155192Srwatson struct kaudit_record *ar; 568155192Srwatson 569155192Srwatson ar = currecord(); 570155192Srwatson if (ar == NULL) 571155192Srwatson return; 572155192Srwatson 573155192Srwatson ar->k_ar.ar_arg_svipc_cmd = cmd; 574155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_CMD); 575155192Srwatson} 576155192Srwatson 577155192Srwatsonvoid 578155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm) 579155192Srwatson{ 580155192Srwatson struct kaudit_record *ar; 581155192Srwatson 582155192Srwatson ar = currecord(); 583155192Srwatson if (ar == NULL) 584155192Srwatson return; 585155192Srwatson 586156889Srwatson bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 587156889Srwatson sizeof(ar->k_ar.ar_arg_svipc_perm)); 588155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_PERM); 589155192Srwatson} 590155192Srwatson 591155192Srwatsonvoid 592155192Srwatsonaudit_arg_svipc_id(int id) 593155192Srwatson{ 594155192Srwatson struct kaudit_record *ar; 595155192Srwatson 596155192Srwatson ar = currecord(); 597155192Srwatson if (ar == NULL) 598155192Srwatson return; 599155192Srwatson 600155192Srwatson ar->k_ar.ar_arg_svipc_id = id; 601155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_ID); 602155192Srwatson} 603155192Srwatson 604155192Srwatsonvoid 605155192Srwatsonaudit_arg_svipc_addr(void * addr) 606155192Srwatson{ 607155192Srwatson struct kaudit_record *ar; 608155192Srwatson 609155192Srwatson ar = currecord(); 610155192Srwatson if (ar == NULL) 611155192Srwatson return; 612155192Srwatson 613155192Srwatson ar->k_ar.ar_arg_svipc_addr = addr; 614155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 615155192Srwatson} 616155192Srwatson 617155192Srwatsonvoid 618155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 619155192Srwatson{ 620155192Srwatson struct kaudit_record *ar; 621155192Srwatson 622155192Srwatson ar = currecord(); 623155192Srwatson if (ar == NULL) 624155192Srwatson return; 625155192Srwatson 626155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 627155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 628155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 629155192Srwatson ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 630155192Srwatson} 631155192Srwatson 632155192Srwatsonvoid 633155192Srwatsonaudit_arg_auditon(union auditon_udata *udata) 634155192Srwatson{ 635155192Srwatson struct kaudit_record *ar; 636155192Srwatson 637155192Srwatson ar = currecord(); 638155192Srwatson if (ar == NULL) 639155192Srwatson return; 640155192Srwatson 641156889Srwatson bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 642156889Srwatson sizeof(ar->k_ar.ar_arg_auditon)); 643155192Srwatson ARG_SET_VALID(ar, ARG_AUDITON); 644155192Srwatson} 645155192Srwatson 646155192Srwatson/* 647155192Srwatson * Audit information about a file, either the file's vnode info, or its 648155192Srwatson * socket address info. 649155192Srwatson */ 650155192Srwatsonvoid 651155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp) 652155192Srwatson{ 653155192Srwatson struct kaudit_record *ar; 654155192Srwatson struct socket *so; 655155192Srwatson struct inpcb *pcb; 656155192Srwatson struct vnode *vp; 657155192Srwatson 658160086Srwatson ar = currecord(); 659160086Srwatson if (ar == NULL) 660160086Srwatson return; 661160086Srwatson 662155192Srwatson switch (fp->f_type) { 663155192Srwatson case DTYPE_VNODE: 664155192Srwatson case DTYPE_FIFO: 665155192Srwatson /* 666155192Srwatson * XXXAUDIT: Only possibly to record as first vnode? 667155192Srwatson */ 668155192Srwatson vp = fp->f_vnode; 669184661Sjhb vn_lock(vp, LK_SHARED | LK_RETRY); 670195926Srwatson audit_arg_vnode1(vp); 671175294Sattilio VOP_UNLOCK(vp, 0); 672155192Srwatson break; 673155192Srwatson 674155192Srwatson case DTYPE_SOCKET: 675155192Srwatson so = (struct socket *)fp->f_data; 676155192Srwatson if (INP_CHECK_SOCKAF(so, PF_INET)) { 677166845Srwatson SOCK_LOCK(so); 678155192Srwatson ar->k_ar.ar_arg_sockinfo.so_type = 679156889Srwatson so->so_type; 680155192Srwatson ar->k_ar.ar_arg_sockinfo.so_domain = 681156889Srwatson INP_SOCKAF(so); 682155192Srwatson ar->k_ar.ar_arg_sockinfo.so_protocol = 683156889Srwatson so->so_proto->pr_protocol; 684166845Srwatson SOCK_UNLOCK(so); 685155192Srwatson pcb = (struct inpcb *)so->so_pcb; 686178322Srwatson INP_RLOCK(pcb); 687155192Srwatson ar->k_ar.ar_arg_sockinfo.so_raddr = 688156889Srwatson pcb->inp_faddr.s_addr; 689155192Srwatson ar->k_ar.ar_arg_sockinfo.so_laddr = 690156889Srwatson pcb->inp_laddr.s_addr; 691155192Srwatson ar->k_ar.ar_arg_sockinfo.so_rport = 692156889Srwatson pcb->inp_fport; 693155192Srwatson ar->k_ar.ar_arg_sockinfo.so_lport = 694156889Srwatson pcb->inp_lport; 695178322Srwatson INP_RUNLOCK(pcb); 696155192Srwatson ARG_SET_VALID(ar, ARG_SOCKINFO); 697155192Srwatson } 698155192Srwatson break; 699155192Srwatson 700155192Srwatson default: 701155192Srwatson /* XXXAUDIT: else? */ 702155192Srwatson break; 703155192Srwatson } 704155192Srwatson} 705155192Srwatson 706156889Srwatson/* 707156889Srwatson * Store a path as given by the user process for auditing into the audit 708180703Srwatson * record stored on the user thread. This function will allocate the memory 709180703Srwatson * to store the path info if not already available. This memory will be 710180703Srwatson * freed when the audit record is freed. 711155192Srwatson */ 712195939Srwatsonstatic void 713243726Spjdaudit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp) 714195939Srwatson{ 715195939Srwatson 716195939Srwatson if (*pathp == NULL) 717195939Srwatson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 718243726Spjd audit_canon_path(td, dirfd, upath, *pathp); 719195939Srwatson} 720195939Srwatson 721155192Srwatsonvoid 722243726Spjdaudit_arg_upath1(struct thread *td, int dirfd, char *upath) 723155192Srwatson{ 724155192Srwatson struct kaudit_record *ar; 725155192Srwatson 726160086Srwatson ar = currecord(); 727160086Srwatson if (ar == NULL) 728160086Srwatson return; 729160086Srwatson 730243726Spjd audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1); 731195939Srwatson ARG_SET_VALID(ar, ARG_UPATH1); 732195939Srwatson} 733155192Srwatson 734195939Srwatsonvoid 735243726Spjdaudit_arg_upath2(struct thread *td, int dirfd, char *upath) 736195939Srwatson{ 737195939Srwatson struct kaudit_record *ar; 738155192Srwatson 739195939Srwatson ar = currecord(); 740195939Srwatson if (ar == NULL) 741195939Srwatson return; 742155192Srwatson 743243726Spjd audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2); 744195939Srwatson ARG_SET_VALID(ar, ARG_UPATH2); 745155192Srwatson} 746155192Srwatson 747155192Srwatson/* 748156889Srwatson * Function to save the path and vnode attr information into the audit 749156889Srwatson * record. 750155192Srwatson * 751155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to 752155192Srwatson * perform a VOP_GETATTR() on the passed vnode. 753155192Srwatson * 754170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always 755170196Srwatson * provides access to the generation number as we need that to construct the 756170196Srwatson * BSM file ID. 757170196Srwatson * 758170196Srwatson * XXX: We should accept the process argument from the caller, since it's 759170196Srwatson * very likely they already have a reference. 760170196Srwatson * 761155192Srwatson * XXX: Error handling in this function is poor. 762155192Srwatson * 763155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 764155192Srwatson */ 765195926Srwatsonstatic int 766195926Srwatsonaudit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp) 767155192Srwatson{ 768155192Srwatson struct vattr vattr; 769155192Srwatson int error; 770155192Srwatson 771155192Srwatson ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 772155192Srwatson 773182371Sattilio error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 774155192Srwatson if (error) { 775155192Srwatson /* XXX: How to handle this case? */ 776195926Srwatson return (error); 777155192Srwatson } 778155192Srwatson 779155192Srwatson vnp->vn_mode = vattr.va_mode; 780155192Srwatson vnp->vn_uid = vattr.va_uid; 781155192Srwatson vnp->vn_gid = vattr.va_gid; 782155192Srwatson vnp->vn_dev = vattr.va_rdev; 783155192Srwatson vnp->vn_fsid = vattr.va_fsid; 784155192Srwatson vnp->vn_fileid = vattr.va_fileid; 785155192Srwatson vnp->vn_gen = vattr.va_gen; 786195926Srwatson return (0); 787195926Srwatson} 788195926Srwatson 789195926Srwatsonvoid 790195926Srwatsonaudit_arg_vnode1(struct vnode *vp) 791195926Srwatson{ 792195926Srwatson struct kaudit_record *ar; 793195926Srwatson int error; 794195926Srwatson 795195926Srwatson ar = currecord(); 796195926Srwatson if (ar == NULL) 797195926Srwatson return; 798195926Srwatson 799195926Srwatson ARG_CLEAR_VALID(ar, ARG_VNODE1); 800195926Srwatson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1); 801195926Srwatson if (error == 0) 802155192Srwatson ARG_SET_VALID(ar, ARG_VNODE1); 803195926Srwatson} 804195926Srwatson 805195926Srwatsonvoid 806195926Srwatsonaudit_arg_vnode2(struct vnode *vp) 807195926Srwatson{ 808195926Srwatson struct kaudit_record *ar; 809195926Srwatson int error; 810195926Srwatson 811195926Srwatson ar = currecord(); 812195926Srwatson if (ar == NULL) 813195926Srwatson return; 814195926Srwatson 815195926Srwatson ARG_CLEAR_VALID(ar, ARG_VNODE2); 816195926Srwatson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2); 817195926Srwatson if (error == 0) 818155192Srwatson ARG_SET_VALID(ar, ARG_VNODE2); 819155192Srwatson} 820155192Srwatson 821155192Srwatson/* 822161813Swsalamon * Audit the argument strings passed to exec. 823161813Swsalamon */ 824161813Swsalamonvoid 825161813Swsalamonaudit_arg_argv(char *argv, int argc, int length) 826161813Swsalamon{ 827161813Swsalamon struct kaudit_record *ar; 828161813Swsalamon 829161813Swsalamon if (audit_argv == 0) 830161813Swsalamon return; 831161813Swsalamon 832161813Swsalamon ar = currecord(); 833161813Swsalamon if (ar == NULL) 834161813Swsalamon return; 835161813Swsalamon 836161813Swsalamon ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 837161813Swsalamon bcopy(argv, ar->k_ar.ar_arg_argv, length); 838161813Swsalamon ar->k_ar.ar_arg_argc = argc; 839161813Swsalamon ARG_SET_VALID(ar, ARG_ARGV); 840161813Swsalamon} 841161813Swsalamon 842161813Swsalamon/* 843161813Swsalamon * Audit the environment strings passed to exec. 844161813Swsalamon */ 845161813Swsalamonvoid 846161813Swsalamonaudit_arg_envv(char *envv, int envc, int length) 847161813Swsalamon{ 848161813Swsalamon struct kaudit_record *ar; 849161813Swsalamon 850161813Swsalamon if (audit_arge == 0) 851161813Swsalamon return; 852161813Swsalamon 853161813Swsalamon ar = currecord(); 854161813Swsalamon if (ar == NULL) 855161813Swsalamon return; 856161813Swsalamon 857161813Swsalamon ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 858161813Swsalamon bcopy(envv, ar->k_ar.ar_arg_envv, length); 859161813Swsalamon ar->k_ar.ar_arg_envc = envc; 860161813Swsalamon ARG_SET_VALID(ar, ARG_ENVV); 861161813Swsalamon} 862161813Swsalamon 863224181Sjonathanvoid 864255219Spjdaudit_arg_rights(cap_rights_t *rightsp) 865224181Sjonathan{ 866224181Sjonathan struct kaudit_record *ar; 867224181Sjonathan 868224181Sjonathan ar = currecord(); 869224181Sjonathan if (ar == NULL) 870224181Sjonathan return; 871224181Sjonathan 872255219Spjd ar->k_ar.ar_arg_rights = *rightsp; 873224181Sjonathan ARG_SET_VALID(ar, ARG_RIGHTS); 874224181Sjonathan} 875224181Sjonathan 876247602Spjdvoid 877247602Spjdaudit_arg_fcntl_rights(uint32_t fcntlrights) 878247602Spjd{ 879247602Spjd struct kaudit_record *ar; 880247602Spjd 881247602Spjd ar = currecord(); 882247602Spjd if (ar == NULL) 883247602Spjd return; 884247602Spjd 885247602Spjd ar->k_ar.ar_arg_fcntl_rights = fcntlrights; 886247602Spjd ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS); 887247602Spjd} 888247602Spjd 889161813Swsalamon/* 890156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode 891156889Srwatson * information because those pieces are not easily obtained within the system 892156889Srwatson * call itself. 893155192Srwatson */ 894155192Srwatsonvoid 895155192Srwatsonaudit_sysclose(struct thread *td, int fd) 896155192Srwatson{ 897160086Srwatson struct kaudit_record *ar; 898155192Srwatson struct vnode *vp; 899155192Srwatson struct file *fp; 900155192Srwatson 901160086Srwatson KASSERT(td != NULL, ("audit_sysclose: td == NULL")); 902160086Srwatson 903160086Srwatson ar = currecord(); 904160086Srwatson if (ar == NULL) 905160086Srwatson return; 906160086Srwatson 907155192Srwatson audit_arg_fd(fd); 908155192Srwatson 909224778Srwatson if (getvnode(td->td_proc->p_fd, fd, 0, &fp) != 0) 910155192Srwatson return; 911155192Srwatson 912155192Srwatson vp = fp->f_vnode; 913184661Sjhb vn_lock(vp, LK_SHARED | LK_RETRY); 914195926Srwatson audit_arg_vnode1(vp); 915175294Sattilio VOP_UNLOCK(vp, 0); 916155192Srwatson fdrop(fp, td); 917156889Srwatson} 918