1f6d4a8a7SRobert Watson /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 4bc9a43d6SRobert Watson * Copyright (c) 1999-2005 Apple Inc. 5b7830259SRobert Watson * Copyright (c) 2016-2017 Robert N. M. Watson 6718c8510SRobert Watson * All rights reserved. 7718c8510SRobert Watson * 8b7830259SRobert Watson * Portions of this software were developed by BAE Systems, the University of 9b7830259SRobert Watson * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL 10b7830259SRobert Watson * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent 11b7830259SRobert Watson * Computing (TC) research program. 12b7830259SRobert Watson * 13718c8510SRobert Watson * Redistribution and use in source and binary forms, with or without 14718c8510SRobert Watson * modification, are permitted provided that the following conditions 15718c8510SRobert Watson * are met: 16718c8510SRobert Watson * 1. Redistributions of source code must retain the above copyright 17718c8510SRobert Watson * notice, this list of conditions and the following disclaimer. 18718c8510SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 19718c8510SRobert Watson * notice, this list of conditions and the following disclaimer in the 20718c8510SRobert Watson * documentation and/or other materials provided with the distribution. 21bc9a43d6SRobert Watson * 3. Neither the name of Apple Inc. ("Apple") nor the names of 22718c8510SRobert Watson * its contributors may be used to endorse or promote products derived 23718c8510SRobert Watson * from this software without specific prior written permission. 24718c8510SRobert Watson * 25718c8510SRobert Watson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 26718c8510SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27718c8510SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28718c8510SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 29718c8510SRobert Watson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30718c8510SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31718c8510SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32718c8510SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33718c8510SRobert Watson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 34718c8510SRobert Watson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35718c8510SRobert Watson * POSSIBILITY OF SUCH DAMAGE. 36718c8510SRobert Watson */ 37718c8510SRobert Watson 38718c8510SRobert Watson #include <sys/param.h> 39718c8510SRobert Watson #include <sys/filedesc.h> 409ef8328dSMateusz Guzik #include <sys/capsicum.h> 41718c8510SRobert Watson #include <sys/ipc.h> 42718c8510SRobert Watson #include <sys/mount.h> 43718c8510SRobert Watson #include <sys/proc.h> 44718c8510SRobert Watson #include <sys/socket.h> 45718c8510SRobert Watson #include <sys/socketvar.h> 46718c8510SRobert Watson #include <sys/protosw.h> 47718c8510SRobert Watson #include <sys/domain.h> 485619113cSRobert Watson #include <sys/sbuf.h> 49718c8510SRobert Watson #include <sys/systm.h> 50718c8510SRobert Watson #include <sys/un.h> 51718c8510SRobert Watson #include <sys/vnode.h> 52718c8510SRobert Watson 53718c8510SRobert Watson #include <netinet/in.h> 54718c8510SRobert Watson #include <netinet/in_pcb.h> 55718c8510SRobert Watson 56718c8510SRobert Watson #include <security/audit/audit.h> 57718c8510SRobert Watson #include <security/audit/audit_private.h> 58718c8510SRobert Watson 59718c8510SRobert Watson /* 60718c8510SRobert Watson * Calls to manipulate elements of the audit record structure from system 61d8c0f4dcSRobert Watson * call code. Macro wrappers will prevent this functions from being entered 62d8c0f4dcSRobert Watson * if auditing is disabled, avoiding the function call cost. We check the 63d8c0f4dcSRobert Watson * thread audit record pointer anyway, as the audit condition could change, 64d8c0f4dcSRobert Watson * and pre-selection may not have allocated an audit record for this event. 65718c8510SRobert Watson * 66718c8510SRobert Watson * XXXAUDIT: Should we assert, in each case, that this field of the record 67718c8510SRobert Watson * hasn't already been filled in? 68718c8510SRobert Watson */ 69718c8510SRobert Watson void 70718c8510SRobert Watson audit_arg_addr(void *addr) 71718c8510SRobert Watson { 72718c8510SRobert Watson struct kaudit_record *ar; 73718c8510SRobert Watson 74718c8510SRobert Watson ar = currecord(); 75718c8510SRobert Watson if (ar == NULL) 76718c8510SRobert Watson return; 77718c8510SRobert Watson 78718c8510SRobert Watson ar->k_ar.ar_arg_addr = addr; 79718c8510SRobert Watson ARG_SET_VALID(ar, ARG_ADDR); 80718c8510SRobert Watson } 81718c8510SRobert Watson 82718c8510SRobert Watson void 83718c8510SRobert Watson audit_arg_exit(int status, int retval) 84718c8510SRobert Watson { 85718c8510SRobert Watson struct kaudit_record *ar; 86718c8510SRobert Watson 87718c8510SRobert Watson ar = currecord(); 88718c8510SRobert Watson if (ar == NULL) 89718c8510SRobert Watson return; 90718c8510SRobert Watson 91718c8510SRobert Watson ar->k_ar.ar_arg_exitstatus = status; 92718c8510SRobert Watson ar->k_ar.ar_arg_exitretval = retval; 93718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EXIT); 94718c8510SRobert Watson } 95718c8510SRobert Watson 96718c8510SRobert Watson void 97718c8510SRobert Watson audit_arg_len(int len) 98718c8510SRobert Watson { 99718c8510SRobert Watson struct kaudit_record *ar; 100718c8510SRobert Watson 101718c8510SRobert Watson ar = currecord(); 102718c8510SRobert Watson if (ar == NULL) 103718c8510SRobert Watson return; 104718c8510SRobert Watson 105718c8510SRobert Watson ar->k_ar.ar_arg_len = len; 106718c8510SRobert Watson ARG_SET_VALID(ar, ARG_LEN); 107718c8510SRobert Watson } 108718c8510SRobert Watson 109718c8510SRobert Watson void 110e4b4bbb6SRobert Watson audit_arg_atfd1(int atfd) 111e4b4bbb6SRobert Watson { 112e4b4bbb6SRobert Watson struct kaudit_record *ar; 113e4b4bbb6SRobert Watson 114e4b4bbb6SRobert Watson ar = currecord(); 115e4b4bbb6SRobert Watson if (ar == NULL) 116e4b4bbb6SRobert Watson return; 117e4b4bbb6SRobert Watson 118e4b4bbb6SRobert Watson ar->k_ar.ar_arg_atfd1 = atfd; 119e4b4bbb6SRobert Watson ARG_SET_VALID(ar, ARG_ATFD1); 120e4b4bbb6SRobert Watson } 121e4b4bbb6SRobert Watson 122e4b4bbb6SRobert Watson void 123e4b4bbb6SRobert Watson audit_arg_atfd2(int atfd) 124e4b4bbb6SRobert Watson { 125e4b4bbb6SRobert Watson struct kaudit_record *ar; 126e4b4bbb6SRobert Watson 127e4b4bbb6SRobert Watson ar = currecord(); 128e4b4bbb6SRobert Watson if (ar == NULL) 129e4b4bbb6SRobert Watson return; 130e4b4bbb6SRobert Watson 131e4b4bbb6SRobert Watson ar->k_ar.ar_arg_atfd2 = atfd; 132e4b4bbb6SRobert Watson ARG_SET_VALID(ar, ARG_ATFD2); 133e4b4bbb6SRobert Watson } 134e4b4bbb6SRobert Watson 135e4b4bbb6SRobert Watson void 136718c8510SRobert Watson audit_arg_fd(int fd) 137718c8510SRobert Watson { 138718c8510SRobert Watson struct kaudit_record *ar; 139718c8510SRobert Watson 140718c8510SRobert Watson ar = currecord(); 141718c8510SRobert Watson if (ar == NULL) 142718c8510SRobert Watson return; 143718c8510SRobert Watson 144718c8510SRobert Watson ar->k_ar.ar_arg_fd = fd; 145718c8510SRobert Watson ARG_SET_VALID(ar, ARG_FD); 146718c8510SRobert Watson } 147718c8510SRobert Watson 148718c8510SRobert Watson void 149718c8510SRobert Watson audit_arg_fflags(int fflags) 150718c8510SRobert Watson { 151718c8510SRobert Watson struct kaudit_record *ar; 152718c8510SRobert Watson 153718c8510SRobert Watson ar = currecord(); 154718c8510SRobert Watson if (ar == NULL) 155718c8510SRobert Watson return; 156718c8510SRobert Watson 157718c8510SRobert Watson ar->k_ar.ar_arg_fflags = fflags; 158718c8510SRobert Watson ARG_SET_VALID(ar, ARG_FFLAGS); 159718c8510SRobert Watson } 160718c8510SRobert Watson 161718c8510SRobert Watson void 162718c8510SRobert Watson audit_arg_gid(gid_t gid) 163718c8510SRobert Watson { 164718c8510SRobert Watson struct kaudit_record *ar; 165718c8510SRobert Watson 166718c8510SRobert Watson ar = currecord(); 167718c8510SRobert Watson if (ar == NULL) 168718c8510SRobert Watson return; 169718c8510SRobert Watson 170718c8510SRobert Watson ar->k_ar.ar_arg_gid = gid; 171718c8510SRobert Watson ARG_SET_VALID(ar, ARG_GID); 172718c8510SRobert Watson } 173718c8510SRobert Watson 174718c8510SRobert Watson void 175718c8510SRobert Watson audit_arg_uid(uid_t uid) 176718c8510SRobert Watson { 177718c8510SRobert Watson struct kaudit_record *ar; 178718c8510SRobert Watson 179718c8510SRobert Watson ar = currecord(); 180718c8510SRobert Watson if (ar == NULL) 181718c8510SRobert Watson return; 182718c8510SRobert Watson 183718c8510SRobert Watson ar->k_ar.ar_arg_uid = uid; 184718c8510SRobert Watson ARG_SET_VALID(ar, ARG_UID); 185718c8510SRobert Watson } 186718c8510SRobert Watson 187718c8510SRobert Watson void 188718c8510SRobert Watson audit_arg_egid(gid_t egid) 189718c8510SRobert Watson { 190718c8510SRobert Watson struct kaudit_record *ar; 191718c8510SRobert Watson 192718c8510SRobert Watson ar = currecord(); 193718c8510SRobert Watson if (ar == NULL) 194718c8510SRobert Watson return; 195718c8510SRobert Watson 196718c8510SRobert Watson ar->k_ar.ar_arg_egid = egid; 197718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EGID); 198718c8510SRobert Watson } 199718c8510SRobert Watson 200718c8510SRobert Watson void 201718c8510SRobert Watson audit_arg_euid(uid_t euid) 202718c8510SRobert Watson { 203718c8510SRobert Watson struct kaudit_record *ar; 204718c8510SRobert Watson 205718c8510SRobert Watson ar = currecord(); 206718c8510SRobert Watson if (ar == NULL) 207718c8510SRobert Watson return; 208718c8510SRobert Watson 209718c8510SRobert Watson ar->k_ar.ar_arg_euid = euid; 210718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EUID); 211718c8510SRobert Watson } 212718c8510SRobert Watson 213718c8510SRobert Watson void 214718c8510SRobert Watson audit_arg_rgid(gid_t rgid) 215718c8510SRobert Watson { 216718c8510SRobert Watson struct kaudit_record *ar; 217718c8510SRobert Watson 218718c8510SRobert Watson ar = currecord(); 219718c8510SRobert Watson if (ar == NULL) 220718c8510SRobert Watson return; 221718c8510SRobert Watson 222718c8510SRobert Watson ar->k_ar.ar_arg_rgid = rgid; 223718c8510SRobert Watson ARG_SET_VALID(ar, ARG_RGID); 224718c8510SRobert Watson } 225718c8510SRobert Watson 226718c8510SRobert Watson void 227718c8510SRobert Watson audit_arg_ruid(uid_t ruid) 228718c8510SRobert Watson { 229718c8510SRobert Watson struct kaudit_record *ar; 230718c8510SRobert Watson 231718c8510SRobert Watson ar = currecord(); 232718c8510SRobert Watson if (ar == NULL) 233718c8510SRobert Watson return; 234718c8510SRobert Watson 235718c8510SRobert Watson ar->k_ar.ar_arg_ruid = ruid; 236718c8510SRobert Watson ARG_SET_VALID(ar, ARG_RUID); 237718c8510SRobert Watson } 238718c8510SRobert Watson 239718c8510SRobert Watson void 240718c8510SRobert Watson audit_arg_sgid(gid_t sgid) 241718c8510SRobert Watson { 242718c8510SRobert Watson struct kaudit_record *ar; 243718c8510SRobert Watson 244718c8510SRobert Watson ar = currecord(); 245718c8510SRobert Watson if (ar == NULL) 246718c8510SRobert Watson return; 247718c8510SRobert Watson 248718c8510SRobert Watson ar->k_ar.ar_arg_sgid = sgid; 249718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SGID); 250718c8510SRobert Watson } 251718c8510SRobert Watson 252718c8510SRobert Watson void 253718c8510SRobert Watson audit_arg_suid(uid_t suid) 254718c8510SRobert Watson { 255718c8510SRobert Watson struct kaudit_record *ar; 256718c8510SRobert Watson 257718c8510SRobert Watson ar = currecord(); 258718c8510SRobert Watson if (ar == NULL) 259718c8510SRobert Watson return; 260718c8510SRobert Watson 261718c8510SRobert Watson ar->k_ar.ar_arg_suid = suid; 262718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SUID); 263718c8510SRobert Watson } 264718c8510SRobert Watson 265718c8510SRobert Watson void 266*abd39811SOlivier Certner audit_arg_groupset(gid_t *gidset, int gidset_size) 267718c8510SRobert Watson { 268*abd39811SOlivier Certner int i; 269718c8510SRobert Watson struct kaudit_record *ar; 270718c8510SRobert Watson 271*abd39811SOlivier Certner KASSERT(gidset_size >= 0 && gidset_size <= ngroups_max + 1, 272*abd39811SOlivier Certner ("audit_arg_groupset: gidset_size < 0 or > (kern.ngroups + 1)")); 27386120afaSStacey Son 274718c8510SRobert Watson ar = currecord(); 275718c8510SRobert Watson if (ar == NULL) 276718c8510SRobert Watson return; 277718c8510SRobert Watson 27886120afaSStacey Son if (ar->k_ar.ar_arg_groups.gidset == NULL) 27986120afaSStacey Son ar->k_ar.ar_arg_groups.gidset = malloc( 28086120afaSStacey Son sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK); 28186120afaSStacey Son 282718c8510SRobert Watson for (i = 0; i < gidset_size; i++) 283718c8510SRobert Watson ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 284718c8510SRobert Watson ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 285718c8510SRobert Watson ARG_SET_VALID(ar, ARG_GROUPSET); 286718c8510SRobert Watson } 287718c8510SRobert Watson 288718c8510SRobert Watson void 289718c8510SRobert Watson audit_arg_login(char *login) 290718c8510SRobert Watson { 291718c8510SRobert Watson struct kaudit_record *ar; 292718c8510SRobert Watson 293718c8510SRobert Watson ar = currecord(); 294718c8510SRobert Watson if (ar == NULL) 295718c8510SRobert Watson return; 296718c8510SRobert Watson 297718c8510SRobert Watson strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 298718c8510SRobert Watson ARG_SET_VALID(ar, ARG_LOGIN); 299718c8510SRobert Watson } 300718c8510SRobert Watson 301718c8510SRobert Watson void 302718c8510SRobert Watson audit_arg_ctlname(int *name, int namelen) 303718c8510SRobert Watson { 304718c8510SRobert Watson struct kaudit_record *ar; 305718c8510SRobert Watson 306718c8510SRobert Watson ar = currecord(); 307718c8510SRobert Watson if (ar == NULL) 308718c8510SRobert Watson return; 309718c8510SRobert Watson 310718c8510SRobert Watson bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 311718c8510SRobert Watson ar->k_ar.ar_arg_len = namelen; 312718c8510SRobert Watson ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 313718c8510SRobert Watson } 314718c8510SRobert Watson 315718c8510SRobert Watson void 316718c8510SRobert Watson audit_arg_mask(int mask) 317718c8510SRobert Watson { 318718c8510SRobert Watson struct kaudit_record *ar; 319718c8510SRobert Watson 320718c8510SRobert Watson ar = currecord(); 321718c8510SRobert Watson if (ar == NULL) 322718c8510SRobert Watson return; 323718c8510SRobert Watson 324718c8510SRobert Watson ar->k_ar.ar_arg_mask = mask; 325718c8510SRobert Watson ARG_SET_VALID(ar, ARG_MASK); 326718c8510SRobert Watson } 327718c8510SRobert Watson 328718c8510SRobert Watson void 329718c8510SRobert Watson audit_arg_mode(mode_t mode) 330718c8510SRobert Watson { 331718c8510SRobert Watson struct kaudit_record *ar; 332718c8510SRobert Watson 333718c8510SRobert Watson ar = currecord(); 334718c8510SRobert Watson if (ar == NULL) 335718c8510SRobert Watson return; 336718c8510SRobert Watson 337718c8510SRobert Watson ar->k_ar.ar_arg_mode = mode; 338718c8510SRobert Watson ARG_SET_VALID(ar, ARG_MODE); 339718c8510SRobert Watson } 340718c8510SRobert Watson 341718c8510SRobert Watson void 342718c8510SRobert Watson audit_arg_dev(int dev) 343718c8510SRobert Watson { 344718c8510SRobert Watson struct kaudit_record *ar; 345718c8510SRobert Watson 346718c8510SRobert Watson ar = currecord(); 347718c8510SRobert Watson if (ar == NULL) 348718c8510SRobert Watson return; 349718c8510SRobert Watson 350718c8510SRobert Watson ar->k_ar.ar_arg_dev = dev; 351718c8510SRobert Watson ARG_SET_VALID(ar, ARG_DEV); 352718c8510SRobert Watson } 353718c8510SRobert Watson 354718c8510SRobert Watson void 355718c8510SRobert Watson audit_arg_value(long value) 356718c8510SRobert Watson { 357718c8510SRobert Watson struct kaudit_record *ar; 358718c8510SRobert Watson 359718c8510SRobert Watson ar = currecord(); 360718c8510SRobert Watson if (ar == NULL) 361718c8510SRobert Watson return; 362718c8510SRobert Watson 363718c8510SRobert Watson ar->k_ar.ar_arg_value = value; 364718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VALUE); 365718c8510SRobert Watson } 366718c8510SRobert Watson 367718c8510SRobert Watson void 368718c8510SRobert Watson audit_arg_owner(uid_t uid, gid_t gid) 369718c8510SRobert Watson { 370718c8510SRobert Watson struct kaudit_record *ar; 371718c8510SRobert Watson 372718c8510SRobert Watson ar = currecord(); 373718c8510SRobert Watson if (ar == NULL) 374718c8510SRobert Watson return; 375718c8510SRobert Watson 376718c8510SRobert Watson ar->k_ar.ar_arg_uid = uid; 377718c8510SRobert Watson ar->k_ar.ar_arg_gid = gid; 378718c8510SRobert Watson ARG_SET_VALID(ar, ARG_UID | ARG_GID); 379718c8510SRobert Watson } 380718c8510SRobert Watson 381718c8510SRobert Watson void 382718c8510SRobert Watson audit_arg_pid(pid_t pid) 383718c8510SRobert Watson { 384718c8510SRobert Watson struct kaudit_record *ar; 385718c8510SRobert Watson 386718c8510SRobert Watson ar = currecord(); 387718c8510SRobert Watson if (ar == NULL) 388718c8510SRobert Watson return; 389718c8510SRobert Watson 390718c8510SRobert Watson ar->k_ar.ar_arg_pid = pid; 391718c8510SRobert Watson ARG_SET_VALID(ar, ARG_PID); 392718c8510SRobert Watson } 393718c8510SRobert Watson 394718c8510SRobert Watson void 395718c8510SRobert Watson audit_arg_process(struct proc *p) 396718c8510SRobert Watson { 397718c8510SRobert Watson struct kaudit_record *ar; 398e6870c95SRobert Watson struct ucred *cred; 399718c8510SRobert Watson 400814fe9e9SRobert Watson KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 401814fe9e9SRobert Watson 402814fe9e9SRobert Watson PROC_LOCK_ASSERT(p, MA_OWNED); 403814fe9e9SRobert Watson 404718c8510SRobert Watson ar = currecord(); 405814fe9e9SRobert Watson if (ar == NULL) 406718c8510SRobert Watson return; 407718c8510SRobert Watson 408e6870c95SRobert Watson cred = p->p_ucred; 409e6870c95SRobert Watson ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; 410e6870c95SRobert Watson ar->k_ar.ar_arg_euid = cred->cr_uid; 411e6870c95SRobert Watson ar->k_ar.ar_arg_egid = cred->cr_groups[0]; 412e6870c95SRobert Watson ar->k_ar.ar_arg_ruid = cred->cr_ruid; 413e6870c95SRobert Watson ar->k_ar.ar_arg_rgid = cred->cr_rgid; 414e6870c95SRobert Watson ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; 415e6870c95SRobert Watson ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; 4165619113cSRobert Watson ar->k_ar.ar_arg_pid = p->p_pid; 417718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 418f0cbfcc4SChristian S.J. Peron ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 419718c8510SRobert Watson } 420718c8510SRobert Watson 421718c8510SRobert Watson void 422718c8510SRobert Watson audit_arg_signum(u_int signum) 423718c8510SRobert Watson { 424718c8510SRobert Watson struct kaudit_record *ar; 425718c8510SRobert Watson 426718c8510SRobert Watson ar = currecord(); 427718c8510SRobert Watson if (ar == NULL) 428718c8510SRobert Watson return; 429718c8510SRobert Watson 430718c8510SRobert Watson ar->k_ar.ar_arg_signum = signum; 431718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SIGNUM); 432718c8510SRobert Watson } 433718c8510SRobert Watson 434718c8510SRobert Watson void 435718c8510SRobert Watson audit_arg_socket(int sodomain, int sotype, int soprotocol) 436718c8510SRobert Watson { 437718c8510SRobert Watson struct kaudit_record *ar; 438718c8510SRobert Watson 439718c8510SRobert Watson ar = currecord(); 440718c8510SRobert Watson if (ar == NULL) 441718c8510SRobert Watson return; 442718c8510SRobert Watson 443718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 444718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_type = sotype; 445718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 446718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SOCKINFO); 447718c8510SRobert Watson } 448718c8510SRobert Watson 449718c8510SRobert Watson void 4507493f24eSPawel Jakub Dawidek audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa) 451718c8510SRobert Watson { 452718c8510SRobert Watson struct kaudit_record *ar; 453718c8510SRobert Watson 454814fe9e9SRobert Watson KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL")); 455814fe9e9SRobert Watson KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 456814fe9e9SRobert Watson 457718c8510SRobert Watson ar = currecord(); 458814fe9e9SRobert Watson if (ar == NULL) 459718c8510SRobert Watson return; 460718c8510SRobert Watson 461130b1468SChristian S.J. Peron bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 462814fe9e9SRobert Watson switch (sa->sa_family) { 463718c8510SRobert Watson case AF_INET: 464718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRINET); 465718c8510SRobert Watson break; 466718c8510SRobert Watson 467718c8510SRobert Watson case AF_INET6: 468718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRINET6); 469718c8510SRobert Watson break; 470718c8510SRobert Watson 471718c8510SRobert Watson case AF_UNIX: 4727493f24eSPawel Jakub Dawidek if (dirfd != AT_FDCWD) 4737493f24eSPawel Jakub Dawidek audit_arg_atfd1(dirfd); 4747493f24eSPawel Jakub Dawidek audit_arg_upath1(td, dirfd, 475499f0f4dSPawel Jakub Dawidek ((struct sockaddr_un *)sa)->sun_path); 476718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRUNIX); 477718c8510SRobert Watson break; 478718c8510SRobert Watson /* XXXAUDIT: default:? */ 479718c8510SRobert Watson } 480718c8510SRobert Watson } 481718c8510SRobert Watson 482718c8510SRobert Watson void 483718c8510SRobert Watson audit_arg_auid(uid_t auid) 484718c8510SRobert Watson { 485718c8510SRobert Watson struct kaudit_record *ar; 486718c8510SRobert Watson 487718c8510SRobert Watson ar = currecord(); 488718c8510SRobert Watson if (ar == NULL) 489718c8510SRobert Watson return; 490718c8510SRobert Watson 491718c8510SRobert Watson ar->k_ar.ar_arg_auid = auid; 492718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID); 493718c8510SRobert Watson } 494718c8510SRobert Watson 495718c8510SRobert Watson void 496718c8510SRobert Watson audit_arg_auditinfo(struct auditinfo *au_info) 497718c8510SRobert Watson { 498718c8510SRobert Watson struct kaudit_record *ar; 499718c8510SRobert Watson 500718c8510SRobert Watson ar = currecord(); 501718c8510SRobert Watson if (ar == NULL) 502718c8510SRobert Watson return; 503718c8510SRobert Watson 504718c8510SRobert Watson ar->k_ar.ar_arg_auid = au_info->ai_auid; 505718c8510SRobert Watson ar->k_ar.ar_arg_asid = au_info->ai_asid; 506718c8510SRobert Watson ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 507718c8510SRobert Watson ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 508718c8510SRobert Watson ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 509718c8510SRobert Watson ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 510718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 511718c8510SRobert Watson } 512718c8510SRobert Watson 513718c8510SRobert Watson void 514cac465aaSChristian S.J. Peron audit_arg_auditinfo_addr(struct auditinfo_addr *au_info) 515cac465aaSChristian S.J. Peron { 516cac465aaSChristian S.J. Peron struct kaudit_record *ar; 517cac465aaSChristian S.J. Peron 518cac465aaSChristian S.J. Peron ar = currecord(); 519cac465aaSChristian S.J. Peron if (ar == NULL) 520cac465aaSChristian S.J. Peron return; 521cac465aaSChristian S.J. Peron 522cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_auid = au_info->ai_auid; 523cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_asid = au_info->ai_asid; 524cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 525cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 526cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; 527cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; 528cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; 529cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; 530cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; 531cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; 532cac465aaSChristian S.J. Peron ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); 533cac465aaSChristian S.J. Peron } 534cac465aaSChristian S.J. Peron 535cac465aaSChristian S.J. Peron void 53612e69f96SBrooks Davis audit_arg_text(const char *text) 537718c8510SRobert Watson { 538718c8510SRobert Watson struct kaudit_record *ar; 539718c8510SRobert Watson 540814fe9e9SRobert Watson KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 541814fe9e9SRobert Watson 542718c8510SRobert Watson ar = currecord(); 543718c8510SRobert Watson if (ar == NULL) 544718c8510SRobert Watson return; 545718c8510SRobert Watson 546718c8510SRobert Watson /* Invalidate the text string */ 547718c8510SRobert Watson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 548718c8510SRobert Watson 549718c8510SRobert Watson if (ar->k_ar.ar_arg_text == NULL) 550718c8510SRobert Watson ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 551718c8510SRobert Watson M_WAITOK); 552718c8510SRobert Watson 553718c8510SRobert Watson strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 554718c8510SRobert Watson ARG_SET_VALID(ar, ARG_TEXT); 555718c8510SRobert Watson } 556718c8510SRobert Watson 557718c8510SRobert Watson void 558718c8510SRobert Watson audit_arg_cmd(int cmd) 559718c8510SRobert Watson { 560718c8510SRobert Watson struct kaudit_record *ar; 561718c8510SRobert Watson 562718c8510SRobert Watson ar = currecord(); 563718c8510SRobert Watson if (ar == NULL) 564718c8510SRobert Watson return; 565718c8510SRobert Watson 566718c8510SRobert Watson ar->k_ar.ar_arg_cmd = cmd; 567718c8510SRobert Watson ARG_SET_VALID(ar, ARG_CMD); 568718c8510SRobert Watson } 569718c8510SRobert Watson 570718c8510SRobert Watson void 571718c8510SRobert Watson audit_arg_svipc_cmd(int cmd) 572718c8510SRobert Watson { 573718c8510SRobert Watson struct kaudit_record *ar; 574718c8510SRobert Watson 575718c8510SRobert Watson ar = currecord(); 576718c8510SRobert Watson if (ar == NULL) 577718c8510SRobert Watson return; 578718c8510SRobert Watson 579718c8510SRobert Watson ar->k_ar.ar_arg_svipc_cmd = cmd; 580718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_CMD); 581718c8510SRobert Watson } 582718c8510SRobert Watson 583718c8510SRobert Watson void 584718c8510SRobert Watson audit_arg_svipc_perm(struct ipc_perm *perm) 585718c8510SRobert Watson { 586718c8510SRobert Watson struct kaudit_record *ar; 587718c8510SRobert Watson 588718c8510SRobert Watson ar = currecord(); 589718c8510SRobert Watson if (ar == NULL) 590718c8510SRobert Watson return; 591718c8510SRobert Watson 592718c8510SRobert Watson bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 593718c8510SRobert Watson sizeof(ar->k_ar.ar_arg_svipc_perm)); 594718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_PERM); 595718c8510SRobert Watson } 596718c8510SRobert Watson 597718c8510SRobert Watson void 598718c8510SRobert Watson audit_arg_svipc_id(int id) 599718c8510SRobert Watson { 600718c8510SRobert Watson struct kaudit_record *ar; 601718c8510SRobert Watson 602718c8510SRobert Watson ar = currecord(); 603718c8510SRobert Watson if (ar == NULL) 604718c8510SRobert Watson return; 605718c8510SRobert Watson 606718c8510SRobert Watson ar->k_ar.ar_arg_svipc_id = id; 607718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_ID); 608718c8510SRobert Watson } 609718c8510SRobert Watson 610718c8510SRobert Watson void 611718c8510SRobert Watson audit_arg_svipc_addr(void * addr) 612718c8510SRobert Watson { 613718c8510SRobert Watson struct kaudit_record *ar; 614718c8510SRobert Watson 615718c8510SRobert Watson ar = currecord(); 616718c8510SRobert Watson if (ar == NULL) 617718c8510SRobert Watson return; 618718c8510SRobert Watson 619718c8510SRobert Watson ar->k_ar.ar_arg_svipc_addr = addr; 620718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 621718c8510SRobert Watson } 622718c8510SRobert Watson 623718c8510SRobert Watson void 624b7830259SRobert Watson audit_arg_svipc_which(int which) 625b7830259SRobert Watson { 626b7830259SRobert Watson struct kaudit_record *ar; 627b7830259SRobert Watson 628b7830259SRobert Watson ar = currecord(); 629b7830259SRobert Watson if (ar == NULL) 630b7830259SRobert Watson return; 631b7830259SRobert Watson 632b7830259SRobert Watson ar->k_ar.ar_arg_svipc_which = which; 633b7830259SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_WHICH); 634b7830259SRobert Watson } 635b7830259SRobert Watson 636b7830259SRobert Watson void 637718c8510SRobert Watson audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 638718c8510SRobert Watson { 639718c8510SRobert Watson struct kaudit_record *ar; 640718c8510SRobert Watson 641718c8510SRobert Watson ar = currecord(); 642718c8510SRobert Watson if (ar == NULL) 643718c8510SRobert Watson return; 644718c8510SRobert Watson 645718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 646718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 647718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 648718c8510SRobert Watson ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 649718c8510SRobert Watson } 650718c8510SRobert Watson 651718c8510SRobert Watson void 652718c8510SRobert Watson audit_arg_auditon(union auditon_udata *udata) 653718c8510SRobert Watson { 654718c8510SRobert Watson struct kaudit_record *ar; 655718c8510SRobert Watson 656718c8510SRobert Watson ar = currecord(); 657718c8510SRobert Watson if (ar == NULL) 658718c8510SRobert Watson return; 659718c8510SRobert Watson 660718c8510SRobert Watson bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 661718c8510SRobert Watson sizeof(ar->k_ar.ar_arg_auditon)); 662718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUDITON); 663718c8510SRobert Watson } 664718c8510SRobert Watson 665718c8510SRobert Watson /* 666718c8510SRobert Watson * Audit information about a file, either the file's vnode info, or its 667718c8510SRobert Watson * socket address info. 668718c8510SRobert Watson */ 669718c8510SRobert Watson void 670718c8510SRobert Watson audit_arg_file(struct proc *p, struct file *fp) 671718c8510SRobert Watson { 672718c8510SRobert Watson struct kaudit_record *ar; 673718c8510SRobert Watson struct socket *so; 674718c8510SRobert Watson struct inpcb *pcb; 675718c8510SRobert Watson struct vnode *vp; 676718c8510SRobert Watson 677814fe9e9SRobert Watson ar = currecord(); 678814fe9e9SRobert Watson if (ar == NULL) 679814fe9e9SRobert Watson return; 680814fe9e9SRobert Watson 681718c8510SRobert Watson switch (fp->f_type) { 682718c8510SRobert Watson case DTYPE_VNODE: 683718c8510SRobert Watson case DTYPE_FIFO: 684718c8510SRobert Watson /* 685718c8510SRobert Watson * XXXAUDIT: Only possibly to record as first vnode? 686718c8510SRobert Watson */ 687718c8510SRobert Watson vp = fp->f_vnode; 688927edcc9SJohn Baldwin vn_lock(vp, LK_SHARED | LK_RETRY); 689b146fc1bSRobert Watson audit_arg_vnode1(vp); 690b249ce48SMateusz Guzik VOP_UNLOCK(vp); 691718c8510SRobert Watson break; 692718c8510SRobert Watson 693718c8510SRobert Watson case DTYPE_SOCKET: 694718c8510SRobert Watson so = (struct socket *)fp->f_data; 695718c8510SRobert Watson if (INP_CHECK_SOCKAF(so, PF_INET)) { 696a1f3b839SRobert Watson SOCK_LOCK(so); 697718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_type = 698718c8510SRobert Watson so->so_type; 699718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_domain = 700718c8510SRobert Watson INP_SOCKAF(so); 701718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_protocol = 702718c8510SRobert Watson so->so_proto->pr_protocol; 703a1f3b839SRobert Watson SOCK_UNLOCK(so); 704718c8510SRobert Watson pcb = (struct inpcb *)so->so_pcb; 7051a46aa80SRobert Watson INP_RLOCK(pcb); 706718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_raddr = 707718c8510SRobert Watson pcb->inp_faddr.s_addr; 708718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_laddr = 709718c8510SRobert Watson pcb->inp_laddr.s_addr; 710718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_rport = 711718c8510SRobert Watson pcb->inp_fport; 712718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_lport = 713718c8510SRobert Watson pcb->inp_lport; 7141a46aa80SRobert Watson INP_RUNLOCK(pcb); 715718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SOCKINFO); 716718c8510SRobert Watson } 717718c8510SRobert Watson break; 718718c8510SRobert Watson 719718c8510SRobert Watson default: 720718c8510SRobert Watson /* XXXAUDIT: else? */ 721718c8510SRobert Watson break; 722718c8510SRobert Watson } 723718c8510SRobert Watson } 724718c8510SRobert Watson 725718c8510SRobert Watson /* 726718c8510SRobert Watson * Store a path as given by the user process for auditing into the audit 727871499feSRobert Watson * record stored on the user thread. This function will allocate the memory 728c2f027ffSRobert Watson * to store the path info if not already available. This memory will be 729d422682fSRobert Watson * freed when the audit record is freed. The path is canonlicalised with 730d422682fSRobert Watson * respect to the thread and directory descriptor passed. 731718c8510SRobert Watson */ 732791b0ad2SRobert Watson static void 733499f0f4dSPawel Jakub Dawidek audit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp) 734791b0ad2SRobert Watson { 735791b0ad2SRobert Watson 736791b0ad2SRobert Watson if (*pathp == NULL) 737791b0ad2SRobert Watson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 738499f0f4dSPawel Jakub Dawidek audit_canon_path(td, dirfd, upath, *pathp); 739791b0ad2SRobert Watson } 740791b0ad2SRobert Watson 741718c8510SRobert Watson void 742499f0f4dSPawel Jakub Dawidek audit_arg_upath1(struct thread *td, int dirfd, char *upath) 743718c8510SRobert Watson { 744718c8510SRobert Watson struct kaudit_record *ar; 745814fe9e9SRobert Watson 746814fe9e9SRobert Watson ar = currecord(); 747814fe9e9SRobert Watson if (ar == NULL) 748814fe9e9SRobert Watson return; 749718c8510SRobert Watson 750499f0f4dSPawel Jakub Dawidek audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1); 751791b0ad2SRobert Watson ARG_SET_VALID(ar, ARG_UPATH1); 752791b0ad2SRobert Watson } 753718c8510SRobert Watson 754791b0ad2SRobert Watson void 755499f0f4dSPawel Jakub Dawidek audit_arg_upath2(struct thread *td, int dirfd, char *upath) 756791b0ad2SRobert Watson { 757791b0ad2SRobert Watson struct kaudit_record *ar; 758718c8510SRobert Watson 759791b0ad2SRobert Watson ar = currecord(); 760791b0ad2SRobert Watson if (ar == NULL) 761791b0ad2SRobert Watson return; 762718c8510SRobert Watson 763499f0f4dSPawel Jakub Dawidek audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2); 764791b0ad2SRobert Watson ARG_SET_VALID(ar, ARG_UPATH2); 765718c8510SRobert Watson } 766718c8510SRobert Watson 7677de6c5ebSMateusz Guzik static void 7687de6c5ebSMateusz Guzik audit_arg_upath_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7697de6c5ebSMateusz Guzik char *upath, char **pathp) 7707de6c5ebSMateusz Guzik { 7717de6c5ebSMateusz Guzik 7727de6c5ebSMateusz Guzik if (*pathp == NULL) 7737de6c5ebSMateusz Guzik *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 7747de6c5ebSMateusz Guzik audit_canon_path_vp(td, rdir, cdir, upath, *pathp); 7757de6c5ebSMateusz Guzik } 7767de6c5ebSMateusz Guzik 7777de6c5ebSMateusz Guzik void 7787de6c5ebSMateusz Guzik audit_arg_upath1_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7797de6c5ebSMateusz Guzik char *upath) 7807de6c5ebSMateusz Guzik { 7817de6c5ebSMateusz Guzik struct kaudit_record *ar; 7827de6c5ebSMateusz Guzik 7837de6c5ebSMateusz Guzik ar = currecord(); 7847de6c5ebSMateusz Guzik if (ar == NULL) 7857de6c5ebSMateusz Guzik return; 7867de6c5ebSMateusz Guzik 7877de6c5ebSMateusz Guzik audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath1); 7887de6c5ebSMateusz Guzik ARG_SET_VALID(ar, ARG_UPATH1); 7897de6c5ebSMateusz Guzik } 7907de6c5ebSMateusz Guzik 7917de6c5ebSMateusz Guzik void 7927de6c5ebSMateusz Guzik audit_arg_upath2_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7937de6c5ebSMateusz Guzik char *upath) 7947de6c5ebSMateusz Guzik { 7957de6c5ebSMateusz Guzik struct kaudit_record *ar; 7967de6c5ebSMateusz Guzik 7977de6c5ebSMateusz Guzik ar = currecord(); 7987de6c5ebSMateusz Guzik if (ar == NULL) 7997de6c5ebSMateusz Guzik return; 8007de6c5ebSMateusz Guzik 8017de6c5ebSMateusz Guzik audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath2); 8027de6c5ebSMateusz Guzik ARG_SET_VALID(ar, ARG_UPATH2); 8037de6c5ebSMateusz Guzik } 8047de6c5ebSMateusz Guzik 805718c8510SRobert Watson /* 80615bcf785SRobert Watson * Variants on path auditing that do not canonicalise the path passed in; 80715bcf785SRobert Watson * these are for use with filesystem-like subsystems that employ string names, 80815bcf785SRobert Watson * but do not support a hierarchical namespace -- for example, POSIX IPC 80915bcf785SRobert Watson * objects. The subsystem should have performed any necessary 81015bcf785SRobert Watson * canonicalisation required to make the paths useful to audit analysis. 81115bcf785SRobert Watson */ 81215bcf785SRobert Watson static void 81315bcf785SRobert Watson audit_arg_upath_canon(char *upath, char **pathp) 81415bcf785SRobert Watson { 81515bcf785SRobert Watson 81615bcf785SRobert Watson if (*pathp == NULL) 81715bcf785SRobert Watson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 81815bcf785SRobert Watson (void)snprintf(*pathp, MAXPATHLEN, "%s", upath); 81915bcf785SRobert Watson } 82015bcf785SRobert Watson 82115bcf785SRobert Watson void 82215bcf785SRobert Watson audit_arg_upath1_canon(char *upath) 82315bcf785SRobert Watson { 82415bcf785SRobert Watson struct kaudit_record *ar; 82515bcf785SRobert Watson 82615bcf785SRobert Watson ar = currecord(); 82715bcf785SRobert Watson if (ar == NULL) 82815bcf785SRobert Watson return; 82915bcf785SRobert Watson 83015bcf785SRobert Watson audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath1); 83115bcf785SRobert Watson ARG_SET_VALID(ar, ARG_UPATH1); 83215bcf785SRobert Watson } 83315bcf785SRobert Watson 83415bcf785SRobert Watson void 83515bcf785SRobert Watson audit_arg_upath2_canon(char *upath) 83615bcf785SRobert Watson { 83715bcf785SRobert Watson struct kaudit_record *ar; 83815bcf785SRobert Watson 83915bcf785SRobert Watson ar = currecord(); 84015bcf785SRobert Watson if (ar == NULL) 84115bcf785SRobert Watson return; 84215bcf785SRobert Watson 84315bcf785SRobert Watson audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath2); 84415bcf785SRobert Watson ARG_SET_VALID(ar, ARG_UPATH2); 84515bcf785SRobert Watson } 84615bcf785SRobert Watson 84715bcf785SRobert Watson /* 848718c8510SRobert Watson * Function to save the path and vnode attr information into the audit 849718c8510SRobert Watson * record. 850718c8510SRobert Watson * 851718c8510SRobert Watson * It is assumed that the caller will hold any vnode locks necessary to 852718c8510SRobert Watson * perform a VOP_GETATTR() on the passed vnode. 853718c8510SRobert Watson * 85451ea7beaSMateusz Guzik * XXX: The attr code is very similar to vfs_default.c:vop_stdstat(), but always 855d8c0f4dcSRobert Watson * provides access to the generation number as we need that to construct the 856d8c0f4dcSRobert Watson * BSM file ID. 857d8c0f4dcSRobert Watson * 858d8c0f4dcSRobert Watson * XXX: We should accept the process argument from the caller, since it's 859d8c0f4dcSRobert Watson * very likely they already have a reference. 860d8c0f4dcSRobert Watson * 861718c8510SRobert Watson * XXX: Error handling in this function is poor. 862718c8510SRobert Watson * 863718c8510SRobert Watson * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 864718c8510SRobert Watson */ 865b146fc1bSRobert Watson static int 866b146fc1bSRobert Watson audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp) 867718c8510SRobert Watson { 868718c8510SRobert Watson struct vattr vattr; 869718c8510SRobert Watson int error; 870718c8510SRobert Watson 871718c8510SRobert Watson ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 872718c8510SRobert Watson 873ecd764b0SMark Johnston VATTR_NULL(&vattr); 8740359a12eSAttilio Rao error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 875718c8510SRobert Watson if (error) { 876718c8510SRobert Watson /* XXX: How to handle this case? */ 877b146fc1bSRobert Watson return (error); 878718c8510SRobert Watson } 879718c8510SRobert Watson 880718c8510SRobert Watson vnp->vn_mode = vattr.va_mode; 881718c8510SRobert Watson vnp->vn_uid = vattr.va_uid; 882718c8510SRobert Watson vnp->vn_gid = vattr.va_gid; 883718c8510SRobert Watson vnp->vn_dev = vattr.va_rdev; 884718c8510SRobert Watson vnp->vn_fsid = vattr.va_fsid; 885718c8510SRobert Watson vnp->vn_fileid = vattr.va_fileid; 886718c8510SRobert Watson vnp->vn_gen = vattr.va_gen; 887b146fc1bSRobert Watson return (0); 888b146fc1bSRobert Watson } 889b146fc1bSRobert Watson 890b146fc1bSRobert Watson void 891b146fc1bSRobert Watson audit_arg_vnode1(struct vnode *vp) 892b146fc1bSRobert Watson { 893b146fc1bSRobert Watson struct kaudit_record *ar; 894b146fc1bSRobert Watson int error; 895b146fc1bSRobert Watson 896b146fc1bSRobert Watson ar = currecord(); 897b146fc1bSRobert Watson if (ar == NULL) 898b146fc1bSRobert Watson return; 899b146fc1bSRobert Watson 900b146fc1bSRobert Watson ARG_CLEAR_VALID(ar, ARG_VNODE1); 901b146fc1bSRobert Watson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1); 902b146fc1bSRobert Watson if (error == 0) 903718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VNODE1); 904b146fc1bSRobert Watson } 905b146fc1bSRobert Watson 906b146fc1bSRobert Watson void 907b146fc1bSRobert Watson audit_arg_vnode2(struct vnode *vp) 908b146fc1bSRobert Watson { 909b146fc1bSRobert Watson struct kaudit_record *ar; 910b146fc1bSRobert Watson int error; 911b146fc1bSRobert Watson 912b146fc1bSRobert Watson ar = currecord(); 913b146fc1bSRobert Watson if (ar == NULL) 914b146fc1bSRobert Watson return; 915b146fc1bSRobert Watson 916b146fc1bSRobert Watson ARG_CLEAR_VALID(ar, ARG_VNODE2); 917b146fc1bSRobert Watson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2); 918b146fc1bSRobert Watson if (error == 0) 919718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VNODE2); 920718c8510SRobert Watson } 921718c8510SRobert Watson 922718c8510SRobert Watson /* 923ae1078d6SWayne Salamon * Audit the argument strings passed to exec. 924ae1078d6SWayne Salamon */ 925ae1078d6SWayne Salamon void 926ae1078d6SWayne Salamon audit_arg_argv(char *argv, int argc, int length) 927ae1078d6SWayne Salamon { 928ae1078d6SWayne Salamon struct kaudit_record *ar; 929ae1078d6SWayne Salamon 930ae1078d6SWayne Salamon if (audit_argv == 0) 931ae1078d6SWayne Salamon return; 932ae1078d6SWayne Salamon 933ae1078d6SWayne Salamon ar = currecord(); 934ae1078d6SWayne Salamon if (ar == NULL) 935ae1078d6SWayne Salamon return; 936ae1078d6SWayne Salamon 937ae1078d6SWayne Salamon ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 938ae1078d6SWayne Salamon bcopy(argv, ar->k_ar.ar_arg_argv, length); 939ae1078d6SWayne Salamon ar->k_ar.ar_arg_argc = argc; 940ae1078d6SWayne Salamon ARG_SET_VALID(ar, ARG_ARGV); 941ae1078d6SWayne Salamon } 942ae1078d6SWayne Salamon 943ae1078d6SWayne Salamon /* 944ae1078d6SWayne Salamon * Audit the environment strings passed to exec. 945ae1078d6SWayne Salamon */ 946ae1078d6SWayne Salamon void 947ae1078d6SWayne Salamon audit_arg_envv(char *envv, int envc, int length) 948ae1078d6SWayne Salamon { 949ae1078d6SWayne Salamon struct kaudit_record *ar; 950ae1078d6SWayne Salamon 951ae1078d6SWayne Salamon if (audit_arge == 0) 952ae1078d6SWayne Salamon return; 953ae1078d6SWayne Salamon 954ae1078d6SWayne Salamon ar = currecord(); 955ae1078d6SWayne Salamon if (ar == NULL) 956ae1078d6SWayne Salamon return; 957ae1078d6SWayne Salamon 958ae1078d6SWayne Salamon ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 959ae1078d6SWayne Salamon bcopy(envv, ar->k_ar.ar_arg_envv, length); 960ae1078d6SWayne Salamon ar->k_ar.ar_arg_envc = envc; 961ae1078d6SWayne Salamon ARG_SET_VALID(ar, ARG_ENVV); 962ae1078d6SWayne Salamon } 963ae1078d6SWayne Salamon 964778b0e42SJonathan Anderson void 9657008be5bSPawel Jakub Dawidek audit_arg_rights(cap_rights_t *rightsp) 966778b0e42SJonathan Anderson { 967778b0e42SJonathan Anderson struct kaudit_record *ar; 968778b0e42SJonathan Anderson 969778b0e42SJonathan Anderson ar = currecord(); 970778b0e42SJonathan Anderson if (ar == NULL) 971778b0e42SJonathan Anderson return; 972778b0e42SJonathan Anderson 9737008be5bSPawel Jakub Dawidek ar->k_ar.ar_arg_rights = *rightsp; 974778b0e42SJonathan Anderson ARG_SET_VALID(ar, ARG_RIGHTS); 975778b0e42SJonathan Anderson } 976778b0e42SJonathan Anderson 9772609222aSPawel Jakub Dawidek void 9782609222aSPawel Jakub Dawidek audit_arg_fcntl_rights(uint32_t fcntlrights) 9792609222aSPawel Jakub Dawidek { 9802609222aSPawel Jakub Dawidek struct kaudit_record *ar; 9812609222aSPawel Jakub Dawidek 9822609222aSPawel Jakub Dawidek ar = currecord(); 9832609222aSPawel Jakub Dawidek if (ar == NULL) 9842609222aSPawel Jakub Dawidek return; 9852609222aSPawel Jakub Dawidek 9862609222aSPawel Jakub Dawidek ar->k_ar.ar_arg_fcntl_rights = fcntlrights; 9872609222aSPawel Jakub Dawidek ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS); 9882609222aSPawel Jakub Dawidek } 9892609222aSPawel Jakub Dawidek 990ae1078d6SWayne Salamon /* 991871499feSRobert Watson * The close() system call uses it's own audit call to capture the path/vnode 992871499feSRobert Watson * information because those pieces are not easily obtained within the system 993871499feSRobert Watson * call itself. 994718c8510SRobert Watson */ 995718c8510SRobert Watson void 99608a5615cSMateusz Guzik audit_sysclose(struct thread *td, int fd, struct file *fp) 997718c8510SRobert Watson { 998814fe9e9SRobert Watson struct kaudit_record *ar; 999718c8510SRobert Watson struct vnode *vp; 1000718c8510SRobert Watson 1001814fe9e9SRobert Watson KASSERT(td != NULL, ("audit_sysclose: td == NULL")); 1002814fe9e9SRobert Watson 1003814fe9e9SRobert Watson ar = currecord(); 1004814fe9e9SRobert Watson if (ar == NULL) 1005814fe9e9SRobert Watson return; 1006814fe9e9SRobert Watson 1007718c8510SRobert Watson audit_arg_fd(fd); 1008718c8510SRobert Watson 1009718c8510SRobert Watson vp = fp->f_vnode; 101008a5615cSMateusz Guzik if (vp == NULL) 101108a5615cSMateusz Guzik return; 1012927edcc9SJohn Baldwin vn_lock(vp, LK_SHARED | LK_RETRY); 1013b146fc1bSRobert Watson audit_arg_vnode1(vp); 1014b249ce48SMateusz Guzik VOP_UNLOCK(vp); 1015718c8510SRobert Watson } 1016