aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2017-03-31 13:43:00 +0000
committerRobert Watson <rwatson@FreeBSD.org>2017-03-31 13:43:00 +0000
commit15bcf785ba268a1fb2b270233a7ae56d9e0ebc3a (patch)
treec1256bc0e58074fd3b7b1fe98a8148f625289b73
parent788e62864f8684da8459c5cbb5b88c34ee1c4bf5 (diff)
downloadsrc-15bcf785ba268a1fb2b270233a7ae56d9e0ebc3a.tar.gz
src-15bcf785ba268a1fb2b270233a7ae56d9e0ebc3a.zip
Audit arguments to POSIX message queues, semaphores, and shared memory.
This requires minor changes to the audit framework to allow capturing paths that are not filesystem paths (i.e., will not be canonicalised relative to the process current working directory and/or filesystem root). Obtained from: TrustedBSD Project MFC after: 3 weeks Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/head/; revision=316332
-rw-r--r--sys/kern/uipc_mqueue.c19
-rw-r--r--sys/kern/uipc_sem.c19
-rw-r--r--sys/kern/uipc_shm.c13
-rw-r--r--sys/security/audit/audit.h14
-rw-r--r--sys/security/audit/audit_arg.c42
5 files changed, 105 insertions, 2 deletions
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index 354564b080fe..a3c2a8d2cbfc 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -1,7 +1,13 @@
/*-
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
+ * Copyright (c) 2016-2017 Robert N. M. Watson
* All rights reserved.
*
+ * Portions of this software were developed by BAE Systems, the University of
+ * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
+ * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
+ * Computing (TC) research program.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -86,6 +92,8 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <machine/atomic.h>
+#include <security/audit/audit.h>
+
FEATURE(p1003_1b_mqueue, "POSIX P1003.1B message queues support");
/*
@@ -2012,6 +2020,9 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
struct mqueue *mq;
int fd, error, len, cmode;
+ AUDIT_ARG_FFLAGS(flags);
+ AUDIT_ARG_MODE(mode);
+
fdp = td->td_proc->p_fd;
cmode = (((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT);
mq = NULL;
@@ -2034,6 +2045,7 @@ kern_kmq_open(struct thread *td, const char *upath, int flags, mode_t mode,
len = strlen(path);
if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
return (EINVAL);
+ AUDIT_ARG_UPATH1_CANON(path);
error = falloc(td, &fp, &fd, O_CLOEXEC);
if (error)
@@ -2133,6 +2145,7 @@ sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap)
len = strlen(path);
if (len < 2 || path[0] != '/' || strchr(path + 1, '/') != NULL)
return (EINVAL);
+ AUDIT_ARG_UPATH1_CANON(path);
sx_xlock(&mqfs_data.mi_lock);
pn = mqfs_search(mqfs_data.mi_root, path + 1, len - 1, td->td_ucred);
@@ -2210,6 +2223,7 @@ kern_kmq_setattr(struct thread *td, int mqd, const struct mq_attr *attr,
u_int oflag, flag;
int error;
+ AUDIT_ARG_FD(mqd);
if (attr != NULL && (attr->mq_flags & ~O_NONBLOCK) != 0)
return (EINVAL);
error = getmq(td, mqd, &fp, NULL, &mq);
@@ -2260,6 +2274,7 @@ sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
int error;
int waitok;
+ AUDIT_ARG_FD(uap->mqd);
error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
@@ -2285,6 +2300,7 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
struct timespec *abs_timeout, ets;
int error, waitok;
+ AUDIT_ARG_FD(uap->mqd);
error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
@@ -2315,6 +2331,7 @@ kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
struct mqueue_notifier *nt, *newnt = NULL;
int error;
+ AUDIT_ARG_FD(mqd);
if (sigev != NULL) {
if (sigev->sigev_notify != SIGEV_SIGNAL &&
sigev->sigev_notify != SIGEV_THREAD_ID &&
@@ -2780,6 +2797,7 @@ freebsd32_kmq_timedsend(struct thread *td,
int error;
int waitok;
+ AUDIT_ARG_FD(uap->mqd);
error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
@@ -2809,6 +2827,7 @@ freebsd32_kmq_timedreceive(struct thread *td,
struct timespec *abs_timeout, ets;
int error, waitok;
+ AUDIT_ARG_FD(uap->mqd);
error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
if (error)
return (error);
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index 0ecff7cc2bbf..9ff29f31006f 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2002 Alfred Perlstein <alfred@FreeBSD.org>
* Copyright (c) 2003-2005 SPARTA, Inc.
- * Copyright (c) 2005 Robert N. M. Watson
+ * Copyright (c) 2005, 2016-2017 Robert N. M. Watson
* All rights reserved.
*
* This software was developed for the FreeBSD Project in part by Network
@@ -9,6 +9,11 @@
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
* as part of the DARPA CHATS research program.
*
+ * Portions of this software were developed by BAE Systems, the University of
+ * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
+ * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
+ * Computing (TC) research program.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -66,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include <sys/user.h>
#include <sys/vnode.h>
+#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
FEATURE(p1003_1b_semaphores, "POSIX P1003.1B semaphores support");
@@ -467,6 +473,10 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
Fnv32_t fnv;
int error, fd;
+ AUDIT_ARG_FFLAGS(flags);
+ AUDIT_ARG_MODE(mode);
+ AUDIT_ARG_VALUE(value);
+
if (value > SEM_VALUE_MAX)
return (EINVAL);
@@ -518,6 +528,7 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
return (error);
}
+ AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&ksem_dict_lock);
ks = ksem_lookup(path, fnv);
@@ -661,6 +672,7 @@ sys_ksem_unlink(struct thread *td, struct ksem_unlink_args *uap)
return (error);
}
+ AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&ksem_dict_lock);
error = ksem_remove(path, fnv, td->td_ucred);
@@ -684,6 +696,7 @@ sys_ksem_close(struct thread *td, struct ksem_close_args *uap)
int error;
/* No capability rights required to close a semaphore. */
+ AUDIT_ARG_FD(uap->id);
error = ksem_get(td, uap->id, cap_rights_init(&rights), &fp);
if (error)
return (error);
@@ -710,6 +723,7 @@ sys_ksem_post(struct thread *td, struct ksem_post_args *uap)
struct ksem *ks;
int error;
+ AUDIT_ARG_FD(uap->id);
error = ksem_get(td, uap->id,
cap_rights_init(&rights, CAP_SEM_POST), &fp);
if (error)
@@ -802,6 +816,7 @@ kern_sem_wait(struct thread *td, semid_t id, int tryflag,
int error;
DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid));
+ AUDIT_ARG_FD(id);
error = ksem_get(td, id, cap_rights_init(&rights, CAP_SEM_WAIT), &fp);
if (error)
return (error);
@@ -869,6 +884,7 @@ sys_ksem_getvalue(struct thread *td, struct ksem_getvalue_args *uap)
struct ksem *ks;
int error, val;
+ AUDIT_ARG_FD(uap->id);
error = ksem_get(td, uap->id,
cap_rights_init(&rights, CAP_SEM_GETVALUE), &fp);
if (error)
@@ -906,6 +922,7 @@ sys_ksem_destroy(struct thread *td, struct ksem_destroy_args *uap)
int error;
/* No capability rights required to close a semaphore. */
+ AUDIT_ARG_FD(uap->id);
error = ksem_get(td, uap->id, cap_rights_init(&rights), &fp);
if (error)
return (error);
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 55362c5ad704..0057f1b51c8a 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1,7 +1,12 @@
/*-
- * Copyright (c) 2006, 2011 Robert N. M. Watson
+ * Copyright (c) 2006, 2011, 2016-2017 Robert N. M. Watson
* All rights reserved.
*
+ * Portions of this software were developed by BAE Systems, the University of
+ * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
+ * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
+ * Computing (TC) research program.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -79,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <sys/unistd.h>
#include <sys/user.h>
+#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
#include <vm/vm.h>
@@ -709,6 +715,9 @@ kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode,
return (ECAPMODE);
#endif
+ AUDIT_ARG_FFLAGS(flags);
+ AUDIT_ARG_MODE(mode);
+
if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR)
return (EINVAL);
@@ -754,6 +763,7 @@ kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode,
return (error);
}
+ AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&shm_dict_lock);
shmfd = shm_lookup(path, fnv);
@@ -858,6 +868,7 @@ sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap)
if (KTRPOINT(curthread, KTR_NAMEI))
ktrnamei(path);
#endif
+ AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&shm_dict_lock);
error = shm_remove(path, fnv, td->td_ucred);
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index 181fc725f76d..184e79ae3765 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -106,7 +106,9 @@ void audit_arg_auid(uid_t auid);
void audit_arg_auditinfo(struct auditinfo *au_info);
void audit_arg_auditinfo_addr(struct auditinfo_addr *au_info);
void audit_arg_upath1(struct thread *td, int dirfd, char *upath);
+void audit_arg_upath1_canon(char *upath);
void audit_arg_upath2(struct thread *td, int dirfd, char *upath);
+void audit_arg_upath2_canon(char *upath);
void audit_arg_vnode1(struct vnode *vp);
void audit_arg_vnode2(struct vnode *vp);
void audit_arg_text(char *text);
@@ -334,11 +336,21 @@ void audit_thread_free(struct thread *td);
audit_arg_upath1((td), (dirfd), (upath)); \
} while (0)
+#define AUDIT_ARG_UPATH1_CANON(upath) do { \
+ if (AUDITING_TD(curthread)) \
+ audit_arg_upath1_canon((upath)); \
+} while (0)
+
#define AUDIT_ARG_UPATH2(td, dirfd, upath) do { \
if (AUDITING_TD(curthread)) \
audit_arg_upath2((td), (dirfd), (upath)); \
} while (0)
+#define AUDIT_ARG_UPATH2_CANON(upath) do { \
+ if (AUDITING_TD(curthread)) \
+ audit_arg_upath2_canon((upath)); \
+} while (0)
+
#define AUDIT_ARG_VALUE(value) do { \
if (AUDITING_TD(curthread)) \
audit_arg_value((value)); \
@@ -419,7 +431,9 @@ void audit_thread_free(struct thread *td);
#define AUDIT_ARG_TEXT(text)
#define AUDIT_ARG_UID(uid)
#define AUDIT_ARG_UPATH1(td, dirfd, upath)
+#define AUDIT_ARG_UPATH1_NONCANON(td, upath)
#define AUDIT_ARG_UPATH2(td, dirfd, upath)
+#define AUDIT_ARG_UPATH2_NONCANON(td, upath)
#define AUDIT_ARG_VALUE(value)
#define AUDIT_ARG_VNODE1(vp)
#define AUDIT_ARG_VNODE2(vp)
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index c5da731c4691..0c106bfecbd1 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -766,6 +766,48 @@ audit_arg_upath2(struct thread *td, int dirfd, char *upath)
}
/*
+ * Variants on path auditing that do not canonicalise the path passed in;
+ * these are for use with filesystem-like subsystems that employ string names,
+ * but do not support a hierarchical namespace -- for example, POSIX IPC
+ * objects. The subsystem should have performed any necessary
+ * canonicalisation required to make the paths useful to audit analysis.
+ */
+static void
+audit_arg_upath_canon(char *upath, char **pathp)
+{
+
+ if (*pathp == NULL)
+ *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
+ (void)snprintf(*pathp, MAXPATHLEN, "%s", upath);
+}
+
+void
+audit_arg_upath1_canon(char *upath)
+{
+ struct kaudit_record *ar;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath1);
+ ARG_SET_VALID(ar, ARG_UPATH1);
+}
+
+void
+audit_arg_upath2_canon(char *upath)
+{
+ struct kaudit_record *ar;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ audit_arg_upath_canon(upath, &ar->k_ar.ar_arg_upath2);
+ ARG_SET_VALID(ar, ARG_UPATH2);
+}
+
+/*
* Function to save the path and vnode attr information into the audit
* record.
*