17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
545916cd2Sjpk * Common Development and Distribution License (the "License").
645916cd2Sjpk * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21794f0adbSRoger A. Faulkner
227c478bd9Sstevel@tonic-gate /*
23134a1f4eSCasper H.S. Dik * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * This file contains the audit hook support code for auditing.
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/proc.h>
327c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
337c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
347c478bd9Sstevel@tonic-gate #include <sys/file.h>
357c478bd9Sstevel@tonic-gate #include <sys/user.h>
367c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
377c478bd9Sstevel@tonic-gate #include <sys/systm.h>
387c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
397c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
407c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
417c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h>
427c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h>
437c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h>
447c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h>
457c478bd9Sstevel@tonic-gate #include <sys/kmem.h> /* for KM_SLEEP */
467c478bd9Sstevel@tonic-gate #include <sys/socket.h>
477c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> /* snprintf... */
487c478bd9Sstevel@tonic-gate #include <sys/debug.h>
497c478bd9Sstevel@tonic-gate #include <sys/thread.h>
507c478bd9Sstevel@tonic-gate #include <netinet/in.h>
517c478bd9Sstevel@tonic-gate #include <c2/audit.h> /* needs to be included before user.h */
527c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h> /* for M_DONTWAIT */
537c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h>
547c478bd9Sstevel@tonic-gate #include <c2/audit_record.h>
557c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
567c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
577c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
587c478bd9Sstevel@tonic-gate #include <sys/timod.h>
597c478bd9Sstevel@tonic-gate #include <sys/model.h> /* for model_t */
607c478bd9Sstevel@tonic-gate #include <sys/disp.h> /* for servicing_interrupt() */
617c478bd9Sstevel@tonic-gate #include <sys/devpolicy.h>
627c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
63134a1f4eSCasper H.S. Dik #include <sys/cred_impl.h>
64799bd290Spwernau #include <net/pfpolicy.h>
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate static void audit_pathbuild(struct pathname *pnp);
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SAVEPATH
737c478bd9Sstevel@tonic-gate * PURPOSE:
747c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN
757c478bd9Sstevel@tonic-gate *
767c478bd9Sstevel@tonic-gate * NOTE: We have reached the end of a path in fs/lookup.c.
777c478bd9Sstevel@tonic-gate * We get two pieces of information here:
787c478bd9Sstevel@tonic-gate * the vnode of the last component (vp) and
797c478bd9Sstevel@tonic-gate * the status of the last access (flag).
807c478bd9Sstevel@tonic-gate * TODO:
817c478bd9Sstevel@tonic-gate * QUESTION:
827c478bd9Sstevel@tonic-gate */
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /*ARGSUSED*/
857c478bd9Sstevel@tonic-gate int
audit_savepath(struct pathname * pnp,struct vnode * vp,struct vnode * pvp,int flag,cred_t * cr)867c478bd9Sstevel@tonic-gate audit_savepath(
877c478bd9Sstevel@tonic-gate struct pathname *pnp, /* pathname to lookup */
887c478bd9Sstevel@tonic-gate struct vnode *vp, /* vnode of the last component */
894a0fa546SMarek Pospisil struct vnode *pvp, /* vnode of the last parent component */
907c478bd9Sstevel@tonic-gate int flag, /* status of the last access */
917c478bd9Sstevel@tonic-gate cred_t *cr) /* cred of requestor */
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */
959e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate tad = U2A(u);
987c478bd9Sstevel@tonic-gate
994a0fa546SMarek Pospisil /*
1004a0fa546SMarek Pospisil * Noise elimination in audit trails - this event will be discarded if:
1014a0fa546SMarek Pospisil * - the public policy is not active AND
1024a0fa546SMarek Pospisil * - the system call is a public operation AND
1034a0fa546SMarek Pospisil * - the file was not found: VFS lookup failed with ENOENT error AND
1044a0fa546SMarek Pospisil * - the missing file would have been located in the public directory
1054a0fa546SMarek Pospisil * owned by root if it had existed
1064a0fa546SMarek Pospisil */
1074a0fa546SMarek Pospisil if (tad->tad_flag != 0 && flag == ENOENT && pvp != NULL &&
1084a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_PUBLIC_EV) &&
1094a0fa546SMarek Pospisil !(kctx->auk_policy & AUDIT_PUBLIC)) {
1104a0fa546SMarek Pospisil struct vattr attr;
1114a0fa546SMarek Pospisil
1124a0fa546SMarek Pospisil attr.va_mask = AT_ALL;
1134a0fa546SMarek Pospisil if (VOP_GETATTR(pvp, &attr, 0, CRED(), NULL) == 0) {
1144a0fa546SMarek Pospisil if (object_is_public(&attr)) {
1154a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOAUDIT;
1164a0fa546SMarek Pospisil }
1174a0fa546SMarek Pospisil }
1184a0fa546SMarek Pospisil }
1194a0fa546SMarek Pospisil
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate * this event being audited or do we need path information
1227c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path
1237c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an
1247c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path.
1257c478bd9Sstevel@tonic-gate *
1264a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
1277c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines
1287c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later.
1294a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It
1307c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per
1317c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple
1327c478bd9Sstevel@tonic-gate * paths are allowed.
1334a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
1347c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to
1357c478bd9Sstevel@tonic-gate * closes.
1367c478bd9Sstevel@tonic-gate */
1374a0fa546SMarek Pospisil if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) ||
1384a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) &&
13951d48dedSMarek Pospisil !(kctx->auk_policy & AUDIT_PATH)) ||
1404a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) {
14151d48dedSMarek Pospisil return (0);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate
1444a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOPATH; /* prevent possible reentry */
14545916cd2Sjpk
1467c478bd9Sstevel@tonic-gate audit_pathbuild(pnp);
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate * are we auditing only if error, or if it is not open or create
1507c478bd9Sstevel@tonic-gate * otherwise audit_setf will do it
1517c478bd9Sstevel@tonic-gate */
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate if (tad->tad_flag) {
1548fd04b83SRoger A. Faulkner if (flag &&
1558fd04b83SRoger A. Faulkner (tad->tad_scid == SYS_open ||
1567c478bd9Sstevel@tonic-gate tad->tad_scid == SYS_open64 ||
1578fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat ||
1588fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat64)) {
1594a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_TRUE_CREATE;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate /* add token to audit record for this name */
1637c478bd9Sstevel@tonic-gate au_uwrite(au_to_path(tad->tad_aupath));
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate /* add the attributes of the object */
1667c478bd9Sstevel@tonic-gate if (vp) {
1677c478bd9Sstevel@tonic-gate /*
1687c478bd9Sstevel@tonic-gate * only capture attributes when there is no error
1697c478bd9Sstevel@tonic-gate * lookup will not return the vnode of the failing
1707c478bd9Sstevel@tonic-gate * component.
1717c478bd9Sstevel@tonic-gate *
1727c478bd9Sstevel@tonic-gate * if there was a lookup error, then don't add
1737c478bd9Sstevel@tonic-gate * attribute. if lookup in vn_create(),
1747c478bd9Sstevel@tonic-gate * then don't add attribute,
1757c478bd9Sstevel@tonic-gate * it will be added at end of vn_create().
1767c478bd9Sstevel@tonic-gate */
1774a0fa546SMarek Pospisil if (!flag && !(tad->tad_ctrl & TAD_NOATTRB))
1787c478bd9Sstevel@tonic-gate audit_attributes(vp);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate
1828fd04b83SRoger A. Faulkner /* free up space if we're not going to save path (open, creat) */
1834a0fa546SMarek Pospisil if ((tad->tad_ctrl & TAD_SAVPATH) == 0) {
1847c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) {
1857c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath);
1867c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL;
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate }
1894a0fa546SMarek Pospisil if (tad->tad_ctrl & TAD_MLD)
1904a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_PATHFND;
1917c478bd9Sstevel@tonic-gate
1924a0fa546SMarek Pospisil tad->tad_ctrl &= ~TAD_NOPATH; /* restore */
1937c478bd9Sstevel@tonic-gate return (0);
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate static void
audit_pathbuild(struct pathname * pnp)1977c478bd9Sstevel@tonic-gate audit_pathbuild(struct pathname *pnp)
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate char *pp; /* pointer to path */
2007c478bd9Sstevel@tonic-gate int len; /* length of incoming segment */
2017c478bd9Sstevel@tonic-gate int newsect; /* path requires a new section */
2027c478bd9Sstevel@tonic-gate struct audit_path *pfxapp; /* prefix for path */
2037c478bd9Sstevel@tonic-gate struct audit_path *newapp; /* new audit_path */
2047c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */
2057c478bd9Sstevel@tonic-gate p_audit_data_t *pad; /* current process */
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate tad = U2A(u);
2087c478bd9Sstevel@tonic-gate ASSERT(tad != NULL);
2097c478bd9Sstevel@tonic-gate pad = P2A(curproc);
2107c478bd9Sstevel@tonic-gate ASSERT(pad != NULL);
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate len = (pnp->pn_path - pnp->pn_buf) + 1; /* +1 for terminator */
2137c478bd9Sstevel@tonic-gate ASSERT(len > 0);
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate /* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */
2167c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock);
2177c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) {
2187c478bd9Sstevel@tonic-gate pfxapp = tad->tad_aupath;
2194a0fa546SMarek Pospisil } else if ((tad->tad_ctrl & TAD_ATCALL) && pnp->pn_buf[0] != '/') {
2207c478bd9Sstevel@tonic-gate ASSERT(tad->tad_atpath != NULL);
2217c478bd9Sstevel@tonic-gate pfxapp = tad->tad_atpath;
2224a0fa546SMarek Pospisil } else if (tad->tad_ctrl & TAD_ABSPATH) {
2237c478bd9Sstevel@tonic-gate pfxapp = pad->pad_root;
2247c478bd9Sstevel@tonic-gate } else {
2257c478bd9Sstevel@tonic-gate pfxapp = pad->pad_cwd;
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate au_pathhold(pfxapp);
2287c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock);
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate /* get an expanded buffer to hold the anchored path */
2314a0fa546SMarek Pospisil newsect = tad->tad_ctrl & TAD_ATTPATH;
2327c478bd9Sstevel@tonic-gate newapp = au_pathdup(pfxapp, newsect, len);
2337c478bd9Sstevel@tonic-gate au_pathrele(pfxapp);
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate pp = newapp->audp_sect[newapp->audp_cnt] - len;
2367c478bd9Sstevel@tonic-gate if (!newsect) {
2377c478bd9Sstevel@tonic-gate /* overlay previous NUL terminator */
2387c478bd9Sstevel@tonic-gate *(pp - 1) = '/';
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate /* now add string of processed path */
2427c478bd9Sstevel@tonic-gate bcopy(pnp->pn_buf, pp, len);
2437c478bd9Sstevel@tonic-gate pp[len - 1] = '\0';
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate /* perform path simplification as necessary */
2467c478bd9Sstevel@tonic-gate audit_fixpath(newapp, len);
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate if (tad->tad_aupath)
2497c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath);
2507c478bd9Sstevel@tonic-gate tad->tad_aupath = newapp;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate /* for case where multiple lookups in one syscall (rename) */
2534a0fa546SMarek Pospisil tad->tad_ctrl &= ~(TAD_ABSPATH | TAD_ATTPATH);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate /*
2587c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_ANCHORPATH
2597c478bd9Sstevel@tonic-gate * PURPOSE:
2607c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN
2617c478bd9Sstevel@tonic-gate * NOTE:
2627c478bd9Sstevel@tonic-gate * anchor path at "/". We have seen a symbolic link or entering for the
2637c478bd9Sstevel@tonic-gate * first time we will throw away any saved path if path is anchored.
2647c478bd9Sstevel@tonic-gate *
2657c478bd9Sstevel@tonic-gate * flag = 0, path is relative.
2664a0fa546SMarek Pospisil * flag = 1, path is absolute. Free any saved path and set flag to TAD_ABSPATH.
2677c478bd9Sstevel@tonic-gate *
2687c478bd9Sstevel@tonic-gate * If the (new) path is absolute, then we have to throw away whatever we have
269da6c28aaSamw * already accumulated since it is being superseded by new path which is
2707c478bd9Sstevel@tonic-gate * anchored at the root.
2717c478bd9Sstevel@tonic-gate * Note that if the path is relative, this function does nothing
2727c478bd9Sstevel@tonic-gate * TODO:
2737c478bd9Sstevel@tonic-gate * QUESTION:
2747c478bd9Sstevel@tonic-gate */
2757c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2767c478bd9Sstevel@tonic-gate void
audit_anchorpath(struct pathname * pnp,int flag)2777c478bd9Sstevel@tonic-gate audit_anchorpath(struct pathname *pnp, int flag)
2787c478bd9Sstevel@tonic-gate {
2799e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
2807c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate tad = U2A(u);
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate /*
2857c478bd9Sstevel@tonic-gate * this event being audited or do we need path information
2867c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path
2877c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an
2887c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path.
2897c478bd9Sstevel@tonic-gate *
2904a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
2917c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines
2927c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later.
2934a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It
2947c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per
2957c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple
2967c478bd9Sstevel@tonic-gate * paths are allowed.
2974a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
2987c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to
2997c478bd9Sstevel@tonic-gate * closes.
3007c478bd9Sstevel@tonic-gate */
3014a0fa546SMarek Pospisil if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) ||
3024a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) &&
30351d48dedSMarek Pospisil !(kctx->auk_policy & AUDIT_PATH)) ||
3044a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) {
30551d48dedSMarek Pospisil return;
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate if (flag) {
3094a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_ABSPATH;
3107c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) {
3117c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath);
3127c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL;
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate * symbolic link. Save previous components.
3207c478bd9Sstevel@tonic-gate *
3217c478bd9Sstevel@tonic-gate * the path seen so far looks like this
3227c478bd9Sstevel@tonic-gate *
3237c478bd9Sstevel@tonic-gate * +-----------------------+----------------+
3247c478bd9Sstevel@tonic-gate * | path processed so far | remaining path |
3257c478bd9Sstevel@tonic-gate * +-----------------------+----------------+
3267c478bd9Sstevel@tonic-gate * \-----------------------/
3277c478bd9Sstevel@tonic-gate * save this string if
3287c478bd9Sstevel@tonic-gate * symbolic link relative
3297c478bd9Sstevel@tonic-gate * (but don't include symlink component)
3307c478bd9Sstevel@tonic-gate */
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SYMLINK
3377c478bd9Sstevel@tonic-gate * PURPOSE:
3387c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN
3397c478bd9Sstevel@tonic-gate * NOTE:
3407c478bd9Sstevel@tonic-gate * TODO:
3417c478bd9Sstevel@tonic-gate * QUESTION:
3427c478bd9Sstevel@tonic-gate */
3437c478bd9Sstevel@tonic-gate void
audit_symlink(struct pathname * pnp,struct pathname * sympath)3447c478bd9Sstevel@tonic-gate audit_symlink(struct pathname *pnp, struct pathname *sympath)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate char *sp; /* saved initial pp */
3477c478bd9Sstevel@tonic-gate char *cp; /* start of symlink path */
3487c478bd9Sstevel@tonic-gate uint_t len_path; /* processed path before symlink */
3497c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
3509e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate tad = U2A(u);
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate * this event being audited or do we need path information
3567c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path
3577c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an
3587c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path.
3597c478bd9Sstevel@tonic-gate *
3604a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
3617c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines
3627c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later.
3634a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It
3647c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per
3657c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple
3667c478bd9Sstevel@tonic-gate * paths are allowed.
3674a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
3687c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to
3697c478bd9Sstevel@tonic-gate * closes.
3707c478bd9Sstevel@tonic-gate */
3717c478bd9Sstevel@tonic-gate if ((tad->tad_flag == 0 &&
3724a0fa546SMarek Pospisil !(tad->tad_ctrl & TAD_SAVPATH)) ||
3734a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) &&
37451d48dedSMarek Pospisil !(kctx->auk_policy & AUDIT_PATH)) ||
3754a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) {
37651d48dedSMarek Pospisil return;
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate /*
3807c478bd9Sstevel@tonic-gate * if symbolic link is anchored at / then do nothing.
3817c478bd9Sstevel@tonic-gate * When we cycle back to begin: in lookuppn() we will
3827c478bd9Sstevel@tonic-gate * call audit_anchorpath() with a flag indicating if the
3837c478bd9Sstevel@tonic-gate * path is anchored at / or is relative. We will release
3847c478bd9Sstevel@tonic-gate * any saved path at that point.
3857c478bd9Sstevel@tonic-gate *
3867c478bd9Sstevel@tonic-gate * Note In the event that an error occurs in pn_combine then
3877c478bd9Sstevel@tonic-gate * we want to remain pointing at the component that caused the
3887c478bd9Sstevel@tonic-gate * path to overflow the pnp structure.
3897c478bd9Sstevel@tonic-gate */
3907c478bd9Sstevel@tonic-gate if (sympath->pn_buf[0] == '/')
3917c478bd9Sstevel@tonic-gate return;
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate /* backup over last component */
3947c478bd9Sstevel@tonic-gate sp = cp = pnp->pn_path;
3957c478bd9Sstevel@tonic-gate while (*--cp != '/' && cp > pnp->pn_buf)
3967c478bd9Sstevel@tonic-gate ;
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate len_path = cp - pnp->pn_buf;
3997c478bd9Sstevel@tonic-gate
4007c478bd9Sstevel@tonic-gate /* is there anything to save? */
4017c478bd9Sstevel@tonic-gate if (len_path) {
402405e5d68Stz pnp->pn_path = pnp->pn_buf;
4037c478bd9Sstevel@tonic-gate audit_pathbuild(pnp);
4047c478bd9Sstevel@tonic-gate pnp->pn_path = sp;
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate /*
4094a0fa546SMarek Pospisil * object_is_public : determine whether events for the object (corresponding to
4104a0fa546SMarek Pospisil * the specified file/directory attr) should be audited or
4114a0fa546SMarek Pospisil * ignored.
4127c478bd9Sstevel@tonic-gate *
413*0f48f68dSToomas Soome * returns: 1 - if audit policy and object attributes indicate that
4144a0fa546SMarek Pospisil * file/directory is effectively public. read events for
4157c478bd9Sstevel@tonic-gate * the file should not be audited.
4167c478bd9Sstevel@tonic-gate * 0 - otherwise
4177c478bd9Sstevel@tonic-gate *
4187c478bd9Sstevel@tonic-gate * The required attributes to be considered a public object are:
4197c478bd9Sstevel@tonic-gate * - owned by root, AND
4207c478bd9Sstevel@tonic-gate * - world-readable (permissions for other include read), AND
4217c478bd9Sstevel@tonic-gate * - NOT world-writeable (permissions for other don't
4227c478bd9Sstevel@tonic-gate * include write)
4237c478bd9Sstevel@tonic-gate * (mode doesn't need to be checked for symlinks)
4247c478bd9Sstevel@tonic-gate */
4257c478bd9Sstevel@tonic-gate int
object_is_public(struct vattr * attr)4264a0fa546SMarek Pospisil object_is_public(struct vattr *attr)
4277c478bd9Sstevel@tonic-gate {
4289e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
4297c478bd9Sstevel@tonic-gate
4307c478bd9Sstevel@tonic-gate if (!(kctx->auk_policy & AUDIT_PUBLIC) && (attr->va_uid == 0) &&
4317c478bd9Sstevel@tonic-gate ((attr->va_type == VLNK) ||
4327c478bd9Sstevel@tonic-gate ((attr->va_mode & (VREAD>>6)) != 0) &&
4337c478bd9Sstevel@tonic-gate ((attr->va_mode & (VWRITE>>6)) == 0))) {
4347c478bd9Sstevel@tonic-gate return (1);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate return (0);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_ATTRIBUTES
442da6c28aaSamw * PURPOSE: Audit the attributes so we can tell why the error occurred
4437c478bd9Sstevel@tonic-gate * CALLBY: AUDIT_SAVEPATH
4447c478bd9Sstevel@tonic-gate * AUDIT_VNCREATE_FINISH
4457c478bd9Sstevel@tonic-gate * AUS_FCHOWN...audit_event.c...audit_path.c
4467c478bd9Sstevel@tonic-gate * NOTE:
4477c478bd9Sstevel@tonic-gate * TODO:
4487c478bd9Sstevel@tonic-gate * QUESTION:
4497c478bd9Sstevel@tonic-gate */
4507c478bd9Sstevel@tonic-gate void
audit_attributes(struct vnode * vp)4517c478bd9Sstevel@tonic-gate audit_attributes(struct vnode *vp)
4527c478bd9Sstevel@tonic-gate {
4537c478bd9Sstevel@tonic-gate struct vattr attr;
4547c478bd9Sstevel@tonic-gate struct t_audit_data *tad;
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate tad = U2A(u);
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate if (vp) {
4597c478bd9Sstevel@tonic-gate attr.va_mask = AT_ALL;
460da6c28aaSamw if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) != 0)
4617c478bd9Sstevel@tonic-gate return;
4627c478bd9Sstevel@tonic-gate
4634a0fa546SMarek Pospisil if (object_is_public(&attr) &&
4644a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_PUBLIC_EV)) {
4657c478bd9Sstevel@tonic-gate /*
4667c478bd9Sstevel@tonic-gate * This is a public object and a "public" event
4677c478bd9Sstevel@tonic-gate * (i.e., read only) -- either by definition
4687c478bd9Sstevel@tonic-gate * (e.g., stat, access...) or by virtue of write access
4697c478bd9Sstevel@tonic-gate * not being requested (e.g. mmap).
4707c478bd9Sstevel@tonic-gate * Flag it in the tad to prevent this audit at the end.
4717c478bd9Sstevel@tonic-gate */
4724a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOAUDIT;
4737c478bd9Sstevel@tonic-gate } else {
4747c478bd9Sstevel@tonic-gate au_uwrite(au_to_attr(&attr));
47545916cd2Sjpk audit_sec_attributes(&(u_ad), vp);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate /*
4827c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_EXIT
4837c478bd9Sstevel@tonic-gate * PURPOSE:
4847c478bd9Sstevel@tonic-gate * CALLBY: EXIT
4857c478bd9Sstevel@tonic-gate * NOTE:
4867c478bd9Sstevel@tonic-gate * TODO:
4877c478bd9Sstevel@tonic-gate * QUESTION: why cmw code as offset by 2 but not here
4887c478bd9Sstevel@tonic-gate */
4897c478bd9Sstevel@tonic-gate /* ARGSUSED */
4907c478bd9Sstevel@tonic-gate void
audit_exit(int code,int what)4917c478bd9Sstevel@tonic-gate audit_exit(int code, int what)
4927c478bd9Sstevel@tonic-gate {
4937c478bd9Sstevel@tonic-gate struct t_audit_data *tad;
4947c478bd9Sstevel@tonic-gate tad = U2A(u);
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate /*
4977c478bd9Sstevel@tonic-gate * tad_scid will be set by audit_start even if we are not auditing
4987c478bd9Sstevel@tonic-gate * the event.
4997c478bd9Sstevel@tonic-gate */
5007c478bd9Sstevel@tonic-gate if (tad->tad_scid == SYS_exit) {
5017c478bd9Sstevel@tonic-gate /*
5027c478bd9Sstevel@tonic-gate * if we are auditing the exit system call, then complete
5037c478bd9Sstevel@tonic-gate * audit record generation (no return from system call).
5047c478bd9Sstevel@tonic-gate */
5057c478bd9Sstevel@tonic-gate if (tad->tad_flag && tad->tad_event == AUE_EXIT)
5067c478bd9Sstevel@tonic-gate audit_finish(0, SYS_exit, 0, 0);
5077c478bd9Sstevel@tonic-gate return;
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate /*
5117c478bd9Sstevel@tonic-gate * Anyone auditing the system call that was aborted?
5127c478bd9Sstevel@tonic-gate */
5137c478bd9Sstevel@tonic-gate if (tad->tad_flag) {
5147c478bd9Sstevel@tonic-gate au_uwrite(au_to_text("event aborted"));
5157c478bd9Sstevel@tonic-gate audit_finish(0, tad->tad_scid, 0, 0);
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate /*
5197c478bd9Sstevel@tonic-gate * Generate an audit record for process exit if preselected.
5207c478bd9Sstevel@tonic-gate */
521005d3febSMarek Pospisil (void) audit_start(0, SYS_exit, AUC_UNSET, 0, 0);
5227c478bd9Sstevel@tonic-gate audit_finish(0, SYS_exit, 0, 0);
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate
5257c478bd9Sstevel@tonic-gate /*
5267c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CORE_START
5277c478bd9Sstevel@tonic-gate * PURPOSE:
528*0f48f68dSToomas Soome * CALLBY: PSIG
5297c478bd9Sstevel@tonic-gate * NOTE:
5307c478bd9Sstevel@tonic-gate * TODO:
5317c478bd9Sstevel@tonic-gate */
5327c478bd9Sstevel@tonic-gate void
audit_core_start(int sig)5337c478bd9Sstevel@tonic-gate audit_core_start(int sig)
5347c478bd9Sstevel@tonic-gate {
5357c478bd9Sstevel@tonic-gate au_event_t event;
5367c478bd9Sstevel@tonic-gate au_state_t estate;
5377c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
5387c478bd9Sstevel@tonic-gate au_kcontext_t *kctx;
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate tad = U2A(u);
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0);
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate ASSERT(tad->tad_scid == 0);
5457c478bd9Sstevel@tonic-gate ASSERT(tad->tad_event == 0);
5467c478bd9Sstevel@tonic-gate ASSERT(tad->tad_evmod == 0);
5477c478bd9Sstevel@tonic-gate ASSERT(tad->tad_ctrl == 0);
5487c478bd9Sstevel@tonic-gate ASSERT(tad->tad_flag == 0);
5497c478bd9Sstevel@tonic-gate ASSERT(tad->tad_aupath == NULL);
5507c478bd9Sstevel@tonic-gate
5519e9e6ab8Spaulson kctx = GET_KCTX_PZ;
5527c478bd9Sstevel@tonic-gate
5537c478bd9Sstevel@tonic-gate /* get basic event for system call */
5547c478bd9Sstevel@tonic-gate event = AUE_CORE;
5557c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[event];
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0)
5587c478bd9Sstevel@tonic-gate return;
5597c478bd9Sstevel@tonic-gate
5607c478bd9Sstevel@tonic-gate /* reset the flags for non-user attributable events */
5614a0fa546SMarek Pospisil tad->tad_ctrl = TAD_CORE;
5627c478bd9Sstevel@tonic-gate tad->tad_scid = 0;
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate /* if auditing not enabled, then don't generate an audit record */
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate if (!((kctx->auk_auditstate == AUC_AUDITING ||
5677c478bd9Sstevel@tonic-gate kctx->auk_auditstate == AUC_INIT_AUDIT) ||
5687c478bd9Sstevel@tonic-gate kctx->auk_auditstate == AUC_NOSPACE)) {
5697c478bd9Sstevel@tonic-gate tad->tad_flag = 0;
5707c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0;
5717c478bd9Sstevel@tonic-gate return;
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate
5747c478bd9Sstevel@tonic-gate tad->tad_event = event;
5757c478bd9Sstevel@tonic-gate tad->tad_evmod = 0;
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate ASSERT(tad->tad_ad == NULL);
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_arg32(1, "signal", (uint32_t)sig));
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate /*
5837c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CORE_FINISH
5847c478bd9Sstevel@tonic-gate * PURPOSE:
5857c478bd9Sstevel@tonic-gate * CALLBY: PSIG
5867c478bd9Sstevel@tonic-gate * NOTE:
5877c478bd9Sstevel@tonic-gate * TODO:
5887c478bd9Sstevel@tonic-gate * QUESTION:
5897c478bd9Sstevel@tonic-gate */
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5927c478bd9Sstevel@tonic-gate void
audit_core_finish(int code)5937c478bd9Sstevel@tonic-gate audit_core_finish(int code)
5947c478bd9Sstevel@tonic-gate {
5957c478bd9Sstevel@tonic-gate int flag;
5967c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
5977c478bd9Sstevel@tonic-gate au_kcontext_t *kctx;
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate tad = U2A(u);
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0);
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate if ((flag = tad->tad_flag) == 0) {
6047c478bd9Sstevel@tonic-gate tad->tad_event = 0;
6057c478bd9Sstevel@tonic-gate tad->tad_evmod = 0;
6067c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0;
6077c478bd9Sstevel@tonic-gate ASSERT(tad->tad_aupath == NULL);
6087c478bd9Sstevel@tonic-gate return;
6097c478bd9Sstevel@tonic-gate }
6107c478bd9Sstevel@tonic-gate tad->tad_flag = 0;
6117c478bd9Sstevel@tonic-gate
6129e9e6ab8Spaulson kctx = GET_KCTX_PZ;
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate /* kludge for error 0, should use `code==CLD_DUMPED' instead */
615799bd290Spwernau if (flag = audit_success(kctx, tad, 0, NULL)) {
6167c478bd9Sstevel@tonic-gate cred_t *cr = CRED();
6177c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr);
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate ASSERT(ainfo != NULL);
6207c478bd9Sstevel@tonic-gate
6217c478bd9Sstevel@tonic-gate /*
62281490fd2Sgww * Add subject information (no locks since our private copy of
6237c478bd9Sstevel@tonic-gate * credential
6247c478bd9Sstevel@tonic-gate */
62581490fd2Sgww AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
62645916cd2Sjpk
6277c478bd9Sstevel@tonic-gate /* Add a return token (should use f argument) */
6287c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx);
6317c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx);
6327c478bd9Sstevel@tonic-gate }
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate /* Close up everything */
635005d3febSMarek Pospisil au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod, NULL);
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate /* free up any space remaining with the path's */
6387c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) {
6397c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath);
6407c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL;
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate tad->tad_event = 0;
6437c478bd9Sstevel@tonic-gate tad->tad_evmod = 0;
6447c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0;
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate
6487c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6497c478bd9Sstevel@tonic-gate void
audit_strgetmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char * pri,int * flag,int fmode)6507c478bd9Sstevel@tonic-gate audit_strgetmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
6517c478bd9Sstevel@tonic-gate unsigned char *pri, int *flag, int fmode)
6527c478bd9Sstevel@tonic-gate {
6537c478bd9Sstevel@tonic-gate struct stdata *stp;
6547c478bd9Sstevel@tonic-gate t_audit_data_t *tad = U2A(u);
6557c478bd9Sstevel@tonic-gate
6567c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0);
6577c478bd9Sstevel@tonic-gate
6587c478bd9Sstevel@tonic-gate stp = vp->v_stream;
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate /* lock stdata from audit_sock */
6617c478bd9Sstevel@tonic-gate mutex_enter(&stp->sd_lock);
6627c478bd9Sstevel@tonic-gate
6637c478bd9Sstevel@tonic-gate /* proceed ONLY if user is being audited */
6647c478bd9Sstevel@tonic-gate if (!tad->tad_flag) {
6657c478bd9Sstevel@tonic-gate /*
6667c478bd9Sstevel@tonic-gate * this is so we will not add audit data onto
6677c478bd9Sstevel@tonic-gate * a thread that is not being audited.
6687c478bd9Sstevel@tonic-gate */
6697c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = NULL;
6707c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock);
6717c478bd9Sstevel@tonic-gate return;
6727c478bd9Sstevel@tonic-gate }
6737c478bd9Sstevel@tonic-gate
6747c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = (caddr_t)curthread;
6757c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate
6787c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6797c478bd9Sstevel@tonic-gate void
audit_strputmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char pri,int flag,int fmode)6807c478bd9Sstevel@tonic-gate audit_strputmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
6817c478bd9Sstevel@tonic-gate unsigned char pri, int flag, int fmode)
6827c478bd9Sstevel@tonic-gate {
6837c478bd9Sstevel@tonic-gate struct stdata *stp;
6847c478bd9Sstevel@tonic-gate t_audit_data_t *tad = U2A(u);
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0);
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate stp = vp->v_stream;
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate /* lock stdata from audit_sock */
6917c478bd9Sstevel@tonic-gate mutex_enter(&stp->sd_lock);
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate /* proceed ONLY if user is being audited */
6947c478bd9Sstevel@tonic-gate if (!tad->tad_flag) {
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate * this is so we will not add audit data onto
6977c478bd9Sstevel@tonic-gate * a thread that is not being audited.
6987c478bd9Sstevel@tonic-gate */
6997c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = NULL;
7007c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock);
7017c478bd9Sstevel@tonic-gate return;
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = (caddr_t)curthread;
7057c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock);
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate /*
7097c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CLOSEF
7107c478bd9Sstevel@tonic-gate * PURPOSE:
7117c478bd9Sstevel@tonic-gate * CALLBY: CLOSEF
7127c478bd9Sstevel@tonic-gate * NOTE:
7137c478bd9Sstevel@tonic-gate * release per file audit resources when file structure is being released.
7147c478bd9Sstevel@tonic-gate *
7157c478bd9Sstevel@tonic-gate * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
7167c478bd9Sstevel@tonic-gate * on the audit queue if it becomes full. This means
7177c478bd9Sstevel@tonic-gate * audit_closef can not be called when f_count == 0. Since
7187c478bd9Sstevel@tonic-gate * f_count == 0 indicates the file structure is free, another
7197c478bd9Sstevel@tonic-gate * process could attempt to use the file while we were still
7207c478bd9Sstevel@tonic-gate * asleep waiting on the audit queue. This would cause the
7217c478bd9Sstevel@tonic-gate * per file audit data to be corrupted when we finally do
7227c478bd9Sstevel@tonic-gate * wakeup.
7237c478bd9Sstevel@tonic-gate * TODO:
7247c478bd9Sstevel@tonic-gate * QUESTION:
7257c478bd9Sstevel@tonic-gate */
7267c478bd9Sstevel@tonic-gate
7277c478bd9Sstevel@tonic-gate void
audit_closef(struct file * fp)7287c478bd9Sstevel@tonic-gate audit_closef(struct file *fp)
729d2a70789SRichard Lowe {
7307c478bd9Sstevel@tonic-gate f_audit_data_t *fad;
7317c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
7327c478bd9Sstevel@tonic-gate int success;
7337c478bd9Sstevel@tonic-gate au_state_t estate;
7347c478bd9Sstevel@tonic-gate struct vnode *vp;
7357c478bd9Sstevel@tonic-gate token_t *ad = NULL;
7367c478bd9Sstevel@tonic-gate struct vattr attr;
737d0fa49b7STony Nguyen au_emod_t evmod = 0;
7387c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo;
7397c478bd9Sstevel@tonic-gate cred_t *cr;
7409e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
741005d3febSMarek Pospisil uint32_t auditing;
742224626ecSMarek Pospisil boolean_t audit_attr = B_FALSE;
7437c478bd9Sstevel@tonic-gate
7447c478bd9Sstevel@tonic-gate fad = F2A(fp);
7457c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_CLOSE];
7467c478bd9Sstevel@tonic-gate tad = U2A(u);
7477c478bd9Sstevel@tonic-gate cr = CRED();
7487c478bd9Sstevel@tonic-gate
7497c478bd9Sstevel@tonic-gate /* audit record already generated by system call envelope */
7507c478bd9Sstevel@tonic-gate if (tad->tad_event == AUE_CLOSE) {
7517c478bd9Sstevel@tonic-gate /* so close audit event will have bits set */
752d0fa49b7STony Nguyen tad->tad_evmod |= (au_emod_t)fad->fad_flags;
7537c478bd9Sstevel@tonic-gate return;
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate /* if auditing not enabled, then don't generate an audit record */
757005d3febSMarek Pospisil auditing = (tad->tad_audit == AUC_UNSET) ?
758005d3febSMarek Pospisil kctx->auk_auditstate : tad->tad_audit;
759005d3febSMarek Pospisil if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT | AUC_NOSPACE))
7607c478bd9Sstevel@tonic-gate return;
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate ainfo = crgetauinfo(cr);
7637c478bd9Sstevel@tonic-gate if (ainfo == NULL)
7647c478bd9Sstevel@tonic-gate return;
7657c478bd9Sstevel@tonic-gate
7667c478bd9Sstevel@tonic-gate success = ainfo->ai_mask.as_success & estate;
7677c478bd9Sstevel@tonic-gate
7687c478bd9Sstevel@tonic-gate /* not selected for this event */
7697c478bd9Sstevel@tonic-gate if (success == 0)
7707c478bd9Sstevel@tonic-gate return;
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gate /*
7737c478bd9Sstevel@tonic-gate * can't use audit_attributes here since we use a private audit area
7747c478bd9Sstevel@tonic-gate * to build the audit record instead of the one off the thread.
7757c478bd9Sstevel@tonic-gate */
7767c478bd9Sstevel@tonic-gate if ((vp = fp->f_vnode) != NULL) {
7777c478bd9Sstevel@tonic-gate attr.va_mask = AT_ALL;
778224626ecSMarek Pospisil if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) == 0) {
779224626ecSMarek Pospisil if ((fp->f_flag & FWRITE) == 0 &&
780224626ecSMarek Pospisil object_is_public(&attr)) {
781224626ecSMarek Pospisil /*
782224626ecSMarek Pospisil * When write was not used and the file can be
783224626ecSMarek Pospisil * considered public, then skip the audit.
784224626ecSMarek Pospisil */
785224626ecSMarek Pospisil return;
786224626ecSMarek Pospisil }
787224626ecSMarek Pospisil audit_attr = B_TRUE;
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate }
7907c478bd9Sstevel@tonic-gate
791d0fa49b7STony Nguyen evmod = (au_emod_t)fad->fad_flags;
7927c478bd9Sstevel@tonic-gate if (fad->fad_aupath != NULL) {
7937c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_path(fad->fad_aupath));
7947c478bd9Sstevel@tonic-gate } else {
7957c478bd9Sstevel@tonic-gate #ifdef _LP64
7967c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_arg64(
797d2a70789SRichard Lowe 1, "no path: fp", (uint64_t)fp));
7987c478bd9Sstevel@tonic-gate #else
7997c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_arg32(
800d2a70789SRichard Lowe 1, "no path: fp", (uint32_t)fp));
8017c478bd9Sstevel@tonic-gate #endif
8027c478bd9Sstevel@tonic-gate }
8037c478bd9Sstevel@tonic-gate
804224626ecSMarek Pospisil if (audit_attr) {
8057c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_attr(&attr));
80645916cd2Sjpk audit_sec_attributes((caddr_t *)&(ad), vp);
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate
80981490fd2Sgww /* Add subject information */
81081490fd2Sgww AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
81145916cd2Sjpk
8127c478bd9Sstevel@tonic-gate /* add a return token */
8137c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(ad), tad->tad_scid, 0, 0);
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx);
8167c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx);
8177c478bd9Sstevel@tonic-gate
8187c478bd9Sstevel@tonic-gate /*
8197c478bd9Sstevel@tonic-gate * Close up everything
8207c478bd9Sstevel@tonic-gate * Note: path space recovery handled by normal system
8217c478bd9Sstevel@tonic-gate * call envelope if not at last close.
8227c478bd9Sstevel@tonic-gate * Note there is no failure at this point since
8237c478bd9Sstevel@tonic-gate * this represents closes due to exit of process,
8247c478bd9Sstevel@tonic-gate * thus we always indicate successful closes.
8257c478bd9Sstevel@tonic-gate */
8267c478bd9Sstevel@tonic-gate au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER,
827005d3febSMarek Pospisil AUE_CLOSE, evmod, NULL);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate /*
8317c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SET
8327c478bd9Sstevel@tonic-gate * PURPOSE: Audit the file path and file attributes.
8337c478bd9Sstevel@tonic-gate * CALLBY: SETF
8347c478bd9Sstevel@tonic-gate * NOTE: SETF associate a file pointer with user area's open files.
8357c478bd9Sstevel@tonic-gate * TODO:
8367c478bd9Sstevel@tonic-gate * call audit_finish directly ???
8377c478bd9Sstevel@tonic-gate * QUESTION:
8387c478bd9Sstevel@tonic-gate */
8397c478bd9Sstevel@tonic-gate
8407c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8417c478bd9Sstevel@tonic-gate void
audit_setf(file_t * fp,int fd)8427c478bd9Sstevel@tonic-gate audit_setf(file_t *fp, int fd)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate f_audit_data_t *fad;
8457c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate if (fp == NULL)
8487c478bd9Sstevel@tonic-gate return;
8497c478bd9Sstevel@tonic-gate
8507c478bd9Sstevel@tonic-gate tad = T2A(curthread);
8517c478bd9Sstevel@tonic-gate fad = F2A(fp);
8527c478bd9Sstevel@tonic-gate
8538fd04b83SRoger A. Faulkner if (!(tad->tad_scid == SYS_open ||
8548fd04b83SRoger A. Faulkner tad->tad_scid == SYS_open64 ||
8558fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat ||
8568fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat64))
8577c478bd9Sstevel@tonic-gate return;
8587c478bd9Sstevel@tonic-gate
8597c478bd9Sstevel@tonic-gate /* no path */
8607c478bd9Sstevel@tonic-gate if (tad->tad_aupath == 0)
8617c478bd9Sstevel@tonic-gate return;
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate /*
8647c478bd9Sstevel@tonic-gate * assign path information associated with file audit data
8657c478bd9Sstevel@tonic-gate * use tad hold
8667c478bd9Sstevel@tonic-gate */
8677c478bd9Sstevel@tonic-gate fad->fad_aupath = tad->tad_aupath;
8687c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL;
8697c478bd9Sstevel@tonic-gate
8704a0fa546SMarek Pospisil if (!(tad->tad_ctrl & TAD_TRUE_CREATE)) {
8718fd04b83SRoger A. Faulkner /* adjust event type by dropping the 'creat' part */
8727c478bd9Sstevel@tonic-gate switch (tad->tad_event) {
8737c478bd9Sstevel@tonic-gate case AUE_OPEN_RC:
8747c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_R;
8754a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_PUBLIC_EV;
8767c478bd9Sstevel@tonic-gate break;
8777c478bd9Sstevel@tonic-gate case AUE_OPEN_RTC:
8787c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RT;
8797c478bd9Sstevel@tonic-gate break;
8807c478bd9Sstevel@tonic-gate case AUE_OPEN_WC:
8817c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_W;
8827c478bd9Sstevel@tonic-gate break;
8837c478bd9Sstevel@tonic-gate case AUE_OPEN_WTC:
8847c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_WT;
8857c478bd9Sstevel@tonic-gate break;
8867c478bd9Sstevel@tonic-gate case AUE_OPEN_RWC:
8877c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RW;
8887c478bd9Sstevel@tonic-gate break;
8897c478bd9Sstevel@tonic-gate case AUE_OPEN_RWTC:
8907c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RWT;
8917c478bd9Sstevel@tonic-gate break;
8927c478bd9Sstevel@tonic-gate default:
8937c478bd9Sstevel@tonic-gate break;
8947c478bd9Sstevel@tonic-gate }
8957c478bd9Sstevel@tonic-gate }
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate
8987c478bd9Sstevel@tonic-gate
8997c478bd9Sstevel@tonic-gate void
audit_ipc(int type,int id,void * vp)9007c478bd9Sstevel@tonic-gate audit_ipc(int type, int id, void *vp)
9017c478bd9Sstevel@tonic-gate {
9027c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */
9037c478bd9Sstevel@tonic-gate if (ad_flag == 0)
9047c478bd9Sstevel@tonic-gate return;
9057c478bd9Sstevel@tonic-gate
9067c478bd9Sstevel@tonic-gate switch (type) {
9077c478bd9Sstevel@tonic-gate case AT_IPC_MSG:
9087c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_MSG, id));
9097c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
9107c478bd9Sstevel@tonic-gate break;
9117c478bd9Sstevel@tonic-gate case AT_IPC_SEM:
9127c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_SEM, id));
9137c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
9147c478bd9Sstevel@tonic-gate break;
9157c478bd9Sstevel@tonic-gate case AT_IPC_SHM:
9167c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_SHM, id));
9177c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
9187c478bd9Sstevel@tonic-gate break;
9197c478bd9Sstevel@tonic-gate }
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate void
audit_ipcget(int type,void * vp)9237c478bd9Sstevel@tonic-gate audit_ipcget(int type, void *vp)
9247c478bd9Sstevel@tonic-gate {
9257c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */
9267c478bd9Sstevel@tonic-gate if (ad_flag == 0)
9277c478bd9Sstevel@tonic-gate return;
9287c478bd9Sstevel@tonic-gate
9297c478bd9Sstevel@tonic-gate switch (type) {
930*0f48f68dSToomas Soome case 0:
9317c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm((struct kipc_perm *)vp));
9327c478bd9Sstevel@tonic-gate break;
9337c478bd9Sstevel@tonic-gate case AT_IPC_MSG:
9347c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
9357c478bd9Sstevel@tonic-gate break;
9367c478bd9Sstevel@tonic-gate case AT_IPC_SEM:
9377c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
9387c478bd9Sstevel@tonic-gate break;
9397c478bd9Sstevel@tonic-gate case AT_IPC_SHM:
9407c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
9417c478bd9Sstevel@tonic-gate break;
9427c478bd9Sstevel@tonic-gate }
9437c478bd9Sstevel@tonic-gate }
9447c478bd9Sstevel@tonic-gate
9457c478bd9Sstevel@tonic-gate /*
9467c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_REBOOT
9477c478bd9Sstevel@tonic-gate * PURPOSE:
9487c478bd9Sstevel@tonic-gate * CALLBY:
9497c478bd9Sstevel@tonic-gate * NOTE:
9507c478bd9Sstevel@tonic-gate * At this point we know that the system call reboot will not return. We thus
9517c478bd9Sstevel@tonic-gate * have to complete the audit record generation and put it onto the queue.
9527c478bd9Sstevel@tonic-gate * This might be fairly useless if the auditing daemon is already dead....
9537c478bd9Sstevel@tonic-gate * TODO:
9547c478bd9Sstevel@tonic-gate * QUESTION: who calls audit_reboot
9557c478bd9Sstevel@tonic-gate */
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate void
audit_reboot(void)9587c478bd9Sstevel@tonic-gate audit_reboot(void)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate int flag;
9617c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
9629e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ;
9637c478bd9Sstevel@tonic-gate
9647c478bd9Sstevel@tonic-gate tad = U2A(u);
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */
9677c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0)
9687c478bd9Sstevel@tonic-gate return;
9697c478bd9Sstevel@tonic-gate
9707c478bd9Sstevel@tonic-gate /* do preselection on success/failure */
971799bd290Spwernau if (flag = audit_success(kctx, tad, 0, NULL)) {
9727c478bd9Sstevel@tonic-gate /* add a process token */
9737c478bd9Sstevel@tonic-gate
9747c478bd9Sstevel@tonic-gate cred_t *cr = CRED();
9757c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr);
9767c478bd9Sstevel@tonic-gate
9777c478bd9Sstevel@tonic-gate if (ainfo == NULL)
9787c478bd9Sstevel@tonic-gate return;
9797c478bd9Sstevel@tonic-gate
98081490fd2Sgww /* Add subject information */
98181490fd2Sgww AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
98245916cd2Sjpk
9837c478bd9Sstevel@tonic-gate /* add a return token */
9847c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
9857c478bd9Sstevel@tonic-gate
9867c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx);
9877c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx);
9887c478bd9Sstevel@tonic-gate }
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate /*
9917c478bd9Sstevel@tonic-gate * Flow control useless here since we're going
9927c478bd9Sstevel@tonic-gate * to drop everything in the queue anyway. Why
9937c478bd9Sstevel@tonic-gate * block and wait. There aint anyone left alive to
9947c478bd9Sstevel@tonic-gate * read the records remaining anyway.
9957c478bd9Sstevel@tonic-gate */
9967c478bd9Sstevel@tonic-gate
9977c478bd9Sstevel@tonic-gate /* Close up everything */
9987c478bd9Sstevel@tonic-gate au_close(kctx, &(u_ad), flag | AU_DONTBLOCK,
999005d3febSMarek Pospisil tad->tad_event, tad->tad_evmod, NULL);
10007c478bd9Sstevel@tonic-gate }
10017c478bd9Sstevel@tonic-gate
10027c478bd9Sstevel@tonic-gate void
audit_setfsat_path(int argnum)10037c478bd9Sstevel@tonic-gate audit_setfsat_path(int argnum)
10047c478bd9Sstevel@tonic-gate {
10057c478bd9Sstevel@tonic-gate klwp_id_t clwp = ttolwp(curthread);
10067c478bd9Sstevel@tonic-gate struct file *fp;
10077c478bd9Sstevel@tonic-gate uint32_t fd;
10087c478bd9Sstevel@tonic-gate t_audit_data_t *tad;
10097c478bd9Sstevel@tonic-gate struct f_audit_data *fad;
10107c478bd9Sstevel@tonic-gate p_audit_data_t *pad; /* current process */
1011c4d3e299SBrent Paulson uint_t fm;
1012da6c28aaSamw struct a {
1013da6c28aaSamw long arg1;
1014da6c28aaSamw long arg2;
1015da6c28aaSamw long arg3;
1016da6c28aaSamw long arg4;
1017da6c28aaSamw long arg5;
1018da6c28aaSamw } *uap;
10197c478bd9Sstevel@tonic-gate
10207c478bd9Sstevel@tonic-gate if (clwp == NULL)
10217c478bd9Sstevel@tonic-gate return;
1022da6c28aaSamw uap = (struct a *)clwp->lwp_ap;
10237c478bd9Sstevel@tonic-gate
10247c478bd9Sstevel@tonic-gate tad = U2A(u);
10257c478bd9Sstevel@tonic-gate ASSERT(tad != NULL);
10267c478bd9Sstevel@tonic-gate
10278fd04b83SRoger A. Faulkner switch (tad->tad_scid) {
10288fd04b83SRoger A. Faulkner case SYS_faccessat:
1029794f0adbSRoger A. Faulkner case SYS_fchmodat:
10308fd04b83SRoger A. Faulkner case SYS_fchownat:
10318fd04b83SRoger A. Faulkner case SYS_fstatat:
10328fd04b83SRoger A. Faulkner case SYS_fstatat64:
1033794f0adbSRoger A. Faulkner case SYS_mkdirat:
1034794f0adbSRoger A. Faulkner case SYS_mknodat:
10358fd04b83SRoger A. Faulkner case SYS_openat:
10368fd04b83SRoger A. Faulkner case SYS_openat64:
1037794f0adbSRoger A. Faulkner case SYS_readlinkat:
10388fd04b83SRoger A. Faulkner case SYS_unlinkat:
10398fd04b83SRoger A. Faulkner fd = uap->arg1;
10407c478bd9Sstevel@tonic-gate break;
1041794f0adbSRoger A. Faulkner case SYS_linkat:
10428fd04b83SRoger A. Faulkner case SYS_renameat:
10438fd04b83SRoger A. Faulkner if (argnum == 3)
10448fd04b83SRoger A. Faulkner fd = uap->arg3;
10458fd04b83SRoger A. Faulkner else
10468fd04b83SRoger A. Faulkner fd = uap->arg1;
10477c478bd9Sstevel@tonic-gate break;
1048794f0adbSRoger A. Faulkner case SYS_symlinkat:
10498fd04b83SRoger A. Faulkner case SYS_utimesys:
10508fd04b83SRoger A. Faulkner fd = uap->arg2;
10517c478bd9Sstevel@tonic-gate break;
1052c4d3e299SBrent Paulson case SYS_open:
1053c4d3e299SBrent Paulson case SYS_open64:
1054c4d3e299SBrent Paulson fd = AT_FDCWD;
1055c4d3e299SBrent Paulson break;
10567c478bd9Sstevel@tonic-gate default:
10577c478bd9Sstevel@tonic-gate return;
10587c478bd9Sstevel@tonic-gate }
10597c478bd9Sstevel@tonic-gate
10607c478bd9Sstevel@tonic-gate if (tad->tad_atpath != NULL) {
10617c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_atpath);
10627c478bd9Sstevel@tonic-gate tad->tad_atpath = NULL;
10637c478bd9Sstevel@tonic-gate }
1064c4d3e299SBrent Paulson
10657c478bd9Sstevel@tonic-gate if (fd != AT_FDCWD) {
1066