Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Mar 2017 13:43:00 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r316332 - in head/sys: kern security/audit
Message-ID:  <201703311343.v2VDh0NJ074438@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Fri Mar 31 13:43:00 2017
New Revision: 316332
URL: https://svnweb.freebsd.org/changeset/base/316332

Log:
  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

Modified:
  head/sys/kern/uipc_mqueue.c
  head/sys/kern/uipc_sem.c
  head/sys/kern/uipc_shm.c
  head/sys/security/audit/audit.h
  head/sys/security/audit/audit_arg.c

Modified: head/sys/kern/uipc_mqueue.c
==============================================================================
--- head/sys/kern/uipc_mqueue.c	Fri Mar 31 11:40:59 2017	(r316331)
+++ head/sys/kern/uipc_mqueue.c	Fri Mar 31 13:43:00 2017	(r316332)
@@ -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 c
 	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 c
 	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
 	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 
 	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, 
 	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, str
 	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 m
 	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 *t
 	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
 	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);

Modified: head/sys/kern/uipc_sem.c
==============================================================================
--- head/sys/kern/uipc_sem.c	Fri Mar 31 11:40:59 2017	(r316331)
+++ head/sys/kern/uipc_sem.c	Fri Mar 31 13:43:00 2017	(r316332)
@@ -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 cha
 	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 cha
 			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, struc
 		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
 	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 
 	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
 	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, str
 	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, stru
 	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);

Modified: head/sys/kern/uipc_shm.c
==============================================================================
--- head/sys/kern/uipc_shm.c	Fri Mar 31 11:40:59 2017	(r316331)
+++ head/sys/kern/uipc_shm.c	Fri Mar 31 13:43:00 2017	(r316332)
@@ -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 c
 		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 c
 			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
 	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);

Modified: head/sys/security/audit/audit.h
==============================================================================
--- head/sys/security/audit/audit.h	Fri Mar 31 11:40:59 2017	(r316331)
+++ head/sys/security/audit/audit.h	Fri Mar 31 13:43:00 2017	(r316332)
@@ -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 *t
 		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 *t
 #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)

Modified: head/sys/security/audit/audit_arg.c
==============================================================================
--- head/sys/security/audit/audit_arg.c	Fri Mar 31 11:40:59 2017	(r316331)
+++ head/sys/security/audit/audit_arg.c	Fri Mar 31 13:43:00 2017	(r316332)
@@ -766,6 +766,48 @@ audit_arg_upath2(struct thread *td, int 
 }
 
 /*
+ * 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.
  *



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703311343.v2VDh0NJ074438>