aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.
*