diff options
-rw-r--r-- | sys/kern/uipc_mqueue.c | 19 | ||||
-rw-r--r-- | sys/kern/uipc_sem.c | 19 | ||||
-rw-r--r-- | sys/kern/uipc_shm.c | 13 | ||||
-rw-r--r-- | sys/security/audit/audit.h | 14 | ||||
-rw-r--r-- | sys/security/audit/audit_arg.c | 42 |
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. * |