audit_arg.c revision 170585
1155192Srwatson/* 2155192Srwatson * Copyright (c) 1999-2005 Apple Computer, 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. 13155192Srwatson * 3. Neither the name of Apple Computer, 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 * $FreeBSD: head/sys/security/audit/audit_arg.c 170585 2007-06-11 22:10:54Z rwatson $ 30155192Srwatson */ 31155192Srwatson 32155192Srwatson#include <sys/param.h> 33155192Srwatson#include <sys/filedesc.h> 34155192Srwatson#include <sys/ipc.h> 35155192Srwatson#include <sys/mount.h> 36155192Srwatson#include <sys/proc.h> 37155192Srwatson#include <sys/socket.h> 38155192Srwatson#include <sys/socketvar.h> 39155192Srwatson#include <sys/protosw.h> 40155192Srwatson#include <sys/domain.h> 41159277Srwatson#include <sys/sbuf.h> 42155192Srwatson#include <sys/systm.h> 43155192Srwatson#include <sys/un.h> 44155192Srwatson#include <sys/vnode.h> 45155192Srwatson 46155192Srwatson#include <netinet/in.h> 47155192Srwatson#include <netinet/in_pcb.h> 48155192Srwatson 49155192Srwatson#include <security/audit/audit.h> 50155192Srwatson#include <security/audit/audit_private.h> 51155192Srwatson 52155192Srwatson/* 53155192Srwatson * Calls to manipulate elements of the audit record structure from system 54170196Srwatson * call code. Macro wrappers will prevent this functions from being entered 55170196Srwatson * if auditing is disabled, avoiding the function call cost. We check the 56170196Srwatson * thread audit record pointer anyway, as the audit condition could change, 57170196Srwatson * and pre-selection may not have allocated an audit record for this event. 58155192Srwatson * 59155192Srwatson * XXXAUDIT: Should we assert, in each case, that this field of the record 60155192Srwatson * hasn't already been filled in? 61155192Srwatson */ 62155192Srwatsonvoid 63170585Srwatsonaudit_arg_addr(void *addr) 64155192Srwatson{ 65155192Srwatson struct kaudit_record *ar; 66155192Srwatson 67155192Srwatson ar = currecord(); 68155192Srwatson if (ar == NULL) 69155192Srwatson return; 70155192Srwatson 71155192Srwatson ar->k_ar.ar_arg_addr = addr; 72155192Srwatson ARG_SET_VALID(ar, ARG_ADDR); 73155192Srwatson} 74155192Srwatson 75155192Srwatsonvoid 76155192Srwatsonaudit_arg_exit(int status, int retval) 77155192Srwatson{ 78155192Srwatson struct kaudit_record *ar; 79155192Srwatson 80155192Srwatson ar = currecord(); 81155192Srwatson if (ar == NULL) 82155192Srwatson return; 83155192Srwatson 84155192Srwatson ar->k_ar.ar_arg_exitstatus = status; 85155192Srwatson ar->k_ar.ar_arg_exitretval = retval; 86155192Srwatson ARG_SET_VALID(ar, ARG_EXIT); 87155192Srwatson} 88155192Srwatson 89155192Srwatsonvoid 90155192Srwatsonaudit_arg_len(int len) 91155192Srwatson{ 92155192Srwatson struct kaudit_record *ar; 93155192Srwatson 94155192Srwatson ar = currecord(); 95155192Srwatson if (ar == NULL) 96155192Srwatson return; 97155192Srwatson 98155192Srwatson ar->k_ar.ar_arg_len = len; 99155192Srwatson ARG_SET_VALID(ar, ARG_LEN); 100155192Srwatson} 101155192Srwatson 102155192Srwatsonvoid 103155192Srwatsonaudit_arg_fd(int fd) 104155192Srwatson{ 105155192Srwatson struct kaudit_record *ar; 106155192Srwatson 107155192Srwatson ar = currecord(); 108155192Srwatson if (ar == NULL) 109155192Srwatson return; 110155192Srwatson 111155192Srwatson ar->k_ar.ar_arg_fd = fd; 112155192Srwatson ARG_SET_VALID(ar, ARG_FD); 113155192Srwatson} 114155192Srwatson 115155192Srwatsonvoid 116155192Srwatsonaudit_arg_fflags(int fflags) 117155192Srwatson{ 118155192Srwatson struct kaudit_record *ar; 119155192Srwatson 120155192Srwatson ar = currecord(); 121155192Srwatson if (ar == NULL) 122155192Srwatson return; 123155192Srwatson 124155192Srwatson ar->k_ar.ar_arg_fflags = fflags; 125155192Srwatson ARG_SET_VALID(ar, ARG_FFLAGS); 126155192Srwatson} 127155192Srwatson 128155192Srwatsonvoid 129155192Srwatsonaudit_arg_gid(gid_t gid) 130155192Srwatson{ 131155192Srwatson struct kaudit_record *ar; 132155192Srwatson 133155192Srwatson ar = currecord(); 134155192Srwatson if (ar == NULL) 135155192Srwatson return; 136155192Srwatson 137155192Srwatson ar->k_ar.ar_arg_gid = gid; 138155192Srwatson ARG_SET_VALID(ar, ARG_GID); 139155192Srwatson} 140155192Srwatson 141155192Srwatsonvoid 142155192Srwatsonaudit_arg_uid(uid_t uid) 143155192Srwatson{ 144155192Srwatson struct kaudit_record *ar; 145155192Srwatson 146155192Srwatson ar = currecord(); 147155192Srwatson if (ar == NULL) 148155192Srwatson return; 149155192Srwatson 150155192Srwatson ar->k_ar.ar_arg_uid = uid; 151155192Srwatson ARG_SET_VALID(ar, ARG_UID); 152155192Srwatson} 153155192Srwatson 154155192Srwatsonvoid 155155192Srwatsonaudit_arg_egid(gid_t egid) 156155192Srwatson{ 157155192Srwatson struct kaudit_record *ar; 158155192Srwatson 159155192Srwatson ar = currecord(); 160155192Srwatson if (ar == NULL) 161155192Srwatson return; 162155192Srwatson 163155192Srwatson ar->k_ar.ar_arg_egid = egid; 164155192Srwatson ARG_SET_VALID(ar, ARG_EGID); 165155192Srwatson} 166155192Srwatson 167155192Srwatsonvoid 168155192Srwatsonaudit_arg_euid(uid_t euid) 169155192Srwatson{ 170155192Srwatson struct kaudit_record *ar; 171155192Srwatson 172155192Srwatson ar = currecord(); 173155192Srwatson if (ar == NULL) 174155192Srwatson return; 175155192Srwatson 176155192Srwatson ar->k_ar.ar_arg_euid = euid; 177155192Srwatson ARG_SET_VALID(ar, ARG_EUID); 178155192Srwatson} 179155192Srwatson 180155192Srwatsonvoid 181155192Srwatsonaudit_arg_rgid(gid_t rgid) 182155192Srwatson{ 183155192Srwatson struct kaudit_record *ar; 184155192Srwatson 185155192Srwatson ar = currecord(); 186155192Srwatson if (ar == NULL) 187155192Srwatson return; 188155192Srwatson 189155192Srwatson ar->k_ar.ar_arg_rgid = rgid; 190155192Srwatson ARG_SET_VALID(ar, ARG_RGID); 191155192Srwatson} 192155192Srwatson 193155192Srwatsonvoid 194155192Srwatsonaudit_arg_ruid(uid_t ruid) 195155192Srwatson{ 196155192Srwatson struct kaudit_record *ar; 197155192Srwatson 198155192Srwatson ar = currecord(); 199155192Srwatson if (ar == NULL) 200155192Srwatson return; 201155192Srwatson 202155192Srwatson ar->k_ar.ar_arg_ruid = ruid; 203155192Srwatson ARG_SET_VALID(ar, ARG_RUID); 204155192Srwatson} 205155192Srwatson 206155192Srwatsonvoid 207155192Srwatsonaudit_arg_sgid(gid_t sgid) 208155192Srwatson{ 209155192Srwatson struct kaudit_record *ar; 210155192Srwatson 211155192Srwatson ar = currecord(); 212155192Srwatson if (ar == NULL) 213155192Srwatson return; 214155192Srwatson 215155192Srwatson ar->k_ar.ar_arg_sgid = sgid; 216155192Srwatson ARG_SET_VALID(ar, ARG_SGID); 217155192Srwatson} 218155192Srwatson 219155192Srwatsonvoid 220155192Srwatsonaudit_arg_suid(uid_t suid) 221155192Srwatson{ 222155192Srwatson struct kaudit_record *ar; 223155192Srwatson 224155192Srwatson ar = currecord(); 225155192Srwatson if (ar == NULL) 226155192Srwatson return; 227155192Srwatson 228155192Srwatson ar->k_ar.ar_arg_suid = suid; 229155192Srwatson ARG_SET_VALID(ar, ARG_SUID); 230155192Srwatson} 231155192Srwatson 232155192Srwatsonvoid 233155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size) 234155192Srwatson{ 235155192Srwatson int i; 236155192Srwatson struct kaudit_record *ar; 237155192Srwatson 238155192Srwatson ar = currecord(); 239155192Srwatson if (ar == NULL) 240155192Srwatson return; 241155192Srwatson 242155192Srwatson for (i = 0; i < gidset_size; i++) 243155192Srwatson ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 244155192Srwatson ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 245155192Srwatson ARG_SET_VALID(ar, ARG_GROUPSET); 246155192Srwatson} 247155192Srwatson 248155192Srwatsonvoid 249155192Srwatsonaudit_arg_login(char *login) 250155192Srwatson{ 251155192Srwatson struct kaudit_record *ar; 252155192Srwatson 253155192Srwatson ar = currecord(); 254155192Srwatson if (ar == NULL) 255155192Srwatson return; 256155192Srwatson 257155192Srwatson strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 258155192Srwatson ARG_SET_VALID(ar, ARG_LOGIN); 259155192Srwatson} 260155192Srwatson 261155192Srwatsonvoid 262155192Srwatsonaudit_arg_ctlname(int *name, int namelen) 263155192Srwatson{ 264155192Srwatson struct kaudit_record *ar; 265155192Srwatson 266155192Srwatson ar = currecord(); 267155192Srwatson if (ar == NULL) 268155192Srwatson return; 269155192Srwatson 270155192Srwatson bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 271155192Srwatson ar->k_ar.ar_arg_len = namelen; 272155192Srwatson ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 273155192Srwatson} 274155192Srwatson 275155192Srwatsonvoid 276155192Srwatsonaudit_arg_mask(int mask) 277155192Srwatson{ 278155192Srwatson struct kaudit_record *ar; 279155192Srwatson 280155192Srwatson ar = currecord(); 281155192Srwatson if (ar == NULL) 282155192Srwatson return; 283155192Srwatson 284155192Srwatson ar->k_ar.ar_arg_mask = mask; 285155192Srwatson ARG_SET_VALID(ar, ARG_MASK); 286155192Srwatson} 287155192Srwatson 288155192Srwatsonvoid 289155192Srwatsonaudit_arg_mode(mode_t mode) 290155192Srwatson{ 291155192Srwatson struct kaudit_record *ar; 292155192Srwatson 293155192Srwatson ar = currecord(); 294155192Srwatson if (ar == NULL) 295155192Srwatson return; 296155192Srwatson 297155192Srwatson ar->k_ar.ar_arg_mode = mode; 298155192Srwatson ARG_SET_VALID(ar, ARG_MODE); 299155192Srwatson} 300155192Srwatson 301155192Srwatsonvoid 302155192Srwatsonaudit_arg_dev(int dev) 303155192Srwatson{ 304155192Srwatson struct kaudit_record *ar; 305155192Srwatson 306155192Srwatson ar = currecord(); 307155192Srwatson if (ar == NULL) 308155192Srwatson return; 309155192Srwatson 310155192Srwatson ar->k_ar.ar_arg_dev = dev; 311155192Srwatson ARG_SET_VALID(ar, ARG_DEV); 312155192Srwatson} 313155192Srwatson 314155192Srwatsonvoid 315155192Srwatsonaudit_arg_value(long value) 316155192Srwatson{ 317155192Srwatson struct kaudit_record *ar; 318155192Srwatson 319155192Srwatson ar = currecord(); 320155192Srwatson if (ar == NULL) 321155192Srwatson return; 322155192Srwatson 323155192Srwatson ar->k_ar.ar_arg_value = value; 324155192Srwatson ARG_SET_VALID(ar, ARG_VALUE); 325155192Srwatson} 326155192Srwatson 327155192Srwatsonvoid 328155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid) 329155192Srwatson{ 330155192Srwatson struct kaudit_record *ar; 331155192Srwatson 332155192Srwatson ar = currecord(); 333155192Srwatson if (ar == NULL) 334155192Srwatson return; 335155192Srwatson 336155192Srwatson ar->k_ar.ar_arg_uid = uid; 337155192Srwatson ar->k_ar.ar_arg_gid = gid; 338155192Srwatson ARG_SET_VALID(ar, ARG_UID | ARG_GID); 339155192Srwatson} 340155192Srwatson 341155192Srwatsonvoid 342155192Srwatsonaudit_arg_pid(pid_t pid) 343155192Srwatson{ 344155192Srwatson struct kaudit_record *ar; 345155192Srwatson 346155192Srwatson ar = currecord(); 347155192Srwatson if (ar == NULL) 348155192Srwatson return; 349155192Srwatson 350155192Srwatson ar->k_ar.ar_arg_pid = pid; 351155192Srwatson ARG_SET_VALID(ar, ARG_PID); 352155192Srwatson} 353155192Srwatson 354155192Srwatsonvoid 355155192Srwatsonaudit_arg_process(struct proc *p) 356155192Srwatson{ 357155192Srwatson struct kaudit_record *ar; 358155192Srwatson 359160086Srwatson KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 360160086Srwatson 361160086Srwatson PROC_LOCK_ASSERT(p, MA_OWNED); 362160086Srwatson 363155192Srwatson ar = currecord(); 364160086Srwatson if (ar == NULL) 365155192Srwatson return; 366155192Srwatson 367170407Srwatson ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid; 368155192Srwatson ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid; 369155192Srwatson ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0]; 370155192Srwatson ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid; 371155192Srwatson ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid; 372170407Srwatson ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid; 373170407Srwatson ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid; 374159277Srwatson ar->k_ar.ar_arg_pid = p->p_pid; 375155192Srwatson ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 376168688Scsjp ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 377155192Srwatson} 378155192Srwatson 379155192Srwatsonvoid 380155192Srwatsonaudit_arg_signum(u_int signum) 381155192Srwatson{ 382155192Srwatson struct kaudit_record *ar; 383155192Srwatson 384155192Srwatson ar = currecord(); 385155192Srwatson if (ar == NULL) 386155192Srwatson return; 387155192Srwatson 388155192Srwatson ar->k_ar.ar_arg_signum = signum; 389155192Srwatson ARG_SET_VALID(ar, ARG_SIGNUM); 390155192Srwatson} 391155192Srwatson 392155192Srwatsonvoid 393155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol) 394155192Srwatson{ 395155192Srwatson struct kaudit_record *ar; 396156889Srwatson 397155192Srwatson ar = currecord(); 398155192Srwatson if (ar == NULL) 399155192Srwatson return; 400155192Srwatson 401155192Srwatson ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 402155192Srwatson ar->k_ar.ar_arg_sockinfo.so_type = sotype; 403155192Srwatson ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 404155192Srwatson ARG_SET_VALID(ar, ARG_SOCKINFO); 405155192Srwatson} 406155192Srwatson 407155192Srwatsonvoid 408160086Srwatsonaudit_arg_sockaddr(struct thread *td, struct sockaddr *sa) 409155192Srwatson{ 410155192Srwatson struct kaudit_record *ar; 411155192Srwatson 412160086Srwatson KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL")); 413160086Srwatson KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 414160086Srwatson 415155192Srwatson ar = currecord(); 416160086Srwatson if (ar == NULL) 417155192Srwatson return; 418155192Srwatson 419164011Scsjp bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 420160086Srwatson switch (sa->sa_family) { 421155192Srwatson case AF_INET: 422155192Srwatson ARG_SET_VALID(ar, ARG_SADDRINET); 423155192Srwatson break; 424155192Srwatson 425155192Srwatson case AF_INET6: 426155192Srwatson ARG_SET_VALID(ar, ARG_SADDRINET6); 427155192Srwatson break; 428155192Srwatson 429155192Srwatson case AF_UNIX: 430160086Srwatson audit_arg_upath(td, ((struct sockaddr_un *)sa)->sun_path, 431155192Srwatson ARG_UPATH1); 432155192Srwatson ARG_SET_VALID(ar, ARG_SADDRUNIX); 433155192Srwatson break; 434155192Srwatson /* XXXAUDIT: default:? */ 435155192Srwatson } 436155192Srwatson} 437155192Srwatson 438155192Srwatsonvoid 439155192Srwatsonaudit_arg_auid(uid_t auid) 440155192Srwatson{ 441155192Srwatson struct kaudit_record *ar; 442155192Srwatson 443155192Srwatson ar = currecord(); 444155192Srwatson if (ar == NULL) 445155192Srwatson return; 446155192Srwatson 447155192Srwatson ar->k_ar.ar_arg_auid = auid; 448155192Srwatson ARG_SET_VALID(ar, ARG_AUID); 449155192Srwatson} 450155192Srwatson 451155192Srwatsonvoid 452155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info) 453155192Srwatson{ 454155192Srwatson struct kaudit_record *ar; 455155192Srwatson 456155192Srwatson ar = currecord(); 457155192Srwatson if (ar == NULL) 458155192Srwatson return; 459155192Srwatson 460155192Srwatson ar->k_ar.ar_arg_auid = au_info->ai_auid; 461155192Srwatson ar->k_ar.ar_arg_asid = au_info->ai_asid; 462155192Srwatson ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 463155192Srwatson ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 464155192Srwatson ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 465155192Srwatson ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 466155192Srwatson ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 467155192Srwatson} 468155192Srwatson 469155192Srwatsonvoid 470155192Srwatsonaudit_arg_text(char *text) 471155192Srwatson{ 472155192Srwatson struct kaudit_record *ar; 473155192Srwatson 474160086Srwatson KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 475160086Srwatson 476155192Srwatson ar = currecord(); 477155192Srwatson if (ar == NULL) 478155192Srwatson return; 479155192Srwatson 480155192Srwatson /* Invalidate the text string */ 481155192Srwatson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 482155192Srwatson 483155192Srwatson if (ar->k_ar.ar_arg_text == NULL) 484155192Srwatson ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 485155192Srwatson M_WAITOK); 486155192Srwatson 487155192Srwatson strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 488155192Srwatson ARG_SET_VALID(ar, ARG_TEXT); 489155192Srwatson} 490155192Srwatson 491155192Srwatsonvoid 492155192Srwatsonaudit_arg_cmd(int cmd) 493155192Srwatson{ 494155192Srwatson struct kaudit_record *ar; 495155192Srwatson 496155192Srwatson ar = currecord(); 497155192Srwatson if (ar == NULL) 498155192Srwatson return; 499155192Srwatson 500155192Srwatson ar->k_ar.ar_arg_cmd = cmd; 501155192Srwatson ARG_SET_VALID(ar, ARG_CMD); 502155192Srwatson} 503155192Srwatson 504155192Srwatsonvoid 505155192Srwatsonaudit_arg_svipc_cmd(int cmd) 506155192Srwatson{ 507155192Srwatson struct kaudit_record *ar; 508155192Srwatson 509155192Srwatson ar = currecord(); 510155192Srwatson if (ar == NULL) 511155192Srwatson return; 512155192Srwatson 513155192Srwatson ar->k_ar.ar_arg_svipc_cmd = cmd; 514155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_CMD); 515155192Srwatson} 516155192Srwatson 517155192Srwatsonvoid 518155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm) 519155192Srwatson{ 520155192Srwatson struct kaudit_record *ar; 521155192Srwatson 522155192Srwatson ar = currecord(); 523155192Srwatson if (ar == NULL) 524155192Srwatson return; 525155192Srwatson 526156889Srwatson bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 527156889Srwatson sizeof(ar->k_ar.ar_arg_svipc_perm)); 528155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_PERM); 529155192Srwatson} 530155192Srwatson 531155192Srwatsonvoid 532155192Srwatsonaudit_arg_svipc_id(int id) 533155192Srwatson{ 534155192Srwatson struct kaudit_record *ar; 535155192Srwatson 536155192Srwatson ar = currecord(); 537155192Srwatson if (ar == NULL) 538155192Srwatson return; 539155192Srwatson 540155192Srwatson ar->k_ar.ar_arg_svipc_id = id; 541155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_ID); 542155192Srwatson} 543155192Srwatson 544155192Srwatsonvoid 545155192Srwatsonaudit_arg_svipc_addr(void * addr) 546155192Srwatson{ 547155192Srwatson struct kaudit_record *ar; 548155192Srwatson 549155192Srwatson ar = currecord(); 550155192Srwatson if (ar == NULL) 551155192Srwatson return; 552155192Srwatson 553155192Srwatson ar->k_ar.ar_arg_svipc_addr = addr; 554155192Srwatson ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 555155192Srwatson} 556155192Srwatson 557155192Srwatsonvoid 558155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 559155192Srwatson{ 560155192Srwatson struct kaudit_record *ar; 561155192Srwatson 562155192Srwatson ar = currecord(); 563155192Srwatson if (ar == NULL) 564155192Srwatson return; 565155192Srwatson 566155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 567155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 568155192Srwatson ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 569155192Srwatson ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 570155192Srwatson} 571155192Srwatson 572155192Srwatsonvoid 573155192Srwatsonaudit_arg_auditon(union auditon_udata *udata) 574155192Srwatson{ 575155192Srwatson struct kaudit_record *ar; 576155192Srwatson 577155192Srwatson ar = currecord(); 578155192Srwatson if (ar == NULL) 579155192Srwatson return; 580155192Srwatson 581156889Srwatson bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 582156889Srwatson sizeof(ar->k_ar.ar_arg_auditon)); 583155192Srwatson ARG_SET_VALID(ar, ARG_AUDITON); 584155192Srwatson} 585155192Srwatson 586155192Srwatson/* 587155192Srwatson * Audit information about a file, either the file's vnode info, or its 588155192Srwatson * socket address info. 589155192Srwatson */ 590155192Srwatsonvoid 591155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp) 592155192Srwatson{ 593155192Srwatson struct kaudit_record *ar; 594155192Srwatson struct socket *so; 595155192Srwatson struct inpcb *pcb; 596155192Srwatson struct vnode *vp; 597155192Srwatson int vfslocked; 598155192Srwatson 599160086Srwatson ar = currecord(); 600160086Srwatson if (ar == NULL) 601160086Srwatson return; 602160086Srwatson 603155192Srwatson switch (fp->f_type) { 604155192Srwatson case DTYPE_VNODE: 605155192Srwatson case DTYPE_FIFO: 606155192Srwatson /* 607155192Srwatson * XXXAUDIT: Only possibly to record as first vnode? 608155192Srwatson */ 609155192Srwatson vp = fp->f_vnode; 610155192Srwatson vfslocked = VFS_LOCK_GIANT(vp->v_mount); 611155192Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); 612155192Srwatson audit_arg_vnode(vp, ARG_VNODE1); 613155192Srwatson VOP_UNLOCK(vp, 0, curthread); 614155192Srwatson VFS_UNLOCK_GIANT(vfslocked); 615155192Srwatson break; 616155192Srwatson 617155192Srwatson case DTYPE_SOCKET: 618155192Srwatson so = (struct socket *)fp->f_data; 619155192Srwatson if (INP_CHECK_SOCKAF(so, PF_INET)) { 620166845Srwatson SOCK_LOCK(so); 621155192Srwatson ar->k_ar.ar_arg_sockinfo.so_type = 622156889Srwatson so->so_type; 623155192Srwatson ar->k_ar.ar_arg_sockinfo.so_domain = 624156889Srwatson INP_SOCKAF(so); 625155192Srwatson ar->k_ar.ar_arg_sockinfo.so_protocol = 626156889Srwatson so->so_proto->pr_protocol; 627166845Srwatson SOCK_UNLOCK(so); 628155192Srwatson pcb = (struct inpcb *)so->so_pcb; 629166845Srwatson INP_LOCK(pcb); 630155192Srwatson ar->k_ar.ar_arg_sockinfo.so_raddr = 631156889Srwatson pcb->inp_faddr.s_addr; 632155192Srwatson ar->k_ar.ar_arg_sockinfo.so_laddr = 633156889Srwatson pcb->inp_laddr.s_addr; 634155192Srwatson ar->k_ar.ar_arg_sockinfo.so_rport = 635156889Srwatson pcb->inp_fport; 636155192Srwatson ar->k_ar.ar_arg_sockinfo.so_lport = 637156889Srwatson pcb->inp_lport; 638166845Srwatson INP_UNLOCK(pcb); 639155192Srwatson ARG_SET_VALID(ar, ARG_SOCKINFO); 640155192Srwatson } 641155192Srwatson break; 642155192Srwatson 643155192Srwatson default: 644155192Srwatson /* XXXAUDIT: else? */ 645155192Srwatson break; 646155192Srwatson } 647155192Srwatson} 648155192Srwatson 649156889Srwatson/* 650156889Srwatson * Store a path as given by the user process for auditing into the audit 651156889Srwatson * record stored on the user thread. This function will allocate the memory 652156889Srwatson * to store the path info if not already available. This memory will be freed 653156889Srwatson * when the audit record is freed. 654155192Srwatson * 655155192Srwatson * XXXAUDIT: Possibly assert that the memory isn't already allocated? 656155192Srwatson */ 657155192Srwatsonvoid 658155192Srwatsonaudit_arg_upath(struct thread *td, char *upath, u_int64_t flag) 659155192Srwatson{ 660155192Srwatson struct kaudit_record *ar; 661155192Srwatson char **pathp; 662155192Srwatson 663160086Srwatson KASSERT(td != NULL, ("audit_arg_upath: td == NULL")); 664160086Srwatson KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL")); 665155192Srwatson 666160086Srwatson ar = currecord(); 667160086Srwatson if (ar == NULL) 668160086Srwatson return; 669160086Srwatson 670155192Srwatson KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2), 671155270Srwatson ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 672155192Srwatson KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2), 673155270Srwatson ("audit_arg_upath: flag %llu", (unsigned long long)flag)); 674155192Srwatson 675155192Srwatson if (flag == ARG_UPATH1) 676155192Srwatson pathp = &ar->k_ar.ar_arg_upath1; 677155192Srwatson else 678155192Srwatson pathp = &ar->k_ar.ar_arg_upath2; 679155192Srwatson 680155192Srwatson if (*pathp == NULL) 681155192Srwatson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 682155192Srwatson 683155192Srwatson canon_path(td, upath, *pathp); 684155192Srwatson 685155192Srwatson ARG_SET_VALID(ar, flag); 686155192Srwatson} 687155192Srwatson 688155192Srwatson/* 689156889Srwatson * Function to save the path and vnode attr information into the audit 690156889Srwatson * record. 691155192Srwatson * 692155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to 693155192Srwatson * perform a VOP_GETATTR() on the passed vnode. 694155192Srwatson * 695170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always 696170196Srwatson * provides access to the generation number as we need that to construct the 697170196Srwatson * BSM file ID. 698170196Srwatson * 699170196Srwatson * XXX: We should accept the process argument from the caller, since it's 700170196Srwatson * very likely they already have a reference. 701170196Srwatson * 702155192Srwatson * XXX: Error handling in this function is poor. 703155192Srwatson * 704155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 705155192Srwatson */ 706155192Srwatsonvoid 707155192Srwatsonaudit_arg_vnode(struct vnode *vp, u_int64_t flags) 708155192Srwatson{ 709155192Srwatson struct kaudit_record *ar; 710155192Srwatson struct vattr vattr; 711155192Srwatson int error; 712155192Srwatson struct vnode_au_info *vnp; 713155192Srwatson 714160086Srwatson KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL")); 715160086Srwatson KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2), 716160086Srwatson ("audit_arg_vnode: flags %jd", (intmax_t)flags)); 717155192Srwatson 718155192Srwatson /* 719155192Srwatson * Assume that if the caller is calling audit_arg_vnode() on a 720155192Srwatson * non-MPSAFE vnode, then it will have acquired Giant. 721155192Srwatson */ 722155192Srwatson VFS_ASSERT_GIANT(vp->v_mount); 723155192Srwatson ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 724155192Srwatson 725155192Srwatson ar = currecord(); 726156889Srwatson if (ar == NULL) 727155192Srwatson return; 728155192Srwatson 729155192Srwatson /* 730155192Srwatson * XXXAUDIT: The below clears, and then resets the flags for valid 731155192Srwatson * arguments. Ideally, either the new vnode is used, or the old one 732155192Srwatson * would be. 733155192Srwatson */ 734155192Srwatson if (flags & ARG_VNODE1) { 735155192Srwatson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1); 736155192Srwatson vnp = &ar->k_ar.ar_arg_vnode1; 737155192Srwatson } else { 738155192Srwatson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2); 739155192Srwatson vnp = &ar->k_ar.ar_arg_vnode2; 740155192Srwatson } 741155192Srwatson 742160086Srwatson error = VOP_GETATTR(vp, &vattr, curthread->td_ucred, curthread); 743155192Srwatson if (error) { 744155192Srwatson /* XXX: How to handle this case? */ 745155192Srwatson return; 746155192Srwatson } 747155192Srwatson 748155192Srwatson vnp->vn_mode = vattr.va_mode; 749155192Srwatson vnp->vn_uid = vattr.va_uid; 750155192Srwatson vnp->vn_gid = vattr.va_gid; 751155192Srwatson vnp->vn_dev = vattr.va_rdev; 752155192Srwatson vnp->vn_fsid = vattr.va_fsid; 753155192Srwatson vnp->vn_fileid = vattr.va_fileid; 754155192Srwatson vnp->vn_gen = vattr.va_gen; 755155192Srwatson if (flags & ARG_VNODE1) 756155192Srwatson ARG_SET_VALID(ar, ARG_VNODE1); 757155192Srwatson else 758155192Srwatson ARG_SET_VALID(ar, ARG_VNODE2); 759155192Srwatson} 760155192Srwatson 761155192Srwatson/* 762161813Swsalamon * Audit the argument strings passed to exec. 763161813Swsalamon */ 764161813Swsalamonvoid 765161813Swsalamonaudit_arg_argv(char *argv, int argc, int length) 766161813Swsalamon{ 767161813Swsalamon struct kaudit_record *ar; 768161813Swsalamon 769161813Swsalamon if (audit_argv == 0) 770161813Swsalamon return; 771161813Swsalamon 772161813Swsalamon ar = currecord(); 773161813Swsalamon if (ar == NULL) 774161813Swsalamon return; 775161813Swsalamon 776161813Swsalamon ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 777161813Swsalamon bcopy(argv, ar->k_ar.ar_arg_argv, length); 778161813Swsalamon ar->k_ar.ar_arg_argc = argc; 779161813Swsalamon ARG_SET_VALID(ar, ARG_ARGV); 780161813Swsalamon} 781161813Swsalamon 782161813Swsalamon/* 783161813Swsalamon * Audit the environment strings passed to exec. 784161813Swsalamon */ 785161813Swsalamonvoid 786161813Swsalamonaudit_arg_envv(char *envv, int envc, int length) 787161813Swsalamon{ 788161813Swsalamon struct kaudit_record *ar; 789161813Swsalamon 790161813Swsalamon if (audit_arge == 0) 791161813Swsalamon return; 792161813Swsalamon 793161813Swsalamon ar = currecord(); 794161813Swsalamon if (ar == NULL) 795161813Swsalamon return; 796161813Swsalamon 797161813Swsalamon ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 798161813Swsalamon bcopy(envv, ar->k_ar.ar_arg_envv, length); 799161813Swsalamon ar->k_ar.ar_arg_envc = envc; 800161813Swsalamon ARG_SET_VALID(ar, ARG_ENVV); 801161813Swsalamon} 802161813Swsalamon 803161813Swsalamon/* 804156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode 805156889Srwatson * information because those pieces are not easily obtained within the system 806156889Srwatson * call itself. 807155192Srwatson */ 808155192Srwatsonvoid 809155192Srwatsonaudit_sysclose(struct thread *td, int fd) 810155192Srwatson{ 811160086Srwatson struct kaudit_record *ar; 812155192Srwatson struct vnode *vp; 813155192Srwatson struct file *fp; 814155192Srwatson int vfslocked; 815155192Srwatson 816160086Srwatson KASSERT(td != NULL, ("audit_sysclose: td == NULL")); 817160086Srwatson 818160086Srwatson ar = currecord(); 819160086Srwatson if (ar == NULL) 820160086Srwatson return; 821160086Srwatson 822155192Srwatson audit_arg_fd(fd); 823155192Srwatson 824155192Srwatson if (getvnode(td->td_proc->p_fd, fd, &fp) != 0) 825155192Srwatson return; 826155192Srwatson 827155192Srwatson vp = fp->f_vnode; 828155192Srwatson vfslocked = VFS_LOCK_GIANT(vp->v_mount); 829155192Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 830155192Srwatson audit_arg_vnode(vp, ARG_VNODE1); 831155192Srwatson VOP_UNLOCK(vp, 0, td); 832155192Srwatson VFS_UNLOCK_GIANT(vfslocked); 833155192Srwatson fdrop(fp, td); 834156889Srwatson} 835