summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Pospisil <Marek.Pospisil@Sun.COM>2010-03-05 13:16:08 -0800
committerMarek Pospisil <Marek.Pospisil@Sun.COM>2010-03-05 13:16:08 -0800
commit005d3feb53a9a10272d4a24b03991575d6a9bcb3 (patch)
tree3c239c5ec7be3de4c1719c4539033149da56a799
parent83d7a2524bdbf7b1da1c47b52bc20eee0f12c60e (diff)
downloadillumos-gate-005d3feb53a9a10272d4a24b03991575d6a9bcb3.tar.gz
PSARC/2009/354 Always on / no reboot Solaris Audit
6192139 Solaris auditing should be able to start collecting audit records without a reboot
-rw-r--r--usr/src/cmd/audit/audit.c35
-rw-r--r--usr/src/cmd/bsmconv/bsmconv.sh79
-rw-r--r--usr/src/cmd/bsmunconv/bsmunconv.sh86
-rw-r--r--usr/src/cmd/tsol/labeld/svc-labeld12
-rw-r--r--usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c17
-rw-r--r--usr/src/uts/common/Makefile.files5
-rw-r--r--usr/src/uts/common/c2/audit.c255
-rw-r--r--usr/src/uts/common/c2/audit.h46
-rw-r--r--usr/src/uts/common/c2/audit_event.c38
-rw-r--r--usr/src/uts/common/c2/audit_io.c34
-rw-r--r--usr/src/uts/common/c2/audit_kernel.h19
-rw-r--r--usr/src/uts/common/c2/audit_mem.c39
-rw-r--r--usr/src/uts/common/c2/audit_path.c69
-rw-r--r--usr/src/uts/common/c2/audit_record.h7
-rw-r--r--usr/src/uts/common/c2/audit_start.c178
-rw-r--r--usr/src/uts/common/c2/audit_syscalls.c1518
-rw-r--r--usr/src/uts/common/crypto/io/cryptoadm.c21
-rw-r--r--usr/src/uts/common/fs/lookup.c27
-rw-r--r--usr/src/uts/common/fs/sockfs/sockstr.c7
-rw-r--r--usr/src/uts/common/fs/sockfs/socksubr.c5
-rw-r--r--usr/src/uts/common/fs/sockfs/socktpi.c13
-rw-r--r--usr/src/uts/common/fs/vnode.c10
-rw-r--r--usr/src/uts/common/inet/ip/spdsock.c52
-rw-r--r--usr/src/uts/common/inet/kssl/kssl.c7
-rw-r--r--usr/src/uts/common/io/timod.c171
-rw-r--r--usr/src/uts/common/os/audit_core.c439
-rw-r--r--usr/src/uts/common/os/audit_memory.c123
-rw-r--r--usr/src/uts/common/os/audit_zone.c (renamed from usr/src/uts/common/c2/audit_zone.c)18
-rw-r--r--usr/src/uts/common/os/cred.c11
-rw-r--r--usr/src/uts/common/os/devpolicy.c6
-rw-r--r--usr/src/uts/common/os/exec.c2
-rw-r--r--usr/src/uts/common/os/exit.c2
-rw-r--r--usr/src/uts/common/os/fio.c10
-rw-r--r--usr/src/uts/common/os/ipc.c16
-rw-r--r--usr/src/uts/common/os/main.c10
-rw-r--r--usr/src/uts/common/os/msg.c6
-rw-r--r--usr/src/uts/common/os/policy.c8
-rw-r--r--usr/src/uts/common/os/shm.c2
-rw-r--r--usr/src/uts/common/os/sig.c11
-rw-r--r--usr/src/uts/common/os/streamio.c18
-rw-r--r--usr/src/uts/common/os/sysent.c4
-rw-r--r--usr/src/uts/common/os/zone.c3
-rw-r--r--usr/src/uts/common/sys/proc.h3
-rw-r--r--usr/src/uts/common/sys/systm.h2
-rw-r--r--usr/src/uts/common/syscall/access.c2
-rw-r--r--usr/src/uts/common/syscall/auditsys.c1386
-rw-r--r--usr/src/uts/common/syscall/chdir.c7
-rw-r--r--usr/src/uts/common/syscall/chown.c2
-rw-r--r--usr/src/uts/common/syscall/open.c8
-rw-r--r--usr/src/uts/common/syscall/ppriv.c2
-rw-r--r--usr/src/uts/common/syscall/sem.c6
-rw-r--r--usr/src/uts/common/syscall/stat.c4
-rw-r--r--usr/src/uts/common/syscall/symlink.c6
-rw-r--r--usr/src/uts/common/syscall/ucredsys.c9
-rw-r--r--usr/src/uts/common/syscall/unlink.c2
-rw-r--r--usr/src/uts/common/syscall/utime.c2
-rw-r--r--usr/src/uts/i86pc/os/machdep.c7
-rw-r--r--usr/src/uts/i86pc/os/trap.c5
-rw-r--r--usr/src/uts/intel/ia32/ml/modstubs.s17
-rw-r--r--usr/src/uts/intel/ia32/os/syscall.c71
-rw-r--r--usr/src/uts/sparc/ml/modstubs.s19
-rw-r--r--usr/src/uts/sparc/os/syscall.c66
-rw-r--r--usr/src/uts/sun4/os/cpu_states.c22
63 files changed, 2618 insertions, 2469 deletions
diff --git a/usr/src/cmd/audit/audit.c b/usr/src/cmd/audit/audit.c
index 66a4553203..bf31448d13 100644
--- a/usr/src/cmd/audit/audit.c
+++ b/usr/src/cmd/audit/audit.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,7 +50,6 @@
/* GLOBALS */
static char *progname = "audit";
static char *usage = "audit [-n] | [-s] | [-t] | [-v filepath]";
-static int silent = 0;
static void display_smf_error();
@@ -70,9 +69,7 @@ static int sig_auditd(int); /* send signal to auditd */
* audit -n
* - signal audit daemon to use next audit_control audit directory.
* audit -t
- * - signal audit daemon to disable auditing.
- * audit -T
- * - signal audit daemon to disable auditing report no errors.
+ * - signal audit daemon to permanently disable auditing.
* audit -v filepath
* - validate audit_control parameters but use filepath for
* the name. Emit errors or "syntax ok"
@@ -95,13 +92,13 @@ main(int argc, char *argv[])
(void) textdomain(TEXT_DOMAIN);
/* first option required */
- if ((c = getopt(argc, argv, "nstTv:")) == -1) {
+ if ((c = getopt(argc, argv, "nstv:")) == -1) {
(void) fprintf(stderr, gettext("usage: %s\n"), usage);
exit(3);
}
first_option = optarg;
/* second or more options not allowed; please pick one */
- if (getopt(argc, argv, "nstTv:") != -1) {
+ if (getopt(argc, argv, "nstv:") != -1) {
(void) fprintf(stderr, gettext("usage: %s\n"), usage);
exit(5);
}
@@ -123,21 +120,11 @@ main(int argc, char *argv[])
case 't':
if (!is_valid_zone(0)) /* 0 == no error message display */
exit(10);
- /* use bmsunconv to permanently disable, -t for temporary */
- if (smf_disable_instance(AUDITD_FMRI, SMF_TEMPORARY) != 0) {
+ if (smf_disable_instance(AUDITD_FMRI, 0) != 0) {
display_smf_error();
exit(11);
}
break;
- case 'T':
- silent = 1;
- if (!is_valid_zone(0)) /* 0 == no error message display */
- exit(10);
-
- if (smf_disable_instance(AUDITD_FMRI, SMF_TEMPORARY) != 0) {
- exit(11);
- }
- break;
case 'v':
if (is_audit_control_ok(first_option)) {
(void) fprintf(stderr, gettext("syntax ok\n"));
@@ -302,11 +289,6 @@ is_audit_control_ok(char *filename) {
/*
* The operations that call this function are only valid in the global
* zone unless the perzone audit policy is set.
- *
- * "!silent" and "show_err" are slightly different; silent is from
- * -T for which no error messages should be displayed and show_err
- * applies to more options (including -T)
- *
*/
static boolean_t
@@ -315,10 +297,9 @@ is_valid_zone(boolean_t show_err)
long policy;
if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) {
- if (!silent)
- (void) fprintf(stderr, gettext(
- "%s: Cannot read audit policy: %s\n"),
- progname, strerror(errno));
+ (void) fprintf(stderr, gettext(
+ "%s: Cannot read audit policy: %s\n"),
+ progname, strerror(errno));
return (0);
}
if (policy & AUDIT_PERZONE)
diff --git a/usr/src/cmd/bsmconv/bsmconv.sh b/usr/src/cmd/bsmconv/bsmconv.sh
index f562c5390d..5a4c653a4d 100644
--- a/usr/src/cmd/bsmconv/bsmconv.sh
+++ b/usr/src/cmd/bsmconv/bsmconv.sh
@@ -20,22 +20,28 @@
#
# CDDL HEADER END
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
PROG=bsmconv
-DEVALLOC=/etc/security/device_allocate
-DEVMAPS=/etc/security/device_maps
+
TEXTDOMAIN="SUNW_OST_OSCMD"
export TEXTDOMAIN
+DEVALLOC=/etc/security/device_allocate
+DEVMAPS=/etc/security/device_maps
+DEVFSADM=/usr/sbin/devfsadm
+MKDEVALLOC=/usr/sbin/mkdevalloc
+MKDEVMAPS=/usr/sbin/mkdevmaps
+ZONENAME=/sbin/zonename
+
# Perform required permission checks, depending on value of LOCAL_ROOT
# (whether we are converting the active OS or just alternative boot
# environments).
permission()
{
-ZONE=`/sbin/zonename`
+ZONE=`${ZONENAME}`
if [ ! "$ZONE" = "global" -a "$LOCAL_ROOT" = "true" ]
then
form=`gettext "%s: ERROR: you must be in the global zone to run this script."`
@@ -54,7 +60,7 @@ fi
RESP="x"
while [ "$RESP" != `gettext "y"` -a "$RESP" != `gettext "n"` ]
do
-gettext "This script is used to enable Solaris Auditing and device allocation.\n"
+gettext "This script is used to enable device allocation.\n"
form=`gettext "Shall we continue with the conversion now? [y/n]"`
echo "$form \c"
read RESP
@@ -74,7 +80,6 @@ sanity_check()
{
for ROOT in $@
do
-
if [ -d $ROOT -a -w $ROOT -a -f $ROOT/etc/system -a -d $ROOT/usr ]
then
# There is a root directory to write to,
@@ -90,12 +95,11 @@ do
done
}
-# bsmconvert
+# dev_allocation_convert
# All the real work gets done in this function
-bsmconvert()
+dev_allocation_convert()
{
-
# Prevent automount of removable and hotpluggable volumes
# by forcing volume.ignore HAL property on all such volumes.
if [ -d ${ROOT}/etc/hal/fdi ] ; then
@@ -116,27 +120,6 @@ if [ -d ${ROOT}/etc/hal/fdi ] ; then
FDI
fi
-# Turn on auditing in the loadable module
-
-form=`gettext "%s: INFO: turning on audit module."`
-printf "${form}\n" $PROG
-if [ ! -f ${ROOT}/etc/system ]
-then
- echo "" > ${ROOT}/etc/system
-fi
-
-grep -v "c2audit:audit_load" ${ROOT}/etc/system > /tmp/etc.system.$$
-echo "set c2audit:audit_load = 1" >> /tmp/etc.system.$$
-mv /tmp/etc.system.$$ ${ROOT}/etc/system
-grep "set c2audit:audit_load = 1" ${ROOT}/etc/system > /dev/null 2>&1
-if [ $? -ne 0 ]
-then
- form=`gettext "%s: ERROR: cannot 'set c2audit:audit_load = 1' in %s/etc/system"`
- printf "${form}\n" $PROG $ROOT
- form=`gettext "%s: Continuing ..."`
- printf "${form}\n" $PROG
-fi
-
# Initialize device allocation
form=`gettext "%s: INFO: initializing device allocation."`
@@ -155,23 +138,18 @@ if [ $? = 0 ]; then
# This is not currently done for alternate boot environments.
if [ -z "$ROOT" -o "$ROOT" = "/" ]
then
- /usr/sbin/devfsadm -e
+ ${DEVFSADM} -e
fi
else
if [ ! -f ${ROOT}/${DEVALLOC} ]
then
- mkdevalloc > ${ROOT}/$DEVALLOC
+ ${MKDEVALLOC} > ${ROOT}/$DEVALLOC
fi
if [ ! -f ${ROOT}/${DEVMAPS} ]
then
- mkdevmaps > ${ROOT}/$DEVMAPS
+ ${MKDEVMAPS} > ${ROOT}/$DEVMAPS
fi
fi
-
-# enable auditd at next boot.
-cat >> ${ROOT}/var/svc/profile/upgrade <<SVC_UPGRADE
-/usr/sbin/svcadm enable system/auditd
-SVC_UPGRADE
}
# main loop
@@ -184,15 +162,13 @@ then
permission
ROOT=
- bsmconvert
+
+ dev_allocation_convert
echo
- gettext "Solaris Auditing and device allocation is ready.\n"
- gettext "If there were any errors, please fix them now.\n"
- gettext "Configure Solaris Auditing and device allocation by editing "
- gettext "files\nlocated in /etc/security.\n"
- gettext "Reboot this system now to come up with auditing "
- gettext "and device allocation enabled.\n"
+ gettext "Device allocation is ready. If there were any errors, please\n"
+ gettext "fix them now. Reboot this system now to come up with device\n"
+ gettext "allocation enabled."
else
# determine if local root is being converted ("/" passed on
# command line), if so, full permission check required
@@ -213,18 +189,15 @@ else
do
form=`gettext "%s: INFO: converting boot environment %s ..."`
printf "${form}\n" $PROG $ROOT
- bsmconvert $ROOT
+ dev_allocation_convert $ROOT
form=`gettext "%s: INFO: done with boot environment %s"`
printf "${form}\n" $PROG $ROOT
done
+
echo
- gettext "Solaris Auditing and device allocation is ready.\n"
- gettext "If there were any errors, please fix them now.\n"
- gettext "Configure Solaris auditing and device allocation by editing "
- gettext "files\nlocated in /etc/security in the root directories "
- gettext "of each host converted.\n"
- gettext "Reboot each system converted to come up with auditing "
- gettext "and device\nallocation enabled.\n"
+ gettext "Device allocation is ready. If there were any errors,\n"
+ gettext "please fix them now. Reboot each non-local system\n"
+ gettext "converted to come up with device allocation enabled.\n"
fi
exit 0
diff --git a/usr/src/cmd/bsmunconv/bsmunconv.sh b/usr/src/cmd/bsmunconv/bsmunconv.sh
index 060662a8b3..f8c1f36e59 100644
--- a/usr/src/cmd/bsmunconv/bsmunconv.sh
+++ b/usr/src/cmd/bsmunconv/bsmunconv.sh
@@ -21,15 +21,18 @@
#
# CDDL HEADER END
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
PROG=bsmunconv
+PATH=/usr/sbin:/usr/bin:/sbin
+
TEXTDOMAIN="SUNW_OST_OSCMD"
export TEXTDOMAIN
+ZONENAME=/sbin/zonename
+DEVFSADM=/usr/sbin/devfsadm
+
# Perform required permission checks, depending on value of LOCAL_ROOT
# (whether we are converting the active OS or just alternative boot
@@ -37,7 +40,7 @@ export TEXTDOMAIN
permission()
{
cd /usr/lib
-ZONE=`/sbin/zonename`
+ZONE=`${ZONENAME}`
if [ ! "$ZONE" = "global" -a "$LOCAL_ROOT" = "true" ]
then
form=`gettext "%s: ERROR: you must be in the global zone to run this script."`
@@ -53,24 +56,10 @@ then
exit 1
fi
-set -- `/usr/bin/who -r`
-RUNLEVEL="$3"
-if [ "$RUNLEVEL" -ne "S" -a "$LOCAL_ROOT" = "true" ]
-then
- form=`gettext "%s: ERROR: this script should be run at run level S."`
- printf "${form}\n" $PROG
- form=`gettext "Are you sure you want to continue? [y/n]"`
- echo "$form \c"
- read RESP
- case $RESP in
- `gettext "n"`*|`gettext "N"`* ) exit 1 ;;
- esac
-fi
-
RESP="x"
while [ "$RESP" != `gettext "y"` -a "$RESP" != `gettext "n"` ]
do
-gettext "This script is used to disable Solaris Auditing and device allocation.\n"
+gettext "This script is used to disable device allocation.\n"
form=`gettext "Would you like to continue now? [y/n]"`
echo "$form \c"
read RESP
@@ -84,56 +73,19 @@ then
fi
}
-bsmunconvert()
+# disable device allocation
+
+dev_allocation_unconvert()
{
# Turn off device allocation. This is not currently done for alternate
# boot environments.
if [ -z "$ROOT" -o "$ROOT" = "/" ]
then
- /usr/sbin/devfsadm -d
+ ${DEVFSADM} -d
fi
-# disable auditd service on next boot
-cat >> ${ROOT}/var/svc/profile/upgrade <<SVC_UPGRADE
-/usr/sbin/svcadm disable system/auditd
-SVC_UPGRADE
-
# Restore default policy for removable and hotpluggable volumes
rm -f ${ROOT}/etc/hal/fdi/policy/30user/90-solaris-device-allocation.fdi
-
-# Turn off auditing in the loadable module
-
-if [ -f ${ROOT}/etc/system ]
-then
- form=`gettext "%s: INFO: removing c2audit:audit_load from %s/etc/system."`
- printf "${form}\n" $PROG $ROOT
- grep -v "c2audit:audit_load" ${ROOT}/etc/system > /tmp/etc.system.$$
- mv /tmp/etc.system.$$ ${ROOT}/etc/system
-else
- form=`gettext "%s: ERROR: can't find %s/etc/system."`
- printf "${form}\n" $PROG $ROOT
- form=`gettext "%s: ERROR: audit module may not be disabled."`
- printf "${form}\n" $PROG
-fi
-
-# If we are currently converting the active host (${ROOT}="/") we will
-# need to ensure that cron is not running. cron should not be running
-# at run-level S, but it may have been started by hand.
-
-if [ -z "$ROOT" -o "$ROOT" = "/" ]
-then
- /usr/bin/pgrep -u root -f /usr/sbin/cron > /dev/null
- if [ $? -eq 0 ]; then
- form=`gettext "%s: INFO: stopping the cron daemon."`
- printf "${form}\n" $PROG
-
- /usr/sbin/svcadm disable -t system/cron
- fi
-fi
-
-rm -f ${ROOT}/var/spool/cron/atjobs/*.au
-rm -f ${ROOT}/var/spool/cron/crontabs/*.au
-
}
# main
@@ -147,10 +99,12 @@ then
# begin conversion
ROOT=
- bsmunconvert
+
+ dev_allocation_unconvert
+
echo
- gettext "Solaris Auditing and device allocation has been disabled.\n"
- gettext "Reboot the system now to come up without these features.\n"
+ gettext "Device allocation has been disabled. Reboot the system now\n"
+ gettext "to come up without this feature.\n"
else
# determine if local root is being converted ("/" passed on
@@ -170,12 +124,12 @@ else
for ROOT in $@
do
- bsmunconvert $ROOT
+ dev_allocation_unconvert $ROOT
done
echo
- gettext "Solaris Auditing and device allocation has been disabled.\n"
- gettext "Reboot each system that was disabled to come up without these features.\n"
+ gettext "Device allocation has been disabled. Reboot each non-local\n"
+ gettext "system that was disabled to come up without this feature.\n"
fi
exit 0
diff --git a/usr/src/cmd/tsol/labeld/svc-labeld b/usr/src/cmd/tsol/labeld/svc-labeld
index e924c28c60..028c93fad6 100644
--- a/usr/src/cmd/tsol/labeld/svc-labeld
+++ b/usr/src/cmd/tsol/labeld/svc-labeld
@@ -90,7 +90,7 @@ __ENABLE_OTHERS
do_bsmconv()
{
- # Run bsmconv so audit and device allocation is enabled by
+ # Run bsmconv so device allocation is enabled by
# default with Trusted Extensions.
if [ "$ROOT_PATH" = "/" -o "$ROOT_PATH" = "" ]; then
BSMDIR=""
@@ -100,6 +100,16 @@ do_bsmconv()
echo "Running bsmconv ..."
echo `TEXTDOMAIN="SUNW_OST_OSCMD" gettext "y"` | \
$ROOT_PATH/etc/security/bsmconv $ROOT_PATH
+ # Run auditd so auditing is enabled by default
+ # with Trusted Extensions.
+ if [ "$BSMDIR" = "" ]; then
+ echo "Starting auditd ..."
+ /usr/sbin/audit -s
+ else
+ cat >> $ROOT_PATH/var/svc/profile/upgrade <<\_ENABLE_AUDITD
+ /usr/sbin/audit -s
+_ENABLE_AUDITD
+ fi
}
do_nscd()
diff --git a/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
index a5176e4179..35a0926d7b 100644
--- a/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
+++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
@@ -1244,6 +1244,7 @@ s10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz)
#define S10_AUDIT_HMASK 0xffffffc0
#define S10_AUDIT_LMASK 0x3f
+#define S10_AUC_NOSPACE 0x3
int
s10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2)
@@ -1270,6 +1271,22 @@ s10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2)
m = ((m >> 1) & S10_AUDIT_HMASK) | (m & S10_AUDIT_LMASK);
return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
a2));
+ } else if ((int)a0 == A_GETCOND) {
+ if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
+ &m, a2)) != 0)
+ return (err);
+ if (m == AUC_NOSPACE)
+ m = S10_AUC_NOSPACE;
+ if (s10_uucopy(&m, (void *)a1, sizeof (m)) != 0)
+ return (EFAULT);
+ return (0);
+ } else if ((int)a0 == A_SETCOND) {
+ if (s10_uucopy((const void *)a1, &m, sizeof (m)) != 0)
+ return (EFAULT);
+ if (m == S10_AUC_NOSPACE)
+ m = AUC_NOSPACE;
+ return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
+ a2));
}
return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, a2));
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index b751c7e30a..acf8cb24c2 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -92,6 +92,9 @@ GENUNIX_OBJS += \
alarm.o \
aio_subr.o \
auditsys.o \
+ audit_core.o \
+ audit_zone.o \
+ audit_memory.o \
autoconf.o \
avl.o \
bdev_dsort.o \
@@ -1535,7 +1538,7 @@ KSSL_OBJS += kssl.o ksslioctl.o ksslapi.o ksslrec.o
C2AUDIT_OBJS += adr.o audit.o audit_event.o audit_io.o \
audit_path.o audit_start.o audit_syscalls.o audit_token.o \
- audit_mem.o audit_zone.o
+ audit_mem.o
PCIC_OBJS += pcic.o
diff --git a/usr/src/uts/common/c2/audit.c b/usr/src/uts/common/c2/audit.c
index 7c12cf3406..3641e2b212 100644
--- a/usr/src/uts/common/c2/audit.c
+++ b/usr/src/uts/common/c2/audit.c
@@ -68,175 +68,6 @@ static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
static void audit_pathbuild(struct pathname *pnp);
-/*
- * ROUTINE: AUDIT_NEWPROC
- * PURPOSE: initialize the child p_audit_data structure
- * CALLBY: GETPROC
- * NOTE: All threads for the parent process are locked at this point.
- * We are essentially running singled threaded for this reason.
- * GETPROC is called when system creates a new process.
- * By the time AUDIT_NEWPROC is called, the child proc
- * structure has already been initialized. What we need
- * to do is to allocate the child p_audit_data and
- * initialize it with the content of current parent process.
- */
-
-void
-audit_newproc(struct proc *cp) /* initialized child proc structure */
-{
- p_audit_data_t *pad; /* child process audit data */
- p_audit_data_t *opad; /* parent process audit data */
-
- pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
-
- P2A(cp) = pad;
-
- opad = P2A(curproc);
-
- /*
- * copy the audit data. Note that all threads of current
- * process have been "held". Thus there is no race condition
- * here with mutiple threads trying to alter the cwrd
- * structure (such as releasing it).
- *
- * The audit context in the cred is "duplicated" for the new
- * proc by elsewhere crhold'ing the parent's cred which it shares.
- *
- * We still want to hold things since auditon() [A_SETUMASK,
- * A_SETSMASK] could be walking through the processes to
- * update things.
- */
- mutex_enter(&opad->pad_lock); /* lock opad structure during copy */
- pad->pad_data = opad->pad_data; /* copy parent's process audit data */
- au_pathhold(pad->pad_root);
- au_pathhold(pad->pad_cwd);
- mutex_exit(&opad->pad_lock); /* current proc will keep cwrd open */
-
- /*
- * finish auditing of parent here so that it will be done
- * before child has a chance to run. We include the child
- * pid since the return value in the return token is a dummy
- * one and contains no useful information (it is included to
- * make the audit record structure consistant).
- *
- * tad_flag is set if auditing is on
- */
- if (((t_audit_data_t *)T2A(curthread))->tad_flag)
- au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
-
- /*
- * finish up audit record generation here because child process
- * is set to run before parent process. We distinguish here
- * between FORK, FORK1, or VFORK by the saved system call ID.
- */
- audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
-}
-
-/*
- * ROUTINE: AUDIT_PFREE
- * PURPOSE: deallocate the per-process udit data structure
- * CALLBY: EXIT
- * FORK_FAIL
- * NOTE: all lwp except current one have stopped in SEXITLWPS
- * why we are single threaded?
- * . all lwp except current one have stopped in SEXITLWPS.
- */
-void
-audit_pfree(struct proc *p) /* proc structure to be freed */
-
-{ /* AUDIT_PFREE */
-
- p_audit_data_t *pad;
-
- pad = P2A(p);
-
- /* better be a per process audit data structure */
- ASSERT(pad != (p_audit_data_t *)0);
-
- if (pad == pad0) {
- return;
- }
-
- /* deallocate all auditing resources for this process */
- au_pathrele(pad->pad_root);
- au_pathrele(pad->pad_cwd);
-
- /*
- * Since the pad structure is completely overwritten after alloc,
- * we don't bother to clear it.
- */
-
- kmem_cache_free(au_pad_cache, pad);
-}
-
-/*
- * ROUTINE: AUDIT_THREAD_CREATE
- * PURPOSE: allocate per-process thread audit data structure
- * CALLBY: THREAD_CREATE
- * NOTE: This is called just after *t was bzero'd.
- * We are single threaded in this routine.
- * TODO:
- * QUESTION:
- */
-
-void
-audit_thread_create(kthread_id_t t)
-{
- t_audit_data_t *tad; /* per-thread audit data */
-
- tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
-
- T2A(t) = tad; /* set up thread audit data ptr */
- tad->tad_thread = t; /* back ptr to thread: DEBUG */
-}
-
-/*
- * ROUTINE: AUDIT_THREAD_FREE
- * PURPOSE: free the per-thread audit data structure
- * CALLBY: THREAD_FREE
- * NOTE: most thread data is clear after return
- */
-void
-audit_thread_free(kthread_t *t)
-{
- t_audit_data_t *tad;
- au_defer_info_t *attr;
-
- tad = T2A(t);
-
- /* thread audit data must still be set */
-
- if (tad == tad0) {
- return;
- }
-
- if (tad == NULL) {
- return;
- }
-
- t->t_audit_data = 0;
-
- /* must not have any audit record residual */
- ASSERT(tad->tad_ad == NULL);
-
- /* saved path must be empty */
- ASSERT(tad->tad_aupath == NULL);
-
- if (tad->tad_atpath)
- au_pathrele(tad->tad_atpath);
-
- attr = tad->tad_defer_head;
- while (attr != NULL) {
- au_defer_info_t *tmp_attr = attr;
-
- au_free_rec(attr->audi_ad);
-
- attr = attr->audi_next;
- kmem_free(tmp_attr, sizeof (au_defer_info_t));
- }
-
- kmem_free(tad, sizeof (*tad));
-}
/*
* ROUTINE: AUDIT_SAVEPATH
@@ -448,12 +279,6 @@ audit_addcomponent(struct pathname *pnp)
} /* AUDIT_ADDCOMPONENT */
-
-
-
-
-
-
/*
* ROUTINE: AUDIT_ANCHORPATH
* PURPOSE:
@@ -678,58 +503,6 @@ audit_attributes(struct vnode *vp)
/*
- * ROUTINE: AUDIT_FALLOC
- * PURPOSE: allocating a new file structure
- * CALLBY: FALLOC
- * NOTE: file structure already initialized
- * TODO:
- * QUESTION:
- */
-
-void
-audit_falloc(struct file *fp)
-{ /* AUDIT_FALLOC */
-
- f_audit_data_t *fad;
-
- /* allocate per file audit structure if there a'int any */
- ASSERT(F2A(fp) == NULL);
-
- fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
-
- F2A(fp) = fad;
-
- fad->fad_thread = curthread; /* file audit data back ptr; DEBUG */
-}
-
-/*
- * ROUTINE: AUDIT_UNFALLOC
- * PURPOSE: deallocate file audit data structure
- * CALLBY: CLOSEF
- * UNFALLOC
- * NOTE:
- * TODO:
- * QUESTION:
- */
-
-void
-audit_unfalloc(struct file *fp)
-{
- f_audit_data_t *fad;
-
- fad = F2A(fp);
-
- if (!fad) {
- return;
- }
- if (fad->fad_aupath != NULL) {
- au_pathrele(fad->fad_aupath);
- }
- fp->f_audit_data = 0;
- kmem_free(fad, sizeof (struct f_audit_data));
-}
-
-/*
* ROUTINE: AUDIT_EXIT
* PURPOSE:
* CALLBY: EXIT
@@ -769,7 +542,7 @@ audit_exit(int code, int what)
/*
* Generate an audit record for process exit if preselected.
*/
- (void) audit_start(0, SYS_exit, 0, 0);
+ (void) audit_start(0, SYS_exit, AUC_UNSET, 0, 0);
audit_finish(0, SYS_exit, 0, 0);
}
@@ -883,7 +656,7 @@ audit_core_finish(int code)
}
/* Close up everything */
- au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod);
+ au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod, NULL);
/* free up any space remaining with the path's */
if (tad->tad_aupath != NULL) {
@@ -1010,6 +783,7 @@ audit_closef(struct file *fp)
int getattr_ret;
cred_t *cr;
au_kcontext_t *kctx = GET_KCTX_PZ;
+ uint32_t auditing;
fad = F2A(fp);
estate = kctx->auk_ets[AUE_CLOSE];
@@ -1024,9 +798,9 @@ audit_closef(struct file *fp)
}
/* if auditing not enabled, then don't generate an audit record */
- if (!((kctx->auk_auditstate == AUC_AUDITING ||
- kctx->auk_auditstate == AUC_INIT_AUDIT) ||
- kctx->auk_auditstate == AUC_NOSPACE))
+ auditing = (tad->tad_audit == AUC_UNSET) ?
+ kctx->auk_auditstate : tad->tad_audit;
+ if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT | AUC_NOSPACE))
return;
ainfo = crgetauinfo(cr);
@@ -1094,7 +868,7 @@ audit_closef(struct file *fp)
* thus we always indicate successful closes.
*/
au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER,
- AUE_CLOSE, evmod);
+ AUE_CLOSE, evmod, NULL);
}
/*
@@ -1281,7 +1055,7 @@ audit_reboot(void)
/* Close up everything */
au_close(kctx, &(u_ad), flag | AU_DONTBLOCK,
- tad->tad_event, tad->tad_evmod);
+ tad->tad_event, tad->tad_evmod, NULL);
}
void
@@ -1517,7 +1291,7 @@ audit_enterprom(int flg)
else
au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
- AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, NULL);
+ AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, NULL, NULL);
}
@@ -1550,7 +1324,7 @@ audit_exitprom(int flg)
else
au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
- AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, NULL);
+ AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, NULL, NULL);
}
struct fcntla {
@@ -2218,7 +1992,8 @@ audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names,
AS_INC(as_generated, 1, kctx);
AS_INC(as_kernel, 1, kctx);
- au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, tad->tad_evmod);
+ au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, tad->tad_evmod,
+ NULL);
}
/*
@@ -2290,7 +2065,8 @@ audit_kssl(int cmd, void *params, int error)
AS_INC(as_generated, 1, kctx);
AS_INC(as_kernel, 1, kctx);
- au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CONFIGKSSL, tad->tad_evmod);
+ au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CONFIGKSSL, tad->tad_evmod,
+ NULL);
}
/*
@@ -2422,7 +2198,8 @@ audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun,
AS_INC(as_kernel, 1, kctx);
}
- au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, tad->tad_evmod);
+ au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, tad->tad_evmod,
+ NULL);
/*
* clear the ctrl flag so that we don't have spurious collection of
diff --git a/usr/src/uts/common/c2/audit.h b/usr/src/uts/common/c2/audit.h
index 0cc71d6cd6..836a66e0f7 100644
--- a/usr/src/uts/common/c2/audit.h
+++ b/usr/src/uts/common/c2/audit.h
@@ -51,10 +51,10 @@ extern "C" {
#define AUC_UNSET 0 /* on/off hasn't been decided */
#define AUC_ENABLED 1 /* loaded and enabled */
/* local zone state */
-#define AUC_INIT_AUDIT 4 /* c2audit is ready but auditd has not run */
-#define AUC_AUDITING 1 /* auditing is being done */
-#define AUC_NOAUDIT 2 /* auditing is not being done */
-#define AUC_NOSPACE 3 /* audit enabled, no space for audit records */
+#define AUC_INIT_AUDIT 0x4 /* c2audit is ready but auditd has not run */
+#define AUC_AUDITING 0x1 /* auditing is being done */
+#define AUC_NOAUDIT 0x2 /* auditing is not being done */
+#define AUC_NOSPACE 0x8 /* audit enabled, no space for audit records */
/*
* The user id -2 is never audited - in fact, a setauid(AU_NOAUDITID)
@@ -470,6 +470,7 @@ typedef struct audit_stat au_stat_t;
#include <c2/audit_door_infc.h>
#include <sys/crypto/ioctladmin.h>
#include <sys/netstack.h>
+#include <sys/zone.h>
#ifdef __cplusplus
extern "C" {
@@ -491,12 +492,11 @@ struct auditcalls {
};
int audit(caddr_t, int);
-int _audit(caddr_t, int);
int auditsys(struct auditcalls *, union rval *); /* fake stub */
-int _auditsys(struct auditcalls *, union rval *); /* real deal */
void audit_cryptoadm(int, char *, crypto_mech_name_t *,
uint_t, uint_t, uint32_t, int);
void audit_init(void);
+void audit_init_module(void);
void audit_newproc(struct proc *);
void audit_pfree(struct proc *);
void audit_thread_create(kthread_id_t);
@@ -534,11 +534,10 @@ void audit_enterprom(int);
void audit_exitprom(int);
void audit_chdirec(struct vnode *, struct vnode **);
void audit_sock(int, struct queue *, struct msgb *, int);
-void audit_free(void);
-int audit_start(unsigned int, unsigned int, int, klwp_t *);
+int audit_start(unsigned int, unsigned int, uint32_t, int, klwp_t *);
void audit_finish(unsigned int, unsigned int, int, union rval *);
int audit_async_start(label_t *, au_event_t, int);
-void audit_async_finish(caddr_t *, au_event_t, au_emod_t);
+void audit_async_finish(caddr_t *, au_event_t, au_emod_t, timestruc_t *);
void audit_async_discard_backend(void *);
void audit_async_done(caddr_t *, int);
void audit_async_drop(caddr_t *, int);
@@ -548,6 +547,35 @@ void audit_async_drop(caddr_t *, int);
typedef struct au_kcontext au_kcontext_t;
#endif
+/* Zone audit context setup routine */
+void au_zone_setup(void);
+
+/*
+ * c2audit module states
+ */
+#define C2AUDIT_DISABLED 0 /* c2audit module excluded in /etc/system */
+#define C2AUDIT_UNLOADED 1 /* c2audit module not loaded */
+#define C2AUDIT_LOADED 2 /* c2audit module loaded */
+
+uint32_t audit_getstate(void);
+int au_zone_getstate(const au_kcontext_t *);
+
+/* The audit mask defining in which case is auditing enabled */
+#define AU_AUDIT_MASK (AUC_AUDITING | AUC_NOSPACE)
+
+/*
+ * Get the given zone audit status. zcontext != NULL serves
+ * as a protection when c2audit module is not loaded.
+ */
+#define AU_ZONE_AUDITING(zcontext) \
+ (audit_active == C2AUDIT_LOADED && \
+ ((AU_AUDIT_MASK) & au_zone_getstate((zcontext))))
+
+/*
+ * Get auditing status
+ */
+#define AU_AUDITING() (audit_getstate())
+
int audit_success(au_kcontext_t *, struct t_audit_data *, int, cred_t *);
int auditme(au_kcontext_t *, struct t_audit_data *, au_state_t);
void audit_fixpath(struct audit_path *, int);
diff --git a/usr/src/uts/common/c2/audit_event.c b/usr/src/uts/common/c2/audit_event.c
index ed1d8c8f76..3ac61782c2 100644
--- a/usr/src/uts/common/c2/audit_event.c
+++ b/usr/src/uts/common/c2/audit_event.c
@@ -1824,7 +1824,7 @@ aus_close(struct t_audit_data *tad)
tad->tad_flag = 0;
tad->tad_evmod = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -3956,7 +3956,7 @@ auf_recvmsg(
/* don't want to audit every recvmsg attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -4002,7 +4002,7 @@ auf_recvmsg(
/* don't want to audit every recvmsg attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
/*
@@ -4158,7 +4158,7 @@ auf_recvfrom(
/* don't want to audit every recvfrom attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -4203,7 +4203,7 @@ auf_recvfrom(
/* don't want to audit every recvfrom attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -4348,7 +4348,7 @@ auf_sendmsg(struct t_audit_data *tad, int error, rval_t *rval)
/* don't want to audit every sendmsg attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -4394,7 +4394,7 @@ auf_sendmsg(struct t_audit_data *tad, int error, rval_t *rval)
/* don't want to audit every sendmsg attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
/*
@@ -4544,7 +4544,7 @@ auf_sendto(struct t_audit_data *tad, int error, rval_t *rval)
/* don't want to audit every sendto attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -4589,7 +4589,7 @@ auf_sendto(struct t_audit_data *tad, int error, rval_t *rval)
/* don't want to audit every sendto attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -5243,7 +5243,7 @@ auf_read(tad, error, rval)
/* don't really want to audit every read attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -5300,7 +5300,7 @@ auf_write(tad, error, rval)
/* don't really want to audit every write attempt */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
releasef(fd);
return;
}
@@ -5349,7 +5349,7 @@ auf_recv(tad, error, rval)
/* Turn off audit record generation here. */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5359,7 +5359,7 @@ auf_recv(tad, error, rval)
/* Turn off audit record generation here. */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5375,7 +5375,7 @@ auf_recv(tad, error, rval)
/* don't really want to audit every recv call */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5418,7 +5418,7 @@ auf_recv(tad, error, rval)
/* don't really want to audit every recv call */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
@@ -5485,7 +5485,7 @@ auf_send(tad, error, rval)
/* Turn off audit record generation here. */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5495,7 +5495,7 @@ auf_send(tad, error, rval)
/* Turn off audit record generation here. */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5511,7 +5511,7 @@ auf_send(tad, error, rval)
/* don't really want to audit every send call */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
}
@@ -5553,7 +5553,7 @@ auf_send(tad, error, rval)
/* don't really want to audit every send call */
tad->tad_flag = 0;
/* free any residual audit data */
- au_close(kctx, &(u_ad), 0, 0, 0);
+ au_close(kctx, &(u_ad), 0, 0, 0, NULL);
return;
diff --git a/usr/src/uts/common/c2/audit_io.c b/usr/src/uts/common/c2/audit_io.c
index c062ca204e..4d6cc3f7c3 100644
--- a/usr/src/uts/common/c2/audit_io.c
+++ b/usr/src/uts/common/c2/audit_io.c
@@ -21,7 +21,7 @@
/*
* Routines for writing audit records.
*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -102,7 +102,7 @@ au_write(caddr_t *d, token_t *m)
*/
void
au_close(au_kcontext_t *kctx, caddr_t *d, int flag, au_event_t e_type,
- au_emod_t e_mod)
+ au_emod_t e_mod, timestruc_t *e_time)
{
token_t *dchain; /* au_membuf chain which is the tokens */
t_audit_data_t *tad = U2A(u);
@@ -122,10 +122,10 @@ au_close(au_kcontext_t *kctx, caddr_t *d, int flag, au_event_t e_type,
*/
if ((flag & AU_DONTBLOCK) || ((flag & AU_DEFER) &&
(tad->tad_scid != 0) && (tad->tad_scid != SYS_exit))) {
- au_close_defer(dchain, flag, e_type, e_mod);
+ au_close_defer(dchain, flag, e_type, e_mod, e_time);
return;
}
- au_close_time(kctx, dchain, flag, e_type, e_mod, NULL);
+ au_close_time(kctx, dchain, flag, e_type, e_mod, e_time);
}
/*
@@ -134,7 +134,8 @@ au_close(au_kcontext_t *kctx, caddr_t *d, int flag, au_event_t e_type,
* syscall end time it will be pulled off.
*/
void
-au_close_defer(token_t *dchain, int flag, au_event_t e_type, au_emod_t e_mod)
+au_close_defer(token_t *dchain, int flag, au_event_t e_type, au_emod_t e_mod,
+ timestruc_t *e_time)
{
au_defer_info_t *attr;
t_audit_data_t *tad = U2A(u);
@@ -159,7 +160,10 @@ au_close_defer(token_t *dchain, int flag, au_event_t e_type, au_emod_t e_mod)
attr->audi_e_type = e_type;
attr->audi_e_mod = e_mod;
attr->audi_flag = flag;
- gethrestime(&attr->audi_atime);
+ if (e_time != NULL)
+ attr->audi_atime = *e_time;
+ else
+ gethrestime(&attr->audi_atime);
/*
* All async events must be queued via softcall to avoid possible
@@ -233,6 +237,7 @@ au_close_time(au_kcontext_t *kctx, token_t *dchain, int flag, au_event_t e_type,
adr_t hadr; /* handle for header token */
adr_t sadr; /* handle for sequence token */
size_t zone_length; /* length of zonename token */
+ uint32_t auditing;
ASSERT(dchain != NULL);
@@ -242,10 +247,14 @@ au_close_time(au_kcontext_t *kctx, token_t *dchain, int flag, au_event_t e_type,
return;
}
/* if auditing not enabled, then don't generate an audit record */
+ ASSERT(U2A(u) != NULL);
ASSERT(kctx != NULL);
- if ((kctx->auk_auditstate != AUC_AUDITING) &&
- (kctx->auk_auditstate != AUC_INIT_AUDIT)) {
+ auditing = (U2A(u)->tad_audit == AUC_UNSET)
+ ? kctx->auk_auditstate
+ : U2A(u)->tad_audit;
+
+ if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT)) {
/*
* at system boot, neither is set yet we want to generate
* an audit record.
@@ -460,7 +469,9 @@ audit_sync_block(au_kcontext_t *kctx)
* Loop while we are at the high watermark.
*/
do {
- if ((kctx->auk_auditstate != AUC_AUDITING) ||
+ if (((U2A(u)->tad_audit != AUC_UNSET)
+ ? (U2A(u)->tad_audit != AUC_AUDITING)
+ : (kctx->auk_auditstate != AUC_AUDITING)) ||
(kctx->auk_policy & AUDIT_CNT)) {
/* just count # of dropped audit records */
@@ -815,13 +826,14 @@ audit_async_start(label_t *jb, au_event_t event, int sorf)
* work can be done in a safe context.
*/
void
-audit_async_finish(caddr_t *ad, au_event_t aid, au_emod_t amod)
+audit_async_finish(caddr_t *ad, au_event_t aid, au_emod_t amod,
+ timestruc_t *e_time)
{
au_kcontext_t *kctx;
kctx = GET_KCTX_GZ;
- au_close(kctx, ad, AU_DONTBLOCK | AU_OK, aid, PAD_NONATTR|amod);
+ au_close(kctx, ad, AU_DONTBLOCK | AU_OK, aid, PAD_NONATTR|amod, e_time);
}
/*
diff --git a/usr/src/uts/common/c2/audit_kernel.h b/usr/src/uts/common/c2/audit_kernel.h
index df6c2910eb..21d648ae83 100644
--- a/usr/src/uts/common/c2/audit_kernel.h
+++ b/usr/src/uts/common/c2/audit_kernel.h
@@ -208,6 +208,7 @@ struct t_audit_data {
int tad_ctrl; /* audit control/status flags */
void *tad_errjmp; /* error longjmp (audit record aborted) */
int tad_flag; /* to audit or not to audit */
+ uint32_t tad_audit; /* auditing enabled/disabled */
struct audit_path *tad_aupath; /* captured at vfs_lookup */
struct audit_path *tad_atpath; /* openat prefix, path of fd */
struct vnode *tad_vn; /* saved inode from vfs_lookup */
@@ -338,8 +339,6 @@ extern zone_key_t au_zone_key;
*/
extern int audit_policy;
extern int audit_active;
-extern int audit_load;
-extern int au_auditstate;
extern struct audit_queue au_queue;
extern struct p_audit_data *pad0;
@@ -352,6 +351,17 @@ void au_pathhold(struct audit_path *);
void au_pathrele(struct audit_path *);
struct audit_path *au_pathdup(const struct audit_path *, int, int);
+void au_pad_init(void);
+
+int auditctl(int cmd, caddr_t data, int length);
+int auditdoor(int fd);
+int getauid(caddr_t);
+int setauid(caddr_t);
+int getaudit(caddr_t);
+int getaudit_addr(caddr_t, int);
+int setaudit(caddr_t);
+int setaudit_addr(caddr_t, int);
+
/*
* Macros to hide asynchronous, non-blocking audit record start and finish
* processing.
@@ -373,8 +383,9 @@ struct audit_path *au_pathdup(const struct audit_path *, int, int);
} \
}
-#define AUDIT_ASYNC_FINISH(rp, audit_event, event_modifier) \
- audit_async_finish((caddr_t *)&(rp), audit_event, event_modifier);
+#define AUDIT_ASYNC_FINISH(rp, audit_event, event_modifier, event_time) \
+ audit_async_finish((caddr_t *)&(rp), audit_event, event_modifier, \
+ event_time);
#ifdef _KERNEL
diff --git a/usr/src/uts/common/c2/audit_mem.c b/usr/src/uts/common/c2/audit_mem.c
index 7e88f2dd5e..9782324d6f 100644
--- a/usr/src/uts/common/c2/audit_mem.c
+++ b/usr/src/uts/common/c2/audit_mem.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/kmem.h>
@@ -36,8 +33,6 @@
#include <c2/audit_kernel.h>
#include <c2/audit_record.h>
-kmem_cache_t *au_pad_cache;
-
static kmem_cache_t *au_buf_cache;
/*
@@ -162,7 +157,7 @@ au_append_buf(const char *data, int len, au_buff_t *buf)
buf = buf->next_buf;
new_len = (uint_t)(buf->len + len) > AU_BUFSIZE ?
- AU_BUFSIZE - buf->len : len;
+ AU_BUFSIZE - buf->len : len;
bcopy(data, (buf->buf + buf->len), (uint_t)new_len);
buf->len += (uchar_t)new_len;
len -= new_len;
@@ -182,33 +177,9 @@ au_append_buf(const char *data, int len, au_buff_t *buf)
return (0);
}
-/*ARGSUSED1*/
-static int
-au_pad_const(void *vpad, void *priv, int flags)
-{
- p_audit_data_t *pad = vpad;
-
- mutex_init(&pad->pad_lock, NULL, MUTEX_DEFAULT, NULL);
-
- return (0);
-}
-
-/*ARGSUSED1*/
-static void
-au_pad_destr(void *vpad, void *priv)
-{
- p_audit_data_t *pad = vpad;
-
- mutex_destroy(&pad->pad_lock);
-}
-
void
au_mem_init()
{
au_buf_cache = kmem_cache_create("audit_buffer",
- sizeof (au_buff_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
-
- au_pad_cache = kmem_cache_create("audit_proc",
- sizeof (p_audit_data_t), 0, au_pad_const, au_pad_destr,
- NULL, NULL, NULL, 0);
+ sizeof (au_buff_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
}
diff --git a/usr/src/uts/common/c2/audit_path.c b/usr/src/uts/common/c2/audit_path.c
index ec0f3ce5de..cf51d2c3b6 100644
--- a/usr/src/uts/common/c2/audit_path.c
+++ b/usr/src/uts/common/c2/audit_path.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* @(#)audit_path.c 2.7 92/02/16 SMI; SunOS CMW
* @(#)audit_path.c 4.2.1.2 91/05/08 SMI; BSM Module
@@ -56,66 +53,6 @@
#include <sys/sysmacros.h>
#include <sys/atomic.h>
-/*
- * allocate a new auditpath
- * newsect = increment sections count,
- * charincr = change in strings storage
- */
-struct audit_path *
-au_pathdup(const struct audit_path *oldapp, int newsect, int charincr)
-{
- struct audit_path *newapp;
- int i, alloc_size, oldlen;
- char *oldcp, *newcp;
-
- newsect = (newsect != 0);
- oldcp = oldapp->audp_sect[0];
- oldlen = (oldapp->audp_sect[oldapp->audp_cnt] - oldcp);
- alloc_size = sizeof (struct audit_path) +
- (oldapp->audp_cnt + newsect) * sizeof (char *) +
- oldlen + charincr;
-
- newapp = kmem_alloc(alloc_size, KM_SLEEP);
- newapp->audp_ref = 1;
- newapp->audp_size = alloc_size;
-
- newapp->audp_cnt = oldapp->audp_cnt + newsect;
- newcp = (char *)(&newapp->audp_sect[newapp->audp_cnt + 1]);
- for (i = 0; i <= oldapp->audp_cnt; i++) {
- newapp->audp_sect[i] = newcp +
- (oldapp->audp_sect[i] - oldcp);
- }
- /*
- * if this is a new section, set its end
- * if this is an extended section, reset its end
- */
- newapp->audp_sect[newapp->audp_cnt] = newcp + oldlen + charincr;
- /* copy all of the old strings */
- bcopy(oldcp, newcp, oldlen);
-
- return (newapp);
-}
-
-/*
- * increment audit path reference count
- */
-void
-au_pathhold(struct audit_path *app)
-{
- atomic_add_32(&app->audp_ref, 1);
-}
-
-/*
- * decrement audit path reference count
- */
-void
-au_pathrele(struct audit_path *app)
-{
- if (atomic_add_32_nv(&app->audp_ref, -1) > 0)
- return;
- kmem_free(app, app->audp_size);
-}
-
int
au_token_size(m)
diff --git a/usr/src/uts/common/c2/audit_record.h b/usr/src/uts/common/c2/audit_record.h
index b41ac34a88..f8818c4b63 100644
--- a/usr/src/uts/common/c2/audit_record.h
+++ b/usr/src/uts/common/c2/audit_record.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -301,8 +301,9 @@ token_t *au_to_label(bslabel_t *);
token_t *au_to_privset(const char *, const priv_set_t *, char, int);
void au_uwrite();
-void au_close(au_kcontext_t *, caddr_t *, int, au_event_t, au_emod_t);
-void au_close_defer(token_t *, int, au_event_t, au_emod_t);
+void au_close(au_kcontext_t *, caddr_t *, int, au_event_t, au_emod_t,
+ timestruc_t *);
+void au_close_defer(token_t *, int, au_event_t, au_emod_t, timestruc_t *);
void au_close_time(au_kcontext_t *, token_t *, int, au_event_t, au_emod_t,
timestruc_t *);
void au_free_rec(au_buff_t *);
diff --git a/usr/src/uts/common/c2/audit_start.c b/usr/src/uts/common/c2/audit_start.c
index 7f9471c1ff..f0e0adb0c4 100644
--- a/usr/src/uts/common/c2/audit_start.c
+++ b/usr/src/uts/common/c2/audit_start.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,87 +50,43 @@
extern uint_t num_syscall; /* size of audit_s2e table */
extern kmutex_t pidlock; /* proc table lock */
-int audit_load = 0; /* set from /etc/system */
+/*
+ * Obsolete and ignored - Historically, the 'set c2audit:audit_load=1' entry
+ * in /etc/system enabled auditing. The No Reboot Audit project does not
+ * use this entry. However, to prevent the system from printing warning
+ * messages, the audit_load entry is being left in /etc/system. It will be
+ * removed when there is a small chance that the entry is used on currently
+ * running systems.
+ */
+int audit_load = 0;
-struct p_audit_data *pad0;
-struct t_audit_data *tad0;
+kmutex_t module_lock; /* audit_module_state lock */
/*
* Das Boot. Initialize first process. Also generate an audit record indicating
* that the system has been booted.
*/
void
-audit_init()
+audit_init_module()
{
- kthread_t *au_thread;
token_t *rp = NULL;
label_t jb;
- struct audit_path apempty;
- auditinfo_addr_t *ainfo;
- if (audit_load == 0) {
- audit_active = 0;
- au_auditstate = AUC_DISABLED;
+ /*
+ * Solaris Auditing module is being loaded -> change the state. The lock
+ * is here to prevent memory leaks caused by multiple initializations.
+ */
+ mutex_enter(&module_lock);
+ if (audit_active != C2AUDIT_UNLOADED) {
+ mutex_exit(&module_lock);
return;
-#ifdef DEBUG
- } else if (audit_load == 2) {
- debug_enter((char *)NULL);
-#endif
}
-
- audit_active = 1;
- set_all_proc_sys(); /* set pre- and post-syscall flags */
+ audit_active = C2AUDIT_LOADED;
+ mutex_exit(&module_lock);
/* initialize memory allocators */
au_mem_init();
- au_zone_setup();
-
- /* inital thread structure */
- tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
-
- /* initial process structure */
- pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
- bzero(&pad0->pad_data, sizeof (pad0->pad_data));
-
- T2A(curthread) = tad0;
- P2A(curproc) = pad0;
-
- /*
- * The kernel allocates a bunch of threads make sure they have
- * a valid tad
- */
-
- mutex_enter(&pidlock);
-
- au_thread = curthread;
- do {
- if (T2A(au_thread) == NULL) {
- T2A(au_thread) = tad0;
- }
- au_thread = au_thread->t_next;
- } while (au_thread != curthread);
-
- tad0->tad_ad = NULL;
- mutex_exit(&pidlock);
-
- /*
- * Initialize audit context in our cred (kcred).
- * No copy-on-write needed here because it's so early in init.
- */
- ainfo = crgetauinfo_modifiable(kcred);
- ASSERT(ainfo != NULL);
- bzero(ainfo, sizeof (auditinfo_addr_t));
- ainfo->ai_auid = AU_NOAUDITID;
-
- /* fabricate an empty audit_path to extend */
- apempty.audp_cnt = 0;
- apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]);
- pad0->pad_root = au_pathdup(&apempty, 1, 2);
- bcopy("/", pad0->pad_root->audp_sect[0], 2);
- au_pathhold(pad0->pad_root);
- pad0->pad_cwd = pad0->pad_root;
-
/*
* setup environment for asynchronous auditing. We can't use
* audit_async_start() here since it assumes the audit system
@@ -150,82 +106,8 @@ audit_init()
/* generate a system-booted audit record */
au_write((caddr_t *)&rp, au_to_text("booting kernel"));
-
- audit_async_finish((caddr_t *)&rp, AUE_SYSTEMBOOT, NULL);
-}
-
-void
-audit_free()
-{
-}
-
-/*
- * Check for any pending changes to the audit context for the given proc.
- * p_crlock and pad_lock for the process are acquired here. Caller is
- * responsible for assuring the process doesn't go away. If context is
- * updated, the specified cralloc'ed cred will be used, otherwise it's freed.
- * If no cred is given, it will be cralloc'ed here and caller assures that
- * it is safe to allocate memory.
- */
-void
-audit_update_context(proc_t *p, cred_t *ncr)
-{
- struct p_audit_data *pad;
- cred_t *newcred = ncr;
-
- pad = P2A(p);
- if (pad == NULL) {
- if (newcred != NULL)
- crfree(newcred);
- return;
- }
-
- /* If a mask update is pending, take care of it. */
- if (pad->pad_flags & PAD_SETMASK) {
- auditinfo_addr_t *ainfo;
-
- if (newcred == NULL)
- newcred = cralloc();
-
- mutex_enter(&pad->pad_lock);
- /* the condition may have been handled by the time we lock */
- if (pad->pad_flags & PAD_SETMASK) {
- ainfo = crgetauinfo_modifiable(newcred);
- if (ainfo == NULL) {
- mutex_enter(&pad->pad_lock);
- crfree(newcred);
- return;
- }
-
- mutex_enter(&p->p_crlock);
- crcopy_to(p->p_cred, newcred);
- p->p_cred = newcred;
-
- ainfo->ai_mask = pad->pad_newmask;
-
- /* Unlock and cleanup. */
- mutex_exit(&p->p_crlock);
- pad->pad_flags &= ~PAD_SETMASK;
-
- /*
- * For curproc, assure that our thread points to right
- * cred, so CRED() will be correct. Otherwise, no need
- * to broadcast changes (via set_proc_pre_sys), since
- * t_pre_sys is ALWAYS on when audit is enabled... due
- * to syscall auditing.
- */
- if (p == curproc)
- crset(p, newcred);
- else
- crfree(newcred);
- } else {
- crfree(newcred);
- }
- mutex_exit(&pad->pad_lock);
- } else {
- if (newcred != NULL)
- crfree(newcred);
- }
+ audit_async_finish((caddr_t *)&rp, AUE_SYSTEMBOOT, NULL,
+ &(p0.p_user.u_start));
}
@@ -241,6 +123,7 @@ int
audit_start(
unsigned type,
unsigned scid,
+ uint32_t audit_state,
int error,
klwp_t *lwp)
{
@@ -250,6 +133,9 @@ audit_start(
tad = U2A(u);
ASSERT(tad != NULL);
+ /* Remember the audit state in the cache */
+ tad->tad_audit = audit_state;
+
if (error) {
tad->tad_ctrl = 0;
tad->tad_flag = 0;
@@ -309,8 +195,7 @@ audit_start(
* if auditing not enabled, then don't generate an audit record
* and don't count it.
*/
- if ((kctx->auk_auditstate != AUC_AUDITING &&
- kctx->auk_auditstate != AUC_INIT_AUDIT)) {
+ if (audit_state & ~(AUC_AUDITING | AUC_INIT_AUDIT)) {
/*
* we assume that audit_finish will always be called.
*/
@@ -323,7 +208,7 @@ audit_start(
* space left to hold audit records. We decide here if records
* should be dropped (but counted).
*/
- if (kctx->auk_auditstate == AUC_NOSPACE) {
+ if (audit_state == AUC_NOSPACE) {
if ((kctx->auk_policy & AUDIT_CNT) ||
(kctx->auk_policy & AUDIT_SCNT)) {
/* assume that audit_finish will always be called. */
@@ -389,6 +274,7 @@ audit_finish(
tad->tad_event = 0;
tad->tad_evmod = 0;
tad->tad_ctrl = 0;
+ tad->tad_audit = AUC_UNSET;
ASSERT(tad->tad_aupath == NULL);
return;
}
@@ -479,7 +365,8 @@ audit_finish(
}
/* Close up everything */
- au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod);
+ au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod,
+ NULL);
}
ASSERT(u_ad == NULL);
@@ -505,6 +392,7 @@ audit_finish(
tad->tad_event = 0;
tad->tad_evmod = 0;
tad->tad_ctrl = 0;
+ tad->tad_audit = AUC_UNSET;
}
int
diff --git a/usr/src/uts/common/c2/audit_syscalls.c b/usr/src/uts/common/c2/audit_syscalls.c
index 9cd0e6b403..fc58881e99 100644
--- a/usr/src/uts/common/c2/audit_syscalls.c
+++ b/usr/src/uts/common/c2/audit_syscalls.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,7 +28,6 @@
*
*/
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/user.h>
@@ -60,83 +59,37 @@
#include <c2/audit_kernel.h>
#include <c2/audit_record.h>
-#define CLEAR_VAL -1
-
#define HEADER_SIZE64 1;
#define HEADER_SIZE32 0;
#define AU_MIN_FILE_SZ 0x80000 /* minumum audit file size */
#define AUDIT_REC_SIZE 0x8000 /* maximum user audit record size */
-extern kmutex_t pidlock;
-
-extern pri_t minclsyspri; /* priority for taskq */
+extern pri_t minclsyspri; /* priority for taskq */
-extern int audit_load; /* defined in audit_start.c */
-
-int au_auditstate = AUC_UNSET; /* global audit state */
-int audit_policy; /* global audit policies in force */
static clock_t au_resid = 15; /* wait .15 sec before droping a rec */
-static int getauid(caddr_t);
-static int setauid(caddr_t);
-static int getaudit(caddr_t);
-static int getaudit_addr(caddr_t, int);
-static int setaudit(caddr_t);
-static int setaudit_addr(caddr_t, int);
-static int auditdoor(int);
-static int auditctl(int, caddr_t, int);
-static int audit_modsysent(char *, int, int (*)());
static void au_output_thread();
+
/*
* This is the loadable module wrapper.
*/
#include <sys/modctl.h>
-#include "sys/syscall.h"
-
-static struct sysent auditsysent = {
- 6,
- 0,
- _auditsys
-};
/*
* Module linkage information for the kernel.
*/
-extern struct mod_ops mod_syscallops;
-
-static struct modlsys modlsys = {
- &mod_syscallops, "C2 system call", &auditsysent
+static struct modlmisc modlmisc = {
+ &mod_miscops, "Solaris Auditing (C2)"
};
static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlsys, 0
+ MODREV_1, (void *)&modlmisc, 0
};
int
_init()
{
- int retval;
-
- if (audit_load == 0)
- return (-1);
-
- /*
- * We are going to do an ugly thing here.
- * Because auditsys is already defined as a regular
- * syscall we have to change the definition for syscall
- * auditsys. Basically or in the SE_LOADABLE flag for
- * auditsys. We no have a static loadable syscall. Also
- * create an rw_lock.
- */
-
- if ((audit_modsysent("c2audit", SE_LOADABLE|SE_NOUNLOAD,
- _auditsys)) == -1)
- return (-1);
-
- if ((retval = mod_install(&modlinkage)) != 0)
- return (retval);
-
- return (0);
+ return (mod_install(&modlinkage));
}
int
@@ -152,358 +105,6 @@ _info(struct modinfo *modinfop)
}
/*
- * when auditing is updated to allow enable/disable without
- * reboot (and when the audit stubs are removed) *most* of these
- * calls should return an error when auditing is off -- some
- * for local zones only.
- */
-
-int
-_auditsys(struct auditcalls *uap, rval_t *rvp)
-{
- int result = 0;
-
- switch (uap->code) {
- case BSM_GETAUID:
- result = getauid((caddr_t)uap->a1);
- break;
- case BSM_SETAUID:
- result = setauid((caddr_t)uap->a1);
- break;
- case BSM_GETAUDIT:
- result = getaudit((caddr_t)uap->a1);
- break;
- case BSM_GETAUDIT_ADDR:
-
- result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
- break;
- case BSM_SETAUDIT:
- result = setaudit((caddr_t)uap->a1);
- break;
- case BSM_SETAUDIT_ADDR:
- result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
- break;
- case BSM_AUDIT:
- result = audit((caddr_t)uap->a1, (int)uap->a2);
- break;
- case BSM_AUDITDOOR:
- result = auditdoor((int)uap->a1);
- break;
- case BSM_AUDITCTL:
- result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
- break;
- default:
- result = EINVAL;
- }
- rvp->r_vals = result;
- return (result);
-}
-
-/*
- * Return the audit user ID for the current process. Currently only
- * the privileged processes may see the audit id. That may change.
- * If copyout is unsucessful return EFAULT.
- */
-static int
-getauid(caddr_t auid_p)
-{
- const auditinfo_addr_t *ainfo;
-
- if (secpolicy_audit_getattr(CRED()) != 0)
- return (EPERM);
-
- ainfo = crgetauinfo(CRED());
- if (ainfo == NULL)
- return (EINVAL);
-
- if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * Set the audit userid, for a process. This can only be changed by
- * privileged processes. The audit userid is inherited across forks & execs.
- * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
- */
-static int
-setauid(caddr_t auid_p)
-{
- proc_t *p;
- au_id_t auid;
- cred_t *newcred;
- auditinfo_addr_t *auinfo;
-
- if (secpolicy_audit_config(CRED()) != 0)
- return (EPERM);
-
- if (copyin(auid_p, &auid, sizeof (au_id_t))) {
- return (EFAULT);
- }
-
- newcred = cralloc();
- if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
- crfree(newcred);
- return (EINVAL);
- }
-
- /* grab p_crlock and switch to new cred */
- p = curproc;
- mutex_enter(&p->p_crlock);
- crcopy_to(p->p_cred, newcred);
- p->p_cred = newcred;
-
- auinfo->ai_auid = auid; /* update the auid */
-
- /* unlock and broadcast the cred changes */
- mutex_exit(&p->p_crlock);
- crset(p, newcred);
-
- return (0);
-}
-
-/*
- * Get the audit state information from the current process.
- * Return EFAULT if copyout fails.
- */
-static int
-getaudit(caddr_t info_p)
-{
- STRUCT_DECL(auditinfo, info);
- const auditinfo_addr_t *ainfo;
- model_t model;
-
- if (secpolicy_audit_getattr(CRED()) != 0)
- return (EPERM);
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- ainfo = crgetauinfo(CRED());
- if (ainfo == NULL)
- return (EINVAL);
-
- /* trying to read a process with an IPv6 address? */
- if (ainfo->ai_termid.at_type == AU_IPv6)
- return (EOVERFLOW);
-
- STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
- STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
-#ifdef _LP64
- if (model == DATAMODEL_ILP32) {
- dev32_t dev;
- /* convert internal 64 bit form to 32 bit version */
- if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
- return (EOVERFLOW);
- }
- STRUCT_FSET(info, ai_termid.port, dev);
- } else
- STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
-#else
- STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
-#endif
- STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
- STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
-
- if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * Get the audit state information from the current process.
- * Return EFAULT if copyout fails.
- */
-static int
-getaudit_addr(caddr_t info_p, int len)
-{
- STRUCT_DECL(auditinfo_addr, info);
- const auditinfo_addr_t *ainfo;
- model_t model;
-
- if (secpolicy_audit_getattr(CRED()) != 0)
- return (EPERM);
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- if (len < STRUCT_SIZE(info))
- return (EOVERFLOW);
-
- ainfo = crgetauinfo(CRED());
-
- if (ainfo == NULL)
- return (EINVAL);
-
- STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
- STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
-#ifdef _LP64
- if (model == DATAMODEL_ILP32) {
- dev32_t dev;
- /* convert internal 64 bit form to 32 bit version */
- if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
- return (EOVERFLOW);
- }
- STRUCT_FSET(info, ai_termid.at_port, dev);
- } else
- STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
-#else
- STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
-#endif
- STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
- STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
- STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
- STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
- STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
- STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
-
- if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * Set the audit state information for the current process.
- * Return EFAULT if copyout fails.
- */
-static int
-setaudit(caddr_t info_p)
-{
- STRUCT_DECL(auditinfo, info);
- proc_t *p;
- cred_t *newcred;
- model_t model;
- auditinfo_addr_t *ainfo;
-
- if (secpolicy_audit_config(CRED()) != 0)
- return (EPERM);
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
- return (EFAULT);
-
- newcred = cralloc();
- if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
- crfree(newcred);
- return (EINVAL);
- }
-
- /* grab p_crlock and switch to new cred */
- p = curproc;
- mutex_enter(&p->p_crlock);
- crcopy_to(p->p_cred, newcred);
- p->p_cred = newcred;
-
- /* Set audit mask, id, termid and session id as specified */
- ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
-#ifdef _LP64
- /* only convert to 64 bit if coming from a 32 bit binary */
- if (model == DATAMODEL_ILP32)
- ainfo->ai_termid.at_port =
- DEVEXPL(STRUCT_FGET(info, ai_termid.port));
- else
- ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
-#else
- ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
-#endif
- ainfo->ai_termid.at_type = AU_IPv4;
- ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
- ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
- ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
-
- /* unlock and broadcast the cred changes */
- mutex_exit(&p->p_crlock);
- crset(p, newcred);
-
- return (0);
-}
-
-/*
- * Set the audit state information for the current process.
- * Return EFAULT if copyin fails.
- */
-static int
-setaudit_addr(caddr_t info_p, int len)
-{
- STRUCT_DECL(auditinfo_addr, info);
- proc_t *p;
- cred_t *newcred;
- model_t model;
- int i;
- int type;
- auditinfo_addr_t *ainfo;
-
- if (secpolicy_audit_config(CRED()) != 0)
- return (EPERM);
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- if (len < STRUCT_SIZE(info))
- return (EOVERFLOW);
-
- if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
- return (EFAULT);
-
- type = STRUCT_FGET(info, ai_termid.at_type);
- if ((type != AU_IPv4) && (type != AU_IPv6))
- return (EINVAL);
-
- newcred = cralloc();
- if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
- crfree(newcred);
- return (EINVAL);
- }
-
- /* grab p_crlock and switch to new cred */
- p = curproc;
- mutex_enter(&p->p_crlock);
- crcopy_to(p->p_cred, newcred);
- p->p_cred = newcred;
-
- /* Set audit mask, id, termid and session id as specified */
- ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
- ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
-#ifdef _LP64
- /* only convert to 64 bit if coming from a 32 bit binary */
- if (model == DATAMODEL_ILP32)
- ainfo->ai_termid.at_port =
- DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
- else
- ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
-#else
- ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
-#endif
- ainfo->ai_termid.at_type = type;
- bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
- for (i = 0; i < (type/sizeof (int)); i++)
- ainfo->ai_termid.at_addr[i] =
- STRUCT_FGET(info, ai_termid.at_addr[i]);
-
- if (ainfo->ai_termid.at_type == AU_IPv6 &&
- IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
- ainfo->ai_termid.at_type = AU_IPv4;
- ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
- ainfo->ai_termid.at_addr[1] = 0;
- ainfo->ai_termid.at_addr[2] = 0;
- ainfo->ai_termid.at_addr[3] = 0;
- }
-
- ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
-
- /* unlock and broadcast the cred changes */
- mutex_exit(&p->p_crlock);
- crset(p, newcred);
-
- return (0);
-}
-
-/*
* The audit system call. Trust what the user has sent down and save it
* away in the audit file. User passes a complete audit record and its
* length. We will fill in the time stamp, check the header and the length
@@ -528,10 +129,12 @@ audit(caddr_t record, int length)
int host_len;
size_t zlen;
au_kcontext_t *kctx = GET_KCTX_PZ;
+ uint32_t auditing;
/* if auditing not enabled, then don't generate an audit record */
- if (kctx->auk_auditstate != AUC_AUDITING &&
- kctx->auk_auditstate != AUC_INIT_AUDIT)
+ auditing = (U2A(u)->tad_audit != AUC_UNSET) ?
+ U2A(u)->tad_audit : kctx->auk_auditstate;
+ if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT))
return (0);
/* Only privileged processes can audit */
@@ -713,19 +316,6 @@ audit(caddr_t record, int length)
return (0);
}
-static void
-audit_dont_stop(void *kctx)
-{
-
- if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
- (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
- return;
-
- mutex_enter(&(((au_kcontext_t *)kctx)->auk_queue.lock));
- cv_broadcast(&(((au_kcontext_t *)kctx)->auk_queue.write_cv));
- mutex_exit(&(((au_kcontext_t *)kctx)->auk_queue.lock));
-}
-
/*
* auditdoor starts a kernel thread to generate output from the audit
* queue. The thread terminates when it detects auditing being turned
@@ -735,7 +325,7 @@ audit_dont_stop(void *kctx)
* for insuring that multiple copies are not running.
*/
-static int
+int
auditdoor(int fd)
{
struct file *fp;
@@ -797,6 +387,19 @@ auditdoor(int fd)
return (0);
}
+static void
+audit_dont_stop(void *kctx)
+{
+
+ if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
+ (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
+ return;
+
+ mutex_enter(&(((au_kcontext_t *)kctx)->auk_queue.lock));
+ cv_broadcast(&(((au_kcontext_t *)kctx)->auk_queue.write_cv));
+ mutex_exit(&(((au_kcontext_t *)kctx)->auk_queue.lock));
+}
+
/*
* au_queue_kick -- wake up the output queue after delay ticks
*/
@@ -893,1074 +496,3 @@ output_exit:
mutex_exit(&(kctx->auk_svc_lock));
}
-
-
-/*
- * Get the global policy flag
- */
-
-static int
-getpolicy(caddr_t data)
-{
- int policy;
- au_kcontext_t *kctx = GET_KCTX_PZ;
-
- policy = audit_policy | kctx->auk_policy;
-
- if (copyout(&policy, data, sizeof (int)))
- return (EFAULT);
- return (0);
-}
-
-/*
- * Set the global and local policy flags
- *
- * The global flags only make sense from the global zone;
- * the local flags depend on the AUDIT_PERZONE policy:
- * if the perzone policy is set, then policy is set separately
- * per zone, else held only in the global zone.
- *
- * The initial value of a local zone's policy flag is determined
- * by the value of the global zone's flags at the time the
- * local zone is created.
- *
- * While auditconfig(1M) allows setting and unsetting policies one bit
- * at a time, the mask passed in from auditconfig() is created by a
- * syscall to getpolicy and then modified based on the auditconfig()
- * cmd line, so the input policy value is used to replace the existing
- * policy.
- */
-
-
-static int
-setpolicy(caddr_t data)
-{
- int policy;
- au_kcontext_t *kctx;
-
- if (copyin(data, &policy, sizeof (int)))
- return (EFAULT);
-
- kctx = GET_KCTX_NGZ;
-
- if (INGLOBALZONE(curproc)) {
- if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
- return (EINVAL);
-
- audit_policy = policy & AUDIT_GLOBAL;
- } else {
- if (!(audit_policy & AUDIT_PERZONE))
- return (EINVAL);
-
- if (policy & ~AUDIT_LOCAL) /* global bits are a no-no */
- return (EINVAL);
- }
- kctx->auk_policy = policy & AUDIT_LOCAL;
-
- /*
- * auk_current_vp is NULL before auditd starts (or during early
- * auditd starup) or if auditd is halted; in either case,
- * notification of a policy change is not needed, since auditd
- * reads policy as it comes up. The error return from au_doormsg()
- * is ignored to avoid a race condition -- for example if auditd
- * segv's, the audit state may be "auditing" but the door may
- * be closed. Returning an error if the door is open makes it
- * impossible for Greenline to restart auditd.
- */
- if (kctx->auk_current_vp != NULL)
- (void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
-
- /*
- * Wake up anyone who might have blocked on full audit
- * partitions. audit daemons need to set AUDIT_FULL when no
- * space so we can tell if we should start dropping records.
- */
- mutex_enter(&(kctx->auk_queue.lock));
-
- if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
- (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
- cv_broadcast(&(kctx->auk_queue.write_cv));
-
- mutex_exit(&(kctx->auk_queue.lock));
-
- return (0);
-}
-
-static int
-getkmask(caddr_t data)
-{
- au_kcontext_t *kctx;
-
- kctx = GET_KCTX_PZ;
-
- if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
- return (EFAULT);
- return (0);
-}
-
-static int
-setkmask(caddr_t data)
-{
- au_mask_t mask;
- au_kcontext_t *kctx;
-
- if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
- return (EINVAL);
-
- kctx = GET_KCTX_NGZ;
-
- if (copyin(data, &mask, sizeof (au_mask_t)))
- return (EFAULT);
-
- kctx->auk_info.ai_mask = mask;
- return (0);
-}
-
-static int
-getkaudit(caddr_t info_p, int len)
-{
- STRUCT_DECL(auditinfo_addr, info);
- model_t model;
- au_kcontext_t *kctx = GET_KCTX_PZ;
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- if (len < STRUCT_SIZE(info))
- return (EOVERFLOW);
-
- STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
- STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
-#ifdef _LP64
- if (model == DATAMODEL_ILP32) {
- dev32_t dev;
- /* convert internal 64 bit form to 32 bit version */
- if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
- return (EOVERFLOW);
- }
- STRUCT_FSET(info, ai_termid.at_port, dev);
- } else {
- STRUCT_FSET(info, ai_termid.at_port,
- kctx->auk_info.ai_termid.at_port);
- }
-#else
- STRUCT_FSET(info, ai_termid.at_port,
- kctx->auk_info.ai_termid.at_port);
-#endif
- STRUCT_FSET(info, ai_termid.at_type,
- kctx->auk_info.ai_termid.at_type);
- STRUCT_FSET(info, ai_termid.at_addr[0],
- kctx->auk_info.ai_termid.at_addr[0]);
- STRUCT_FSET(info, ai_termid.at_addr[1],
- kctx->auk_info.ai_termid.at_addr[1]);
- STRUCT_FSET(info, ai_termid.at_addr[2],
- kctx->auk_info.ai_termid.at_addr[2]);
- STRUCT_FSET(info, ai_termid.at_addr[3],
- kctx->auk_info.ai_termid.at_addr[3]);
- STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
-
- if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * the host address for AUDIT_PERZONE == 0 is that of the global
- * zone and for local zones it is of the current zone.
- */
-
-static int
-setkaudit(caddr_t info_p, int len)
-{
- STRUCT_DECL(auditinfo_addr, info);
- model_t model;
- au_kcontext_t *kctx;
-
- if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
- return (EINVAL);
-
- kctx = GET_KCTX_NGZ;
-
- model = get_udatamodel();
- STRUCT_INIT(info, model);
-
- if (len < STRUCT_SIZE(info))
- return (EOVERFLOW);
-
- if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
- return (EFAULT);
-
- if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
- (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
- return (EINVAL);
-
- /* Set audit mask, termid and session id as specified */
- kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
- kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
-#ifdef _LP64
- /* only convert to 64 bit if coming from a 32 bit binary */
- if (model == DATAMODEL_ILP32)
- kctx->auk_info.ai_termid.at_port =
- DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
- else
- kctx->auk_info.ai_termid.at_port =
- STRUCT_FGET(info, ai_termid.at_port);
-#else
- kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
-#endif
- kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
- bzero(&kctx->auk_info.ai_termid.at_addr[0],
- sizeof (kctx->auk_info.ai_termid.at_addr));
- kctx->auk_info.ai_termid.at_addr[0] =
- STRUCT_FGET(info, ai_termid.at_addr[0]);
- kctx->auk_info.ai_termid.at_addr[1] =
- STRUCT_FGET(info, ai_termid.at_addr[1]);
- kctx->auk_info.ai_termid.at_addr[2] =
- STRUCT_FGET(info, ai_termid.at_addr[2]);
- kctx->auk_info.ai_termid.at_addr[3] =
- STRUCT_FGET(info, ai_termid.at_addr[3]);
- kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
-
- if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
- IN6_IS_ADDR_V4MAPPED(
- ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
- kctx->auk_info.ai_termid.at_type = AU_IPv4;
- kctx->auk_info.ai_termid.at_addr[0] =
- kctx->auk_info.ai_termid.at_addr[3];
- kctx->auk_info.ai_termid.at_addr[1] = 0;
- kctx->auk_info.ai_termid.at_addr[2] = 0;
- kctx->auk_info.ai_termid.at_addr[3] = 0;
- }
- if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
- kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
- (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
- else
- kctx->auk_hostaddr_valid =
- (kctx->auk_info.ai_termid.at_addr[0] ==
- htonl(INADDR_ANY)) ? 0 : 1;
-
- return (0);
-}
-
-static int
-getqctrl(caddr_t data)
-{
- au_kcontext_t *kctx = GET_KCTX_PZ;
- STRUCT_DECL(au_qctrl, qctrl);
- STRUCT_INIT(qctrl, get_udatamodel());
-
- mutex_enter(&(kctx->auk_queue.lock));
- STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
- STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
- STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
- STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
- mutex_exit(&(kctx->auk_queue.lock));
-
- if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
- return (EFAULT);
-
- return (0);
-}
-
-static int
-setqctrl(caddr_t data)
-{
- au_kcontext_t *kctx;
- struct au_qctrl qctrl_tmp;
- STRUCT_DECL(au_qctrl, qctrl);
- STRUCT_INIT(qctrl, get_udatamodel());
-
- if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
- return (EINVAL);
- kctx = GET_KCTX_NGZ;
-
- if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
- return (EFAULT);
-
- qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
- qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
- qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
- qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
-
- /* enforce sane values */
-
- if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
- return (EINVAL);
-
- if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
- return (EINVAL);
-
- if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
- return (EINVAL);
-
- if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
- return (EINVAL);
-
- if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
- return (EINVAL);
-
- if (qctrl_tmp.aq_delay == 0)
- return (EINVAL);
-
- if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
- return (EINVAL);
-
- /* update everything at once so things are consistant */
- mutex_enter(&(kctx->auk_queue.lock));
- kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
- kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
- kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
- kctx->auk_queue.delay = qctrl_tmp.aq_delay;
-
- if (kctx->auk_queue.rd_block &&
- kctx->auk_queue.cnt > kctx->auk_queue.lowater)
- cv_broadcast(&(kctx->auk_queue.read_cv));
-
- if (kctx->auk_queue.wt_block &&
- kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
- cv_broadcast(&(kctx->auk_queue.write_cv));
-
- mutex_exit(&(kctx->auk_queue.lock));
-
- return (0);
-}
-
-static int
-getcwd(caddr_t data, int length)
-{
- struct p_audit_data *pad;
- struct audit_path *app;
- int pathlen;
-
- pad = P2A(curproc);
- ASSERT(pad != NULL);
-
- mutex_enter(&(pad->pad_lock));
- app = pad->pad_cwd;
- au_pathhold(app);
- mutex_exit(&(pad->pad_lock));
-
- pathlen = app->audp_sect[1] - app->audp_sect[0];
- if (pathlen > length) {
- au_pathrele(app);
- return (E2BIG);
- }
-
- if (copyout(app->audp_sect[0], data, pathlen)) {
- au_pathrele(app);
- return (EFAULT);
- }
-
- au_pathrele(app);
- return (0);
-}
-
-static int
-getcar(caddr_t data, int length)
-{
- struct p_audit_data *pad;
- struct audit_path *app;
- int pathlen;
-
- pad = P2A(curproc);
- ASSERT(pad != NULL);
-
- mutex_enter(&(pad->pad_lock));
- app = pad->pad_root;
- au_pathhold(app);
- mutex_exit(&(pad->pad_lock));
-
- pathlen = app->audp_sect[1] - app->audp_sect[0];
- if (pathlen > length) {
- au_pathrele(app);
- return (E2BIG);
- }
-
- if (copyout(app->audp_sect[0], data, pathlen)) {
- au_pathrele(app);
- return (EFAULT);
- }
-
- au_pathrele(app);
- return (0);
-}
-
-static int
-getstat(caddr_t data)
-{
- au_kcontext_t *kctx = GET_KCTX_PZ;
-
- membar_consumer();
-
- if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
- return (EFAULT);
- return (0);
-}
-
-
-static int
-setstat(caddr_t data)
-{
- au_kcontext_t *kctx = GET_KCTX_PZ;
- au_stat_t au_stat;
-
- if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
- return (EINVAL);
-
- if (copyin(data, &au_stat, sizeof (au_stat_t)))
- return (EFAULT);
-
- if (au_stat.as_generated == CLEAR_VAL)
- kctx->auk_statistics.as_generated = 0;
- if (au_stat.as_nonattrib == CLEAR_VAL)
- kctx->auk_statistics.as_nonattrib = 0;
- if (au_stat.as_kernel == CLEAR_VAL)
- kctx->auk_statistics.as_kernel = 0;
- if (au_stat.as_audit == CLEAR_VAL)
- kctx->auk_statistics.as_audit = 0;
- if (au_stat.as_auditctl == CLEAR_VAL)
- kctx->auk_statistics.as_auditctl = 0;
- if (au_stat.as_enqueue == CLEAR_VAL)
- kctx->auk_statistics.as_enqueue = 0;
- if (au_stat.as_written == CLEAR_VAL)
- kctx->auk_statistics.as_written = 0;
- if (au_stat.as_wblocked == CLEAR_VAL)
- kctx->auk_statistics.as_wblocked = 0;
- if (au_stat.as_rblocked == CLEAR_VAL)
- kctx->auk_statistics.as_rblocked = 0;
- if (au_stat.as_dropped == CLEAR_VAL)
- kctx->auk_statistics.as_dropped = 0;
- if (au_stat.as_totalsize == CLEAR_VAL)
- kctx->auk_statistics.as_totalsize = 0;
-
- membar_producer();
-
- return (0);
-
-}
-
-static int
-setumask(caddr_t data)
-{
- STRUCT_DECL(auditinfo, user_info);
- struct proc *p;
- const auditinfo_addr_t *ainfo;
- model_t model;
-
- /* setumask not applicable in non-global zones without perzone policy */
- if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
- return (EINVAL);
-
- model = get_udatamodel();
- STRUCT_INIT(user_info, model);
-
- if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
- return (EFAULT);
-
- mutex_enter(&pidlock); /* lock the process queue against updates */
- for (p = practive; p != NULL; p = p->p_next) {
- cred_t *cr;
-
- /* if in non-global zone only modify processes in same zone */
- if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
- continue;
-
- mutex_enter(&p->p_lock); /* so process doesn't go away */
-
- /* skip system processes and ones being created or going away */
- if (p->p_stat == SIDL || p->p_stat == SZOMB ||
- (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
- mutex_exit(&p->p_lock);
- continue;
- }
-
- mutex_enter(&p->p_crlock);
- crhold(cr = p->p_cred);
- mutex_exit(&p->p_crlock);
- ainfo = crgetauinfo(cr);
- if (ainfo == NULL) {
- mutex_exit(&p->p_lock);
- crfree(cr);
- continue;
- }
-
- if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
- au_mask_t mask;
- int err;
-
- /*
- * Here's a process which matches the specified auid.
- * If its mask doesn't already match the new mask,
- * save the new mask in the pad, to be picked up
- * next syscall.
- */
- mask = STRUCT_FGET(user_info, ai_mask);
- err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
- crfree(cr);
- if (err != 0) {
- struct p_audit_data *pad = P2A(p);
- ASSERT(pad != NULL);
-
- mutex_enter(&(pad->pad_lock));
- pad->pad_flags |= PAD_SETMASK;
- pad->pad_newmask = mask;
- mutex_exit(&(pad->pad_lock));
-
- /*
- * No need to call set_proc_pre_sys(), since
- * t_pre_sys is ALWAYS on when audit is
- * enabled...due to syscall auditing.
- */
- }
- } else {
- crfree(cr);
- }
- mutex_exit(&p->p_lock);
- }
- mutex_exit(&pidlock);
-
- return (0);
-}
-
-static int
-setsmask(caddr_t data)
-{
- STRUCT_DECL(auditinfo, user_info);
- struct proc *p;
- const auditinfo_addr_t *ainfo;
- model_t model;
-
- /* setsmask not applicable in non-global zones without perzone policy */
- if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
- return (EINVAL);
-
- model = get_udatamodel();
- STRUCT_INIT(user_info, model);
-
- if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
- return (EFAULT);
-
- mutex_enter(&pidlock); /* lock the process queue against updates */
- for (p = practive; p != NULL; p = p->p_next) {
- cred_t *cr;
-
- /* if in non-global zone only modify processes in same zone */
- if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
- continue;
-
- mutex_enter(&p->p_lock); /* so process doesn't go away */
-
- /* skip system processes and ones being created or going away */
- if (p->p_stat == SIDL || p->p_stat == SZOMB ||
- (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
- mutex_exit(&p->p_lock);
- continue;
- }
-
- mutex_enter(&p->p_crlock);
- crhold(cr = p->p_cred);
- mutex_exit(&p->p_crlock);
- ainfo = crgetauinfo(cr);
- if (ainfo == NULL) {
- mutex_exit(&p->p_lock);
- crfree(cr);
- continue;
- }
-
- if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
- au_mask_t mask;
- int err;
-
- /*
- * Here's a process which matches the specified asid.
- * If its mask doesn't already match the new mask,
- * save the new mask in the pad, to be picked up
- * next syscall.
- */
- mask = STRUCT_FGET(user_info, ai_mask);
- err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
- crfree(cr);
- if (err != 0) {
- struct p_audit_data *pad = P2A(p);
- ASSERT(pad != NULL);
-
- mutex_enter(&(pad->pad_lock));
- pad->pad_flags |= PAD_SETMASK;
- pad->pad_newmask = mask;
- mutex_exit(&(pad->pad_lock));
-
- /*
- * No need to call set_proc_pre_sys(), since
- * t_pre_sys is ALWAYS on when audit is
- * enabled...due to syscall auditing.
- */
- }
- } else {
- crfree(cr);
- }
- mutex_exit(&p->p_lock);
- }
- mutex_exit(&pidlock);
-
- return (0);
-}
-
-/*
- * Get the current audit state of the system
- */
-static int
-getcond(caddr_t data)
-{
- au_kcontext_t *kctx;
-
- if (au_auditstate == AUC_DISABLED)
- if (copyout(&au_auditstate, data, sizeof (int)))
- return (EFAULT);
-
- kctx = GET_KCTX_PZ;
-
- if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
- return (EFAULT);
-
- return (0);
-}
-
-/*
- * Set the current audit state of the system to on (AUC_AUDITING) or
- * off (AUC_NOAUDIT).
- */
-/* ARGSUSED */
-static int
-setcond(caddr_t data)
-{
- int auditstate;
- au_kcontext_t *kctx;
-
- if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
- return (EINVAL);
-
- kctx = GET_KCTX_NGZ;
-
- if (copyin(data, &auditstate, sizeof (int)))
- return (EFAULT);
-
- switch (auditstate) {
- case AUC_AUDITING: /* Turn auditing on */
- kctx->auk_auditstate = AUC_AUDITING;
- au_auditstate = AUC_ENABLED;
- break;
-
- case AUC_NOAUDIT: /* Turn auditing off */
- if (kctx->auk_auditstate == AUC_NOAUDIT)
- break;
- kctx->auk_auditstate = AUC_NOAUDIT;
-
- /* clear out the audit queue */
-
- mutex_enter(&(kctx->auk_queue.lock));
- if (kctx->auk_queue.wt_block)
- cv_broadcast(&(kctx->auk_queue.write_cv));
-
- /* unblock au_output_thread */
- cv_broadcast(&(kctx->auk_queue.read_cv));
-
- mutex_exit(&(kctx->auk_queue.lock));
- break;
-
- default:
- return (EINVAL);
- }
-
- return (0);
-}
-
-static int
-getclass(caddr_t data)
-{
- au_evclass_map_t event;
- au_kcontext_t *kctx = GET_KCTX_PZ;
-
- if (copyin(data, &event, sizeof (au_evclass_map_t)))
- return (EFAULT);
-
- if (event.ec_number > MAX_KEVENTS)
- return (EINVAL);
-
- event.ec_class = kctx->auk_ets[event.ec_number];
-
- if (copyout(&event, data, sizeof (au_evclass_map_t)))
- return (EFAULT);
-
- return (0);
-}
-
-static int
-setclass(caddr_t data)
-{
- au_evclass_map_t event;
- au_kcontext_t *kctx;
-
- if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
- return (EINVAL);
-
- kctx = GET_KCTX_NGZ;
-
- if (copyin(data, &event, sizeof (au_evclass_map_t)))
- return (EFAULT);
-
- if (event.ec_number > MAX_KEVENTS)
- return (EINVAL);
-
- kctx->auk_ets[event.ec_number] = event.ec_class;
-
- return (0);
-}
-
-static int
-getpinfo(caddr_t data)
-{
- STRUCT_DECL(auditpinfo, apinfo);
- proc_t *proc;
- const auditinfo_addr_t *ainfo;
- model_t model;
- cred_t *cr, *newcred;
-
- model = get_udatamodel();
- STRUCT_INIT(apinfo, model);
-
- if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
- return (EFAULT);
-
- newcred = cralloc();
-
- mutex_enter(&pidlock);
- if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
- mutex_exit(&pidlock);
- crfree(newcred);
- return (ESRCH); /* no such process */
- }
- mutex_enter(&proc->p_lock); /* so process doesn't go away */
- mutex_exit(&pidlock);
-
- audit_update_context(proc, newcred); /* make sure it's up-to-date */
-
- mutex_enter(&proc->p_crlock);
- crhold(cr = proc->p_cred);
- mutex_exit(&proc->p_crlock);
- mutex_exit(&proc->p_lock);
-
- ainfo = crgetauinfo(cr);
- if (ainfo == NULL) {
- crfree(cr);
- return (EINVAL);
- }
-
- /* designated process has an ipv6 address? */
- if (ainfo->ai_termid.at_type == AU_IPv6) {
- crfree(cr);
- return (EOVERFLOW);
- }
-
- STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
- STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
-#ifdef _LP64
- if (model == DATAMODEL_ILP32) {
- dev32_t dev;
- /* convert internal 64 bit form to 32 bit version */
- if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
- crfree(cr);
- return (EOVERFLOW);
- }
- STRUCT_FSET(apinfo, ap_termid.port, dev);
- } else
- STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
-#else
- STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
-#endif
- STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
- STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
-
- crfree(cr);
-
- if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
- return (EFAULT);
-
- return (0);
-}
-
-static int
-getpinfo_addr(caddr_t data, int len)
-{
- STRUCT_DECL(auditpinfo_addr, apinfo);
- proc_t *proc;
- const auditinfo_addr_t *ainfo;
- model_t model;
- cred_t *cr, *newcred;
-
- model = get_udatamodel();
- STRUCT_INIT(apinfo, model);
-
- if (len < STRUCT_SIZE(apinfo))
- return (EOVERFLOW);
-
- if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
- return (EFAULT);
-
- newcred = cralloc();
-
- mutex_enter(&pidlock);
- if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
- mutex_exit(&pidlock);
- crfree(newcred);
- return (ESRCH);
- }
- mutex_enter(&proc->p_lock); /* so process doesn't go away */
- mutex_exit(&pidlock);
-
- audit_update_context(proc, newcred); /* make sure it's up-to-date */
-
- mutex_enter(&proc->p_crlock);
- crhold(cr = proc->p_cred);
- mutex_exit(&proc->p_crlock);
- mutex_exit(&proc->p_lock);
-
- ainfo = crgetauinfo(cr);
- if (ainfo == NULL) {
- crfree(cr);
- return (EINVAL);
- }
-
- STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
- STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
-#ifdef _LP64
- if (model == DATAMODEL_ILP32) {
- dev32_t dev;
- /* convert internal 64 bit form to 32 bit version */
- if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
- crfree(cr);
- return (EOVERFLOW);
- }
- STRUCT_FSET(apinfo, ap_termid.at_port, dev);
- } else
- STRUCT_FSET(apinfo, ap_termid.at_port,
- ainfo->ai_termid.at_port);
-#else
- STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
-#endif
- STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
- STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
- STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
- STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
- STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
- STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
-
- crfree(cr);
-
- if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
- return (EFAULT);
-
- return (0);
-}
-
-static int
-setpmask(caddr_t data)
-{
- STRUCT_DECL(auditpinfo, apinfo);
- proc_t *proc;
- cred_t *newcred;
- auditinfo_addr_t *ainfo;
- struct p_audit_data *pad;
-
- model_t model;
-
- model = get_udatamodel();
- STRUCT_INIT(apinfo, model);
-
- if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
- return (EFAULT);
-
- mutex_enter(&pidlock);
- if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
- mutex_exit(&pidlock);
- return (ESRCH);
- }
- mutex_enter(&proc->p_lock); /* so process doesn't go away */
- mutex_exit(&pidlock);
-
- newcred = cralloc();
- if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
- mutex_exit(&proc->p_lock);
- crfree(newcred);
- return (EINVAL);
- }
-
- mutex_enter(&proc->p_crlock);
- crcopy_to(proc->p_cred, newcred);
- proc->p_cred = newcred;
-
- ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
-
- /*
- * Unlock. No need to broadcast changes via set_proc_pre_sys(),
- * since t_pre_sys is ALWAYS on when audit is enabled... due to
- * syscall auditing.
- */
- crfree(newcred);
- mutex_exit(&proc->p_crlock);
-
- /* Reset flag for any previous pending mask change; this supercedes */
- pad = P2A(proc);
- ASSERT(pad != NULL);
- mutex_enter(&(pad->pad_lock));
- pad->pad_flags &= ~PAD_SETMASK;
- mutex_exit(&(pad->pad_lock));
-
- mutex_exit(&proc->p_lock);
-
- return (0);
-}
-
-/*
- * The out of control system call
- * This is audit kitchen sink aka auditadm, aka auditon
- */
-static int
-auditctl(
- int cmd,
- caddr_t data,
- int length)
-{
- int result;
-
- if (!audit_active)
- return (EINVAL);
-
- switch (cmd) {
- case A_GETCOND:
- case A_GETCAR:
- case A_GETCLASS:
- case A_GETCWD:
- case A_GETKAUDIT:
- case A_GETKMASK:
- case A_GETPINFO:
- case A_GETPINFO_ADDR:
- case A_GETPOLICY:
- case A_GETQCTRL:
- case A_GETSTAT:
- if (secpolicy_audit_getattr(CRED()) != 0)
- return (EPERM);
- break;
- default:
- if (secpolicy_audit_config(CRED()) != 0)
- return (EPERM);
- break;
- }
-
- switch (cmd) {
- case A_GETPOLICY:
- result = getpolicy(data);
- break;
- case A_SETPOLICY:
- result = setpolicy(data);
- break;
- case A_GETKMASK:
- result = getkmask(data);
- break;
- case A_SETKMASK:
- result = setkmask(data);
- break;
- case A_GETKAUDIT:
- result = getkaudit(data, length);
- break;
- case A_SETKAUDIT:
- result = setkaudit(data, length);
- break;
- case A_GETQCTRL:
- result = getqctrl(data);
- break;
- case A_SETQCTRL:
- result = setqctrl(data);
- break;
- case A_GETCWD:
- result = getcwd(data, length);
- break;
- case A_GETCAR:
- result = getcar(data, length);
- break;
- case A_GETSTAT:
- result = getstat(data);
- break;
- case A_SETSTAT:
- result = setstat(data);
- break;
- case A_SETUMASK:
- result = setumask(data);
- break;
- case A_SETSMASK:
- result = setsmask(data);
- break;
- case A_GETCOND:
- result = getcond(data);
- break;
- case A_SETCOND:
- result = setcond(data);
- break;
- case A_GETCLASS:
- result = getclass(data);
- break;
- case A_SETCLASS:
- result = setclass(data);
- break;
- case A_GETPINFO:
- result = getpinfo(data);
- break;
- case A_GETPINFO_ADDR:
- result = getpinfo_addr(data, length);
- break;
- case A_SETPMASK:
- result = setpmask(data);
- break;
- default:
- result = EINVAL;
- break;
- }
- return (result);
-}
-
-static int
-audit_modsysent(char *modname, int flags, int (*func)())
-{
- struct sysent *sysp;
- int sysnum;
- krwlock_t *kl;
-
- if ((sysnum = mod_getsysnum(modname)) == -1) {
- cmn_err(CE_WARN, "system call missing from bind file");
- return (-1);
- }
-
- kl = (krwlock_t *)kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
-
- sysp = &sysent[sysnum];
- sysp->sy_narg = auditsysent.sy_narg;
-#ifdef _LP64
- sysp->sy_flags = (unsigned short)flags;
-#else
- sysp->sy_flags = (unsigned char)flags;
-#endif
- sysp->sy_call = func;
- sysp->sy_lock = kl;
-
-#ifdef _SYSCALL32_IMPL
- sysp = &sysent32[sysnum];
- sysp->sy_narg = auditsysent.sy_narg;
- sysp->sy_flags = (unsigned short)flags;
- sysp->sy_call = func;
- sysp->sy_lock = kl;
-#endif
-
- rw_init(sysp->sy_lock, NULL, RW_DEFAULT, NULL);
-
- return (0);
-}
diff --git a/usr/src/uts/common/crypto/io/cryptoadm.c b/usr/src/uts/common/crypto/io/cryptoadm.c
index 9f7a839f77..bddc6d4778 100644
--- a/usr/src/uts/common/crypto/io/cryptoadm.c
+++ b/usr/src/uts/common/crypto/io/cryptoadm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -558,7 +558,7 @@ out:
error = EFAULT;
}
out2:
- if (audit_active)
+ if (AU_AUDITING())
audit_cryptoadm(CRYPTO_LOAD_DEV_DISABLED, dev_name, entries,
count, instance, rv, error);
return (error);
@@ -636,7 +636,7 @@ out:
error = EFAULT;
}
out2:
- if (audit_active)
+ if (AU_AUDITING())
audit_cryptoadm(CRYPTO_LOAD_SOFT_DISABLED, name, entries,
count, 0, rv, error);
return (error);
@@ -718,7 +718,7 @@ out:
error = EFAULT;
}
out2:
- if (audit_active)
+ if (AU_AUDITING())
audit_cryptoadm(CRYPTO_LOAD_SOFT_CONFIG, name, entries, count,
0, rv, error);
return (error);
@@ -763,7 +763,7 @@ out:
error = EFAULT;
}
out2:
- if (audit_active)
+ if (AU_AUDITING())
audit_cryptoadm(CRYPTO_UNLOAD_SOFT_MODULE, name, NULL, 0, 0,
rv, error);
@@ -799,7 +799,7 @@ out:
error = EFAULT;
out2:
- if (audit_active)
+ if (AU_AUDITING())
audit_cryptoadm(CRYPTO_LOAD_DOOR, NULL, NULL,
0, 0, rv, error);
return (error);
@@ -882,6 +882,7 @@ static int
cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
int *rval)
{
+ uint32_t auditing = AU_AUDITING();
int error;
#define ARG ((caddr_t)arg)
@@ -932,7 +933,7 @@ cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
* So, this is a no op. We are keeping this ioctl around
* to be used for any future threadpool related work.
*/
- if (audit_active)
+ if (auditing)
audit_cryptoadm(CRYPTO_POOL_CREATE, NULL, NULL,
0, 0, 0, 0);
return (0);
@@ -945,7 +946,7 @@ cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
== -1)
err = EFAULT;
}
- if (audit_active)
+ if (auditing)
audit_cryptoadm(CRYPTO_POOL_WAIT, NULL, NULL,
0, 0, 0, err);
return (err);
@@ -955,7 +956,7 @@ cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
int err;
err = kcf_svc_do_run();
- if (audit_active)
+ if (auditing)
audit_cryptoadm(CRYPTO_POOL_RUN, NULL, NULL,
0, 0, 0, err);
return (err);
@@ -969,7 +970,7 @@ cryptoadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
int err;
err = fips140_actions(dev, ARG, mode, rval, cmd);
- if (audit_active)
+ if (auditing)
audit_cryptoadm(CRYPTO_FIPS140_SET, NULL, NULL,
0, 0, 0, err);
return (err);
diff --git a/usr/src/uts/common/fs/lookup.c b/usr/src/uts/common/fs/lookup.c
index 076887fdbc..940b2f17d1 100644
--- a/usr/src/uts/common/fs/lookup.c
+++ b/usr/src/uts/common/fs/lookup.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -92,7 +92,7 @@ lookupnameatcred(
error = pn_get_buf(fnamep, seg, &lookpn, namebuf, sizeof (namebuf));
if (error == 0) {
- if (audit_active)
+ if (AU_AUDITING())
audit_lookupname();
error = lookuppnatcred(&lookpn, NULL, followlink,
dirvpp, compvpp, startvp, cr);
@@ -230,6 +230,7 @@ lookuppnvp(
vnode_t *zonevp = curproc->p_zone->zone_rootvp; /* zone root */
int must_be_directory = 0;
boolean_t retry_with_kcred;
+ uint32_t auditing = AU_AUDITING();
CPU_STATS_ADDQ(CPU, sys, namei, 1);
nlink = 0;
@@ -244,7 +245,7 @@ lookuppnvp(
pp = &presrvd;
}
- if (audit_active)
+ if (auditing)
audit_anchorpath(pnp, vp == rootvp);
/*
@@ -276,7 +277,7 @@ next:
* Process the next component of the pathname.
*/
if (error = pn_getcomponent(pnp, component)) {
- if (audit_active)
+ if (auditing)
audit_addcomponent(pnp);
goto bad;
}
@@ -408,7 +409,7 @@ checkforroot:
*/
if (pn_pathleft(pnp) || dirvpp == NULL || error != ENOENT)
goto bad;
- if (audit_active) { /* directory access */
+ if (auditing) { /* directory access */
if (error = audit_savepath(pnp, vp, error, cr))
goto bad_noaudit;
}
@@ -466,7 +467,7 @@ checkforroot:
*/
if (cvp->v_type == VLNK && ((flags & FOLLOW) || pn_pathleft(pnp))) {
struct pathname linkpath;
- if (audit_active) {
+ if (auditing) {
if (error = audit_pathcomp(pnp, cvp, cr))
goto bad;
}
@@ -481,7 +482,7 @@ checkforroot:
goto bad;
}
- if (audit_active)
+ if (auditing)
audit_symlink(pnp, &linkpath);
if (pn_pathleft(&linkpath) == 0)
@@ -505,7 +506,7 @@ checkforroot:
vp = rootvp;
VN_HOLD(vp);
}
- if (audit_active)
+ if (auditing)
audit_anchorpath(pnp, vp == rootvp);
if (pn_fixslash(pnp)) {
flags |= FOLLOW;
@@ -578,7 +579,7 @@ checkforroot:
* an alias of the last component.
*/
if (vn_compare(vp, cvp)) {
- if (audit_active)
+ if (auditing)
(void) audit_savepath(pnp, cvp,
EINVAL, cr);
pn_setlast(pnp);
@@ -590,14 +591,14 @@ checkforroot:
pn_free(pp);
return (EINVAL);
}
- if (audit_active) {
+ if (auditing) {
if (error = audit_pathcomp(pnp, vp, cr))
goto bad;
}
*dirvpp = vp;
} else
VN_RELE(vp);
- if (audit_active)
+ if (auditing)
(void) audit_savepath(pnp, cvp, 0, cr);
if (pnp->pn_path == pnp->pn_buf)
(void) pn_set(pnp, ".");
@@ -621,7 +622,7 @@ checkforroot:
return (0);
}
- if (audit_active) {
+ if (auditing) {
if (error = audit_pathcomp(pnp, cvp, cr))
goto bad;
}
@@ -645,7 +646,7 @@ checkforroot:
goto next;
bad:
- if (audit_active) /* reached end of path */
+ if (auditing) /* reached end of path */
(void) audit_savepath(pnp, cvp, error, cr);
bad_noaudit:
/*
diff --git a/usr/src/uts/common/fs/sockfs/sockstr.c b/usr/src/uts/common/fs/sockfs/sockstr.c
index dc2af07a93..4b08e4aac3 100644
--- a/usr/src/uts/common/fs/sockfs/sockstr.c
+++ b/usr/src/uts/common/fs/sockfs/sockstr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1679,6 +1679,7 @@ strsock_proto(vnode_t *vp, mblk_t *mp,
union T_primitives *tpr;
struct sonode *so;
sotpi_info_t *sti;
+ uint32_t auditing = AU_AUDITING();
so = VTOSO(vp);
sti = SOTOTPI(so);
@@ -1788,7 +1789,7 @@ strsock_proto(vnode_t *vp, mblk_t *mp,
*allmsgsigs = S_INPUT | S_RDNORM;
*pollwakeups = POLLIN | POLLRDNORM;
*wakeups = RSLEEP;
- if (audit_active)
+ if (auditing)
audit_sock(T_UNITDATA_IND, strvp2wq(vp),
mp, 0);
return (mp);
@@ -2279,7 +2280,7 @@ strsock_proto(vnode_t *vp, mblk_t *mp,
return (NULL);
}
- if (audit_active)
+ if (auditing)
audit_sock(T_CONN_IND, strvp2wq(vp), mp, 0);
if (!(so->so_state & SS_ACCEPTCONN)) {
zcmn_err(getzoneid(), CE_WARN,
diff --git a/usr/src/uts/common/fs/sockfs/socksubr.c b/usr/src/uts/common/fs/sockfs/socksubr.c
index 526fdd4937..2a329da653 100644
--- a/usr/src/uts/common/fs/sockfs/socksubr.c
+++ b/usr/src/uts/common/fs/sockfs/socksubr.c
@@ -62,7 +62,6 @@
#include <sys/socketvar.h>
#include <netinet/in.h>
#include <sys/un.h>
-
#include <sys/ucred.h>
#include <sys/tiuser.h>
@@ -756,7 +755,7 @@ fdbuf_extract(struct fdbuf *fdbuf, void *rights, int rightslen)
mutex_exit(&fp->f_tlock);
setf(fd, fp);
*rp++ = fd;
- if (audit_active)
+ if (AU_AUDITING())
audit_fdrecv(fd, fp);
dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
i, fd, (void *)fp, fp->f_count));
@@ -830,7 +829,7 @@ fdbuf_create(void *rights, int rightslen, struct fdbuf **fdbufp)
fdbuf->fd_fds[i] = fp;
fdbuf->fd_numfd++;
releasef(fds[i]);
- if (audit_active)
+ if (AU_AUDITING())
audit_fdsend(fds[i], fp, 0);
}
*fdbufp = fdbuf;
diff --git a/usr/src/uts/common/fs/sockfs/socktpi.c b/usr/src/uts/common/fs/sockfs/socktpi.c
index bfbd67ad81..de0293e710 100644
--- a/usr/src/uts/common/fs/sockfs/socktpi.c
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2591,7 +2591,7 @@ sotpi_connect(struct sonode *so,
soisconnecting(so);
mutex_exit(&so->so_lock);
- if (audit_active)
+ if (AU_AUDITING())
audit_sock(T_CONN_REQ, strvp2wq(SOTOV(so)), mp, 0);
error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
@@ -3857,7 +3857,7 @@ sosend_dgramcmsg(struct sonode *so, struct sockaddr *name, socklen_t namelen,
ASSERT(MBLKL(mp) <= (ssize_t)size);
ASSERT(mp->b_wptr <= mp->b_datap->db_lim);
- if (audit_active)
+ if (AU_AUDITING())
audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
error = kstrputmsg(SOTOV(so), mp, uiop, len, 0, MSG_BAND, 0);
@@ -4135,7 +4135,7 @@ sosend_dgram(struct sonode *so, struct sockaddr *name, socklen_t namelen,
ASSERT(mp->b_wptr <= mp->b_datap->db_lim);
}
- if (audit_active)
+ if (AU_AUDITING())
audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
error = kstrputmsg(SOTOV(so), mp, uiop, len, 0, MSG_BAND, 0);
@@ -4657,6 +4657,7 @@ sodgram_direct(struct sonode *so, struct sockaddr *name,
boolean_t connected;
mblk_t *mpdata = NULL;
sotpi_info_t *sti = SOTOTPI(so);
+ uint32_t auditing = AU_AUDITING();
ASSERT(name != NULL && namelen != 0);
ASSERT(!(so->so_mode & SM_CONNREQUIRED));
@@ -4721,7 +4722,7 @@ sodgram_direct(struct sonode *so, struct sockaddr *name,
linkb(mp, mpdata);
else
mp = mpdata;
- if (audit_active)
+ if (auditing)
audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
udp_wput(udp_wq, mp);
@@ -4741,7 +4742,7 @@ sodgram_direct(struct sonode *so, struct sockaddr *name,
if (connected)
return (strwrite(SOTOV(so), uiop, CRED()));
- if (audit_active)
+ if (auditing)
audit_sock(T_UNITDATA_REQ, strvp2wq(SOTOV(so)), mp, 0);
error = kstrputmsg(SOTOV(so), mp, uiop, len, 0, MSG_BAND, 0);
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index acdfdb36a1..f1a69479b8 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -1295,6 +1295,7 @@ vn_createat(
struct vattr vattr;
enum symfollow follow;
int estale_retry = 0;
+ uint32_t auditing = AU_AUDITING();
ASSERT((vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE));
@@ -1318,7 +1319,7 @@ top:
*/
if (error = pn_get(pnamep, seg, &pn))
return (error);
- if (audit_active)
+ if (auditing)
audit_vncreate_start();
dvp = NULL;
*vpp = NULL;
@@ -1526,7 +1527,7 @@ top:
out:
- if (audit_active)
+ if (auditing)
audit_vncreate_finish(*vpp, error);
if (in_crit) {
nbl_end_crit(vp);
@@ -1628,6 +1629,7 @@ vn_renameat(vnode_t *fdvp, char *fname, vnode_t *tdvp,
vnode_t *fromvp, *fvp;
vnode_t *tovp, *targvp;
int estale_retry = 0;
+ uint32_t auditing = AU_AUDITING();
top:
fvp = fromvp = tovp = targvp = NULL;
@@ -1651,7 +1653,7 @@ top:
* use the lib directory for the rename.
*/
- if (audit_active)
+ if (auditing)
audit_setfsat_path(1);
/*
* Lookup to and from directories.
@@ -1668,7 +1670,7 @@ top:
goto out;
}
- if (audit_active)
+ if (auditing)
audit_setfsat_path(3);
if (error = lookuppnat(&tpn, NULL, NO_FOLLOW, &tovp, &targvp, tdvp)) {
goto out;
diff --git a/usr/src/uts/common/inet/ip/spdsock.c b/usr/src/uts/common/inet/ip/spdsock.c
index 1ff0cff31d..4a9053cddf 100644
--- a/usr/src/uts/common/inet/ip/spdsock.c
+++ b/usr/src/uts/common/inet/ip/spdsock.c
@@ -590,10 +590,11 @@ spdsock_flush(queue_t *q, ipsec_policy_head_t *iph, ipsec_tun_pol_t *itp,
boolean_t active;
spdsock_t *ss = (spdsock_t *)q->q_ptr;
netstack_t *ns = ss->spdsock_spds->spds_netstack;
+ uint32_t auditing = AU_AUDITING();
if (iph != ALL_ACTIVE_POLHEADS && iph != ALL_INACTIVE_POLHEADS) {
spdsock_flush_one(iph, ns);
- if (audit_active) {
+ if (auditing) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
pid_t cpid;
@@ -609,7 +610,7 @@ spdsock_flush(queue_t *q, ipsec_policy_head_t *iph, ipsec_tun_pol_t *itp,
/* First flush the global policy. */
spdsock_flush_one(active ? ipsec_system_policy(ns) :
ipsec_inactive_policy(ns), ns);
- if (audit_active) {
+ if (auditing) {
cred_t *cr;
pid_t cpid;
@@ -619,7 +620,7 @@ spdsock_flush(queue_t *q, ipsec_policy_head_t *iph, ipsec_tun_pol_t *itp,
}
/* Then flush every tunnel's appropriate one. */
itp_walk(spdsock_flush_node, (void *)active, ns);
- if (audit_active) {
+ if (auditing) {
cred_t *cr;
pid_t cpid;
@@ -1024,11 +1025,12 @@ spdsock_addrule(queue_t *q, ipsec_policy_head_t *iph, mblk_t *mp,
boolean_t tunnel_mode, empty_itp, active;
uint64_t *index = (itp == NULL) ? NULL : &itp->itp_next_policy_index;
spdsock_t *ss = (spdsock_t *)q->q_ptr;
- spd_stack_t *spds = ss->spdsock_spds;
+ spd_stack_t *spds = ss->spdsock_spds;
+ uint32_t auditing = AU_AUDITING();
if (rule == NULL) {
spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
- if (audit_active) {
+ if (auditing) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
pid_t cpid;
@@ -1138,7 +1140,7 @@ spdsock_addrule(queue_t *q, ipsec_policy_head_t *iph, mblk_t *mp,
ipsec_actvec_free(actp, nact);
spd_echo(q, mp);
- if (audit_active) {
+ if (auditing) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
pid_t cpid;
@@ -1162,7 +1164,7 @@ fail2:
mutex_exit(&itp->itp_lock);
}
spdsock_error(q, mp, error, diag);
- if (audit_active) {
+ if (auditing) {
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
pid_t cpid;
@@ -1183,10 +1185,11 @@ spdsock_deleterule(queue_t *q, ipsec_policy_head_t *iph, mblk_t *mp,
int err, diag = 0;
spdsock_t *ss = (spdsock_t *)q->q_ptr;
netstack_t *ns = ss->spdsock_spds->spds_netstack;
+ uint32_t auditing = AU_AUDITING();
if (rule == NULL) {
spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1247,7 +1250,7 @@ spdsock_deleterule(queue_t *q, ipsec_policy_head_t *iph, mblk_t *mp,
mutex_exit(&itp->itp_lock);
}
spd_echo(q, mp);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1263,7 +1266,7 @@ fail:
if (itp != NULL)
mutex_exit(&itp->itp_lock);
spdsock_error(q, mp, err, diag);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1296,13 +1299,14 @@ spdsock_flip(queue_t *q, mblk_t *mp, spd_if_t *tunname)
ipsec_tun_pol_t *itp;
spdsock_t *ss = (spdsock_t *)q->q_ptr;
netstack_t *ns = ss->spdsock_spds->spds_netstack;
+ uint32_t auditing = AU_AUDITING();
if (tunname != NULL) {
tname = (char *)tunname->spd_if_name;
if (*tname == '\0') {
/* can't fail */
ipsec_swap_global_policy(ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1314,7 +1318,7 @@ spdsock_flip(queue_t *q, mblk_t *mp, spd_if_t *tunname)
NULL, active, 0, cpid);
}
itp_walk(spdsock_flip_node, NULL, ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1330,7 +1334,7 @@ spdsock_flip(queue_t *q, mblk_t *mp, spd_if_t *tunname)
if (itp == NULL) {
/* Better idea for "tunnel not found"? */
spdsock_error(q, mp, ESRCH, 0);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
@@ -1347,7 +1351,7 @@ spdsock_flip(queue_t *q, mblk_t *mp, spd_if_t *tunname)
return;
}
spdsock_flip_node(itp, NULL, ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -1362,7 +1366,7 @@ spdsock_flip(queue_t *q, mblk_t *mp, spd_if_t *tunname)
}
} else {
ipsec_swap_global_policy(ns); /* can't fail */
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -2106,12 +2110,13 @@ spdsock_clone(queue_t *q, mblk_t *mp, spd_if_t *tunname)
ipsec_tun_pol_t *itp;
spdsock_t *ss = (spdsock_t *)q->q_ptr;
netstack_t *ns = ss->spdsock_spds->spds_netstack;
+ uint32_t auditing = AU_AUDITING();
if (tunname != NULL) {
tname = (char *)tunname->spd_if_name;
if (*tname == '\0') {
error = ipsec_clone_system_policy(ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -2124,7 +2129,7 @@ spdsock_clone(queue_t *q, mblk_t *mp, spd_if_t *tunname)
}
if (error == 0) {
itp_walk(spdsock_clone_node, &error, ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
@@ -2143,7 +2148,7 @@ spdsock_clone(queue_t *q, mblk_t *mp, spd_if_t *tunname)
itp = get_tunnel_policy(tname, ns);
if (itp == NULL) {
spdsock_error(q, mp, ENOENT, 0);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg =
(spd_msg_t *)mp->b_rptr;
@@ -2159,7 +2164,7 @@ spdsock_clone(queue_t *q, mblk_t *mp, spd_if_t *tunname)
return;
}
spdsock_clone_node(itp, &error, NULL);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -2174,7 +2179,7 @@ spdsock_clone(queue_t *q, mblk_t *mp, spd_if_t *tunname)
}
} else {
error = ipsec_clone_system_policy(ns);
- if (audit_active) {
+ if (auditing) {
boolean_t active;
spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
cred_t *cr;
@@ -2769,6 +2774,7 @@ spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
spdsock_t *ss = (spdsock_t *)q->q_ptr;
spd_stack_t *spds = ss->spdsock_spds;
ipsec_stack_t *ipss = spds->spds_netstack->netstack_ipsec;
+ uint32_t auditing = AU_AUDITING();
if (!ipsec_loaded(ipss)) {
/*
@@ -2790,7 +2796,7 @@ spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
spds->spds_mp_algs = mp;
spds->spds_algs_pending = B_TRUE;
mutex_exit(&spds->spds_alg_lock);
- if (audit_active) {
+ if (auditing) {
cred_t *cr;
pid_t cpid;
@@ -2814,7 +2820,7 @@ spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
spds->spds_netstack);
mutex_exit(&spds->spds_alg_lock);
spd_echo(q, mp);
- if (audit_active) {
+ if (auditing) {
cred_t *cr;
pid_t cpid;
@@ -2826,7 +2832,7 @@ spdsock_updatealg(queue_t *q, mblk_t *mp, spd_ext_t *extv[])
} else {
mutex_exit(&spds->spds_alg_lock);
spdsock_diag(q, mp, diag);
- if (audit_active) {
+ if (auditing) {
cred_t *cr;
pid_t cpid;
diff --git a/usr/src/uts/common/inet/kssl/kssl.c b/usr/src/uts/common/inet/kssl/kssl.c
index 19699a3990..0b6890fadb 100644
--- a/usr/src/uts/common/inet/kssl/kssl.c
+++ b/usr/src/uts/common/inet/kssl/kssl.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -278,6 +278,7 @@ kssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
int *rval)
{
int error = EINVAL;
+ uint32_t auditing = AU_AUDITING();
#define ARG ((caddr_t)arg)
@@ -310,7 +311,7 @@ kssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
return (EFAULT);
}
error = kssl_add_entry(kssl_params);
- if (audit_active)
+ if (auditing)
audit_kssl(KSSL_ADD_ENTRY, kssl_params, error);
off = offsetof(kssl_params_t, kssl_token) +
offsetof(kssl_tokinfo_t, ck_rv);
@@ -331,7 +332,7 @@ kssl_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c,
}
error = kssl_delete_entry(&server_addr);
- if (audit_active)
+ if (auditing)
audit_kssl(KSSL_DELETE_ENTRY, &server_addr, error);
break;
}
diff --git a/usr/src/uts/common/io/timod.c b/usr/src/uts/common/io/timod.c
index 4d9e4eaa6e..41bf9ce7dc 100644
--- a/usr/src/uts/common/io/timod.c
+++ b/usr/src/uts/common/io/timod.c
@@ -20,7 +20,7 @@
*/
/* ONC_PLUS EXTRACT START */
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -695,6 +695,7 @@ timodprocessinfo(queue_t *q, struct tim_tim *tp, struct T_info_ack *tia)
static int
timodrproc(queue_t *q, mblk_t *mp)
{
+ uint32_t auditing = AU_AUDITING();
union T_primitives *pptr;
struct tim_tim *tp;
struct iocblk *iocbp;
@@ -787,7 +788,7 @@ timodrproc(queue_t *q, mblk_t *mp)
default:
/* ONC_PLUS EXTRACT END */
- if (audit_active)
+ if (auditing)
audit_sock(T_UNITDATA_IND, q, mp, TIMOD_ID);
/* ONC_PLUS EXTRACT START */
putnext(q, mp);
@@ -969,23 +970,24 @@ timodrproc(queue_t *q, mblk_t *mp)
/* ONC_PLUS EXTRACT END */
case T_OPTMGMT_ACK:
- tilog("timodrproc: Got T_OPTMGMT_ACK\n", 0);
+ tilog("timodrproc: Got T_OPTMGMT_ACK\n", 0);
- /* Restore db_type - recover() might have change it */
- mp->b_datap->db_type = M_PCPROTO;
+ /* Restore db_type - recover() might have change it */
+ mp->b_datap->db_type = M_PCPROTO;
- if (((tp->tim_flags & WAITIOCACK) == 0) ||
- ((tp->tim_saved_prim != T_SVR4_OPTMGMT_REQ) &&
- (tp->tim_saved_prim != T_OPTMGMT_REQ))) {
- putnext(q, mp);
- } else {
- ASSERT(tp->tim_iocsave != NULL);
- tim_ioctl_send_reply(q, tp->tim_iocsave, mp);
- tp->tim_iocsave = NULL;
- tp->tim_saved_prim = -1;
- tp->tim_flags &= ~(WAITIOCACK | WAIT_IOCINFOACK |
- TI_CAP_RECVD | CAP_WANTS_INFO);
- }
+ if (((tp->tim_flags & WAITIOCACK) == 0) ||
+ ((tp->tim_saved_prim != T_SVR4_OPTMGMT_REQ) &&
+ (tp->tim_saved_prim != T_OPTMGMT_REQ))) {
+ putnext(q, mp);
+ } else {
+ ASSERT(tp->tim_iocsave != NULL);
+ tim_ioctl_send_reply(q, tp->tim_iocsave, mp);
+ tp->tim_iocsave = NULL;
+ tp->tim_saved_prim = -1;
+ tp->tim_flags &= ~(WAITIOCACK |
+ WAIT_IOCINFOACK | TI_CAP_RECVD |
+ CAP_WANTS_INFO);
+ }
break;
case T_INFO_ACK: {
@@ -1109,31 +1111,31 @@ timodrproc(queue_t *q, mblk_t *mp)
deficit) {
mblk_t *tmp = allocb(expected_ack_size,
BPRI_HI);
- if (tmp == NULL) {
- ASSERT(MBLKSIZE(mp) >=
- sizeof (struct T_error_ack));
-
- tilog("timodrproc: allocb failed no "
- "recovery attempt\n", 0);
-
- mp->b_rptr = mp->b_datap->db_base;
- pptr = (union T_primitives *)
- mp->b_rptr;
- pptr->error_ack.ERROR_prim = T_INFO_REQ;
- pptr->error_ack.TLI_error = TSYSERR;
- pptr->error_ack.UNIX_error = EAGAIN;
- pptr->error_ack.PRIM_type = T_ERROR_ACK;
- mp->b_datap->db_type = M_PCPROTO;
- tim_send_ioc_error_ack(q, tp, mp);
- break;
- } else {
- bcopy(mp->b_rptr, tmp->b_rptr, blen);
- tmp->b_wptr += blen;
- pptr = (union T_primitives *)
- tmp->b_rptr;
- freemsg(mp);
- mp = tmp;
- }
+ if (tmp == NULL) {
+ ASSERT(MBLKSIZE(mp) >=
+ sizeof (struct T_error_ack));
+
+ tilog("timodrproc: allocb failed no "
+ "recovery attempt\n", 0);
+
+ mp->b_rptr = mp->b_datap->db_base;
+ pptr = (union T_primitives *)
+ mp->b_rptr;
+ pptr->error_ack.ERROR_prim = T_INFO_REQ;
+ pptr->error_ack.TLI_error = TSYSERR;
+ pptr->error_ack.UNIX_error = EAGAIN;
+ pptr->error_ack.PRIM_type = T_ERROR_ACK;
+ mp->b_datap->db_type = M_PCPROTO;
+ tim_send_ioc_error_ack(q, tp, mp);
+ break;
+ } else {
+ bcopy(mp->b_rptr, tmp->b_rptr, blen);
+ tmp->b_wptr += blen;
+ pptr = (union T_primitives *)
+ tmp->b_rptr;
+ freemsg(mp);
+ mp = tmp;
+ }
}
}
/*
@@ -1218,7 +1220,7 @@ timodrproc(queue_t *q, mblk_t *mp)
}
}
/* ONC_PLUS EXTRACT END */
- if (audit_active)
+ if (auditing)
audit_sock(T_CONN_IND, q, mp, TIMOD_ID);
/* ONC_PLUS EXTRACT START */
putnext(q, mp);
@@ -1281,16 +1283,16 @@ timodrproc(queue_t *q, mblk_t *mp)
case T_ORDREL_IND:
- tilog("timodrproc: Got T_ORDREL_IND\n", 0);
+ tilog("timodrproc: Got T_ORDREL_IND\n", 0);
- if (tp->tim_flags & LOCORDREL) {
- tp->tim_flags &= ~(LOCORDREL|REMORDREL);
- tim_clear_peer(tp);
- } else {
- tp->tim_flags |= REMORDREL;
- }
- putnext(q, mp);
- break;
+ if (tp->tim_flags & LOCORDREL) {
+ tp->tim_flags &= ~(LOCORDREL|REMORDREL);
+ tim_clear_peer(tp);
+ } else {
+ tp->tim_flags |= REMORDREL;
+ }
+ putnext(q, mp);
+ break;
case T_EXDATA_IND:
case T_DATA_IND:
@@ -1430,36 +1432,36 @@ timodrproc(queue_t *q, mblk_t *mp)
/* ONC_PLUS EXTRACT START */
case M_IOCNAK:
- tilog("timodrproc: Got M_IOCNAK\n", 0);
+ tilog("timodrproc: Got M_IOCNAK\n", 0);
- iocbp = (struct iocblk *)mp->b_rptr;
- if (((iocbp->ioc_cmd == TI_GETMYNAME) ||
- (iocbp->ioc_cmd == TI_GETPEERNAME)) &&
- ((iocbp->ioc_error == EINVAL) || (iocbp->ioc_error == 0))) {
- PI_PROVLOCK(tp->tim_provinfo);
- if (iocbp->ioc_cmd == TI_GETMYNAME) {
- if (tp->tim_provinfo->tpi_myname == PI_DONTKNOW)
- tp->tim_provinfo->tpi_myname = PI_NO;
- } else if (iocbp->ioc_cmd == TI_GETPEERNAME) {
- if (tp->tim_provinfo->tpi_peername == PI_DONTKNOW)
- tp->tim_provinfo->tpi_peername = PI_NO;
- }
- PI_PROVUNLOCK(tp->tim_provinfo);
- /* tim_iocsave may already be overwritten. */
- if ((tp->tim_iocsave != NULL) &&
- (tp->tim_saved_prim == -1)) {
- freemsg(mp);
- mp = tp->tim_iocsave;
- tp->tim_iocsave = NULL;
- tp->tim_flags |= NAMEPROC;
- if (ti_doname(WR(q), mp) != DONAME_CONT) {
- tp->tim_flags &= ~NAMEPROC;
- }
- break;
- }
- }
- putnext(q, mp);
- break;
+ iocbp = (struct iocblk *)mp->b_rptr;
+ if (((iocbp->ioc_cmd == TI_GETMYNAME) ||
+ (iocbp->ioc_cmd == TI_GETPEERNAME)) &&
+ ((iocbp->ioc_error == EINVAL) || (iocbp->ioc_error == 0))) {
+ PI_PROVLOCK(tp->tim_provinfo);
+ if (iocbp->ioc_cmd == TI_GETMYNAME) {
+ if (tp->tim_provinfo->tpi_myname == PI_DONTKNOW)
+ tp->tim_provinfo->tpi_myname = PI_NO;
+ } else if (iocbp->ioc_cmd == TI_GETPEERNAME) {
+ if (tp->tim_provinfo->tpi_peername == PI_DONTKNOW)
+ tp->tim_provinfo->tpi_peername = PI_NO;
+ }
+ PI_PROVUNLOCK(tp->tim_provinfo);
+ /* tim_iocsave may already be overwritten. */
+ if ((tp->tim_iocsave != NULL) &&
+ (tp->tim_saved_prim == -1)) {
+ freemsg(mp);
+ mp = tp->tim_iocsave;
+ tp->tim_iocsave = NULL;
+ tp->tim_flags |= NAMEPROC;
+ if (ti_doname(WR(q), mp) != DONAME_CONT) {
+ tp->tim_flags &= ~NAMEPROC;
+ }
+ break;
+ }
+ }
+ putnext(q, mp);
+ break;
/* ONC_PLUS EXTRACT END */
}
@@ -1614,6 +1616,7 @@ timodwproc(queue_t *q, mblk_t *mp)
{
union T_primitives *pptr;
struct tim_tim *tp;
+ uint32_t auditing = AU_AUDITING();
mblk_t *tmp;
struct iocblk *iocbp;
int error;
@@ -1997,7 +2000,7 @@ getname:
mp = tmp;
}
}
- if (audit_active)
+ if (auditing)
audit_sock(T_UNITDATA_REQ, q, mp, TIMOD_ID);
if (!bcanputnext(q, mp->b_band)) {
(void) putbq(q, mp);
@@ -2053,12 +2056,12 @@ getname:
if (tp->tim_flags & COTS)
tp->tim_flags |= CONNWAIT;
/* ONC_PLUS EXTRACT END */
- if (audit_active)
+ if (auditing)
audit_sock(T_CONN_REQ, q, mp, TIMOD_ID);
/* ONC_PLUS EXTRACT START */
putnext(q, mp);
break;
- }
+ }
case O_T_CONN_RES:
case T_CONN_RES: {
diff --git a/usr/src/uts/common/os/audit_core.c b/usr/src/uts/common/os/audit_core.c
new file mode 100644
index 0000000000..74fcf3b937
--- /dev/null
+++ b/usr/src/uts/common/os/audit_core.c
@@ -0,0 +1,439 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/kmem.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/file.h>
+#include <sys/user.h>
+#include <sys/stropts.h>
+#include <sys/systm.h>
+#include <sys/pathname.h>
+#include <sys/debug.h>
+#include <sys/cred_impl.h>
+#include <sys/zone.h>
+#include <sys/modctl.h>
+#include <sys/sysconf.h>
+#include <c2/audit.h>
+#include <c2/audit_kernel.h>
+#include <c2/audit_kevents.h>
+#include <c2/audit_record.h>
+
+
+struct p_audit_data *pad0;
+struct t_audit_data *tad0;
+
+extern uint_t num_syscall; /* size of audit_s2e table */
+extern kmutex_t pidlock; /* proc table lock */
+
+
+void
+audit_init()
+{
+ kthread_t *au_thread;
+ auditinfo_addr_t *ainfo;
+ struct audit_path apempty;
+
+ /*
+ * If the c2audit module is explicitely excluded in /etc/system,
+ * it cannot be loaded later (e.g. using modload). Make a notice
+ * that the module won't be present and do nothing.
+ */
+
+ if (mod_sysctl(SYS_CHECK_EXCLUDE, "c2audit") != 0) {
+ audit_active = C2AUDIT_DISABLED;
+ return;
+ }
+
+ /* c2audit module can be loaded anytime */
+ audit_active = C2AUDIT_UNLOADED;
+
+ /* initialize the process audit data (pad) memory allocator */
+ au_pad_init();
+
+ /* initialize the zone audit context */
+ au_zone_setup();
+
+ /* inital thread structure */
+ tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
+
+ /* initial process structure */
+ pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
+ bzero(&pad0->pad_data, sizeof (pad0->pad_data));
+
+ curthread->t_audit_data = tad0;
+ curproc->p_audit_data = pad0;
+
+ /*
+ * The kernel allocates a bunch of threads make sure they have
+ * a valid tad
+ */
+
+ mutex_enter(&pidlock);
+
+ au_thread = curthread;
+ do {
+ if (T2A(au_thread) == NULL) {
+ T2A(au_thread) = tad0;
+ }
+ au_thread = au_thread->t_next;
+ } while (au_thread != curthread);
+
+ tad0->tad_ad = NULL;
+ mutex_exit(&pidlock);
+
+ /*
+ * Initialize audit context in our cred (kcred).
+ * No copy-on-write needed here because it's so early in init.
+ */
+
+ ainfo = crgetauinfo_modifiable(kcred);
+ ASSERT(ainfo != NULL);
+ bzero(ainfo, sizeof (auditinfo_addr_t));
+ ainfo->ai_auid = AU_NOAUDITID;
+
+ /* fabricate an empty audit_path to extend */
+ apempty.audp_cnt = 0;
+ apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]);
+ pad0->pad_root = au_pathdup(&apempty, 1, 2);
+ bcopy("/", pad0->pad_root->audp_sect[0], 2);
+ au_pathhold(pad0->pad_root);
+ pad0->pad_cwd = pad0->pad_root;
+}
+
+/*
+ * Check for any pending changes to the audit context for the given proc.
+ * p_crlock and pad_lock for the process are acquired here. Caller is
+ * responsible for assuring the process doesn't go away. If context is
+ * updated, the specified cralloc'ed cred will be used, otherwise it's freed.
+ * If no cred is given, it will be cralloc'ed here and caller assures that
+ * it is safe to allocate memory.
+ */
+
+void
+audit_update_context(proc_t *p, cred_t *ncr)
+{
+ struct p_audit_data *pad;
+ cred_t *newcred = ncr;
+
+ pad = P2A(p);
+ if (pad == NULL) {
+ if (newcred != NULL)
+ crfree(newcred);
+ return;
+ }
+
+ /* If a mask update is pending, take care of it. */
+ if (pad->pad_flags & PAD_SETMASK) {
+ auditinfo_addr_t *ainfo;
+
+ if (newcred == NULL)
+ newcred = cralloc();
+
+ mutex_enter(&pad->pad_lock);
+ /* the condition may have been handled by the time we lock */
+ if (pad->pad_flags & PAD_SETMASK) {
+ ainfo = crgetauinfo_modifiable(newcred);
+ if (ainfo == NULL) {
+ mutex_enter(&pad->pad_lock);
+ crfree(newcred);
+ return;
+ }
+
+ mutex_enter(&p->p_crlock);
+ crcopy_to(p->p_cred, newcred);
+ p->p_cred = newcred;
+
+ ainfo->ai_mask = pad->pad_newmask;
+
+ /* Unlock and cleanup. */
+ mutex_exit(&p->p_crlock);
+ pad->pad_flags &= ~PAD_SETMASK;
+
+ /*
+ * For curproc, assure that our thread points to right
+ * cred, so CRED() will be correct. Otherwise, no need
+ * to broadcast changes (via set_proc_pre_sys), since
+ * t_pre_sys is ALWAYS on when audit is enabled... due
+ * to syscall auditing.
+ */
+ if (p == curproc)
+ crset(p, newcred);
+ else
+ crfree(newcred);
+ } else {
+ crfree(newcred);
+ }
+ mutex_exit(&pad->pad_lock);
+ } else {
+ if (newcred != NULL)
+ crfree(newcred);
+ }
+}
+
+/*
+ * ROUTINE: AUDIT_NEWPROC
+ * PURPOSE: initialize the child p_audit_data structure
+ * CALLBY: GETPROC
+ * NOTE: All threads for the parent process are locked at this point.
+ * We are essentially running singled threaded for this reason.
+ * GETPROC is called when system creates a new process.
+ * By the time AUDIT_NEWPROC is called, the child proc
+ * structure has already been initialized. What we need
+ * to do is to allocate the child p_audit_data and
+ * initialize it with the content of current parent process.
+ */
+
+void
+audit_newproc(struct proc *cp) /* initialized child proc structure */
+{
+ p_audit_data_t *pad; /* child process audit data */
+ p_audit_data_t *opad; /* parent process audit data */
+
+ pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
+
+ P2A(cp) = pad;
+
+ opad = P2A(curproc);
+
+ /*
+ * copy the audit data. Note that all threads of current
+ * process have been "held". Thus there is no race condition
+ * here with mutiple threads trying to alter the cwrd
+ * structure (such as releasing it).
+ *
+ * The audit context in the cred is "duplicated" for the new
+ * proc by elsewhere crhold'ing the parent's cred which it shares.
+ *
+ * We still want to hold things since auditon() [A_SETUMASK,
+ * A_SETSMASK] could be walking through the processes to
+ * update things.
+ */
+ mutex_enter(&opad->pad_lock); /* lock opad structure during copy */
+ pad->pad_data = opad->pad_data; /* copy parent's process audit data */
+ au_pathhold(pad->pad_root);
+ au_pathhold(pad->pad_cwd);
+ mutex_exit(&opad->pad_lock); /* current proc will keep cwrd open */
+
+ /*
+ * If we are in the limited mode, there is nothing to audit and
+ * there could not have been anything to audit, since it is not
+ * possible to switch from the full mode into the limited mode
+ * once the full mode is set.
+ */
+ if (audit_active != C2AUDIT_LOADED)
+ return;
+
+ /*
+ * finish auditing of parent here so that it will be done
+ * before child has a chance to run. We include the child
+ * pid since the return value in the return token is a dummy
+ * one and contains no useful information (it is included to
+ * make the audit record structure consistant).
+ *
+ * tad_flag is set if auditing is on
+ */
+ if (((t_audit_data_t *)T2A(curthread))->tad_flag)
+ au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
+
+ /*
+ * finish up audit record generation here because child process
+ * is set to run before parent process. We distinguish here
+ * between FORK, FORK1, or VFORK by the saved system call ID.
+ */
+ audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
+}
+
+/*
+ * ROUTINE: AUDIT_PFREE
+ * PURPOSE: deallocate the per-process udit data structure
+ * CALLBY: EXIT
+ * FORK_FAIL
+ * NOTE: all lwp except current one have stopped in SEXITLWPS
+ * why we are single threaded?
+ * . all lwp except current one have stopped in SEXITLWPS.
+ */
+
+void
+audit_pfree(struct proc *p) /* proc structure to be freed */
+
+{ /* AUDIT_PFREE */
+
+ p_audit_data_t *pad;
+
+ pad = P2A(p);
+
+ /* better be a per process audit data structure */
+ ASSERT(pad != (p_audit_data_t *)0);
+
+ if (pad == pad0) {
+ return;
+ }
+
+ /* deallocate all auditing resources for this process */
+ au_pathrele(pad->pad_root);
+ au_pathrele(pad->pad_cwd);
+
+ /*
+ * Since the pad structure is completely overwritten after alloc,
+ * we don't bother to clear it.
+ */
+
+ kmem_cache_free(au_pad_cache, pad);
+}
+
+/*
+ * ROUTINE: AUDIT_THREAD_CREATE
+ * PURPOSE: allocate per-process thread audit data structure
+ * CALLBY: THREAD_CREATE
+ * NOTE: This is called just after *t was bzero'd.
+ * We are single threaded in this routine.
+ * TODO:
+ * QUESTION:
+ */
+
+void
+audit_thread_create(kthread_id_t t)
+{
+ t_audit_data_t *tad; /* per-thread audit data */
+
+ tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
+
+ T2A(t) = tad; /* set up thread audit data ptr */
+ tad->tad_thread = t; /* back ptr to thread: DEBUG */
+}
+
+/*
+ * ROUTINE: AUDIT_THREAD_FREE
+ * PURPOSE: free the per-thread audit data structure
+ * CALLBY: THREAD_FREE
+ * NOTE: most thread data is clear after return
+ */
+
+void
+audit_thread_free(kthread_t *t)
+{
+ t_audit_data_t *tad;
+ au_defer_info_t *attr;
+
+ tad = T2A(t);
+
+ /* thread audit data must still be set */
+
+ if (tad == tad0) {
+ return;
+ }
+
+ if (tad == NULL) {
+ return;
+ }
+
+ t->t_audit_data = 0;
+
+ /* must not have any audit record residual */
+ ASSERT(tad->tad_ad == NULL);
+
+ /* saved path must be empty */
+ ASSERT(tad->tad_aupath == NULL);
+
+ if (tad->tad_atpath)
+ au_pathrele(tad->tad_atpath);
+
+ if (audit_active == C2AUDIT_LOADED) {
+ attr = tad->tad_defer_head;
+ while (attr != NULL) {
+ au_defer_info_t *tmp_attr = attr;
+
+ au_free_rec(attr->audi_ad);
+
+ attr = attr->audi_next;
+ kmem_free(tmp_attr, sizeof (au_defer_info_t));
+ }
+ }
+
+ kmem_free(tad, sizeof (*tad));
+}
+
+/*
+ * ROUTINE: AUDIT_FALLOC
+ * PURPOSE: allocating a new file structure
+ * CALLBY: FALLOC
+ * NOTE: file structure already initialized
+ * TODO:
+ * QUESTION:
+ */
+
+void
+audit_falloc(struct file *fp)
+{ /* AUDIT_FALLOC */
+
+ f_audit_data_t *fad;
+
+ /* allocate per file audit structure if there a'int any */
+ ASSERT(F2A(fp) == NULL);
+
+ fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
+
+ F2A(fp) = fad;
+
+ fad->fad_thread = curthread; /* file audit data back ptr; DEBUG */
+}
+
+/*
+ * ROUTINE: AUDIT_UNFALLOC
+ * PURPOSE: deallocate file audit data structure
+ * CALLBY: CLOSEF
+ * UNFALLOC
+ * NOTE:
+ * TODO:
+ * QUESTION:
+ */
+
+void
+audit_unfalloc(struct file *fp)
+{
+ f_audit_data_t *fad;
+
+ fad = F2A(fp);
+
+ if (!fad) {
+ return;
+ }
+ if (fad->fad_aupath != NULL) {
+ au_pathrele(fad->fad_aupath);
+ }
+ fp->f_audit_data = 0;
+ kmem_free(fad, sizeof (struct f_audit_data));
+}
+
+uint32_t
+audit_getstate()
+{
+ return (audit_active == C2AUDIT_LOADED &&
+ ((AU_AUDIT_MASK) & U2A(u)->tad_audit));
+}
diff --git a/usr/src/uts/common/os/audit_memory.c b/usr/src/uts/common/os/audit_memory.c
new file mode 100644
index 0000000000..a3b61e13e2
--- /dev/null
+++ b/usr/src/uts/common/os/audit_memory.c
@@ -0,0 +1,123 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kmem.h>
+#include <c2/audit.h>
+#include <c2/audit_kernel.h>
+
+
+/* process audit data (pad) cache */
+kmem_cache_t *au_pad_cache;
+
+/*
+ * increment audit path reference count
+ */
+void
+au_pathhold(struct audit_path *app)
+{
+ atomic_add_32(&app->audp_ref, 1);
+}
+
+/*
+ * decrement audit path reference count
+ */
+void
+au_pathrele(struct audit_path *app)
+{
+ if (atomic_add_32_nv(&app->audp_ref, -1) > 0)
+ return;
+ kmem_free(app, app->audp_size);
+}
+
+/*
+ * allocate a new auditpath
+ * newsect = increment sections count,
+ * charincr = change in strings storage
+ */
+
+struct audit_path *
+au_pathdup(const struct audit_path *oldapp, int newsect, int charincr)
+{
+ struct audit_path *newapp;
+ int i, alloc_size, oldlen;
+ char *oldcp, *newcp;
+
+ newsect = (newsect != 0);
+ oldcp = oldapp->audp_sect[0];
+ oldlen = (oldapp->audp_sect[oldapp->audp_cnt] - oldcp);
+ alloc_size = sizeof (struct audit_path) +
+ (oldapp->audp_cnt + newsect) * sizeof (char *) +
+ oldlen + charincr;
+
+ newapp = kmem_alloc(alloc_size, KM_SLEEP);
+ newapp->audp_ref = 1;
+ newapp->audp_size = alloc_size;
+
+ newapp->audp_cnt = oldapp->audp_cnt + newsect;
+ newcp = (char *)(&newapp->audp_sect[newapp->audp_cnt + 1]);
+ for (i = 0; i <= oldapp->audp_cnt; i++) {
+ newapp->audp_sect[i] = newcp +
+ (oldapp->audp_sect[i] - oldcp);
+ }
+ /*
+ * if this is a new section, set its end
+ * if this is an extended section, reset its end
+ */
+ newapp->audp_sect[newapp->audp_cnt] = newcp + oldlen + charincr;
+ /* copy all of the old strings */
+ bcopy(oldcp, newcp, oldlen);
+
+ return (newapp);
+}
+
+/*ARGSUSED1*/
+static int
+au_pad_const(void *vpad, void *priv, int flags)
+{
+ p_audit_data_t *pad = vpad;
+
+ mutex_init(&pad->pad_lock, NULL, MUTEX_DEFAULT, NULL);
+
+ return (0);
+}
+
+/*ARGSUSED1*/
+static void
+au_pad_destr(void *vpad, void *priv)
+{
+ p_audit_data_t *pad = vpad;
+
+ mutex_destroy(&pad->pad_lock);
+}
+
+void
+au_pad_init()
+{
+ au_pad_cache = kmem_cache_create("audit_proc",
+ sizeof (p_audit_data_t), 0, au_pad_const, au_pad_destr,
+ NULL, NULL, NULL, 0);
+}
diff --git a/usr/src/uts/common/c2/audit_zone.c b/usr/src/uts/common/os/audit_zone.c
index dedc943f23..a42f4e6ee2 100644
--- a/usr/src/uts/common/c2/audit_zone.c
+++ b/usr/src/uts/common/os/audit_zone.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -99,9 +99,8 @@ au_zone_shutdown(zoneid_t zone, void *arg)
{
au_kcontext_t *kctx = arg;
- if ((kctx->auk_zid == GLOBAL_ZONEID ||
- (audit_policy | AUDIT_PERZONE)) &&
- (kctx->auk_current_vp != NULL))
+ if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID ||
+ (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL))
(void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL);
kctx->auk_valid = AUK_INVALID;
@@ -154,3 +153,14 @@ au_zone_setup()
au_zone_destroy);
}
+
+int
+au_zone_getstate(const au_kcontext_t *context)
+{
+ au_kcontext_t *tcontext;
+
+ if (context != NULL)
+ return (context->auk_auditstate);
+ tcontext = GET_KCTX_PZ;
+ return (tcontext->auk_auditstate);
+}
diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c
index 7a208b331e..01dc69774d 100644
--- a/usr/src/uts/common/os/cred.c
+++ b/usr/src/uts/common/os/cred.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,6 +62,7 @@
#include <sys/idmap.h>
#include <sys/klpd.h>
#include <sys/varargs.h>
+#include <sys/sysconf.h>
#include <util/qsort.h>
@@ -1063,14 +1064,14 @@ get_c2audit_load(void)
{
static int gotit = 0;
static int c2audit_load;
- u_longlong_t audit_load_val;
if (gotit)
return (c2audit_load);
- audit_load_val = 0; /* set default value once */
- (void) mod_sysvar("c2audit", "audit_load", &audit_load_val);
- c2audit_load = (int)audit_load_val;
+ c2audit_load = 1; /* set default value once */
+ if (mod_sysctl(SYS_CHECK_EXCLUDE, "c2audit") != 0)
+ c2audit_load = 0;
gotit++;
+
return (c2audit_load);
}
diff --git a/usr/src/uts/common/os/devpolicy.c b/usr/src/uts/common/os/devpolicy.c
index beb573a357..441b1d7c17 100644
--- a/usr/src/uts/common/os/devpolicy.c
+++ b/usr/src/uts/common/os/devpolicy.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Device policy implementation.
*
@@ -483,7 +481,7 @@ devpolicy_load(int nitems, size_t sz, devplcysys_t *uitmp)
lastwild = wild;
}
- if (audit_active)
+ if (AU_AUDITING())
audit_devpolicy(nitems, items);
/*
diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c
index fc299421fa..f6d31f8e8b 100644
--- a/usr/src/uts/common/os/exec.c
+++ b/usr/src/uts/common/os/exec.c
@@ -1829,7 +1829,7 @@ exec_args(execa_t *uap, uarg_t *args, intpdata_t *intp, void **auxvpp)
*/
delete_itimer_realprof();
- if (audit_active)
+ if (AU_AUDITING())
audit_exec(args->stk_base, args->stk_base + args->arglen,
args->na - args->ne, args->ne);
diff --git a/usr/src/uts/common/os/exit.c b/usr/src/uts/common/os/exit.c
index d2f5fd5767..f86c422fd8 100644
--- a/usr/src/uts/common/os/exit.c
+++ b/usr/src/uts/common/os/exit.c
@@ -561,7 +561,7 @@ proc_exit(int why, int what)
/*
* Release any resources associated with C2 auditing
*/
- if (audit_active) {
+ if (AU_AUDITING()) {
/*
* audit exit system call
*/
diff --git a/usr/src/uts/common/os/fio.c b/usr/src/uts/common/os/fio.c
index c3641dd331..57bdc54c85 100644
--- a/usr/src/uts/common/os/fio.c
+++ b/usr/src/uts/common/os/fio.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -610,7 +610,7 @@ getf(int fd)
/*
* archive per file audit data
*/
- if (audit_active)
+ if (AU_AUDITING())
(void) audit_getf(fd);
set_active_fd(fd); /* record the active file descriptor */
@@ -688,7 +688,7 @@ closeandsetf(int fd, file_t *newfp)
/*
* archive per file audit data
*/
- if (audit_active)
+ if (AU_AUDITING())
(void) audit_getf(fd);
ASSERT(ufp->uf_busy);
ufp->uf_file = NULL;
@@ -942,7 +942,7 @@ closef(file_t *fp)
/*
* audit close of file (may be exit)
*/
- if (audit_active)
+ if (AU_AUDITING())
audit_closef(fp);
ASSERT(MUTEX_NOT_HELD(&P_FINFO(curproc)->fi_lock));
@@ -1167,7 +1167,7 @@ setf(int fd, file_t *fp)
uf_info_t *fip = P_FINFO(curproc);
uf_entry_t *ufp;
- if (audit_active)
+ if (AU_AUDITING())
audit_setf(fp, fd);
if (fp == NULL) {
diff --git a/usr/src/uts/common/os/ipc.c b/usr/src/uts/common/os/ipc.c
index 06324b140a..8f47821566 100644
--- a/usr/src/uts/common/os/ipc.c
+++ b/usr/src/uts/common/os/ipc.c
@@ -19,16 +19,14 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Common Inter-Process Communication routines.
*
@@ -538,7 +536,7 @@ ipcperm_set(ipc_service_t *service, struct cred *cr,
kperm->ipc_gid = gid;
kperm->ipc_mode = (mode & 0777) | (kperm->ipc_mode & ~0777);
- if (audit_active)
+ if (AU_AUDITING())
audit_ipcget(service->ipcs_atype, kperm);
return (0);
@@ -580,7 +578,7 @@ ipcperm_set64(ipc_service_t *service, struct cred *cr,
kperm->ipc_mode = (perm64->ipcx_mode & 0777) |
(kperm->ipc_mode & ~0777);
- if (audit_active)
+ if (AU_AUDITING())
audit_ipcget(service->ipcs_atype, kperm);
return (0);
@@ -806,7 +804,7 @@ ipc_lookup(ipc_service_t *service, int id, kipc_perm_t **perm)
ASSERT(IPC_SEQ(id) == service->ipcs_table[index].ipct_seq);
*perm = result;
- if (audit_active)
+ if (AU_AUDITING())
audit_ipc(service->ipcs_atype, id, result);
return (&service->ipcs_table[index].ipct_lock);
@@ -928,7 +926,7 @@ ipc_keylookup(ipc_service_t *service, key_t key, int flag, kipc_perm_t **permp)
if ((flag & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
return (EEXIST);
if ((flag & 0777) & ~perm->ipc_mode) {
- if (audit_active)
+ if (AU_AUDITING())
audit_ipcget(NULL, (void *)perm);
return (EACCES);
}
diff --git a/usr/src/uts/common/os/main.c b/usr/src/uts/common/os/main.c
index 5845c9efd3..0e11b8b30f 100644
--- a/usr/src/uts/common/os/main.c
+++ b/usr/src/uts/common/os/main.c
@@ -87,12 +87,20 @@ proc_t *proc_fsflush; /* fsflush daemon */
pgcnt_t maxmem; /* Maximum available memory in pages. */
pgcnt_t freemem; /* Current available memory in pages. */
-int audit_active;
int interrupts_unleashed; /* set when we do the first spl0() */
kmem_cache_t *process_cache; /* kmem cache for proc structures */
/*
+ * Indicates whether the auditing module (c2audit) is loaded. Possible
+ * values are:
+ * 0 - c2audit module is excluded in /etc/system and cannot be loaded
+ * 1 - c2audit module is not loaded but can be anytime
+ * 2 - c2audit module is loaded
+ */
+int audit_active = C2AUDIT_DISABLED;
+
+/*
* Process 0's lwp directory and lwpid hash table.
*/
lwpdir_t p0_lwpdir[2];
diff --git a/usr/src/uts/common/os/msg.c b/usr/src/uts/common/os/msg.c
index 4d547c9df6..5b763e187b 100644
--- a/usr/src/uts/common/os/msg.c
+++ b/usr/src/uts/common/os/msg.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -653,8 +653,10 @@ top:
pp->p_rctls, pp);
lock = ipc_commit_end(msq_svc, &qp->msg_perm);
}
- if (audit_active)
+
+ if (AU_AUDITING())
audit_ipcget(AT_IPC_MSG, (void *)qp);
+
id = qp->msg_perm.ipc_id;
mutex_exit(lock);
return (id);
diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c
index aaddff4756..d6444e7fc3 100644
--- a/usr/src/uts/common/os/policy.c
+++ b/usr/src/uts/common/os/policy.c
@@ -356,7 +356,7 @@ static void
priv_policy_err(const cred_t *cr, int priv, boolean_t allzone, const char *msg)
{
- if (audit_active)
+ if (AU_AUDITING())
audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 0);
DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
@@ -387,7 +387,7 @@ priv_policy_ap(const cred_t *cr, int priv, boolean_t allzone, int err,
!PRIV_ISASSERT(priv_basic, priv)) &&
!servicing_interrupt()) {
PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */
- if (audit_active)
+ if (AU_AUDITING())
audit_priv(priv,
allzone ? ZONEPRIVS(cr) : NULL, 1);
}
@@ -431,7 +431,7 @@ priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone)
(!allzone || HAS_ALLZONEPRIVS(cr));
/* Audit success only */
- if (res && audit_active &&
+ if (res && AU_AUDITING() &&
(allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) &&
!servicing_interrupt()) {
audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1);
@@ -488,7 +488,7 @@ secpolicy_require_set(const cred_t *cr, const priv_set_t *req, const char *msg)
priv_inverse(&pset); /* all non present privileges */
priv_intersect(req, &pset); /* the actual missing privs */
- if (audit_active)
+ if (AU_AUDITING())
audit_priv(PRIV_NONE, &pset, 0);
/*
* Privilege debugging; special case "one privilege in set".
diff --git a/usr/src/uts/common/os/shm.c b/usr/src/uts/common/os/shm.c
index 869bbd5a38..bf18627c34 100644
--- a/usr/src/uts/common/os/shm.c
+++ b/usr/src/uts/common/os/shm.c
@@ -935,7 +935,7 @@ top:
lock = ipc_commit_end(shm_svc, &sp->shm_perm);
}
- if (audit_active)
+ if (AU_AUDITING())
audit_ipcget(AT_IPC_SHM, (void *)sp);
*rvp = (uintptr_t)(sp->shm_perm.ipc_id);
diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c
index 0988b6a486..f22f10063e 100644
--- a/usr/src/uts/common/os/sig.c
+++ b/usr/src/uts/common/os/sig.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1267,6 +1267,7 @@ psig(void)
id_t ctid = 0;
zoneid_t zoneid = -1;
sigqueue_t *sqp = NULL;
+ uint32_t auditing = AU_AUDITING();
mutex_enter(&p->p_lock);
schedctl_finish_sigblock(t);
@@ -1447,11 +1448,11 @@ psig(void)
sig = SIGKILL;
ext = (p->p_flag & SEXTKILLED) != 0;
} else {
- if (audit_active) /* audit core dump */
+ if (auditing) /* audit core dump */
audit_core_start(sig);
if (core(sig, ext) == 0)
code = CLD_DUMPED;
- if (audit_active) /* audit core dump */
+ if (auditing) /* audit core dump */
audit_core_finish(code);
}
}
@@ -2649,11 +2650,11 @@ realsigprof_fast(int sysnum, int nsysarg, int error)
mutex_enter(&p->p_lock);
lwp_exit();
}
- if (audit_active)
+ if (audit_active == C2AUDIT_LOADED)
audit_core_start(SIGSEGV);
if (core(SIGSEGV, 0) == 0)
code = CLD_DUMPED;
- if (audit_active)
+ if (audit_active == C2AUDIT_LOADED)
audit_core_finish(code);
exit(code, SIGSEGV);
}
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index 0cf8d66056..2ac660e419 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -23,7 +23,7 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,6 +77,7 @@
#include <sys/policy.h>
#include <sys/dld.h>
#include <sys/zone.h>
+#include <c2/audit.h>
/*
* This define helps improve the readability of streams code while
@@ -250,7 +251,7 @@ stropen(vnode_t *vp, dev_t *devp, int flag, cred_t *crp)
zoneid_t zoneid;
uint_t anchor;
- if (audit_active)
+ if (AU_AUDITING())
audit_stropen(vp, devp, flag, crp);
/*
@@ -619,7 +620,7 @@ strclose(struct vnode *vp, int flag, cred_t *crp)
int freestp = 1;
queue_t *rmq;
- if (audit_active)
+ if (AU_AUDITING())
audit_strclose(vp, flag, crp);
TRACE_1(TR_FAC_STREAMS_FR,
@@ -3210,6 +3211,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
queue_t *wrq;
queue_t *rdq;
boolean_t kioctl = B_FALSE;
+ uint32_t auditing = AU_AUDITING();
if (flag & FKIOCTL) {
copyflag = K_TO_K;
@@ -3222,7 +3224,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
TRACE_3(TR_FAC_STREAMS_FR, TR_IOCTL_ENTER,
"strioctl:stp %p cmd %X arg %lX", stp, cmd, arg);
- if (audit_active)
+ if (auditing)
audit_strioctl(vp, cmd, arg, flag, copyflag, crp, rvalp);
/*
@@ -5296,7 +5298,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
if ((fp = getf((int)arg)) == NULL)
return (EBADF);
error = do_sendfp(stp, fp, crp);
- if (audit_active) {
+ if (auditing) {
audit_fdsend((int)arg, fp, error);
}
releasef((int)arg);
@@ -5385,7 +5387,7 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
mutex_exit(&stp->sd_lock);
return (error);
}
- if (audit_active) {
+ if (auditing) {
audit_fdrecv(fd, srf->fp);
}
@@ -7756,7 +7758,7 @@ strputmsg(
xpg4 = (flag & MSG_XPG4) ? 1 : 0;
flag &= ~MSG_XPG4;
- if (audit_active)
+ if (AU_AUDITING())
audit_strputmsg(vp, mctl, mdata, pri, flag, fmode);
mutex_enter(&stp->sd_lock);
@@ -7945,7 +7947,7 @@ kstrputmsg(
ASSERT(vp->v_stream);
stp = vp->v_stream;
wqp = stp->sd_wrq;
- if (audit_active)
+ if (AU_AUDITING())
audit_strputmsg(vp, NULL, NULL, pri, flag, fmode);
if (mctl == NULL)
return (EINVAL);
diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c
index 07c8fe03f6..44dd747a0b 100644
--- a/usr/src/uts/common/os/sysent.c
+++ b/usr/src/uts/common/os/sysent.c
@@ -637,7 +637,7 @@ struct sysent sysent[NSYSCALL] =
/* 183 */ SYSENT_CI("pollsys", pollsys, 4),
/* 184 */ SYSENT_CI("labelsys", labelsys, 5),
/* 185 */ SYSENT_CI("acl", acl, 4),
- /* 186 */ SYSENT_AP("auditsys", auditsys, 2),
+ /* 186 */ SYSENT_AP("auditsys", auditsys, 6),
/* 187 */ SYSENT_CI("processor_bind", processor_bind, 4),
/* 188 */ SYSENT_CI("processor_info", processor_info, 2),
/* 189 */ SYSENT_CI("p_online", p_online, 2),
@@ -993,7 +993,7 @@ struct sysent sysent32[NSYSCALL] =
/* 183 */ SYSENT_CI("pollsys", pollsys, 4),
/* 184 */ SYSENT_CI("labelsys", labelsys, 5),
/* 185 */ SYSENT_CI("acl", acl, 4),
- /* 186 */ SYSENT_AP("auditsys", auditsys, 2),
+ /* 186 */ SYSENT_AP("auditsys", auditsys, 6),
/* 187 */ SYSENT_CI("processor_bind", processor_bind, 4),
/* 188 */ SYSENT_CI("processor_info", processor_info, 2),
/* 189 */ SYSENT_CI("p_online", p_online, 2),
diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c
index ed1286bf97..4f08e77f59 100644
--- a/usr/src/uts/common/os/zone.c
+++ b/usr/src/uts/common/os/zone.c
@@ -3072,7 +3072,8 @@ zone_chdir(vnode_t *vp, vnode_t **vpp, proc_t *pp)
/* we're going to hold a reference here to the directory */
VN_HOLD(vp);
- if (audit_active) /* update abs cwd/root path see c2audit.c */
+ /* update abs cwd/root path see c2/audit.c */
+ if (AU_AUDITING())
audit_chdirec(vp, vpp);
mutex_enter(&pp->p_lock);
diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h
index 6ecd15093a..b419f8235f 100644
--- a/usr/src/uts/common/sys/proc.h
+++ b/usr/src/uts/common/sys/proc.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -671,6 +671,7 @@ extern void set_proc_post_sys(proc_t *p);
extern void set_proc_sys(proc_t *p);
extern void set_proc_ast(proc_t *p);
extern void set_all_proc_sys(void);
+extern void set_all_zone_usr_proc_sys(zoneid_t);
/* thread function prototypes */
diff --git a/usr/src/uts/common/sys/systm.h b/usr/src/uts/common/sys/systm.h
index ca477d3746..e5ee80c404 100644
--- a/usr/src/uts/common/sys/systm.h
+++ b/usr/src/uts/common/sys/systm.h
@@ -98,7 +98,7 @@ extern int klustsize;
extern int abort_enable; /* Platform input-device abort policy */
-extern int audit_active; /* Solaris Auditing active 1, absent 0. */
+extern int audit_active; /* Solaris Auditing module state */
extern int avenrun[]; /* array of load averages */
diff --git a/usr/src/uts/common/syscall/access.c b/usr/src/uts/common/syscall/access.c
index bf71b77b8c..16b7ff7534 100644
--- a/usr/src/uts/common/syscall/access.c
+++ b/usr/src/uts/common/syscall/access.c
@@ -152,7 +152,7 @@ faccessat(int fd, char *fname, int fmode, int flag)
}
}
- if (audit_active)
+ if (AU_AUDITING())
audit_setfsat_path(1);
/* Do not allow E_OK unless AT_EACCESS flag is set */
diff --git a/usr/src/uts/common/syscall/auditsys.c b/usr/src/uts/common/syscall/auditsys.c
index a940bd7d18..538709e2d2 100644
--- a/usr/src/uts/common/syscall/auditsys.c
+++ b/usr/src/uts/common/syscall/auditsys.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,35 +28,63 @@
#include <sys/policy.h>
#include <c2/audit.h>
+#include <c2/audit_kernel.h>
+#include <c2/audit_record.h>
+
+#define CLEAR_VAL -1
+
+extern kmutex_t pidlock;
+
+int audit_policy; /* global audit policies in force */
+
/*ARGSUSED1*/
int
auditsys(struct auditcalls *uap, rval_t *rvp)
{
int err;
+ int result = 0;
- /*
- * this ugly hack is because auditsys returns
- * 0 for all cases except audit_active == 0
- * and uap->code == BSM_AUDITCTL || default)
- */
-
- if (!audit_active)
+ if (audit_active == C2AUDIT_DISABLED)
return (ENOTSUP);
switch (uap->code) {
case BSM_GETAUID:
+ result = getauid((caddr_t)uap->a1);
+ break;
case BSM_SETAUID:
+ result = setauid((caddr_t)uap->a1);
+ break;
case BSM_GETAUDIT:
+ result = getaudit((caddr_t)uap->a1);
+ break;
+ case BSM_GETAUDIT_ADDR:
+ result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
+ break;
case BSM_SETAUDIT:
- case BSM_AUDIT:
- return (0);
+ result = setaudit((caddr_t)uap->a1);
+ break;
+ case BSM_SETAUDIT_ADDR:
+ result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
+ break;
case BSM_AUDITCTL:
- if ((int)uap->a1 == A_GETCOND)
- err = secpolicy_audit_getattr(CRED());
- else
- /* FALLTHROUGH */
+ result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
+ break;
+ case BSM_AUDIT:
+ if (audit_active == C2AUDIT_UNLOADED)
+ return (0);
+ result = audit((caddr_t)uap->a1, (int)uap->a2);
+ break;
+ case BSM_AUDITDOOR:
+ if (audit_active == C2AUDIT_LOADED) {
+ result = auditdoor((int)uap->a1);
+ break;
+ }
default:
+ if (audit_active == C2AUDIT_LOADED) {
+ result = EINVAL;
+ break;
+ }
/* Return a different error when not privileged */
err = secpolicy_audit_config(CRED());
if (err == 0)
@@ -64,4 +92,1334 @@ auditsys(struct auditcalls *uap, rval_t *rvp)
else
return (err);
}
+ rvp->r_vals = result;
+ return (result);
+}
+
+/*
+ * Return the audit user ID for the current process. Currently only
+ * the privileged processes may see the audit id. That may change.
+ * If copyout is unsucessful return EFAULT.
+ */
+int
+getauid(caddr_t auid_p)
+{
+ const auditinfo_addr_t *ainfo;
+
+ if (secpolicy_audit_getattr(CRED()) != 0)
+ return (EPERM);
+
+ ainfo = crgetauinfo(CRED());
+ if (ainfo == NULL)
+ return (EINVAL);
+
+ if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * Set the audit userid, for a process. This can only be changed by
+ * privileged processes. The audit userid is inherited across forks & execs.
+ * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
+ */
+int
+setauid(caddr_t auid_p)
+{
+ proc_t *p;
+ au_id_t auid;
+ cred_t *newcred;
+ auditinfo_addr_t *auinfo;
+
+ if (secpolicy_audit_config(CRED()) != 0)
+ return (EPERM);
+
+ if (copyin(auid_p, &auid, sizeof (au_id_t))) {
+ return (EFAULT);
+ }
+
+ newcred = cralloc();
+ if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
+ crfree(newcred);
+ return (EINVAL);
+ }
+
+ /* grab p_crlock and switch to new cred */
+ p = curproc;
+ mutex_enter(&p->p_crlock);
+ crcopy_to(p->p_cred, newcred);
+ p->p_cred = newcred;
+
+ auinfo->ai_auid = auid; /* update the auid */
+
+ /* unlock and broadcast the cred changes */
+ mutex_exit(&p->p_crlock);
+ crset(p, newcred);
+
+ return (0);
+}
+
+/*
+ * Get the audit state information from the current process.
+ * Return EFAULT if copyout fails.
+ */
+int
+getaudit(caddr_t info_p)
+{
+ STRUCT_DECL(auditinfo, info);
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+
+ if (secpolicy_audit_getattr(CRED()) != 0)
+ return (EPERM);
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ ainfo = crgetauinfo(CRED());
+ if (ainfo == NULL)
+ return (EINVAL);
+
+ /* trying to read a process with an IPv6 address? */
+ if (ainfo->ai_termid.at_type == AU_IPv6)
+ return (EOVERFLOW);
+
+ STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
+ STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
+#ifdef _LP64
+ if (model == DATAMODEL_ILP32) {
+ dev32_t dev;
+ /* convert internal 64 bit form to 32 bit version */
+ if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
+ return (EOVERFLOW);
+ }
+ STRUCT_FSET(info, ai_termid.port, dev);
+ } else
+ STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
+#else
+ STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
+#endif
+ STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
+ STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
+
+ if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * Get the audit state information from the current process.
+ * Return EFAULT if copyout fails.
+ */
+int
+getaudit_addr(caddr_t info_p, int len)
+{
+ STRUCT_DECL(auditinfo_addr, info);
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+
+ if (secpolicy_audit_getattr(CRED()) != 0)
+ return (EPERM);
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ if (len < STRUCT_SIZE(info))
+ return (EOVERFLOW);
+
+ ainfo = crgetauinfo(CRED());
+
+ if (ainfo == NULL)
+ return (EINVAL);
+
+ STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
+ STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
+#ifdef _LP64
+ if (model == DATAMODEL_ILP32) {
+ dev32_t dev;
+ /* convert internal 64 bit form to 32 bit version */
+ if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
+ return (EOVERFLOW);
+ }
+ STRUCT_FSET(info, ai_termid.at_port, dev);
+ } else
+ STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
+#else
+ STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
+#endif
+ STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
+ STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
+ STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
+ STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
+ STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
+ STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
+
+ if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * Set the audit state information for the current process.
+ * Return EFAULT if copyout fails.
+ */
+int
+setaudit(caddr_t info_p)
+{
+ STRUCT_DECL(auditinfo, info);
+ proc_t *p;
+ cred_t *newcred;
+ model_t model;
+ auditinfo_addr_t *ainfo;
+
+ if (secpolicy_audit_config(CRED()) != 0)
+ return (EPERM);
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ newcred = cralloc();
+ if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
+ crfree(newcred);
+ return (EINVAL);
+ }
+
+ /* grab p_crlock and switch to new cred */
+ p = curproc;
+ mutex_enter(&p->p_crlock);
+ crcopy_to(p->p_cred, newcred);
+ p->p_cred = newcred;
+
+ /* Set audit mask, id, termid and session id as specified */
+ ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
+#ifdef _LP64
+ /* only convert to 64 bit if coming from a 32 bit binary */
+ if (model == DATAMODEL_ILP32)
+ ainfo->ai_termid.at_port =
+ DEVEXPL(STRUCT_FGET(info, ai_termid.port));
+ else
+ ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
+#else
+ ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
+#endif
+ ainfo->ai_termid.at_type = AU_IPv4;
+ ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
+ ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
+ ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
+
+ /* unlock and broadcast the cred changes */
+ mutex_exit(&p->p_crlock);
+ crset(p, newcred);
+
+ return (0);
+}
+
+/*
+ * Set the audit state information for the current process.
+ * Return EFAULT if copyin fails.
+ */
+int
+setaudit_addr(caddr_t info_p, int len)
+{
+ STRUCT_DECL(auditinfo_addr, info);
+ proc_t *p;
+ cred_t *newcred;
+ model_t model;
+ int i;
+ int type;
+ auditinfo_addr_t *ainfo;
+
+ if (secpolicy_audit_config(CRED()) != 0)
+ return (EPERM);
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ if (len < STRUCT_SIZE(info))
+ return (EOVERFLOW);
+
+ if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ type = STRUCT_FGET(info, ai_termid.at_type);
+ if ((type != AU_IPv4) && (type != AU_IPv6))
+ return (EINVAL);
+
+ newcred = cralloc();
+ if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
+ crfree(newcred);
+ return (EINVAL);
+ }
+
+ /* grab p_crlock and switch to new cred */
+ p = curproc;
+ mutex_enter(&p->p_crlock);
+ crcopy_to(p->p_cred, newcred);
+ p->p_cred = newcred;
+
+ /* Set audit mask, id, termid and session id as specified */
+ ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
+ ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
+#ifdef _LP64
+ /* only convert to 64 bit if coming from a 32 bit binary */
+ if (model == DATAMODEL_ILP32)
+ ainfo->ai_termid.at_port =
+ DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
+ else
+ ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
+#else
+ ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
+#endif
+ ainfo->ai_termid.at_type = type;
+ bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
+ for (i = 0; i < (type/sizeof (int)); i++)
+ ainfo->ai_termid.at_addr[i] =
+ STRUCT_FGET(info, ai_termid.at_addr[i]);
+
+ if (ainfo->ai_termid.at_type == AU_IPv6 &&
+ IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
+ ainfo->ai_termid.at_type = AU_IPv4;
+ ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
+ ainfo->ai_termid.at_addr[1] = 0;
+ ainfo->ai_termid.at_addr[2] = 0;
+ ainfo->ai_termid.at_addr[3] = 0;
+ }
+
+ ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
+
+ /* unlock and broadcast the cred changes */
+ mutex_exit(&p->p_crlock);
+ crset(p, newcred);
+
+ return (0);
+}
+
+/*
+ * Get the global policy flag
+ */
+static int
+getpolicy(caddr_t data)
+{
+ int policy;
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+
+ policy = audit_policy | kctx->auk_policy;
+
+ if (copyout(&policy, data, sizeof (int)))
+ return (EFAULT);
+ return (0);
+}
+
+/*
+ * Set the global and local policy flags
+ *
+ * The global flags only make sense from the global zone;
+ * the local flags depend on the AUDIT_PERZONE policy:
+ * if the perzone policy is set, then policy is set separately
+ * per zone, else held only in the global zone.
+ *
+ * The initial value of a local zone's policy flag is determined
+ * by the value of the global zone's flags at the time the
+ * local zone is created.
+ *
+ * While auditconfig(1M) allows setting and unsetting policies one bit
+ * at a time, the mask passed in from auditconfig() is created by a
+ * syscall to getpolicy and then modified based on the auditconfig()
+ * cmd line, so the input policy value is used to replace the existing
+ * policy.
+ */
+static int
+setpolicy(caddr_t data)
+{
+ int policy;
+ au_kcontext_t *kctx;
+
+ if (copyin(data, &policy, sizeof (int)))
+ return (EFAULT);
+
+ kctx = GET_KCTX_NGZ;
+
+ if (INGLOBALZONE(curproc)) {
+ if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
+ return (EINVAL);
+
+ audit_policy = policy & AUDIT_GLOBAL;
+ } else {
+ if (!(audit_policy & AUDIT_PERZONE))
+ return (EINVAL);
+
+ if (policy & ~AUDIT_LOCAL) /* global bits are a no-no */
+ return (EINVAL);
+ }
+ kctx->auk_policy = policy & AUDIT_LOCAL;
+
+ /*
+ * auk_current_vp is NULL before auditd starts (or during early
+ * auditd starup) or if auditd is halted; in either case,
+ * notification of a policy change is not needed, since auditd
+ * reads policy as it comes up. The error return from au_doormsg()
+ * is ignored to avoid a race condition -- for example if auditd
+ * segv's, the audit state may be "auditing" but the door may
+ * be closed. Returning an error if the door is open makes it
+ * impossible for Greenline to restart auditd.
+ */
+ if (kctx->auk_current_vp != NULL)
+ (void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
+
+ /*
+ * Wake up anyone who might have blocked on full audit
+ * partitions. audit daemons need to set AUDIT_FULL when no
+ * space so we can tell if we should start dropping records.
+ */
+ mutex_enter(&(kctx->auk_queue.lock));
+
+ if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
+ (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
+ cv_broadcast(&(kctx->auk_queue.write_cv));
+
+ mutex_exit(&(kctx->auk_queue.lock));
+
+ return (0);
+}
+
+static int
+getkmask(caddr_t data)
+{
+ au_kcontext_t *kctx;
+
+ kctx = GET_KCTX_PZ;
+
+ if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
+ return (EFAULT);
+ return (0);
+}
+
+static int
+setkmask(caddr_t data)
+{
+ au_mask_t mask;
+ au_kcontext_t *kctx;
+
+ if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+ return (EINVAL);
+
+ kctx = GET_KCTX_NGZ;
+
+ if (copyin(data, &mask, sizeof (au_mask_t)))
+ return (EFAULT);
+
+ kctx->auk_info.ai_mask = mask;
+ return (0);
+}
+
+static int
+getkaudit(caddr_t info_p, int len)
+{
+ STRUCT_DECL(auditinfo_addr, info);
+ model_t model;
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ if (len < STRUCT_SIZE(info))
+ return (EOVERFLOW);
+
+ STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
+ STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
+#ifdef _LP64
+ if (model == DATAMODEL_ILP32) {
+ dev32_t dev;
+ /* convert internal 64 bit form to 32 bit version */
+ if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
+ return (EOVERFLOW);
+ }
+ STRUCT_FSET(info, ai_termid.at_port, dev);
+ } else {
+ STRUCT_FSET(info, ai_termid.at_port,
+ kctx->auk_info.ai_termid.at_port);
+ }
+#else
+ STRUCT_FSET(info, ai_termid.at_port,
+ kctx->auk_info.ai_termid.at_port);
+#endif
+ STRUCT_FSET(info, ai_termid.at_type,
+ kctx->auk_info.ai_termid.at_type);
+ STRUCT_FSET(info, ai_termid.at_addr[0],
+ kctx->auk_info.ai_termid.at_addr[0]);
+ STRUCT_FSET(info, ai_termid.at_addr[1],
+ kctx->auk_info.ai_termid.at_addr[1]);
+ STRUCT_FSET(info, ai_termid.at_addr[2],
+ kctx->auk_info.ai_termid.at_addr[2]);
+ STRUCT_FSET(info, ai_termid.at_addr[3],
+ kctx->auk_info.ai_termid.at_addr[3]);
+ STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
+
+ if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * the host address for AUDIT_PERZONE == 0 is that of the global
+ * zone and for local zones it is of the current zone.
+ */
+static int
+setkaudit(caddr_t info_p, int len)
+{
+ STRUCT_DECL(auditinfo_addr, info);
+ model_t model;
+ au_kcontext_t *kctx;
+
+ if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+ return (EINVAL);
+
+ kctx = GET_KCTX_NGZ;
+
+ model = get_udatamodel();
+ STRUCT_INIT(info, model);
+
+ if (len < STRUCT_SIZE(info))
+ return (EOVERFLOW);
+
+ if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
+ return (EFAULT);
+
+ if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
+ (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
+ return (EINVAL);
+
+ /* Set audit mask, termid and session id as specified */
+ kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
+ kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
+#ifdef _LP64
+ /* only convert to 64 bit if coming from a 32 bit binary */
+ if (model == DATAMODEL_ILP32)
+ kctx->auk_info.ai_termid.at_port =
+ DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
+ else
+ kctx->auk_info.ai_termid.at_port =
+ STRUCT_FGET(info, ai_termid.at_port);
+#else
+ kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
+#endif
+ kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
+ bzero(&kctx->auk_info.ai_termid.at_addr[0],
+ sizeof (kctx->auk_info.ai_termid.at_addr));
+ kctx->auk_info.ai_termid.at_addr[0] =
+ STRUCT_FGET(info, ai_termid.at_addr[0]);
+ kctx->auk_info.ai_termid.at_addr[1] =
+ STRUCT_FGET(info, ai_termid.at_addr[1]);
+ kctx->auk_info.ai_termid.at_addr[2] =
+ STRUCT_FGET(info, ai_termid.at_addr[2]);
+ kctx->auk_info.ai_termid.at_addr[3] =
+ STRUCT_FGET(info, ai_termid.at_addr[3]);
+ kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
+
+ if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
+ IN6_IS_ADDR_V4MAPPED(
+ ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
+ kctx->auk_info.ai_termid.at_type = AU_IPv4;
+ kctx->auk_info.ai_termid.at_addr[0] =
+ kctx->auk_info.ai_termid.at_addr[3];
+ kctx->auk_info.ai_termid.at_addr[1] = 0;
+ kctx->auk_info.ai_termid.at_addr[2] = 0;
+ kctx->auk_info.ai_termid.at_addr[3] = 0;
+ }
+ if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
+ kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
+ (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
+ else
+ kctx->auk_hostaddr_valid =
+ (kctx->auk_info.ai_termid.at_addr[0] ==
+ htonl(INADDR_ANY)) ? 0 : 1;
+
+ return (0);
+}
+
+static int
+getqctrl(caddr_t data)
+{
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+ STRUCT_DECL(au_qctrl, qctrl);
+ STRUCT_INIT(qctrl, get_udatamodel());
+
+ mutex_enter(&(kctx->auk_queue.lock));
+ STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
+ STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
+ STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
+ STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
+ mutex_exit(&(kctx->auk_queue.lock));
+
+ if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
+ return (EFAULT);
+
+ return (0);
+}
+
+static int
+setqctrl(caddr_t data)
+{
+ au_kcontext_t *kctx;
+ struct au_qctrl qctrl_tmp;
+ STRUCT_DECL(au_qctrl, qctrl);
+ STRUCT_INIT(qctrl, get_udatamodel());
+
+ if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+ return (EINVAL);
+ kctx = GET_KCTX_NGZ;
+
+ if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
+ return (EFAULT);
+
+ qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
+ qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
+ qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
+ qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
+
+ /* enforce sane values */
+
+ if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_delay == 0)
+ return (EINVAL);
+
+ if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
+ return (EINVAL);
+
+ /* update everything at once so things are consistant */
+ mutex_enter(&(kctx->auk_queue.lock));
+ kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
+ kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
+ kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
+ kctx->auk_queue.delay = qctrl_tmp.aq_delay;
+
+ if (kctx->auk_queue.rd_block &&
+ kctx->auk_queue.cnt > kctx->auk_queue.lowater)
+ cv_broadcast(&(kctx->auk_queue.read_cv));
+
+ if (kctx->auk_queue.wt_block &&
+ kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
+ cv_broadcast(&(kctx->auk_queue.write_cv));
+
+ mutex_exit(&(kctx->auk_queue.lock));
+
+ return (0);
+}
+
+static int
+getcwd(caddr_t data, int length)
+{
+ struct p_audit_data *pad;
+ struct audit_path *app;
+ int pathlen;
+
+ pad = P2A(curproc);
+ ASSERT(pad != NULL);
+
+ mutex_enter(&(pad->pad_lock));
+ app = pad->pad_cwd;
+ au_pathhold(app);
+ mutex_exit(&(pad->pad_lock));
+
+ pathlen = app->audp_sect[1] - app->audp_sect[0];
+ if (pathlen > length) {
+ au_pathrele(app);
+ return (E2BIG);
+ }
+
+ if (copyout(app->audp_sect[0], data, pathlen)) {
+ au_pathrele(app);
+ return (EFAULT);
+ }
+
+ au_pathrele(app);
+ return (0);
+}
+
+static int
+getcar(caddr_t data, int length)
+{
+ struct p_audit_data *pad;
+ struct audit_path *app;
+ int pathlen;
+
+ pad = P2A(curproc);
+ ASSERT(pad != NULL);
+
+ mutex_enter(&(pad->pad_lock));
+ app = pad->pad_root;
+ au_pathhold(app);
+ mutex_exit(&(pad->pad_lock));
+
+ pathlen = app->audp_sect[1] - app->audp_sect[0];
+ if (pathlen > length) {
+ au_pathrele(app);
+ return (E2BIG);
+ }
+
+ if (copyout(app->audp_sect[0], data, pathlen)) {
+ au_pathrele(app);
+ return (EFAULT);
+ }
+
+ au_pathrele(app);
+ return (0);
+}
+
+static int
+getstat(caddr_t data)
+{
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+
+ membar_consumer();
+
+ if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
+ return (EFAULT);
+ return (0);
+}
+
+static int
+setstat(caddr_t data)
+{
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+ au_stat_t au_stat;
+
+ if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+ return (EINVAL);
+
+ if (copyin(data, &au_stat, sizeof (au_stat_t)))
+ return (EFAULT);
+
+ if (au_stat.as_generated == CLEAR_VAL)
+ kctx->auk_statistics.as_generated = 0;
+ if (au_stat.as_nonattrib == CLEAR_VAL)
+ kctx->auk_statistics.as_nonattrib = 0;
+ if (au_stat.as_kernel == CLEAR_VAL)
+ kctx->auk_statistics.as_kernel = 0;
+ if (au_stat.as_audit == CLEAR_VAL)
+ kctx->auk_statistics.as_audit = 0;
+ if (au_stat.as_auditctl == CLEAR_VAL)
+ kctx->auk_statistics.as_auditctl = 0;
+ if (au_stat.as_enqueue == CLEAR_VAL)
+ kctx->auk_statistics.as_enqueue = 0;
+ if (au_stat.as_written == CLEAR_VAL)
+ kctx->auk_statistics.as_written = 0;
+ if (au_stat.as_wblocked == CLEAR_VAL)
+ kctx->auk_statistics.as_wblocked = 0;
+ if (au_stat.as_rblocked == CLEAR_VAL)
+ kctx->auk_statistics.as_rblocked = 0;
+ if (au_stat.as_dropped == CLEAR_VAL)
+ kctx->auk_statistics.as_dropped = 0;
+ if (au_stat.as_totalsize == CLEAR_VAL)
+ kctx->auk_statistics.as_totalsize = 0;
+
+ membar_producer();
+
+ return (0);
+
+}
+
+static int
+setumask(caddr_t data)
+{
+ STRUCT_DECL(auditinfo, user_info);
+ struct proc *p;
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+
+ /* setumask not applicable in non-global zones without perzone policy */
+ if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
+ return (EINVAL);
+
+ model = get_udatamodel();
+ STRUCT_INIT(user_info, model);
+
+ if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
+ return (EFAULT);
+
+ mutex_enter(&pidlock); /* lock the process queue against updates */
+ for (p = practive; p != NULL; p = p->p_next) {
+ cred_t *cr;
+
+ /* if in non-global zone only modify processes in same zone */
+ if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
+ continue;
+
+ mutex_enter(&p->p_lock); /* so process doesn't go away */
+
+ /* skip system processes and ones being created or going away */
+ if (p->p_stat == SIDL || p->p_stat == SZOMB ||
+ (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
+ mutex_exit(&p->p_lock);
+ continue;
+ }
+
+ mutex_enter(&p->p_crlock);
+ crhold(cr = p->p_cred);
+ mutex_exit(&p->p_crlock);
+ ainfo = crgetauinfo(cr);
+ if (ainfo == NULL) {
+ mutex_exit(&p->p_lock);
+ crfree(cr);
+ continue;
+ }
+
+ if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
+ au_mask_t mask;
+ int err;
+
+ /*
+ * Here's a process which matches the specified auid.
+ * If its mask doesn't already match the new mask,
+ * save the new mask in the pad, to be picked up
+ * next syscall.
+ */
+ mask = STRUCT_FGET(user_info, ai_mask);
+ err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
+ crfree(cr);
+ if (err != 0) {
+ struct p_audit_data *pad = P2A(p);
+ ASSERT(pad != NULL);
+
+ mutex_enter(&(pad->pad_lock));
+ pad->pad_flags |= PAD_SETMASK;
+ pad->pad_newmask = mask;
+ mutex_exit(&(pad->pad_lock));
+
+ /*
+ * No need to call set_proc_pre_sys(), since
+ * t_pre_sys is ALWAYS on when audit is
+ * enabled...due to syscall auditing.
+ */
+ }
+ } else {
+ crfree(cr);
+ }
+ mutex_exit(&p->p_lock);
+ }
+ mutex_exit(&pidlock);
+
+ return (0);
+}
+
+static int
+setsmask(caddr_t data)
+{
+ STRUCT_DECL(auditinfo, user_info);
+ struct proc *p;
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+
+ /* setsmask not applicable in non-global zones without perzone policy */
+ if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
+ return (EINVAL);
+
+ model = get_udatamodel();
+ STRUCT_INIT(user_info, model);
+
+ if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
+ return (EFAULT);
+
+ mutex_enter(&pidlock); /* lock the process queue against updates */
+ for (p = practive; p != NULL; p = p->p_next) {
+ cred_t *cr;
+
+ /* if in non-global zone only modify processes in same zone */
+ if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
+ continue;
+
+ mutex_enter(&p->p_lock); /* so process doesn't go away */
+
+ /* skip system processes and ones being created or going away */
+ if (p->p_stat == SIDL || p->p_stat == SZOMB ||
+ (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
+ mutex_exit(&p->p_lock);
+ continue;
+ }
+
+ mutex_enter(&p->p_crlock);
+ crhold(cr = p->p_cred);
+ mutex_exit(&p->p_crlock);
+ ainfo = crgetauinfo(cr);
+ if (ainfo == NULL) {
+ mutex_exit(&p->p_lock);
+ crfree(cr);
+ continue;
+ }
+
+ if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
+ au_mask_t mask;
+ int err;
+
+ /*
+ * Here's a process which matches the specified asid.
+ * If its mask doesn't already match the new mask,
+ * save the new mask in the pad, to be picked up
+ * next syscall.
+ */
+ mask = STRUCT_FGET(user_info, ai_mask);
+ err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
+ crfree(cr);
+ if (err != 0) {
+ struct p_audit_data *pad = P2A(p);
+ ASSERT(pad != NULL);
+
+ mutex_enter(&(pad->pad_lock));
+ pad->pad_flags |= PAD_SETMASK;
+ pad->pad_newmask = mask;
+ mutex_exit(&(pad->pad_lock));
+
+ /*
+ * No need to call set_proc_pre_sys(), since
+ * t_pre_sys is ALWAYS on when audit is
+ * enabled...due to syscall auditing.
+ */
+ }
+ } else {
+ crfree(cr);
+ }
+ mutex_exit(&p->p_lock);
+ }
+ mutex_exit(&pidlock);
+
+ return (0);
+}
+
+/*
+ * Get the current audit state of the system
+ */
+static int
+getcond(caddr_t data)
+{
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+
+ if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
+ return (EFAULT);
+
+ return (0);
+}
+
+/*
+ * Set the current audit state of the system to on (AUC_AUDITING) or
+ * off (AUC_NOAUDIT).
+ */
+/* ARGSUSED */
+static int
+setcond(caddr_t data)
+{
+ int auditstate;
+ au_kcontext_t *kctx;
+
+ if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
+ return (EINVAL);
+
+ kctx = GET_KCTX_NGZ;
+
+ if (copyin(data, &auditstate, sizeof (int)))
+ return (EFAULT);
+
+ switch (auditstate) {
+ case AUC_AUDITING: /* Turn auditing on */
+ if (audit_active == C2AUDIT_UNLOADED)
+ audit_init_module();
+ kctx->auk_auditstate = AUC_AUDITING;
+ if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc))
+ set_all_zone_usr_proc_sys(ALL_ZONES);
+ else
+ set_all_zone_usr_proc_sys(curproc->p_zone->zone_id);
+ break;
+
+ case AUC_NOAUDIT: /* Turn auditing off */
+ if (kctx->auk_auditstate == AUC_NOAUDIT)
+ break;
+ kctx->auk_auditstate = AUC_NOAUDIT;
+
+ /* clear out the audit queue */
+
+ mutex_enter(&(kctx->auk_queue.lock));
+ if (kctx->auk_queue.wt_block)
+ cv_broadcast(&(kctx->auk_queue.write_cv));
+
+ /* unblock au_output_thread */
+ cv_broadcast(&(kctx->auk_queue.read_cv));
+
+ mutex_exit(&(kctx->auk_queue.lock));
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static int
+getclass(caddr_t data)
+{
+ au_evclass_map_t event;
+ au_kcontext_t *kctx = GET_KCTX_PZ;
+
+ if (copyin(data, &event, sizeof (au_evclass_map_t)))
+ return (EFAULT);
+
+ if (event.ec_number > MAX_KEVENTS)
+ return (EINVAL);
+
+ event.ec_class = kctx->auk_ets[event.ec_number];
+
+ if (copyout(&event, data, sizeof (au_evclass_map_t)))
+ return (EFAULT);
+
+ return (0);
+}
+
+static int
+setclass(caddr_t data)
+{
+ au_evclass_map_t event;
+ au_kcontext_t *kctx;
+
+ if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+ return (EINVAL);
+
+ kctx = GET_KCTX_NGZ;
+
+ if (copyin(data, &event, sizeof (au_evclass_map_t)))
+ return (EFAULT);
+
+ if (event.ec_number > MAX_KEVENTS)
+ return (EINVAL);
+
+ kctx->auk_ets[event.ec_number] = event.ec_class;
+
+ return (0);
+}
+
+static int
+getpinfo(caddr_t data)
+{
+ STRUCT_DECL(auditpinfo, apinfo);
+ proc_t *proc;
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+ cred_t *cr, *newcred;
+
+ model = get_udatamodel();
+ STRUCT_INIT(apinfo, model);
+
+ if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
+ return (EFAULT);
+
+ newcred = cralloc();
+
+ mutex_enter(&pidlock);
+ if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
+ mutex_exit(&pidlock);
+ crfree(newcred);
+ return (ESRCH); /* no such process */
+ }
+ mutex_enter(&proc->p_lock); /* so process doesn't go away */
+ mutex_exit(&pidlock);
+
+ audit_update_context(proc, newcred); /* make sure it's up-to-date */
+
+ mutex_enter(&proc->p_crlock);
+ crhold(cr = proc->p_cred);
+ mutex_exit(&proc->p_crlock);
+ mutex_exit(&proc->p_lock);
+
+ ainfo = crgetauinfo(cr);
+ if (ainfo == NULL) {
+ crfree(cr);
+ return (EINVAL);
+ }
+
+ /* designated process has an ipv6 address? */
+ if (ainfo->ai_termid.at_type == AU_IPv6) {
+ crfree(cr);
+ return (EOVERFLOW);
+ }
+
+ STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
+ STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
+#ifdef _LP64
+ if (model == DATAMODEL_ILP32) {
+ dev32_t dev;
+ /* convert internal 64 bit form to 32 bit version */
+ if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
+ crfree(cr);
+ return (EOVERFLOW);
+ }
+ STRUCT_FSET(apinfo, ap_termid.port, dev);
+ } else
+ STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
+#else
+ STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
+#endif
+ STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
+ STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
+
+ crfree(cr);
+
+ if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
+ return (EFAULT);
+
+ return (0);
+}
+
+static int
+getpinfo_addr(caddr_t data, int len)
+{
+ STRUCT_DECL(auditpinfo_addr, apinfo);
+ proc_t *proc;
+ const auditinfo_addr_t *ainfo;
+ model_t model;
+ cred_t *cr, *newcred;
+
+ model = get_udatamodel();
+ STRUCT_INIT(apinfo, model);
+
+ if (len < STRUCT_SIZE(apinfo))
+ return (EOVERFLOW);
+
+ if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
+ return (EFAULT);
+
+ newcred = cralloc();
+
+ mutex_enter(&pidlock);
+ if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
+ mutex_exit(&pidlock);
+ crfree(newcred);
+ return (ESRCH);
+ }
+ mutex_enter(&proc->p_lock); /* so process doesn't go away */
+ mutex_exit(&pidlock);
+
+ audit_update_context(proc, newcred); /* make sure it's up-to-date */
+
+ mutex_enter(&proc->p_crlock);
+ crhold(cr = proc->p_cred);
+ mutex_exit(&proc->p_crlock);
+ mutex_exit(&proc->p_lock);
+
+ ainfo = crgetauinfo(cr);
+ if (ainfo == NULL) {
+ crfree(cr);
+ return (EINVAL);
+ }
+
+ STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
+ STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
+#ifdef _LP64
+ if (model == DATAMODEL_ILP32) {
+ dev32_t dev;
+ /* convert internal 64 bit form to 32 bit version */
+ if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
+ crfree(cr);
+ return (EOVERFLOW);
+ }
+ STRUCT_FSET(apinfo, ap_termid.at_port, dev);
+ } else
+ STRUCT_FSET(apinfo, ap_termid.at_port,
+ ainfo->ai_termid.at_port);
+#else
+ STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
+#endif
+ STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
+ STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
+ STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
+ STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
+ STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
+ STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
+
+ crfree(cr);
+
+ if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
+ return (EFAULT);
+
+ return (0);
+}
+
+static int
+setpmask(caddr_t data)
+{
+ STRUCT_DECL(auditpinfo, apinfo);
+ proc_t *proc;
+ cred_t *newcred;
+ auditinfo_addr_t *ainfo;
+ struct p_audit_data *pad;
+
+ model_t model;
+
+ model = get_udatamodel();
+ STRUCT_INIT(apinfo, model);
+
+ if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
+ return (EFAULT);
+
+ mutex_enter(&pidlock);
+ if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
+ mutex_exit(&pidlock);
+ return (ESRCH);
+ }
+ mutex_enter(&proc->p_lock); /* so process doesn't go away */
+ mutex_exit(&pidlock);
+
+ newcred = cralloc();
+ if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
+ mutex_exit(&proc->p_lock);
+ crfree(newcred);
+ return (EINVAL);
+ }
+
+ mutex_enter(&proc->p_crlock);
+ crcopy_to(proc->p_cred, newcred);
+ proc->p_cred = newcred;
+
+ ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
+
+ /*
+ * Unlock. No need to broadcast changes via set_proc_pre_sys(),
+ * since t_pre_sys is ALWAYS on when audit is enabled... due to
+ * syscall auditing.
+ */
+ crfree(newcred);
+ mutex_exit(&proc->p_crlock);
+
+ /* Reset flag for any previous pending mask change; this supercedes */
+ pad = P2A(proc);
+ ASSERT(pad != NULL);
+ mutex_enter(&(pad->pad_lock));
+ pad->pad_flags &= ~PAD_SETMASK;
+ mutex_exit(&(pad->pad_lock));
+
+ mutex_exit(&proc->p_lock);
+
+ return (0);
+}
+
+/*
+ * The out of control system call
+ * This is audit kitchen sink aka auditadm, aka auditon
+ */
+int
+auditctl(
+ int cmd,
+ caddr_t data,
+ int length)
+{
+ int result;
+
+ switch (cmd) {
+ case A_GETCOND:
+ case A_GETCAR:
+ case A_GETCLASS:
+ case A_GETCWD:
+ case A_GETKAUDIT:
+ case A_GETKMASK:
+ case A_GETPINFO:
+ case A_GETPINFO_ADDR:
+ case A_GETPOLICY:
+ case A_GETQCTRL:
+ case A_GETSTAT:
+ if (secpolicy_audit_getattr(CRED()) != 0)
+ return (EPERM);
+ break;
+ default:
+ if (secpolicy_audit_config(CRED()) != 0)
+ return (EPERM);
+ break;
+ }
+
+ switch (cmd) {
+ case A_GETPOLICY:
+ result = getpolicy(data);
+ break;
+ case A_SETPOLICY:
+ result = setpolicy(data);
+ break;
+ case A_GETKMASK:
+ result = getkmask(data);
+ break;
+ case A_SETKMASK:
+ result = setkmask(data);
+ break;
+ case A_GETKAUDIT:
+ result = getkaudit(data, length);
+ break;
+ case A_SETKAUDIT:
+ result = setkaudit(data, length);
+ break;
+ case A_GETQCTRL:
+ result = getqctrl(data);
+ break;
+ case A_SETQCTRL:
+ result = setqctrl(data);
+ break;
+ case A_GETCWD:
+ result = getcwd(data, length);
+ break;
+ case A_GETCAR:
+ result = getcar(data, length);
+ break;
+ case A_GETSTAT:
+ result = getstat(data);
+ break;
+ case A_SETSTAT:
+ result = setstat(data);
+ break;
+ case A_SETUMASK:
+ result = setumask(data);
+ break;
+ case A_SETSMASK:
+ result = setsmask(data);
+ break;
+ case A_GETCOND:
+ result = getcond(data);
+ break;
+ case A_SETCOND:
+ result = setcond(data);
+ break;
+ case A_GETCLASS:
+ result = getclass(data);
+ break;
+ case A_SETCLASS:
+ result = setclass(data);
+ break;
+ case A_GETPINFO:
+ result = getpinfo(data);
+ break;
+ case A_GETPINFO_ADDR:
+ result = getpinfo_addr(data, length);
+ break;
+ case A_SETPMASK:
+ result = setpmask(data);
+ break;
+ default:
+ result = EINVAL;
+ break;
+ }
+ return (result);
}
diff --git a/usr/src/uts/common/syscall/chdir.c b/usr/src/uts/common/syscall/chdir.c
index 66459ef689..84c924f570 100644
--- a/usr/src/uts/common/syscall/chdir.c
+++ b/usr/src/uts/common/syscall/chdir.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,8 +31,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/isa_defs.h>
#include <sys/types.h>
@@ -216,7 +214,8 @@ chdirec(vnode_t *vp, int ischroot, int do_traverse)
vpp = &PTOU(pp)->u_cdir;
}
- if (audit_active) /* update abs cwd/root path see c2audit.c */
+ /* update abs cwd/root path see c2/audit.c */
+ if (AU_AUDITING())
audit_chdirec(vp, vpp);
mutex_enter(&pp->p_lock);
diff --git a/usr/src/uts/common/syscall/chown.c b/usr/src/uts/common/syscall/chown.c
index 04250e1e35..a0a5821374 100644
--- a/usr/src/uts/common/syscall/chown.c
+++ b/usr/src/uts/common/syscall/chown.c
@@ -106,7 +106,7 @@ fchownat(int fd, char *name, uid_t uid, gid_t gid, int flags)
}
}
- if (audit_active)
+ if (AU_AUDITING())
audit_setfsat_path(1);
/*
diff --git a/usr/src/uts/common/syscall/open.c b/usr/src/uts/common/syscall/open.c
index e4fc89f3ec..3f5f484f6d 100644
--- a/usr/src/uts/common/syscall/open.c
+++ b/usr/src/uts/common/syscall/open.c
@@ -48,7 +48,6 @@
#include <sys/uio.h>
#include <sys/debug.h>
#include <c2/audit.h>
-#include <sys/cmn_err.h>
/*
* Common code for openat(). Check permissions, allocate an open
@@ -68,6 +67,7 @@ copen(int startfd, char *fname, int filemode, int createmode)
proc_t *p = curproc;
uio_seg_t seg = UIO_USERSPACE;
char *open_filename = fname;
+ uint32_t auditing = AU_AUDITING();
if (startfd == AT_FDCWD) {
/*
@@ -101,7 +101,7 @@ copen(int startfd, char *fname, int filemode, int createmode)
* Handle openattrdirat request
*/
if (filemode & FXATTRDIROPEN) {
- if (audit_active)
+ if (auditing)
audit_setfsat_path(1);
if (error = lookupnameat(fname, seg, FOLLOW,
@@ -185,7 +185,7 @@ copen(int startfd, char *fname, int filemode, int createmode)
filemode &= ~FNDELAY;
error = falloc((vnode_t *)NULL, filemode, &fp, &fd);
if (error == 0) {
- if (audit_active)
+ if (auditing)
audit_setfsat_path(1);
/*
* Last arg is a don't-care term if
@@ -200,7 +200,7 @@ copen(int startfd, char *fname, int filemode, int createmode)
if (startvp != NULL)
VN_RELE(startvp);
if (error == 0) {
- if (audit_active)
+ if (auditing)
audit_copen(fd, fp, vp);
if ((vp->v_flag & VDUP) == 0) {
fp->f_vnode = vp;
diff --git a/usr/src/uts/common/syscall/ppriv.c b/usr/src/uts/common/syscall/ppriv.c
index dfce48662b..14858710d9 100644
--- a/usr/src/uts/common/syscall/ppriv.c
+++ b/usr/src/uts/common/syscall/ppriv.c
@@ -73,7 +73,7 @@ setppriv(priv_op_t op, priv_ptype_t type, priv_set_t *in_pset)
retry:
pcr = p->p_cred;
- if (audit_active)
+ if (AU_AUDITING())
audit_setppriv(op, type, &pset, pcr);
/*
diff --git a/usr/src/uts/common/syscall/sem.c b/usr/src/uts/common/syscall/sem.c
index 7029b95c02..316f806c4d 100644
--- a/usr/src/uts/common/syscall/sem.c
+++ b/usr/src/uts/common/syscall/sem.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -725,8 +725,10 @@ top:
}
lock = ipc_commit_end(sem_svc, &sp->sem_perm);
}
- if (audit_active)
+
+ if (AU_AUDITING())
audit_ipcget(AT_IPC_SEM, (void *)sp);
+
id = sp->sem_perm.ipc_id;
mutex_exit(lock);
return (id);
diff --git a/usr/src/uts/common/syscall/stat.c b/usr/src/uts/common/syscall/stat.c
index 87ede7fe62..90d191bd9e 100644
--- a/usr/src/uts/common/syscall/stat.c
+++ b/usr/src/uts/common/syscall/stat.c
@@ -103,7 +103,7 @@ cstatat_getvp(int fd, char *name, int follow, vnode_t **vp, cred_t **cred)
}
*cred = cr;
- if (audit_active)
+ if (AU_AUDITING())
audit_setfsat_path(1);
lookup:
@@ -144,7 +144,7 @@ static int cstat(vnode_t *vp, struct stat *, int, cred_t *);
return (set_errno(EFAULT)); \
if ((fp = getf(fd)) == NULL) \
return (set_errno(EBADF)); \
- if (audit_active) \
+ if (AU_AUDITING()) \
audit_setfsat_path(1); \
error = statfn(fp->f_vnode, sb, 0, fp->f_cred); \
releasef(fd); \
diff --git a/usr/src/uts/common/syscall/symlink.c b/usr/src/uts/common/syscall/symlink.c
index 700029cf73..99dcdf01a4 100644
--- a/usr/src/uts/common/syscall/symlink.c
+++ b/usr/src/uts/common/syscall/symlink.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,8 +31,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/isa_defs.h>
#include <sys/types.h>
@@ -84,7 +82,7 @@ top:
vattr.va_mask = AT_TYPE|AT_MODE;
error = VOP_SYMLINK(dvp, lpn.pn_path, &vattr,
tbuf, CRED(), NULL, 0);
- if (audit_active)
+ if (AU_AUDITING())
audit_symlink_create(dvp, lpn.pn_path,
tbuf, error);
}
diff --git a/usr/src/uts/common/syscall/ucredsys.c b/usr/src/uts/common/syscall/ucredsys.c
index 0f5c0e6303..3a9447a147 100644
--- a/usr/src/uts/common/syscall/ucredsys.c
+++ b/usr/src/uts/common/syscall/ucredsys.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ucred.h>
@@ -133,6 +131,7 @@ ucred_get(pid_t pid, void *ubuf)
cred_t *pcr;
int err;
struct ucred_s *uc;
+ uint32_t auditing = AU_AUDITING();
if (pid == P_MYID || pid == curproc->p_pid) {
pcr = CRED();
@@ -144,7 +143,7 @@ ucred_get(pid_t pid, void *ubuf)
if (pid < 0)
return (set_errno(EINVAL));
- if (audit_active)
+ if (auditing)
updcred = cralloc();
mutex_enter(&pidlock);
@@ -161,7 +160,7 @@ ucred_get(pid_t pid, void *ubuf)
* Assure that audit data in cred is up-to-date.
* updcred will be used or freed.
*/
- if (audit_active)
+ if (auditing)
audit_update_context(p, updcred);
err = priv_proc_cred_perm(CRED(), p, &pcr, VREAD);
diff --git a/usr/src/uts/common/syscall/unlink.c b/usr/src/uts/common/syscall/unlink.c
index 27546c959a..d8ba91ac9b 100644
--- a/usr/src/uts/common/syscall/unlink.c
+++ b/usr/src/uts/common/syscall/unlink.c
@@ -80,7 +80,7 @@ unlinkat(int fd, char *name, int flags)
}
}
- if (audit_active)
+ if (AU_AUDITING())
audit_setfsat_path(1);
error = vn_removeat(dirvp, name,
diff --git a/usr/src/uts/common/syscall/utime.c b/usr/src/uts/common/syscall/utime.c
index 43cdf1d62b..d0ccd869e3 100644
--- a/usr/src/uts/common/syscall/utime.c
+++ b/usr/src/uts/common/syscall/utime.c
@@ -84,7 +84,7 @@ cfutimesat(int fd, char *fname, int nmflag, vattr_t *vap, int flags, int follow)
}
}
- if (audit_active)
+ if (AU_AUDITING())
audit_setfsat_path(1);
if ((nmflag == 1) || ((nmflag == 2) && (fname != NULL))) {
diff --git a/usr/src/uts/i86pc/os/machdep.c b/usr/src/uts/i86pc/os/machdep.c
index 9563b061e4..c9f97fc046 100644
--- a/usr/src/uts/i86pc/os/machdep.c
+++ b/usr/src/uts/i86pc/os/machdep.c
@@ -130,6 +130,7 @@
#include <sys/traptrace.h>
#endif /* TRAPTRACE */
+#include <c2/audit.h>
#include <sys/clock_impl.h>
extern void audit_enterprom(int);
@@ -392,14 +393,14 @@ void
abort_sequence_enter(char *msg)
{
if (abort_enable == 0) {
- if (audit_active)
+ if (AU_ZONE_AUDITING(GET_KCTX_GZ))
audit_enterprom(0);
return;
}
- if (audit_active)
+ if (AU_ZONE_AUDITING(GET_KCTX_GZ))
audit_enterprom(1);
debug_enter(msg);
- if (audit_active)
+ if (AU_ZONE_AUDITING(GET_KCTX_GZ))
audit_exitprom(1);
}
diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c
index ab873d569e..c679eb2626 100644
--- a/usr/src/uts/i86pc/os/trap.c
+++ b/usr/src/uts/i86pc/os/trap.c
@@ -1850,6 +1850,7 @@ kern_gpfault(struct regs *rp)
struct regs tmpregs, *trp = NULL;
caddr_t pc = (caddr_t)rp->r_pc;
int v;
+ uint32_t auditing = AU_AUDITING();
/*
* if we're not an lwp, or in the case of running native the
@@ -1962,10 +1963,10 @@ kern_gpfault(struct regs *rp)
lwp_exit();
}
- if (audit_active) /* audit core dump */
+ if (auditing) /* audit core dump */
audit_core_start(SIGSEGV);
v = core(SIGSEGV, B_FALSE);
- if (audit_active) /* audit core dump */
+ if (auditing) /* audit core dump */
audit_core_finish(v ? CLD_KILLED : CLD_DUMPED);
exit(v ? CLD_KILLED : CLD_DUMPED, SIGSEGV);
return (0);
diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s
index 5c83b2ff0d..87e1323772 100644
--- a/usr/src/uts/intel/ia32/ml/modstubs.s
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s
@@ -951,17 +951,11 @@ fcnname/**/_info: \
*/
#ifndef C2AUDIT_MODULE
MODULE(c2audit,sys);
- STUB(c2audit, audit_init, nomod_zero);
- STUB(c2audit, _auditsys, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_free, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, audit_init_module, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_start, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_finish, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_newproc, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_pfree, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_thread_free, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_thread_create, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_falloc, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_unfalloc, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, audit, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, auditdoor, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_closef, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_copen, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_core_start, nomod_zero);
@@ -998,9 +992,12 @@ fcnname/**/_info: \
NO_UNLOAD_STUB(c2audit, audit_devpolicy, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_setfsat_path, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_cryptoadm, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_update_context, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_kssl, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_pf_policy, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_doormsg, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_uwrite, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_to_arg32, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_free_rec, nomod_zero);
END_MODULE(c2audit);
#endif
diff --git a/usr/src/uts/intel/ia32/os/syscall.c b/usr/src/uts/intel/ia32/os/syscall.c
index 0f670853a1..e2b6fd0a88 100644
--- a/usr/src/uts/intel/ia32/os/syscall.c
+++ b/usr/src/uts/intel/ia32/os/syscall.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -349,14 +349,23 @@ pre_syscall()
return (1); /* don't do system call, return EINTR */
}
- if (audit_active) { /* begin auditing for this syscall */
- int error;
- if (error = audit_start(T_SYSCALL, code, 0, lwp)) {
- t->t_pre_sys = 1; /* repost anyway */
- (void) set_errno(error);
- return (1);
+ /*
+ * begin auditing for this syscall if the c2audit module is loaded
+ * and auditing is enabled
+ */
+ if (audit_active == C2AUDIT_LOADED) {
+ uint32_t auditing = au_zone_getstate(NULL);
+
+ if (auditing & AU_AUDIT_MASK) {
+ int error;
+ if (error = audit_start(T_SYSCALL, code, auditing, \
+ 0, lwp)) {
+ t->t_pre_sys = 1; /* repost anyway */
+ (void) set_errno(error);
+ return (1);
+ }
+ repost = 1;
}
- repost = 1;
}
#ifndef NPROBE
@@ -458,7 +467,9 @@ post_syscall(long rval1, long rval2)
rp->r_ps &= ~PS_T;
aston(curthread);
}
- if (audit_active) { /* put out audit record for this syscall */
+
+ /* put out audit record for this syscall */
+ if (AU_AUDITING()) {
rval_t rval;
/* XX64 -- truncation of 64-bit return values? */
@@ -1321,6 +1332,48 @@ set_all_proc_sys()
}
/*
+ * set_all_zone_usr_proc_sys - set pre- and post-syscall processing flags for
+ * all user processes running in the zone of the current process
+ *
+ * This is needed when auditing, tracing, or other facilities which affect
+ * all processes are turned on.
+ */
+void
+set_all_zone_usr_proc_sys(zoneid_t zoneid)
+{
+ proc_t *p;
+ kthread_t *t;
+
+ mutex_enter(&pidlock);
+ for (p = practive; p != NULL; p = p->p_next) {
+ /* skip kernel and incomplete processes */
+ if (p->p_exec == NULLVP || p->p_as == &kas ||
+ p->p_stat == SIDL || p->p_stat == SZOMB ||
+ (p->p_flag & (SSYS | SEXITING | SEXITLWPS)))
+ continue;
+ /*
+ * Only processes in the given zone (eventually in
+ * all zones) are taken into account
+ */
+ if (zoneid == ALL_ZONES || p->p_zone->zone_id == zoneid) {
+ mutex_enter(&p->p_lock);
+ if ((t = p->p_tlist) == NULL)
+ continue;
+ /*
+ * Set pre- and post-syscall processing flags
+ * for all threads of the process
+ */
+ do {
+ t->t_pre_sys = 1;
+ t->t_post_sys = 1;
+ } while (p->p_tlist != (t = t->t_forw));
+ mutex_exit(&p->p_lock);
+ }
+ }
+ mutex_exit(&pidlock);
+}
+
+/*
* set_proc_ast - Set asynchronous service trap (AST) flag for all
* threads in process.
*/
diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s
index e3720f8d34..c04ceea2c9 100644
--- a/usr/src/uts/sparc/ml/modstubs.s
+++ b/usr/src/uts/sparc/ml/modstubs.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -871,17 +871,11 @@ stubs_base:
*/
#ifndef C2AUDIT_MODULE
MODULE(c2audit,sys);
- STUB(c2audit, audit_init, nomod_zero);
- STUB(c2audit, _auditsys, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_free, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, audit_init_module, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_start, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_finish, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_newproc, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_pfree, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_thread_free, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_thread_create, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_falloc, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_unfalloc, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, audit, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, auditdoor, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_closef, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_copen, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_core_start, nomod_zero);
@@ -918,9 +912,12 @@ stubs_base:
NO_UNLOAD_STUB(c2audit, audit_devpolicy, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_setfsat_path, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_cryptoadm, nomod_zero);
- NO_UNLOAD_STUB(c2audit, audit_update_context, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_kssl, nomod_zero);
NO_UNLOAD_STUB(c2audit, audit_pf_policy, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_doormsg, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_uwrite, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_to_arg32, nomod_zero);
+ NO_UNLOAD_STUB(c2audit, au_free_rec, nomod_zero);
END_MODULE(c2audit);
#endif
diff --git a/usr/src/uts/sparc/os/syscall.c b/usr/src/uts/sparc/os/syscall.c
index 4bb8851d9e..6157f6addd 100644
--- a/usr/src/uts/sparc/os/syscall.c
+++ b/usr/src/uts/sparc/os/syscall.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -452,14 +452,20 @@ pre_syscall(int arg0)
return (1); /* don't do system call, return EINTR */
}
- if (audit_active) { /* begin auditing for this syscall */
- int error;
- if (error = audit_start(T_SYSCALL, code, 0, lwp)) {
- t->t_pre_sys = 1; /* repost anyway */
- lwp->lwp_error = 0; /* for old drivers */
- return (error);
+ /* begin auditing for this syscall */
+ if (audit_active == C2AUDIT_LOADED) {
+ uint32_t auditing = au_zone_getstate(NULL);
+
+ if (auditing & AU_AUDIT_MASK) {
+ int error;
+ if (error = audit_start(T_SYSCALL, code, auditing, \
+ 0, lwp)) {
+ t->t_pre_sys = 1; /* repost anyway */
+ lwp->lwp_error = 0; /* for old drivers */
+ return (error);
+ }
+ repost = 1;
}
- repost = 1;
}
#ifndef NPROBE
@@ -550,7 +556,8 @@ post_syscall(long rval1, long rval2)
if (code == 0)
goto sig_check;
- if (audit_active) { /* put out audit record for this syscall */
+ /* put out audit record for this syscall */
+ if (AU_AUDITING()) {
rval_t rval; /* fix audit_finish() someday */
/* XX64 -- truncation of 64-bit return values? */
@@ -1166,6 +1173,47 @@ set_all_proc_sys()
}
/*
+ * set_all_zone_usr_proc_sys - set pre- and post-syscall processing flags for
+ * all user processes running in the zone of the current process
+ *
+ * This is needed when auditing is turned on.
+ */
+void
+set_all_zone_usr_proc_sys(zoneid_t zoneid)
+{
+ proc_t *p;
+ kthread_t *t;
+
+ mutex_enter(&pidlock);
+ for (p = practive; p != NULL; p = p->p_next) {
+ /* skip kernel processes */
+ if (p->p_exec == NULLVP || p->p_as == &kas ||
+ p->p_stat == SIDL || p->p_stat == SZOMB ||
+ (p->p_flag & (SSYS | SEXITING | SEXITLWPS)))
+ continue;
+ /*
+ * Only processes in the given zone (eventually in
+ * all zones) are taken into account
+ */
+ if (zoneid == ALL_ZONES || p->p_zone->zone_id == zoneid) {
+ mutex_enter(&p->p_lock);
+ if ((t = p->p_tlist) == NULL)
+ continue;
+ /*
+ * Set pre- and post-syscall processing flags
+ * for all threads of the process
+ */
+ do {
+ t->t_pre_sys = 1;
+ t->t_post_sys = 1;
+ } while (p->p_tlist != (t = t->t_forw));
+ mutex_exit(&p->p_lock);
+ }
+ }
+ mutex_exit(&pidlock);
+}
+
+/*
* set_proc_ast - Set asynchronous service trap (AST) flag for all
* threads in process.
*/
diff --git a/usr/src/uts/sun4/os/cpu_states.c b/usr/src/uts/sun4/os/cpu_states.c
index 34298bbb06..5c53df1182 100644
--- a/usr/src/uts/sun4/os/cpu_states.c
+++ b/usr/src/uts/sun4/os/cpu_states.c
@@ -19,11 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/reboot.h>
#include <sys/systm.h>
@@ -38,6 +37,7 @@
#include <sys/kdi_machimpl.h>
#include <sys/callb.h>
#include <sys/wdt.h>
+#include <c2/audit.h>
#ifdef TRAPTRACE
#include <sys/traptrace.h>
@@ -97,8 +97,9 @@ static char abort_seq_msgbuf[ABORT_SEQ_MSGBUFSZ];
static uint_t
abort_seq_softintr(caddr_t arg)
{
- char *msg;
- char msgbuf[ABORT_SEQ_MSGBUFSZ];
+ char *msg;
+ char msgbuf[ABORT_SEQ_MSGBUFSZ];
+ uint32_t auditing = AU_ZONE_AUDITING(GET_KCTX_GZ);
mutex_enter(&abort_seq_lock);
if (abort_enable != 0 && abort_seq_tstamp != 0LL) {
@@ -109,14 +110,14 @@ abort_seq_softintr(caddr_t arg)
msg = NULL;
abort_seq_tstamp = 0LL;
mutex_exit(&abort_seq_lock);
- if (audit_active)
+ if (auditing)
audit_enterprom(1);
(*abort_seq_handler)(msg);
- if (audit_active)
+ if (auditing)
audit_exitprom(1);
} else {
mutex_exit(&abort_seq_lock);
- if (audit_active)
+ if (auditing)
audit_enterprom(0);
}
return (1);
@@ -141,6 +142,7 @@ abort_sequence_enter(char *msg)
int s, on_intr;
size_t msglen;
hrtime_t tstamp;
+ int auditing = AU_ZONE_AUDITING(GET_KCTX_GZ);
if (abort_enable != 0) {
s = splhi();
@@ -183,14 +185,14 @@ abort_sequence_enter(char *msg)
*/
abort_seq_tstamp = 0LL;
mutex_exit(&abort_seq_lock);
- if (!on_intr && audit_active)
+ if (!on_intr && auditing)
audit_enterprom(1);
(*abort_seq_handler)(msg);
- if (!on_intr && audit_active)
+ if (!on_intr && auditing)
audit_exitprom(1);
}
} else {
- if (audit_active)
+ if (auditing)
audit_enterprom(0);
}
}