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 38dda409d4SRobert Watson #include <sys/cdefs.h> 39dda409d4SRobert Watson __FBSDID("$FreeBSD$"); 40dda409d4SRobert Watson 41718c8510SRobert Watson #include <sys/param.h> 42718c8510SRobert Watson #include <sys/filedesc.h> 439ef8328dSMateusz Guzik #include <sys/capsicum.h> 44718c8510SRobert Watson #include <sys/ipc.h> 45718c8510SRobert Watson #include <sys/mount.h> 46718c8510SRobert Watson #include <sys/proc.h> 47718c8510SRobert Watson #include <sys/socket.h> 48718c8510SRobert Watson #include <sys/socketvar.h> 49718c8510SRobert Watson #include <sys/protosw.h> 50718c8510SRobert Watson #include <sys/domain.h> 515619113cSRobert Watson #include <sys/sbuf.h> 52718c8510SRobert Watson #include <sys/systm.h> 53718c8510SRobert Watson #include <sys/un.h> 54718c8510SRobert Watson #include <sys/vnode.h> 55718c8510SRobert Watson 56718c8510SRobert Watson #include <netinet/in.h> 57718c8510SRobert Watson #include <netinet/in_pcb.h> 58718c8510SRobert Watson 59718c8510SRobert Watson #include <security/audit/audit.h> 60718c8510SRobert Watson #include <security/audit/audit_private.h> 61718c8510SRobert Watson 62718c8510SRobert Watson /* 63718c8510SRobert Watson * Calls to manipulate elements of the audit record structure from system 64d8c0f4dcSRobert Watson * call code. Macro wrappers will prevent this functions from being entered 65d8c0f4dcSRobert Watson * if auditing is disabled, avoiding the function call cost. We check the 66d8c0f4dcSRobert Watson * thread audit record pointer anyway, as the audit condition could change, 67d8c0f4dcSRobert Watson * and pre-selection may not have allocated an audit record for this event. 68718c8510SRobert Watson * 69718c8510SRobert Watson * XXXAUDIT: Should we assert, in each case, that this field of the record 70718c8510SRobert Watson * hasn't already been filled in? 71718c8510SRobert Watson */ 72718c8510SRobert Watson void 73718c8510SRobert Watson audit_arg_addr(void *addr) 74718c8510SRobert Watson { 75718c8510SRobert Watson struct kaudit_record *ar; 76718c8510SRobert Watson 77718c8510SRobert Watson ar = currecord(); 78718c8510SRobert Watson if (ar == NULL) 79718c8510SRobert Watson return; 80718c8510SRobert Watson 81718c8510SRobert Watson ar->k_ar.ar_arg_addr = addr; 82718c8510SRobert Watson ARG_SET_VALID(ar, ARG_ADDR); 83718c8510SRobert Watson } 84718c8510SRobert Watson 85718c8510SRobert Watson void 86718c8510SRobert Watson audit_arg_exit(int status, int retval) 87718c8510SRobert Watson { 88718c8510SRobert Watson struct kaudit_record *ar; 89718c8510SRobert Watson 90718c8510SRobert Watson ar = currecord(); 91718c8510SRobert Watson if (ar == NULL) 92718c8510SRobert Watson return; 93718c8510SRobert Watson 94718c8510SRobert Watson ar->k_ar.ar_arg_exitstatus = status; 95718c8510SRobert Watson ar->k_ar.ar_arg_exitretval = retval; 96718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EXIT); 97718c8510SRobert Watson } 98718c8510SRobert Watson 99718c8510SRobert Watson void 100718c8510SRobert Watson audit_arg_len(int len) 101718c8510SRobert Watson { 102718c8510SRobert Watson struct kaudit_record *ar; 103718c8510SRobert Watson 104718c8510SRobert Watson ar = currecord(); 105718c8510SRobert Watson if (ar == NULL) 106718c8510SRobert Watson return; 107718c8510SRobert Watson 108718c8510SRobert Watson ar->k_ar.ar_arg_len = len; 109718c8510SRobert Watson ARG_SET_VALID(ar, ARG_LEN); 110718c8510SRobert Watson } 111718c8510SRobert Watson 112718c8510SRobert Watson void 113e4b4bbb6SRobert Watson audit_arg_atfd1(int atfd) 114e4b4bbb6SRobert Watson { 115e4b4bbb6SRobert Watson struct kaudit_record *ar; 116e4b4bbb6SRobert Watson 117e4b4bbb6SRobert Watson ar = currecord(); 118e4b4bbb6SRobert Watson if (ar == NULL) 119e4b4bbb6SRobert Watson return; 120e4b4bbb6SRobert Watson 121e4b4bbb6SRobert Watson ar->k_ar.ar_arg_atfd1 = atfd; 122e4b4bbb6SRobert Watson ARG_SET_VALID(ar, ARG_ATFD1); 123e4b4bbb6SRobert Watson } 124e4b4bbb6SRobert Watson 125e4b4bbb6SRobert Watson void 126e4b4bbb6SRobert Watson audit_arg_atfd2(int atfd) 127e4b4bbb6SRobert Watson { 128e4b4bbb6SRobert Watson struct kaudit_record *ar; 129e4b4bbb6SRobert Watson 130e4b4bbb6SRobert Watson ar = currecord(); 131e4b4bbb6SRobert Watson if (ar == NULL) 132e4b4bbb6SRobert Watson return; 133e4b4bbb6SRobert Watson 134e4b4bbb6SRobert Watson ar->k_ar.ar_arg_atfd2 = atfd; 135e4b4bbb6SRobert Watson ARG_SET_VALID(ar, ARG_ATFD2); 136e4b4bbb6SRobert Watson } 137e4b4bbb6SRobert Watson 138e4b4bbb6SRobert Watson void 139718c8510SRobert Watson audit_arg_fd(int fd) 140718c8510SRobert Watson { 141718c8510SRobert Watson struct kaudit_record *ar; 142718c8510SRobert Watson 143718c8510SRobert Watson ar = currecord(); 144718c8510SRobert Watson if (ar == NULL) 145718c8510SRobert Watson return; 146718c8510SRobert Watson 147718c8510SRobert Watson ar->k_ar.ar_arg_fd = fd; 148718c8510SRobert Watson ARG_SET_VALID(ar, ARG_FD); 149718c8510SRobert Watson } 150718c8510SRobert Watson 151718c8510SRobert Watson void 152718c8510SRobert Watson audit_arg_fflags(int fflags) 153718c8510SRobert Watson { 154718c8510SRobert Watson struct kaudit_record *ar; 155718c8510SRobert Watson 156718c8510SRobert Watson ar = currecord(); 157718c8510SRobert Watson if (ar == NULL) 158718c8510SRobert Watson return; 159718c8510SRobert Watson 160718c8510SRobert Watson ar->k_ar.ar_arg_fflags = fflags; 161718c8510SRobert Watson ARG_SET_VALID(ar, ARG_FFLAGS); 162718c8510SRobert Watson } 163718c8510SRobert Watson 164718c8510SRobert Watson void 165718c8510SRobert Watson audit_arg_gid(gid_t gid) 166718c8510SRobert Watson { 167718c8510SRobert Watson struct kaudit_record *ar; 168718c8510SRobert Watson 169718c8510SRobert Watson ar = currecord(); 170718c8510SRobert Watson if (ar == NULL) 171718c8510SRobert Watson return; 172718c8510SRobert Watson 173718c8510SRobert Watson ar->k_ar.ar_arg_gid = gid; 174718c8510SRobert Watson ARG_SET_VALID(ar, ARG_GID); 175718c8510SRobert Watson } 176718c8510SRobert Watson 177718c8510SRobert Watson void 178718c8510SRobert Watson audit_arg_uid(uid_t uid) 179718c8510SRobert Watson { 180718c8510SRobert Watson struct kaudit_record *ar; 181718c8510SRobert Watson 182718c8510SRobert Watson ar = currecord(); 183718c8510SRobert Watson if (ar == NULL) 184718c8510SRobert Watson return; 185718c8510SRobert Watson 186718c8510SRobert Watson ar->k_ar.ar_arg_uid = uid; 187718c8510SRobert Watson ARG_SET_VALID(ar, ARG_UID); 188718c8510SRobert Watson } 189718c8510SRobert Watson 190718c8510SRobert Watson void 191718c8510SRobert Watson audit_arg_egid(gid_t egid) 192718c8510SRobert Watson { 193718c8510SRobert Watson struct kaudit_record *ar; 194718c8510SRobert Watson 195718c8510SRobert Watson ar = currecord(); 196718c8510SRobert Watson if (ar == NULL) 197718c8510SRobert Watson return; 198718c8510SRobert Watson 199718c8510SRobert Watson ar->k_ar.ar_arg_egid = egid; 200718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EGID); 201718c8510SRobert Watson } 202718c8510SRobert Watson 203718c8510SRobert Watson void 204718c8510SRobert Watson audit_arg_euid(uid_t euid) 205718c8510SRobert Watson { 206718c8510SRobert Watson struct kaudit_record *ar; 207718c8510SRobert Watson 208718c8510SRobert Watson ar = currecord(); 209718c8510SRobert Watson if (ar == NULL) 210718c8510SRobert Watson return; 211718c8510SRobert Watson 212718c8510SRobert Watson ar->k_ar.ar_arg_euid = euid; 213718c8510SRobert Watson ARG_SET_VALID(ar, ARG_EUID); 214718c8510SRobert Watson } 215718c8510SRobert Watson 216718c8510SRobert Watson void 217718c8510SRobert Watson audit_arg_rgid(gid_t rgid) 218718c8510SRobert Watson { 219718c8510SRobert Watson struct kaudit_record *ar; 220718c8510SRobert Watson 221718c8510SRobert Watson ar = currecord(); 222718c8510SRobert Watson if (ar == NULL) 223718c8510SRobert Watson return; 224718c8510SRobert Watson 225718c8510SRobert Watson ar->k_ar.ar_arg_rgid = rgid; 226718c8510SRobert Watson ARG_SET_VALID(ar, ARG_RGID); 227718c8510SRobert Watson } 228718c8510SRobert Watson 229718c8510SRobert Watson void 230718c8510SRobert Watson audit_arg_ruid(uid_t ruid) 231718c8510SRobert Watson { 232718c8510SRobert Watson struct kaudit_record *ar; 233718c8510SRobert Watson 234718c8510SRobert Watson ar = currecord(); 235718c8510SRobert Watson if (ar == NULL) 236718c8510SRobert Watson return; 237718c8510SRobert Watson 238718c8510SRobert Watson ar->k_ar.ar_arg_ruid = ruid; 239718c8510SRobert Watson ARG_SET_VALID(ar, ARG_RUID); 240718c8510SRobert Watson } 241718c8510SRobert Watson 242718c8510SRobert Watson void 243718c8510SRobert Watson audit_arg_sgid(gid_t sgid) 244718c8510SRobert Watson { 245718c8510SRobert Watson struct kaudit_record *ar; 246718c8510SRobert Watson 247718c8510SRobert Watson ar = currecord(); 248718c8510SRobert Watson if (ar == NULL) 249718c8510SRobert Watson return; 250718c8510SRobert Watson 251718c8510SRobert Watson ar->k_ar.ar_arg_sgid = sgid; 252718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SGID); 253718c8510SRobert Watson } 254718c8510SRobert Watson 255718c8510SRobert Watson void 256718c8510SRobert Watson audit_arg_suid(uid_t suid) 257718c8510SRobert Watson { 258718c8510SRobert Watson struct kaudit_record *ar; 259718c8510SRobert Watson 260718c8510SRobert Watson ar = currecord(); 261718c8510SRobert Watson if (ar == NULL) 262718c8510SRobert Watson return; 263718c8510SRobert Watson 264718c8510SRobert Watson ar->k_ar.ar_arg_suid = suid; 265718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SUID); 266718c8510SRobert Watson } 267718c8510SRobert Watson 268718c8510SRobert Watson void 269718c8510SRobert Watson audit_arg_groupset(gid_t *gidset, u_int gidset_size) 270718c8510SRobert Watson { 27159b622e6SRobert Watson u_int i; 272718c8510SRobert Watson struct kaudit_record *ar; 273718c8510SRobert Watson 274412f9500SBrooks Davis KASSERT(gidset_size <= ngroups_max + 1, 275412f9500SBrooks Davis ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)")); 27686120afaSStacey Son 277718c8510SRobert Watson ar = currecord(); 278718c8510SRobert Watson if (ar == NULL) 279718c8510SRobert Watson return; 280718c8510SRobert Watson 28186120afaSStacey Son if (ar->k_ar.ar_arg_groups.gidset == NULL) 28286120afaSStacey Son ar->k_ar.ar_arg_groups.gidset = malloc( 28386120afaSStacey Son sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK); 28486120afaSStacey Son 285718c8510SRobert Watson for (i = 0; i < gidset_size; i++) 286718c8510SRobert Watson ar->k_ar.ar_arg_groups.gidset[i] = gidset[i]; 287718c8510SRobert Watson ar->k_ar.ar_arg_groups.gidset_size = gidset_size; 288718c8510SRobert Watson ARG_SET_VALID(ar, ARG_GROUPSET); 289718c8510SRobert Watson } 290718c8510SRobert Watson 291718c8510SRobert Watson void 292718c8510SRobert Watson audit_arg_login(char *login) 293718c8510SRobert Watson { 294718c8510SRobert Watson struct kaudit_record *ar; 295718c8510SRobert Watson 296718c8510SRobert Watson ar = currecord(); 297718c8510SRobert Watson if (ar == NULL) 298718c8510SRobert Watson return; 299718c8510SRobert Watson 300718c8510SRobert Watson strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME); 301718c8510SRobert Watson ARG_SET_VALID(ar, ARG_LOGIN); 302718c8510SRobert Watson } 303718c8510SRobert Watson 304718c8510SRobert Watson void 305718c8510SRobert Watson audit_arg_ctlname(int *name, int namelen) 306718c8510SRobert Watson { 307718c8510SRobert Watson struct kaudit_record *ar; 308718c8510SRobert Watson 309718c8510SRobert Watson ar = currecord(); 310718c8510SRobert Watson if (ar == NULL) 311718c8510SRobert Watson return; 312718c8510SRobert Watson 313718c8510SRobert Watson bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int)); 314718c8510SRobert Watson ar->k_ar.ar_arg_len = namelen; 315718c8510SRobert Watson ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN); 316718c8510SRobert Watson } 317718c8510SRobert Watson 318718c8510SRobert Watson void 319718c8510SRobert Watson audit_arg_mask(int mask) 320718c8510SRobert Watson { 321718c8510SRobert Watson struct kaudit_record *ar; 322718c8510SRobert Watson 323718c8510SRobert Watson ar = currecord(); 324718c8510SRobert Watson if (ar == NULL) 325718c8510SRobert Watson return; 326718c8510SRobert Watson 327718c8510SRobert Watson ar->k_ar.ar_arg_mask = mask; 328718c8510SRobert Watson ARG_SET_VALID(ar, ARG_MASK); 329718c8510SRobert Watson } 330718c8510SRobert Watson 331718c8510SRobert Watson void 332718c8510SRobert Watson audit_arg_mode(mode_t mode) 333718c8510SRobert Watson { 334718c8510SRobert Watson struct kaudit_record *ar; 335718c8510SRobert Watson 336718c8510SRobert Watson ar = currecord(); 337718c8510SRobert Watson if (ar == NULL) 338718c8510SRobert Watson return; 339718c8510SRobert Watson 340718c8510SRobert Watson ar->k_ar.ar_arg_mode = mode; 341718c8510SRobert Watson ARG_SET_VALID(ar, ARG_MODE); 342718c8510SRobert Watson } 343718c8510SRobert Watson 344718c8510SRobert Watson void 345718c8510SRobert Watson audit_arg_dev(int dev) 346718c8510SRobert Watson { 347718c8510SRobert Watson struct kaudit_record *ar; 348718c8510SRobert Watson 349718c8510SRobert Watson ar = currecord(); 350718c8510SRobert Watson if (ar == NULL) 351718c8510SRobert Watson return; 352718c8510SRobert Watson 353718c8510SRobert Watson ar->k_ar.ar_arg_dev = dev; 354718c8510SRobert Watson ARG_SET_VALID(ar, ARG_DEV); 355718c8510SRobert Watson } 356718c8510SRobert Watson 357718c8510SRobert Watson void 358718c8510SRobert Watson audit_arg_value(long value) 359718c8510SRobert Watson { 360718c8510SRobert Watson struct kaudit_record *ar; 361718c8510SRobert Watson 362718c8510SRobert Watson ar = currecord(); 363718c8510SRobert Watson if (ar == NULL) 364718c8510SRobert Watson return; 365718c8510SRobert Watson 366718c8510SRobert Watson ar->k_ar.ar_arg_value = value; 367718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VALUE); 368718c8510SRobert Watson } 369718c8510SRobert Watson 370718c8510SRobert Watson void 371718c8510SRobert Watson audit_arg_owner(uid_t uid, gid_t gid) 372718c8510SRobert Watson { 373718c8510SRobert Watson struct kaudit_record *ar; 374718c8510SRobert Watson 375718c8510SRobert Watson ar = currecord(); 376718c8510SRobert Watson if (ar == NULL) 377718c8510SRobert Watson return; 378718c8510SRobert Watson 379718c8510SRobert Watson ar->k_ar.ar_arg_uid = uid; 380718c8510SRobert Watson ar->k_ar.ar_arg_gid = gid; 381718c8510SRobert Watson ARG_SET_VALID(ar, ARG_UID | ARG_GID); 382718c8510SRobert Watson } 383718c8510SRobert Watson 384718c8510SRobert Watson void 385718c8510SRobert Watson audit_arg_pid(pid_t pid) 386718c8510SRobert Watson { 387718c8510SRobert Watson struct kaudit_record *ar; 388718c8510SRobert Watson 389718c8510SRobert Watson ar = currecord(); 390718c8510SRobert Watson if (ar == NULL) 391718c8510SRobert Watson return; 392718c8510SRobert Watson 393718c8510SRobert Watson ar->k_ar.ar_arg_pid = pid; 394718c8510SRobert Watson ARG_SET_VALID(ar, ARG_PID); 395718c8510SRobert Watson } 396718c8510SRobert Watson 397718c8510SRobert Watson void 398718c8510SRobert Watson audit_arg_process(struct proc *p) 399718c8510SRobert Watson { 400718c8510SRobert Watson struct kaudit_record *ar; 401e6870c95SRobert Watson struct ucred *cred; 402718c8510SRobert Watson 403814fe9e9SRobert Watson KASSERT(p != NULL, ("audit_arg_process: p == NULL")); 404814fe9e9SRobert Watson 405814fe9e9SRobert Watson PROC_LOCK_ASSERT(p, MA_OWNED); 406814fe9e9SRobert Watson 407718c8510SRobert Watson ar = currecord(); 408814fe9e9SRobert Watson if (ar == NULL) 409718c8510SRobert Watson return; 410718c8510SRobert Watson 411e6870c95SRobert Watson cred = p->p_ucred; 412e6870c95SRobert Watson ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid; 413e6870c95SRobert Watson ar->k_ar.ar_arg_euid = cred->cr_uid; 414e6870c95SRobert Watson ar->k_ar.ar_arg_egid = cred->cr_groups[0]; 415e6870c95SRobert Watson ar->k_ar.ar_arg_ruid = cred->cr_ruid; 416e6870c95SRobert Watson ar->k_ar.ar_arg_rgid = cred->cr_rgid; 417e6870c95SRobert Watson ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid; 418e6870c95SRobert Watson ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid; 4195619113cSRobert Watson ar->k_ar.ar_arg_pid = p->p_pid; 420718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID | 421f0cbfcc4SChristian S.J. Peron ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS); 422718c8510SRobert Watson } 423718c8510SRobert Watson 424718c8510SRobert Watson void 425718c8510SRobert Watson audit_arg_signum(u_int signum) 426718c8510SRobert Watson { 427718c8510SRobert Watson struct kaudit_record *ar; 428718c8510SRobert Watson 429718c8510SRobert Watson ar = currecord(); 430718c8510SRobert Watson if (ar == NULL) 431718c8510SRobert Watson return; 432718c8510SRobert Watson 433718c8510SRobert Watson ar->k_ar.ar_arg_signum = signum; 434718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SIGNUM); 435718c8510SRobert Watson } 436718c8510SRobert Watson 437718c8510SRobert Watson void 438718c8510SRobert Watson audit_arg_socket(int sodomain, int sotype, int soprotocol) 439718c8510SRobert Watson { 440718c8510SRobert Watson struct kaudit_record *ar; 441718c8510SRobert Watson 442718c8510SRobert Watson ar = currecord(); 443718c8510SRobert Watson if (ar == NULL) 444718c8510SRobert Watson return; 445718c8510SRobert Watson 446718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_domain = sodomain; 447718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_type = sotype; 448718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol; 449718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SOCKINFO); 450718c8510SRobert Watson } 451718c8510SRobert Watson 452718c8510SRobert Watson void 4537493f24eSPawel Jakub Dawidek audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa) 454718c8510SRobert Watson { 455718c8510SRobert Watson struct kaudit_record *ar; 456718c8510SRobert Watson 457814fe9e9SRobert Watson KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL")); 458814fe9e9SRobert Watson KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL")); 459814fe9e9SRobert Watson 460718c8510SRobert Watson ar = currecord(); 461814fe9e9SRobert Watson if (ar == NULL) 462718c8510SRobert Watson return; 463718c8510SRobert Watson 464130b1468SChristian S.J. Peron bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len); 465814fe9e9SRobert Watson switch (sa->sa_family) { 466718c8510SRobert Watson case AF_INET: 467718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRINET); 468718c8510SRobert Watson break; 469718c8510SRobert Watson 470718c8510SRobert Watson case AF_INET6: 471718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRINET6); 472718c8510SRobert Watson break; 473718c8510SRobert Watson 474718c8510SRobert Watson case AF_UNIX: 4757493f24eSPawel Jakub Dawidek if (dirfd != AT_FDCWD) 4767493f24eSPawel Jakub Dawidek audit_arg_atfd1(dirfd); 4777493f24eSPawel Jakub Dawidek audit_arg_upath1(td, dirfd, 478499f0f4dSPawel Jakub Dawidek ((struct sockaddr_un *)sa)->sun_path); 479718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SADDRUNIX); 480718c8510SRobert Watson break; 481718c8510SRobert Watson /* XXXAUDIT: default:? */ 482718c8510SRobert Watson } 483718c8510SRobert Watson } 484718c8510SRobert Watson 485718c8510SRobert Watson void 486718c8510SRobert Watson audit_arg_auid(uid_t auid) 487718c8510SRobert Watson { 488718c8510SRobert Watson struct kaudit_record *ar; 489718c8510SRobert Watson 490718c8510SRobert Watson ar = currecord(); 491718c8510SRobert Watson if (ar == NULL) 492718c8510SRobert Watson return; 493718c8510SRobert Watson 494718c8510SRobert Watson ar->k_ar.ar_arg_auid = auid; 495718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID); 496718c8510SRobert Watson } 497718c8510SRobert Watson 498718c8510SRobert Watson void 499718c8510SRobert Watson audit_arg_auditinfo(struct auditinfo *au_info) 500718c8510SRobert Watson { 501718c8510SRobert Watson struct kaudit_record *ar; 502718c8510SRobert Watson 503718c8510SRobert Watson ar = currecord(); 504718c8510SRobert Watson if (ar == NULL) 505718c8510SRobert Watson return; 506718c8510SRobert Watson 507718c8510SRobert Watson ar->k_ar.ar_arg_auid = au_info->ai_auid; 508718c8510SRobert Watson ar->k_ar.ar_arg_asid = au_info->ai_asid; 509718c8510SRobert Watson ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 510718c8510SRobert Watson ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 511718c8510SRobert Watson ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port; 512718c8510SRobert Watson ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine; 513718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID); 514718c8510SRobert Watson } 515718c8510SRobert Watson 516718c8510SRobert Watson void 517cac465aaSChristian S.J. Peron audit_arg_auditinfo_addr(struct auditinfo_addr *au_info) 518cac465aaSChristian S.J. Peron { 519cac465aaSChristian S.J. Peron struct kaudit_record *ar; 520cac465aaSChristian S.J. Peron 521cac465aaSChristian S.J. Peron ar = currecord(); 522cac465aaSChristian S.J. Peron if (ar == NULL) 523cac465aaSChristian S.J. Peron return; 524cac465aaSChristian S.J. Peron 525cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_auid = au_info->ai_auid; 526cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_asid = au_info->ai_asid; 527cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success; 528cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure; 529cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type; 530cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port; 531cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0]; 532cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1]; 533cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2]; 534cac465aaSChristian S.J. Peron ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3]; 535cac465aaSChristian S.J. Peron ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR); 536cac465aaSChristian S.J. Peron } 537cac465aaSChristian S.J. Peron 538cac465aaSChristian S.J. Peron void 53912e69f96SBrooks Davis audit_arg_text(const char *text) 540718c8510SRobert Watson { 541718c8510SRobert Watson struct kaudit_record *ar; 542718c8510SRobert Watson 543814fe9e9SRobert Watson KASSERT(text != NULL, ("audit_arg_text: text == NULL")); 544814fe9e9SRobert Watson 545718c8510SRobert Watson ar = currecord(); 546718c8510SRobert Watson if (ar == NULL) 547718c8510SRobert Watson return; 548718c8510SRobert Watson 549718c8510SRobert Watson /* Invalidate the text string */ 550718c8510SRobert Watson ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT); 551718c8510SRobert Watson 552718c8510SRobert Watson if (ar->k_ar.ar_arg_text == NULL) 553718c8510SRobert Watson ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT, 554718c8510SRobert Watson M_WAITOK); 555718c8510SRobert Watson 556718c8510SRobert Watson strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN); 557718c8510SRobert Watson ARG_SET_VALID(ar, ARG_TEXT); 558718c8510SRobert Watson } 559718c8510SRobert Watson 560718c8510SRobert Watson void 561718c8510SRobert Watson audit_arg_cmd(int cmd) 562718c8510SRobert Watson { 563718c8510SRobert Watson struct kaudit_record *ar; 564718c8510SRobert Watson 565718c8510SRobert Watson ar = currecord(); 566718c8510SRobert Watson if (ar == NULL) 567718c8510SRobert Watson return; 568718c8510SRobert Watson 569718c8510SRobert Watson ar->k_ar.ar_arg_cmd = cmd; 570718c8510SRobert Watson ARG_SET_VALID(ar, ARG_CMD); 571718c8510SRobert Watson } 572718c8510SRobert Watson 573718c8510SRobert Watson void 574718c8510SRobert Watson audit_arg_svipc_cmd(int cmd) 575718c8510SRobert Watson { 576718c8510SRobert Watson struct kaudit_record *ar; 577718c8510SRobert Watson 578718c8510SRobert Watson ar = currecord(); 579718c8510SRobert Watson if (ar == NULL) 580718c8510SRobert Watson return; 581718c8510SRobert Watson 582718c8510SRobert Watson ar->k_ar.ar_arg_svipc_cmd = cmd; 583718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_CMD); 584718c8510SRobert Watson } 585718c8510SRobert Watson 586718c8510SRobert Watson void 587718c8510SRobert Watson audit_arg_svipc_perm(struct ipc_perm *perm) 588718c8510SRobert Watson { 589718c8510SRobert Watson struct kaudit_record *ar; 590718c8510SRobert Watson 591718c8510SRobert Watson ar = currecord(); 592718c8510SRobert Watson if (ar == NULL) 593718c8510SRobert Watson return; 594718c8510SRobert Watson 595718c8510SRobert Watson bcopy(perm, &ar->k_ar.ar_arg_svipc_perm, 596718c8510SRobert Watson sizeof(ar->k_ar.ar_arg_svipc_perm)); 597718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_PERM); 598718c8510SRobert Watson } 599718c8510SRobert Watson 600718c8510SRobert Watson void 601718c8510SRobert Watson audit_arg_svipc_id(int id) 602718c8510SRobert Watson { 603718c8510SRobert Watson struct kaudit_record *ar; 604718c8510SRobert Watson 605718c8510SRobert Watson ar = currecord(); 606718c8510SRobert Watson if (ar == NULL) 607718c8510SRobert Watson return; 608718c8510SRobert Watson 609718c8510SRobert Watson ar->k_ar.ar_arg_svipc_id = id; 610718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_ID); 611718c8510SRobert Watson } 612718c8510SRobert Watson 613718c8510SRobert Watson void 614718c8510SRobert Watson audit_arg_svipc_addr(void * addr) 615718c8510SRobert Watson { 616718c8510SRobert Watson struct kaudit_record *ar; 617718c8510SRobert Watson 618718c8510SRobert Watson ar = currecord(); 619718c8510SRobert Watson if (ar == NULL) 620718c8510SRobert Watson return; 621718c8510SRobert Watson 622718c8510SRobert Watson ar->k_ar.ar_arg_svipc_addr = addr; 623718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_ADDR); 624718c8510SRobert Watson } 625718c8510SRobert Watson 626718c8510SRobert Watson void 627b7830259SRobert Watson audit_arg_svipc_which(int which) 628b7830259SRobert Watson { 629b7830259SRobert Watson struct kaudit_record *ar; 630b7830259SRobert Watson 631b7830259SRobert Watson ar = currecord(); 632b7830259SRobert Watson if (ar == NULL) 633b7830259SRobert Watson return; 634b7830259SRobert Watson 635b7830259SRobert Watson ar->k_ar.ar_arg_svipc_which = which; 636b7830259SRobert Watson ARG_SET_VALID(ar, ARG_SVIPC_WHICH); 637b7830259SRobert Watson } 638b7830259SRobert Watson 639b7830259SRobert Watson void 640718c8510SRobert Watson audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode) 641718c8510SRobert Watson { 642718c8510SRobert Watson struct kaudit_record *ar; 643718c8510SRobert Watson 644718c8510SRobert Watson ar = currecord(); 645718c8510SRobert Watson if (ar == NULL) 646718c8510SRobert Watson return; 647718c8510SRobert Watson 648718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid; 649718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid; 650718c8510SRobert Watson ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode; 651718c8510SRobert Watson ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM); 652718c8510SRobert Watson } 653718c8510SRobert Watson 654718c8510SRobert Watson void 655718c8510SRobert Watson audit_arg_auditon(union auditon_udata *udata) 656718c8510SRobert Watson { 657718c8510SRobert Watson struct kaudit_record *ar; 658718c8510SRobert Watson 659718c8510SRobert Watson ar = currecord(); 660718c8510SRobert Watson if (ar == NULL) 661718c8510SRobert Watson return; 662718c8510SRobert Watson 663718c8510SRobert Watson bcopy((void *)udata, &ar->k_ar.ar_arg_auditon, 664718c8510SRobert Watson sizeof(ar->k_ar.ar_arg_auditon)); 665718c8510SRobert Watson ARG_SET_VALID(ar, ARG_AUDITON); 666718c8510SRobert Watson } 667718c8510SRobert Watson 668718c8510SRobert Watson /* 669718c8510SRobert Watson * Audit information about a file, either the file's vnode info, or its 670718c8510SRobert Watson * socket address info. 671718c8510SRobert Watson */ 672718c8510SRobert Watson void 673718c8510SRobert Watson audit_arg_file(struct proc *p, struct file *fp) 674718c8510SRobert Watson { 675718c8510SRobert Watson struct kaudit_record *ar; 676718c8510SRobert Watson struct socket *so; 677718c8510SRobert Watson struct inpcb *pcb; 678718c8510SRobert Watson struct vnode *vp; 679718c8510SRobert Watson 680814fe9e9SRobert Watson ar = currecord(); 681814fe9e9SRobert Watson if (ar == NULL) 682814fe9e9SRobert Watson return; 683814fe9e9SRobert Watson 684718c8510SRobert Watson switch (fp->f_type) { 685718c8510SRobert Watson case DTYPE_VNODE: 686718c8510SRobert Watson case DTYPE_FIFO: 687718c8510SRobert Watson /* 688718c8510SRobert Watson * XXXAUDIT: Only possibly to record as first vnode? 689718c8510SRobert Watson */ 690718c8510SRobert Watson vp = fp->f_vnode; 691927edcc9SJohn Baldwin vn_lock(vp, LK_SHARED | LK_RETRY); 692b146fc1bSRobert Watson audit_arg_vnode1(vp); 693b249ce48SMateusz Guzik VOP_UNLOCK(vp); 694718c8510SRobert Watson break; 695718c8510SRobert Watson 696718c8510SRobert Watson case DTYPE_SOCKET: 697718c8510SRobert Watson so = (struct socket *)fp->f_data; 698718c8510SRobert Watson if (INP_CHECK_SOCKAF(so, PF_INET)) { 699a1f3b839SRobert Watson SOCK_LOCK(so); 700718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_type = 701718c8510SRobert Watson so->so_type; 702718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_domain = 703718c8510SRobert Watson INP_SOCKAF(so); 704718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_protocol = 705718c8510SRobert Watson so->so_proto->pr_protocol; 706a1f3b839SRobert Watson SOCK_UNLOCK(so); 707718c8510SRobert Watson pcb = (struct inpcb *)so->so_pcb; 7081a46aa80SRobert Watson INP_RLOCK(pcb); 709718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_raddr = 710718c8510SRobert Watson pcb->inp_faddr.s_addr; 711718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_laddr = 712718c8510SRobert Watson pcb->inp_laddr.s_addr; 713718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_rport = 714718c8510SRobert Watson pcb->inp_fport; 715718c8510SRobert Watson ar->k_ar.ar_arg_sockinfo.so_lport = 716718c8510SRobert Watson pcb->inp_lport; 7171a46aa80SRobert Watson INP_RUNLOCK(pcb); 718718c8510SRobert Watson ARG_SET_VALID(ar, ARG_SOCKINFO); 719718c8510SRobert Watson } 720718c8510SRobert Watson break; 721718c8510SRobert Watson 722718c8510SRobert Watson default: 723718c8510SRobert Watson /* XXXAUDIT: else? */ 724718c8510SRobert Watson break; 725718c8510SRobert Watson } 726718c8510SRobert Watson } 727718c8510SRobert Watson 728718c8510SRobert Watson /* 729718c8510SRobert Watson * Store a path as given by the user process for auditing into the audit 730871499feSRobert Watson * record stored on the user thread. This function will allocate the memory 731c2f027ffSRobert Watson * to store the path info if not already available. This memory will be 732d422682fSRobert Watson * freed when the audit record is freed. The path is canonlicalised with 733d422682fSRobert Watson * respect to the thread and directory descriptor passed. 734718c8510SRobert Watson */ 735791b0ad2SRobert Watson static void 736499f0f4dSPawel Jakub Dawidek audit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp) 737791b0ad2SRobert Watson { 738791b0ad2SRobert Watson 739791b0ad2SRobert Watson if (*pathp == NULL) 740791b0ad2SRobert Watson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 741499f0f4dSPawel Jakub Dawidek audit_canon_path(td, dirfd, upath, *pathp); 742791b0ad2SRobert Watson } 743791b0ad2SRobert Watson 744718c8510SRobert Watson void 745499f0f4dSPawel Jakub Dawidek audit_arg_upath1(struct thread *td, int dirfd, char *upath) 746718c8510SRobert Watson { 747718c8510SRobert Watson struct kaudit_record *ar; 748814fe9e9SRobert Watson 749814fe9e9SRobert Watson ar = currecord(); 750814fe9e9SRobert Watson if (ar == NULL) 751814fe9e9SRobert Watson return; 752718c8510SRobert Watson 753499f0f4dSPawel Jakub Dawidek audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1); 754791b0ad2SRobert Watson ARG_SET_VALID(ar, ARG_UPATH1); 755791b0ad2SRobert Watson } 756718c8510SRobert Watson 757791b0ad2SRobert Watson void 758499f0f4dSPawel Jakub Dawidek audit_arg_upath2(struct thread *td, int dirfd, char *upath) 759791b0ad2SRobert Watson { 760791b0ad2SRobert Watson struct kaudit_record *ar; 761718c8510SRobert Watson 762791b0ad2SRobert Watson ar = currecord(); 763791b0ad2SRobert Watson if (ar == NULL) 764791b0ad2SRobert Watson return; 765718c8510SRobert Watson 766499f0f4dSPawel Jakub Dawidek audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2); 767791b0ad2SRobert Watson ARG_SET_VALID(ar, ARG_UPATH2); 768718c8510SRobert Watson } 769718c8510SRobert Watson 7707de6c5ebSMateusz Guzik static void 7717de6c5ebSMateusz Guzik audit_arg_upath_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7727de6c5ebSMateusz Guzik char *upath, char **pathp) 7737de6c5ebSMateusz Guzik { 7747de6c5ebSMateusz Guzik 7757de6c5ebSMateusz Guzik if (*pathp == NULL) 7767de6c5ebSMateusz Guzik *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 7777de6c5ebSMateusz Guzik audit_canon_path_vp(td, rdir, cdir, upath, *pathp); 7787de6c5ebSMateusz Guzik } 7797de6c5ebSMateusz Guzik 7807de6c5ebSMateusz Guzik void 7817de6c5ebSMateusz Guzik audit_arg_upath1_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7827de6c5ebSMateusz Guzik char *upath) 7837de6c5ebSMateusz Guzik { 7847de6c5ebSMateusz Guzik struct kaudit_record *ar; 7857de6c5ebSMateusz Guzik 7867de6c5ebSMateusz Guzik ar = currecord(); 7877de6c5ebSMateusz Guzik if (ar == NULL) 7887de6c5ebSMateusz Guzik return; 7897de6c5ebSMateusz Guzik 7907de6c5ebSMateusz Guzik audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath1); 7917de6c5ebSMateusz Guzik ARG_SET_VALID(ar, ARG_UPATH1); 7927de6c5ebSMateusz Guzik } 7937de6c5ebSMateusz Guzik 7947de6c5ebSMateusz Guzik void 7957de6c5ebSMateusz Guzik audit_arg_upath2_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir, 7967de6c5ebSMateusz Guzik char *upath) 7977de6c5ebSMateusz Guzik { 7987de6c5ebSMateusz Guzik struct kaudit_record *ar; 7997de6c5ebSMateusz Guzik 8007de6c5ebSMateusz Guzik ar = currecord(); 8017de6c5ebSMateusz Guzik if (ar == NULL) 8027de6c5ebSMateusz Guzik return; 8037de6c5ebSMateusz Guzik 8047de6c5ebSMateusz Guzik audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath2); 8057de6c5ebSMateusz Guzik ARG_SET_VALID(ar, ARG_UPATH2); 8067de6c5ebSMateusz Guzik } 8077de6c5ebSMateusz Guzik 808718c8510SRobert Watson /* 80915bcf785SRobert Watson * Variants on path auditing that do not canonicalise the path passed in; 81015bcf785SRobert Watson * these are for use with filesystem-like subsystems that employ string names, 81115bcf785SRobert Watson * but do not support a hierarchical namespace -- for example, POSIX IPC 81215bcf785SRobert Watson * objects. The subsystem should have performed any necessary 81315bcf785SRobert Watson * canonicalisation required to make the paths useful to audit analysis. 81415bcf785SRobert Watson */ 81515bcf785SRobert Watson static void 81615bcf785SRobert Watson audit_arg_upath_canon(char *upath, char **pathp) 81715bcf785SRobert Watson { 81815bcf785SRobert Watson 81915bcf785SRobert Watson if (*pathp == NULL) 82015bcf785SRobert Watson *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 82115bcf785SRobert Watson (void)snprintf(*pathp, MAXPATHLEN, "%s", upath); 82215bcf785SRobert Watson } 82315bcf785SRobert Watson 82415bcf785SRobert Watson void 82515bcf785SRobert Watson audit_arg_upath1_canon(char *upath) 82615bcf785SRobert Watson { 82715bcf785SRobert Watson struct kaudit_record *ar; 82815bcf785SRobert Watson 82915bcf785SRobert Watson ar = currecord(); 83015bcf785SRobert Watson if (ar == NULL) 83115bcf785SRobert Watson return; 83215bcf785SRobert Watson 83315bcf785SRobert Watson audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath1); 83415bcf785SRobert Watson ARG_SET_VALID(ar, ARG_UPATH1); 83515bcf785SRobert Watson } 83615bcf785SRobert Watson 83715bcf785SRobert Watson void 83815bcf785SRobert Watson audit_arg_upath2_canon(char *upath) 83915bcf785SRobert Watson { 84015bcf785SRobert Watson struct kaudit_record *ar; 84115bcf785SRobert Watson 84215bcf785SRobert Watson ar = currecord(); 84315bcf785SRobert Watson if (ar == NULL) 84415bcf785SRobert Watson return; 84515bcf785SRobert Watson 84615bcf785SRobert Watson audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath2); 84715bcf785SRobert Watson ARG_SET_VALID(ar, ARG_UPATH2); 84815bcf785SRobert Watson } 84915bcf785SRobert Watson 85015bcf785SRobert Watson /* 851718c8510SRobert Watson * Function to save the path and vnode attr information into the audit 852718c8510SRobert Watson * record. 853718c8510SRobert Watson * 854718c8510SRobert Watson * It is assumed that the caller will hold any vnode locks necessary to 855718c8510SRobert Watson * perform a VOP_GETATTR() on the passed vnode. 856718c8510SRobert Watson * 857*51ea7beaSMateusz Guzik * XXX: The attr code is very similar to vfs_default.c:vop_stdstat(), but always 858d8c0f4dcSRobert Watson * provides access to the generation number as we need that to construct the 859d8c0f4dcSRobert Watson * BSM file ID. 860d8c0f4dcSRobert Watson * 861d8c0f4dcSRobert Watson * XXX: We should accept the process argument from the caller, since it's 862d8c0f4dcSRobert Watson * very likely they already have a reference. 863d8c0f4dcSRobert Watson * 864718c8510SRobert Watson * XXX: Error handling in this function is poor. 865718c8510SRobert Watson * 866718c8510SRobert Watson * XXXAUDIT: Possibly KASSERT the path pointer is NULL? 867718c8510SRobert Watson */ 868b146fc1bSRobert Watson static int 869b146fc1bSRobert Watson audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp) 870718c8510SRobert Watson { 871718c8510SRobert Watson struct vattr vattr; 872718c8510SRobert Watson int error; 873718c8510SRobert Watson 874718c8510SRobert Watson ASSERT_VOP_LOCKED(vp, "audit_arg_vnode"); 875718c8510SRobert Watson 8760359a12eSAttilio Rao error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 877718c8510SRobert Watson if (error) { 878718c8510SRobert Watson /* XXX: How to handle this case? */ 879b146fc1bSRobert Watson return (error); 880718c8510SRobert Watson } 881718c8510SRobert Watson 882718c8510SRobert Watson vnp->vn_mode = vattr.va_mode; 883718c8510SRobert Watson vnp->vn_uid = vattr.va_uid; 884718c8510SRobert Watson vnp->vn_gid = vattr.va_gid; 885718c8510SRobert Watson vnp->vn_dev = vattr.va_rdev; 886718c8510SRobert Watson vnp->vn_fsid = vattr.va_fsid; 887718c8510SRobert Watson vnp->vn_fileid = vattr.va_fileid; 888718c8510SRobert Watson vnp->vn_gen = vattr.va_gen; 889b146fc1bSRobert Watson return (0); 890b146fc1bSRobert Watson } 891b146fc1bSRobert Watson 892b146fc1bSRobert Watson void 893b146fc1bSRobert Watson audit_arg_vnode1(struct vnode *vp) 894b146fc1bSRobert Watson { 895b146fc1bSRobert Watson struct kaudit_record *ar; 896b146fc1bSRobert Watson int error; 897b146fc1bSRobert Watson 898b146fc1bSRobert Watson ar = currecord(); 899b146fc1bSRobert Watson if (ar == NULL) 900b146fc1bSRobert Watson return; 901b146fc1bSRobert Watson 902b146fc1bSRobert Watson ARG_CLEAR_VALID(ar, ARG_VNODE1); 903b146fc1bSRobert Watson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1); 904b146fc1bSRobert Watson if (error == 0) 905718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VNODE1); 906b146fc1bSRobert Watson } 907b146fc1bSRobert Watson 908b146fc1bSRobert Watson void 909b146fc1bSRobert Watson audit_arg_vnode2(struct vnode *vp) 910b146fc1bSRobert Watson { 911b146fc1bSRobert Watson struct kaudit_record *ar; 912b146fc1bSRobert Watson int error; 913b146fc1bSRobert Watson 914b146fc1bSRobert Watson ar = currecord(); 915b146fc1bSRobert Watson if (ar == NULL) 916b146fc1bSRobert Watson return; 917b146fc1bSRobert Watson 918b146fc1bSRobert Watson ARG_CLEAR_VALID(ar, ARG_VNODE2); 919b146fc1bSRobert Watson error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2); 920b146fc1bSRobert Watson if (error == 0) 921718c8510SRobert Watson ARG_SET_VALID(ar, ARG_VNODE2); 922718c8510SRobert Watson } 923718c8510SRobert Watson 924718c8510SRobert Watson /* 925ae1078d6SWayne Salamon * Audit the argument strings passed to exec. 926ae1078d6SWayne Salamon */ 927ae1078d6SWayne Salamon void 928ae1078d6SWayne Salamon audit_arg_argv(char *argv, int argc, int length) 929ae1078d6SWayne Salamon { 930ae1078d6SWayne Salamon struct kaudit_record *ar; 931ae1078d6SWayne Salamon 932ae1078d6SWayne Salamon if (audit_argv == 0) 933ae1078d6SWayne Salamon return; 934ae1078d6SWayne Salamon 935ae1078d6SWayne Salamon ar = currecord(); 936ae1078d6SWayne Salamon if (ar == NULL) 937ae1078d6SWayne Salamon return; 938ae1078d6SWayne Salamon 939ae1078d6SWayne Salamon ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK); 940ae1078d6SWayne Salamon bcopy(argv, ar->k_ar.ar_arg_argv, length); 941ae1078d6SWayne Salamon ar->k_ar.ar_arg_argc = argc; 942ae1078d6SWayne Salamon ARG_SET_VALID(ar, ARG_ARGV); 943ae1078d6SWayne Salamon } 944ae1078d6SWayne Salamon 945ae1078d6SWayne Salamon /* 946ae1078d6SWayne Salamon * Audit the environment strings passed to exec. 947ae1078d6SWayne Salamon */ 948ae1078d6SWayne Salamon void 949ae1078d6SWayne Salamon audit_arg_envv(char *envv, int envc, int length) 950ae1078d6SWayne Salamon { 951ae1078d6SWayne Salamon struct kaudit_record *ar; 952ae1078d6SWayne Salamon 953ae1078d6SWayne Salamon if (audit_arge == 0) 954ae1078d6SWayne Salamon return; 955ae1078d6SWayne Salamon 956ae1078d6SWayne Salamon ar = currecord(); 957ae1078d6SWayne Salamon if (ar == NULL) 958ae1078d6SWayne Salamon return; 959ae1078d6SWayne Salamon 960ae1078d6SWayne Salamon ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK); 961ae1078d6SWayne Salamon bcopy(envv, ar->k_ar.ar_arg_envv, length); 962ae1078d6SWayne Salamon ar->k_ar.ar_arg_envc = envc; 963ae1078d6SWayne Salamon ARG_SET_VALID(ar, ARG_ENVV); 964ae1078d6SWayne Salamon } 965ae1078d6SWayne Salamon 966778b0e42SJonathan Anderson void 9677008be5bSPawel Jakub Dawidek audit_arg_rights(cap_rights_t *rightsp) 968778b0e42SJonathan Anderson { 969778b0e42SJonathan Anderson struct kaudit_record *ar; 970778b0e42SJonathan Anderson 971778b0e42SJonathan Anderson ar = currecord(); 972778b0e42SJonathan Anderson if (ar == NULL) 973778b0e42SJonathan Anderson return; 974778b0e42SJonathan Anderson 9757008be5bSPawel Jakub Dawidek ar->k_ar.ar_arg_rights = *rightsp; 976778b0e42SJonathan Anderson ARG_SET_VALID(ar, ARG_RIGHTS); 977778b0e42SJonathan Anderson } 978778b0e42SJonathan Anderson 9792609222aSPawel Jakub Dawidek void 9802609222aSPawel Jakub Dawidek audit_arg_fcntl_rights(uint32_t fcntlrights) 9812609222aSPawel Jakub Dawidek { 9822609222aSPawel Jakub Dawidek struct kaudit_record *ar; 9832609222aSPawel Jakub Dawidek 9842609222aSPawel Jakub Dawidek ar = currecord(); 9852609222aSPawel Jakub Dawidek if (ar == NULL) 9862609222aSPawel Jakub Dawidek return; 9872609222aSPawel Jakub Dawidek 9882609222aSPawel Jakub Dawidek ar->k_ar.ar_arg_fcntl_rights = fcntlrights; 9892609222aSPawel Jakub Dawidek ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS); 9902609222aSPawel Jakub Dawidek } 9912609222aSPawel Jakub Dawidek 992ae1078d6SWayne Salamon /* 993871499feSRobert Watson * The close() system call uses it's own audit call to capture the path/vnode 994871499feSRobert Watson * information because those pieces are not easily obtained within the system 995871499feSRobert Watson * call itself. 996718c8510SRobert Watson */ 997718c8510SRobert Watson void 998718c8510SRobert Watson audit_sysclose(struct thread *td, int fd) 999718c8510SRobert Watson { 10009ef8328dSMateusz Guzik cap_rights_t rights; 1001814fe9e9SRobert Watson struct kaudit_record *ar; 1002718c8510SRobert Watson struct vnode *vp; 1003718c8510SRobert Watson struct file *fp; 1004718c8510SRobert Watson 1005814fe9e9SRobert Watson KASSERT(td != NULL, ("audit_sysclose: td == NULL")); 1006814fe9e9SRobert Watson 1007814fe9e9SRobert Watson ar = currecord(); 1008814fe9e9SRobert Watson if (ar == NULL) 1009814fe9e9SRobert Watson return; 1010814fe9e9SRobert Watson 1011718c8510SRobert Watson audit_arg_fd(fd); 1012718c8510SRobert Watson 10134da8456fSMateusz Guzik if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0) 1014718c8510SRobert Watson return; 1015718c8510SRobert Watson 1016718c8510SRobert Watson vp = fp->f_vnode; 1017927edcc9SJohn Baldwin vn_lock(vp, LK_SHARED | LK_RETRY); 1018b146fc1bSRobert Watson audit_arg_vnode1(vp); 1019b249ce48SMateusz Guzik VOP_UNLOCK(vp); 1020718c8510SRobert Watson fdrop(fp, td); 1021718c8510SRobert Watson } 1022