From 2197ab2d9342ec86dee8d80f036f78a3fced3ff7 Mon Sep 17 00:00:00 2001 From: rwatson Date: Wed, 4 May 2005 10:39:15 +0000 Subject: Introduce MAC Framework and MAC Policy entry points to label and control access to POSIX Semaphores: mac_init_posix_sem() Initialize label for POSIX semaphore mac_create_posix_sem() Create POSIX semaphore mac_destroy_posix_sem() Destroy POSIX semaphore mac_check_posix_sem_destroy() Check whether semaphore may be destroyed mac_check_posix_sem_getvalue() Check whether semaphore may be queried mac_check_possix_sem_open() Check whether semaphore may be opened mac_check_posix_sem_post() Check whether semaphore may be posted to mac_check_posix_sem_unlink() Check whether semaphore may be unlinked mac_check_posix_sem_wait() Check whether may wait on semaphore Update Biba, MLS, Stub, and Test policies to implement these entry points. For information flow policies, most semaphore operations are effectively read/write. Submitted by: Dandekar Hrishikesh Sponsored by: DARPA, McAfee, SPARTA Obtained from: TrustedBSD Project --- sys/conf/files | 1 + sys/kern/uipc_sem.c | 65 ++++++++++++-- sys/modules/sem/Makefile | 2 +- sys/posix4/ksem.h | 4 + sys/security/mac/mac_framework.h | 15 ++++ sys/security/mac/mac_policy.h | 21 +++++ sys/security/mac/mac_posix_sem.c | 181 +++++++++++++++++++++++++++++++++++++++ sys/security/mac_biba/mac_biba.c | 59 +++++++++++++ sys/security/mac_mls/mac_mls.c | 59 +++++++++++++ sys/security/mac_stub/mac_stub.c | 66 ++++++++++++++ sys/security/mac_test/mac_test.c | 61 +++++++++++++ sys/sys/ksem.h | 4 + sys/sys/mac.h | 15 ++++ sys/sys/mac_policy.h | 21 +++++ 14 files changed, 564 insertions(+), 10 deletions(-) create mode 100644 sys/security/mac/mac_posix_sem.c diff --git a/sys/conf/files b/sys/conf/files index 19f5c45..5579e4c 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1733,6 +1733,7 @@ security/mac/mac_inet.c optional mac inet security/mac/mac_label.c optional mac security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac +security/mac/mac_posix_sem.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_system.c optional mac diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index ea5dedc..394b6cb 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -1,8 +1,14 @@ /*- * Copyright (c) 2002 Alfred Perlstein + * Copyright (c) 2003-2005 SPARTA, Inc. * Copyright (c) 2005 Robert N. M. Watson * All rights reserved. * + * This software was developed for the FreeBSD Project in part by Network + * Associates Laboratories, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), + * as part of the DARPA CHATS research program. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -28,6 +34,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_mac.h" #include "opt_posix.h" #include @@ -47,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -210,6 +218,10 @@ sem_create(td, name, ksret, mode, value) ret->ks_onlist = 0; cv_init(&ret->ks_cv, "sem"); LIST_INIT(&ret->ks_users); +#ifdef MAC + mac_init_posix_sem(ret); + mac_create_posix_sem(uc, ret); +#endif if (name != NULL) sem_enter(td->td_proc, ret); *ksret = ret; @@ -385,17 +397,20 @@ kern_sem_open(td, dir, name, oflag, mode, value, idp) ksnew->ks_onlist = 1; DP(("sem_create: done, about to unlock...\n")); } - mtx_unlock(&sem_lock); } else { +#ifdef MAC + error = mac_check_posix_sem_open(td->td_ucred, ks); + if (error) + goto err_open; +#endif /* * if we aren't the creator, then enforce permissions. */ error = sem_perm(td, ks); - if (!error) - sem_ref(ks); - mtx_unlock(&sem_lock); if (error) - return (error); + goto err_open; + sem_ref(ks); + mtx_unlock(&sem_lock); id = SEM_TO_ID(ks); if (dir == UIO_USERSPACE) { error = copyout(&id, idp, sizeof(id)); @@ -411,8 +426,9 @@ kern_sem_open(td, dir, name, oflag, mode, value, idp) sem_enter(td->td_proc, ks); mtx_lock(&sem_lock); sem_rel(ks); - mtx_unlock(&sem_lock); } +err_open: + mtx_unlock(&sem_lock); return (error); } @@ -545,10 +561,17 @@ kern_sem_unlink(td, name) mtx_lock(&sem_lock); ks = sem_lookup_byname(name); - if (ks == NULL) - error = ENOENT; - else + if (ks != NULL) { +#ifdef MAC + error = mac_check_posix_sem_unlink(td->td_ucred, ks); + if (error) { + mtx_unlock(&sem_lock); + return (error); + } +#endif error = sem_perm(td, ks); + } else + error = ENOENT; DP(("sem_unlink: '%s' ks = %p, error = %d\n", name, ks, error)); if (error == 0) { LIST_REMOVE(ks, ks_entry); @@ -620,6 +643,11 @@ kern_sem_post(td, id) error = EINVAL; goto err; } +#ifdef MAC + error = mac_check_posix_sem_post(td->td_ucred, ks); + if (error) + goto err; +#endif if (ks->ks_value == SEM_VALUE_MAX) { error = EOVERFLOW; goto err; @@ -720,6 +748,13 @@ kern_sem_wait(td, id, tryflag, abstime) error = EINVAL; goto err; } +#ifdef MAC + error = mac_check_posix_sem_wait(td->td_ucred, ks); + if (error) { + DP(("kern_sem_wait mac failed\n")); + goto err; + } +#endif DP(("kern_sem_wait value = %d, tryflag %d\n", ks->ks_value, tryflag)); if (ks->ks_value == 0) { ks->ks_waiters++; @@ -778,6 +813,13 @@ ksem_getvalue(td, uap) mtx_unlock(&sem_lock); return (EINVAL); } +#ifdef MAC + error = mac_check_posix_sem_getvalue(td->td_ucred, ks); + if (error) { + mtx_unlock(&sem_lock); + return (error); + } +#endif val = ks->ks_value; mtx_unlock(&sem_lock); error = copyout(&val, uap->val, sizeof(val)); @@ -805,6 +847,11 @@ ksem_destroy(td, uap) error = EINVAL; goto err; } +#ifdef MAC + error = mac_check_posix_sem_destroy(td->td_ucred, ks); + if (error) + goto err; +#endif if (ks->ks_waiters != 0) { error = EBUSY; goto err; diff --git a/sys/modules/sem/Makefile b/sys/modules/sem/Makefile index 0a1dba5..8b88444 100644 --- a/sys/modules/sem/Makefile +++ b/sys/modules/sem/Makefile @@ -3,6 +3,6 @@ .PATH: ${.CURDIR}/../../kern KMOD= sem -SRCS= uipc_sem.c opt_posix.h +SRCS= uipc_sem.c opt_mac.h opt_posix.h .include diff --git a/sys/posix4/ksem.h b/sys/posix4/ksem.h index 29b0a53..71979da 100644 --- a/sys/posix4/ksem.h +++ b/sys/posix4/ksem.h @@ -33,6 +33,9 @@ #error "no user-servicable parts inside" #endif +#include +#include + struct kuser { pid_t ku_pid; LIST_ENTRY(kuser) ku_next; @@ -50,6 +53,7 @@ struct ksem { struct cv ks_cv; /* waiters sleep here */ int ks_waiters; /* number of waiters */ LIST_HEAD(, kuser) ks_users; /* pids using this sem */ + struct label *ks_label; /* MAC label */ }; #endif /* !_POSIX4_KSEM_H_ */ diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 8e5037a..38c85ff 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -116,6 +116,7 @@ struct inpcb; struct image_params; struct inpcb; struct ipq; +struct ksem; struct m_tag; struct mbuf; struct mount; @@ -155,6 +156,7 @@ void mac_init_sysv_shm(struct shmid_kernel*); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipepair *); +void mac_init_posix_sem(struct ksem *); int mac_init_mbuf(struct mbuf *mbuf, int flag); int mac_init_mbuf_tag(struct m_tag *, int flag); void mac_init_mount(struct mount *); @@ -174,6 +176,7 @@ void mac_destroy_sysv_shm(struct shmid_kernel *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipepair *); +void mac_destroy_posix_sem(struct ksem *); void mac_destroy_proc(struct proc *); void mac_destroy_mbuf_tag(struct m_tag *); void mac_destroy_mount(struct mount *); @@ -233,6 +236,12 @@ void mac_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr); /* + * Labeling event operations: POSIX (global/inter-process) semaphores. + */ +void mac_create_posix_sem(struct ucred *cred, struct ksem *ksemptr); + + +/* * Labeling event operations: network objects. */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); @@ -329,6 +338,12 @@ int mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_read(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_write(struct ucred *cred, struct pipepair *pp); +int mac_check_posix_sem_destroy(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_getvalue(struct ucred *cred,struct ksem *ksemptr); +int mac_check_posix_sem_open(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_post(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_unlink(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_wait(struct ucred *cred, struct ksem *ksemptr); int mac_check_proc_debug(struct ucred *cred, struct proc *proc); int mac_check_proc_sched(struct ucred *cred, struct proc *proc); int mac_check_proc_setuid(struct proc *proc, struct ucred *cred, diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index e519cb3..cb4ff1c 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -59,6 +59,7 @@ struct ifnet; struct image_params; struct inpcb; struct ipq; +struct ksem; struct label; struct mac_policy_conf; struct mbuf; @@ -114,6 +115,7 @@ struct mac_policy_ops { int (*mpo_init_socket_label)(struct label *label, int flag); int (*mpo_init_socket_peer_label)(struct label *label, int flag); void (*mpo_init_pipe_label)(struct label *label); + void (*mpo_init_posix_sem_label)(struct label *label); void (*mpo_init_proc_label)(struct label *label); void (*mpo_init_vnode_label)(struct label *label); void (*mpo_destroy_bpfdesc_label)(struct label *label); @@ -132,6 +134,7 @@ struct mac_policy_ops { void (*mpo_destroy_socket_label)(struct label *label); void (*mpo_destroy_socket_peer_label)(struct label *label); void (*mpo_destroy_pipe_label)(struct label *label); + void (*mpo_destroy_posix_sem_label)(struct label *label); void (*mpo_destroy_proc_label)(struct label *label); void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_cleanup_sysv_msgmsg)(struct label *msglabel); @@ -253,6 +256,12 @@ struct mac_policy_ops { struct shmid_kernel *shmsegptr, struct label *shmlabel); /* + * Labeling event operations: POSIX (global/inter-process) semaphores. + */ + void (*mpo_create_posix_sem)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + + /* * Labeling event operations: network objects. */ void (*mpo_create_bpfdesc)(struct ucred *cred, struct bpf_d *bpf_d, @@ -404,6 +413,18 @@ struct mac_policy_ops { struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_write)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); + int (*mpo_check_posix_sem_destroy)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_getvalue)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_open)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_post)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_unlink)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_wait)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); int (*mpo_check_proc_debug)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_sched)(struct ucred *cred, diff --git a/sys/security/mac/mac_posix_sem.c b/sys/security/mac/mac_posix_sem.c new file mode 100644 index 0000000..7304bb25 --- /dev/null +++ b/sys/security/mac/mac_posix_sem.c @@ -0,0 +1,181 @@ +/*- + * Copyright (c) 2003-2005 SPARTA, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project in part by Network + * Associates Laboratories, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), + * as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_mac.h" +#include "opt_posix.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +static int mac_enforce_posix_sem = 1; +SYSCTL_INT(_security_mac, OID_AUTO, enforce_posix_sem, CTLFLAG_RW, + &mac_enforce_posix_sem, 0, "Enforce MAC policy on global POSIX semaphores"); +TUNABLE_INT("security.mac.enforce_posix_sem", &mac_enforce_posix_sem); + +#ifdef MAC_DEBUG +static unsigned int nmacposixsems; +SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, posix_sems, CTLFLAG_RD, + &nmacposixsems, 0, "number of posix global semaphores inuse"); +#endif + +static struct label * +mac_posix_sem_label_alloc(void) +{ + struct label *label; + + label = mac_labelzone_alloc(M_WAITOK); + MAC_PERFORM(init_posix_sem_label, label); + MAC_DEBUG_COUNTER_INC(&nmacposixsems); + return (label); +} + +void +mac_init_posix_sem(struct ksem *ksemptr) +{ + + ksemptr->ks_label = mac_posix_sem_label_alloc(); +} + +static void +mac_posix_sem_label_free(struct label *label) +{ + + MAC_PERFORM(destroy_posix_sem_label, label); + MAC_DEBUG_COUNTER_DEC(&nmacposixsems); +} + +void +mac_destroy_posix_sem(struct ksem *ksemptr) +{ + + mac_posix_sem_label_free(ksemptr->ks_label); + ksemptr->ks_label = NULL; +} + +void +mac_create_posix_sem(struct ucred *cred, struct ksem *ksemptr) +{ + + MAC_PERFORM(create_posix_sem, cred, ksemptr, ksemptr->ks_label); +} + +int +mac_check_posix_sem_destroy(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_destroy, cred, ksemptr, ksemptr->ks_label); + + return(error); +} + +int +mac_check_posix_sem_open(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_open, cred, ksemptr, ksemptr->ks_label); + + return(error); +} + +int +mac_check_posix_sem_getvalue(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_getvalue, cred, ksemptr, + ksemptr->ks_label); + + return(error); +} + +int +mac_check_posix_sem_post(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_post, cred, ksemptr, ksemptr->ks_label); + + return(error); +} + +int +mac_check_posix_sem_unlink(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_unlink, cred, ksemptr, ksemptr->ks_label); + + return(error); +} + +int +mac_check_posix_sem_wait(struct ucred *cred, struct ksem *ksemptr) +{ + int error; + + if (!mac_enforce_posix_sem) + return (0); + + MAC_CHECK(check_posix_sem_wait, cred, ksemptr, ksemptr->ks_label); + + return(error); +} diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index 1ff1f0f..b1c7900 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -65,6 +65,8 @@ #include #include +#include + #include #include @@ -1035,6 +1037,18 @@ mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp, } static void +mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_biba *source, *dest; + + source = SLOT(cred->cr_label); + dest = SLOT(ks_label); + + mac_biba_copy_effective(source, dest); +} + +static void mac_biba_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) @@ -2088,6 +2102,42 @@ mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, } static int +mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_biba *subj, *obj; + + if (!mac_biba_enabled) + return (0); + + subj = SLOT(cred->cr_label); + obj = SLOT(ks_label); + + if (!mac_biba_dominate_effective(subj, obj)) + return (EACCES); + + return (0); +} + +static int +mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_biba *subj, *obj; + + if (!mac_biba_enabled) + return (0); + + subj = SLOT(cred->cr_label); + obj = SLOT(ks_label); + + if (!mac_biba_dominate_effective(obj, subj)) + return (EACCES); + + return (0); +} + +static int mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) { struct mac_biba *subj, *obj; @@ -3014,6 +3064,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_init_mount_label = mac_biba_init_label, .mpo_init_mount_fs_label = mac_biba_init_label, .mpo_init_pipe_label = mac_biba_init_label, + .mpo_init_posix_sem_label = mac_biba_init_label, .mpo_init_socket_label = mac_biba_init_label_waitcheck, .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, .mpo_init_vnode_label = mac_biba_init_label, @@ -3031,6 +3082,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_destroy_mount_label = mac_biba_destroy_label, .mpo_destroy_mount_fs_label = mac_biba_destroy_label, .mpo_destroy_pipe_label = mac_biba_destroy_label, + .mpo_destroy_posix_sem_label = mac_biba_destroy_label, .mpo_destroy_socket_label = mac_biba_destroy_label, .mpo_destroy_socket_peer_label = mac_biba_destroy_label, .mpo_destroy_vnode_label = mac_biba_destroy_label, @@ -3065,6 +3117,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, .mpo_create_pipe = mac_biba_create_pipe, + .mpo_create_posix_sem = mac_biba_create_posix_sem, .mpo_create_socket = mac_biba_create_socket, .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, .mpo_relabel_pipe = mac_biba_relabel_pipe, @@ -3126,6 +3179,12 @@ static struct mac_policy_ops mac_biba_ops = .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, .mpo_check_pipe_stat = mac_biba_check_pipe_stat, .mpo_check_pipe_write = mac_biba_check_pipe_write, + .mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write, + .mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly, + .mpo_check_posix_sem_open = mac_biba_check_posix_sem_write, + .mpo_check_posix_sem_post = mac_biba_check_posix_sem_write, + .mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write, + .mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write, .mpo_check_proc_debug = mac_biba_check_proc_debug, .mpo_check_proc_sched = mac_biba_check_proc_sched, .mpo_check_proc_signal = mac_biba_check_proc_signal, diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index fb0c2a5..c1ef756 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -65,6 +65,8 @@ #include #include +#include + #include #include @@ -1004,6 +1006,18 @@ mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp, } static void +mac_mls_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_mls *source, *dest; + + source = SLOT(cred->cr_label); + dest = SLOT(ks_label); + + mac_mls_copy_effective(source, dest); +} + +static void mac_mls_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) @@ -1975,6 +1989,42 @@ mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp, } static int +mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_mls *subj, *obj; + + if (!mac_mls_enabled) + return (0); + + subj = SLOT(cred->cr_label); + obj = SLOT(ks_label); + + if (!mac_mls_dominate_effective(obj, subj)) + return (EACCES); + + return (0); +} + +static int +mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + struct mac_mls *subj, *obj; + + if (!mac_mls_enabled) + return (0); + + subj = SLOT(cred->cr_label); + obj = SLOT(ks_label); + + if (!mac_mls_dominate_effective(subj, obj)) + return (EACCES); + + return (0); +} + +static int mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) { struct mac_mls *subj, *obj; @@ -2788,6 +2838,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_init_mount_label = mac_mls_init_label, .mpo_init_mount_fs_label = mac_mls_init_label, .mpo_init_pipe_label = mac_mls_init_label, + .mpo_init_posix_sem_label = mac_mls_init_label, .mpo_init_socket_label = mac_mls_init_label_waitcheck, .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck, .mpo_init_vnode_label = mac_mls_init_label, @@ -2805,6 +2856,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_destroy_mount_label = mac_mls_destroy_label, .mpo_destroy_mount_fs_label = mac_mls_destroy_label, .mpo_destroy_pipe_label = mac_mls_destroy_label, + .mpo_destroy_posix_sem_label = mac_mls_destroy_label, .mpo_destroy_socket_label = mac_mls_destroy_label, .mpo_destroy_socket_peer_label = mac_mls_destroy_label, .mpo_destroy_vnode_label = mac_mls_destroy_label, @@ -2839,6 +2891,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr, .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket, .mpo_create_pipe = mac_mls_create_pipe, + .mpo_create_posix_sem = mac_mls_create_posix_sem, .mpo_create_socket = mac_mls_create_socket, .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket, .mpo_relabel_pipe = mac_mls_relabel_pipe, @@ -2898,6 +2951,12 @@ static struct mac_policy_ops mac_mls_ops = .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel, .mpo_check_pipe_stat = mac_mls_check_pipe_stat, .mpo_check_pipe_write = mac_mls_check_pipe_write, + .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write, + .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly, + .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write, + .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write, + .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write, + .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write, .mpo_check_proc_debug = mac_mls_check_proc_debug, .mpo_check_proc_sched = mac_mls_check_proc_sched, .mpo_check_proc_signal = mac_mls_check_proc_signal, diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index 64a06d9..0581247 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -63,6 +63,8 @@ #include #include +#include + #include #include @@ -273,6 +275,13 @@ stub_create_pipe(struct ucred *cred, struct pipepair *pp, } static void +stub_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + +} + +static void stub_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) @@ -821,6 +830,54 @@ stub_check_pipe_write(struct ucred *cred, struct pipepair *pp, } static int +stub_check_posix_sem_destroy(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int +stub_check_posix_sem_getvalue(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int +stub_check_posix_sem_open(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int +stub_check_posix_sem_post(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int +stub_check_posix_sem_unlink(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int +stub_check_posix_sem_wait(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + return (0); +} + +static int stub_check_proc_debug(struct ucred *cred, struct proc *proc) { @@ -1326,6 +1383,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_init_mount_label = stub_init_label, .mpo_init_mount_fs_label = stub_init_label, .mpo_init_pipe_label = stub_init_label, + .mpo_init_posix_sem_label = stub_init_label, .mpo_init_socket_label = stub_init_label_waitcheck, .mpo_init_socket_peer_label = stub_init_label_waitcheck, .mpo_init_vnode_label = stub_init_label, @@ -1343,6 +1401,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_destroy_mount_label = stub_destroy_label, .mpo_destroy_mount_fs_label = stub_destroy_label, .mpo_destroy_pipe_label = stub_destroy_label, + .mpo_destroy_posix_sem_label = stub_destroy_label, .mpo_destroy_socket_label = stub_destroy_label, .mpo_destroy_socket_peer_label = stub_destroy_label, .mpo_destroy_vnode_label = stub_destroy_label, @@ -1381,6 +1440,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_update_devfsdirent = stub_update_devfsdirent, .mpo_create_mbuf_from_socket = stub_create_mbuf_from_socket, .mpo_create_pipe = stub_create_pipe, + .mpo_create_posix_sem = stub_create_posix_sem, .mpo_create_socket = stub_create_socket, .mpo_create_socket_from_socket = stub_create_socket_from_socket, .mpo_relabel_pipe = stub_relabel_pipe, @@ -1451,6 +1511,12 @@ static struct mac_policy_ops mac_stub_ops = .mpo_check_pipe_relabel = stub_check_pipe_relabel, .mpo_check_pipe_stat = stub_check_pipe_stat, .mpo_check_pipe_write = stub_check_pipe_write, + .mpo_check_posix_sem_destroy = stub_check_posix_sem_destroy, + .mpo_check_posix_sem_getvalue = stub_check_posix_sem_getvalue, + .mpo_check_posix_sem_open = stub_check_posix_sem_open, + .mpo_check_posix_sem_post = stub_check_posix_sem_post, + .mpo_check_posix_sem_unlink = stub_check_posix_sem_unlink, + .mpo_check_posix_sem_wait = stub_check_posix_sem_wait, .mpo_check_proc_debug = stub_check_proc_debug, .mpo_check_proc_sched = stub_check_proc_sched, .mpo_check_proc_setuid = stub_check_proc_setuid, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index b2fa853..735a643 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -62,6 +62,8 @@ #include #include +#include + #include #include @@ -130,6 +132,8 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, enabled, CTLFLAG_RW, SLOT(x) == 0, ("%s: Bad SYSVIPCSHM label", __func__ )) #define ASSERT_PIPE_LABEL(x) KASSERT(SLOT(x) == PIPEMAGIC || \ SLOT(x) == 0, ("%s: Bad PIPE label", __func__ )) +#define ASSERT_POSIX_LABEL(x) KASSERT(SLOT(x) == POSIXSEMMAGIC || \ + SLOT(x) == 0, ("%s: Bad POSIX ksem label", __func__ )) #define ASSERT_PROC_LABEL(x) KASSERT(SLOT(x) == PROCMAGIC || \ SLOT(x) == 0, ("%s: Bad PROC label", __func__ )) #define ASSERT_CRED_LABEL(x) KASSERT(SLOT(x) == CREDMAGIC || \ @@ -190,6 +194,9 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_socket_peerlabel, static int init_count_pipe; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_pipe, CTLFLAG_RD, &init_count_pipe, 0, "pipe init calls"); +static int init_count_posixsems; +SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_posixsems, CTLFLAG_RD, + &init_count_posixsems, 0, "posix sems init calls"); static int init_count_proc; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_proc, CTLFLAG_RD, &init_count_proc, 0, "proc init calls"); @@ -247,6 +254,9 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_socket_peerlabel, static int destroy_count_pipe; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_pipe, CTLFLAG_RD, &destroy_count_pipe, 0, "pipe destroy calls"); +static int destroy_count_posixsems; +SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_posixsems, CTLFLAG_RD, + &destroy_count_posixsems, 0, "posix sems destroy calls"); static int destroy_count_proc; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_proc, CTLFLAG_RD, &destroy_count_proc, 0, "proc destroy calls"); @@ -447,6 +457,14 @@ mac_test_init_pipe_label(struct label *label) } static void +mac_test_init_posix_sem_label(struct label *label) +{ + + SLOT(label) = POSIXSEMMAGIC; + atomic_add_int(&init_count_posixsems, 1); +} + +static void mac_test_init_proc_label(struct label *label) { @@ -697,6 +715,20 @@ mac_test_destroy_pipe_label(struct label *label) } static void +mac_test_destroy_posix_sem_label(struct label *label) +{ + + if ((SLOT(label) == POSIXSEMMAGIC || SLOT(label) == 0)) { + atomic_add_int(&destroy_count_posixsems, 1); + SLOT(label) = EXMAGIC; + } else if (SLOT(label) == EXMAGIC) { + DEBUGGER("mac_test_destroy_posix_sem: dup destroy"); + } else { + DEBUGGER("mac_test_destroy_posix_sem: corrupted label"); + } +} + +static void mac_test_destroy_proc_label(struct label *label) { @@ -954,6 +986,15 @@ mac_test_create_pipe(struct ucred *cred, struct pipepair *pp, } static void +mac_test_create_posix_sem(struct ucred *cred, struct ksem *ksem, + struct label *posixlabel) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_POSIX_LABEL(posixlabel); +} + +static void mac_test_create_socket_from_socket(struct socket *oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label *newsocketlabel) @@ -1677,6 +1718,17 @@ mac_test_check_pipe_write(struct ucred *cred, struct pipepair *pp, } static int +mac_test_check_posix_sem(struct ucred *cred, struct ksem *ksemptr, + struct label *ks_label) +{ + + ASSERT_CRED_LABEL(cred->cr_label); + ASSERT_POSIX_LABEL(ks_label); + + return (0); +} + +static int mac_test_check_proc_debug(struct ucred *cred, struct proc *proc) { @@ -2377,6 +2429,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_init_mount_label = mac_test_init_mount_label, .mpo_init_mount_fs_label = mac_test_init_mount_fs_label, .mpo_init_pipe_label = mac_test_init_pipe_label, + .mpo_init_posix_sem_label = mac_test_init_posix_sem_label, .mpo_init_proc_label = mac_test_init_proc_label, .mpo_init_socket_label = mac_test_init_socket_label, .mpo_init_socket_peer_label = mac_test_init_socket_peer_label, @@ -2396,6 +2449,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_destroy_mount_label = mac_test_destroy_mount_label, .mpo_destroy_mount_fs_label = mac_test_destroy_mount_fs_label, .mpo_destroy_pipe_label = mac_test_destroy_pipe_label, + .mpo_destroy_posix_sem_label = mac_test_destroy_posix_sem_label, .mpo_destroy_proc_label = mac_test_destroy_proc_label, .mpo_destroy_socket_label = mac_test_destroy_socket_label, .mpo_destroy_socket_peer_label = mac_test_destroy_socket_peer_label, @@ -2431,6 +2485,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_update_devfsdirent = mac_test_update_devfsdirent, .mpo_create_mbuf_from_socket = mac_test_create_mbuf_from_socket, .mpo_create_pipe = mac_test_create_pipe, + .mpo_create_posix_sem = mac_test_create_posix_sem, .mpo_create_socket = mac_test_create_socket, .mpo_create_socket_from_socket = mac_test_create_socket_from_socket, .mpo_relabel_pipe = mac_test_relabel_pipe, @@ -2504,6 +2559,12 @@ static struct mac_policy_ops mac_test_ops = .mpo_check_pipe_relabel = mac_test_check_pipe_relabel, .mpo_check_pipe_stat = mac_test_check_pipe_stat, .mpo_check_pipe_write = mac_test_check_pipe_write, + .mpo_check_posix_sem_destroy = mac_test_check_posix_sem, + .mpo_check_posix_sem_getvalue = mac_test_check_posix_sem, + .mpo_check_posix_sem_open = mac_test_check_posix_sem, + .mpo_check_posix_sem_post = mac_test_check_posix_sem, + .mpo_check_posix_sem_unlink = mac_test_check_posix_sem, + .mpo_check_posix_sem_wait = mac_test_check_posix_sem, .mpo_check_proc_debug = mac_test_check_proc_debug, .mpo_check_proc_sched = mac_test_check_proc_sched, .mpo_check_proc_setuid = mac_test_check_proc_setuid, diff --git a/sys/sys/ksem.h b/sys/sys/ksem.h index 29b0a53..71979da 100644 --- a/sys/sys/ksem.h +++ b/sys/sys/ksem.h @@ -33,6 +33,9 @@ #error "no user-servicable parts inside" #endif +#include +#include + struct kuser { pid_t ku_pid; LIST_ENTRY(kuser) ku_next; @@ -50,6 +53,7 @@ struct ksem { struct cv ks_cv; /* waiters sleep here */ int ks_waiters; /* number of waiters */ LIST_HEAD(, kuser) ks_users; /* pids using this sem */ + struct label *ks_label; /* MAC label */ }; #endif /* !_POSIX4_KSEM_H_ */ diff --git a/sys/sys/mac.h b/sys/sys/mac.h index 8e5037a..38c85ff 100644 --- a/sys/sys/mac.h +++ b/sys/sys/mac.h @@ -116,6 +116,7 @@ struct inpcb; struct image_params; struct inpcb; struct ipq; +struct ksem; struct m_tag; struct mbuf; struct mount; @@ -155,6 +156,7 @@ void mac_init_sysv_shm(struct shmid_kernel*); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipepair *); +void mac_init_posix_sem(struct ksem *); int mac_init_mbuf(struct mbuf *mbuf, int flag); int mac_init_mbuf_tag(struct m_tag *, int flag); void mac_init_mount(struct mount *); @@ -174,6 +176,7 @@ void mac_destroy_sysv_shm(struct shmid_kernel *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipepair *); +void mac_destroy_posix_sem(struct ksem *); void mac_destroy_proc(struct proc *); void mac_destroy_mbuf_tag(struct m_tag *); void mac_destroy_mount(struct mount *); @@ -233,6 +236,12 @@ void mac_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr); /* + * Labeling event operations: POSIX (global/inter-process) semaphores. + */ +void mac_create_posix_sem(struct ucred *cred, struct ksem *ksemptr); + + +/* * Labeling event operations: network objects. */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); @@ -329,6 +338,12 @@ int mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_read(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp); int mac_check_pipe_write(struct ucred *cred, struct pipepair *pp); +int mac_check_posix_sem_destroy(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_getvalue(struct ucred *cred,struct ksem *ksemptr); +int mac_check_posix_sem_open(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_post(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_unlink(struct ucred *cred, struct ksem *ksemptr); +int mac_check_posix_sem_wait(struct ucred *cred, struct ksem *ksemptr); int mac_check_proc_debug(struct ucred *cred, struct proc *proc); int mac_check_proc_sched(struct ucred *cred, struct proc *proc); int mac_check_proc_setuid(struct proc *proc, struct ucred *cred, diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index e519cb3..cb4ff1c 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -59,6 +59,7 @@ struct ifnet; struct image_params; struct inpcb; struct ipq; +struct ksem; struct label; struct mac_policy_conf; struct mbuf; @@ -114,6 +115,7 @@ struct mac_policy_ops { int (*mpo_init_socket_label)(struct label *label, int flag); int (*mpo_init_socket_peer_label)(struct label *label, int flag); void (*mpo_init_pipe_label)(struct label *label); + void (*mpo_init_posix_sem_label)(struct label *label); void (*mpo_init_proc_label)(struct label *label); void (*mpo_init_vnode_label)(struct label *label); void (*mpo_destroy_bpfdesc_label)(struct label *label); @@ -132,6 +134,7 @@ struct mac_policy_ops { void (*mpo_destroy_socket_label)(struct label *label); void (*mpo_destroy_socket_peer_label)(struct label *label); void (*mpo_destroy_pipe_label)(struct label *label); + void (*mpo_destroy_posix_sem_label)(struct label *label); void (*mpo_destroy_proc_label)(struct label *label); void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_cleanup_sysv_msgmsg)(struct label *msglabel); @@ -253,6 +256,12 @@ struct mac_policy_ops { struct shmid_kernel *shmsegptr, struct label *shmlabel); /* + * Labeling event operations: POSIX (global/inter-process) semaphores. + */ + void (*mpo_create_posix_sem)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + + /* * Labeling event operations: network objects. */ void (*mpo_create_bpfdesc)(struct ucred *cred, struct bpf_d *bpf_d, @@ -404,6 +413,18 @@ struct mac_policy_ops { struct pipepair *pp, struct label *pipelabel); int (*mpo_check_pipe_write)(struct ucred *cred, struct pipepair *pp, struct label *pipelabel); + int (*mpo_check_posix_sem_destroy)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_getvalue)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_open)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_post)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_unlink)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); + int (*mpo_check_posix_sem_wait)(struct ucred *cred, + struct ksem *ksemptr, struct label *ks_label); int (*mpo_check_proc_debug)(struct ucred *cred, struct proc *proc); int (*mpo_check_proc_sched)(struct ucred *cred, -- cgit v1.1