From bdafd84660c26924f39b67ef1ab7c2814f47367d Mon Sep 17 00:00:00 2001 From: rwatson Date: Tue, 3 Dec 2002 15:12:36 +0000 Subject: [PATCH] Unhook the old LOMAC module, now replaced with mac_lomac. Approved by: re (jhb) Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories --- sys/modules/Makefile | 2 - sys/modules/lomac/Makefile | 41 - sys/modules/lomac/Makefile.inc | 3 - sys/modules/lomac/plm/Makefile | 14 - sys/modules/lomac/syscall_gate/Makefile | 13 - sys/security/lomac/kernel_interface.c | 506 ---------- sys/security/lomac/kernel_interface.h | 101 -- sys/security/lomac/kernel_lkm.c | 286 ------ sys/security/lomac/kernel_log.c | 206 ---- sys/security/lomac/kernel_log.h | 77 -- sys/security/lomac/kernel_mediate.c | 289 ------ sys/security/lomac/kernel_mediate.h | 68 -- sys/security/lomac/kernel_mmap.c | 591 ------------ sys/security/lomac/kernel_monitor.c | 206 ---- sys/security/lomac/kernel_monitor.h | 62 -- sys/security/lomac/kernel_pipe.c | 241 ----- sys/security/lomac/kernel_pipe.h | 44 - sys/security/lomac/kernel_plm.c | 382 -------- sys/security/lomac/kernel_plm.h | 45 - sys/security/lomac/kernel_socket.c | 813 ---------------- sys/security/lomac/kernel_socket.h | 45 - sys/security/lomac/kernel_util.c | 696 -------------- sys/security/lomac/kernel_util.h | 64 -- sys/security/lomac/lomac.h | 114 --- sys/security/lomac/lomacfs.h | 115 --- sys/security/lomac/lomacfs_subr.c | 127 --- sys/security/lomac/lomacfs_vfsops.c | 199 ---- sys/security/lomac/lomacfs_vnops.c | 1151 ----------------------- sys/security/lomac/lomacio.h | 59 -- sys/security/lomac/policy_plm.h | 119 --- sys/security/lomac/syscall_gate.c | 125 --- sys/security/lomac/syscall_gate.h | 56 -- 32 files changed, 6860 deletions(-) delete mode 100644 sys/modules/lomac/Makefile delete mode 100644 sys/modules/lomac/Makefile.inc delete mode 100644 sys/modules/lomac/plm/Makefile delete mode 100644 sys/modules/lomac/syscall_gate/Makefile delete mode 100644 sys/security/lomac/kernel_interface.c delete mode 100644 sys/security/lomac/kernel_interface.h delete mode 100644 sys/security/lomac/kernel_lkm.c delete mode 100644 sys/security/lomac/kernel_log.c delete mode 100644 sys/security/lomac/kernel_log.h delete mode 100644 sys/security/lomac/kernel_mediate.c delete mode 100644 sys/security/lomac/kernel_mediate.h delete mode 100644 sys/security/lomac/kernel_mmap.c delete mode 100644 sys/security/lomac/kernel_monitor.c delete mode 100644 sys/security/lomac/kernel_monitor.h delete mode 100644 sys/security/lomac/kernel_pipe.c delete mode 100644 sys/security/lomac/kernel_pipe.h delete mode 100644 sys/security/lomac/kernel_plm.c delete mode 100644 sys/security/lomac/kernel_plm.h delete mode 100644 sys/security/lomac/kernel_socket.c delete mode 100644 sys/security/lomac/kernel_socket.h delete mode 100644 sys/security/lomac/kernel_util.c delete mode 100644 sys/security/lomac/kernel_util.h delete mode 100644 sys/security/lomac/lomac.h delete mode 100644 sys/security/lomac/lomacfs.h delete mode 100644 sys/security/lomac/lomacfs_subr.c delete mode 100644 sys/security/lomac/lomacfs_vfsops.c delete mode 100644 sys/security/lomac/lomacfs_vnops.c delete mode 100644 sys/security/lomac/lomacio.h delete mode 100644 sys/security/lomac/policy_plm.h delete mode 100644 sys/security/lomac/syscall_gate.c delete mode 100644 sys/security/lomac/syscall_gate.h diff --git a/sys/modules/Makefile b/sys/modules/Makefile index b4d69cf8161b..ff6b0be447d6 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -239,7 +239,6 @@ SUBDIR+=aic \ hea \ hfa \ iir \ - lomac \ mly \ netgraph \ pccard \ @@ -260,7 +259,6 @@ SUBDIR+=aic \ .if ${MACHINE_ARCH} == "alpha" SUBDIR+=linprocfs \ linux \ - lomac \ osf1 \ sound \ sppp \ diff --git a/sys/modules/lomac/Makefile b/sys/modules/lomac/Makefile deleted file mode 100644 index e661792b578d..000000000000 --- a/sys/modules/lomac/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# $FreeBSD$ - -KMOD= lomac -SRCS= vnode_if.h kernel_lkm.c kernel_interface.c kernel_util.c \ - kernel_log.c kernel_mediate.c lomacfs_vfsops.c lomacfs_vnops.c \ - lomacfs_subr.c kernel_monitor.c kernel_mmap.c kernel_pipe.c \ - kernel_socket.c -SUBDIR+= syscall_gate -SUBDIR+= plm -CFLAGS+= -I${.CURDIR}/../../security/lomac -CFLAGS+= -DUSES_LOCKMGR # necessary until VM uses sx locks -#CFLAGS+= -DP_CAN_HOOKS # There are no hooks for p_can*() ops in the -# kernel yet. Until then, all subject-subject -# mediation is effectively "off". -#CFLAGS+= -DLOMAC_DEBUG_LOOKUPSTATS # relatively cheap -#CFLAGS+= -DLOMAC_DEBUG_NODE_ALLOC # pretty verbose -#CFLAGS+= -DLOMAC_DEBUG_LINK # pretty verbose -#CFLAGS+= -DLOMAC_DEBUG_INCNAME # can starve memory -#CFLAGS+= -DLOMAC_DEBUG_INACTIVE # extremely verbose -#CFLAGS+= -DLOMAC_DEBUG_RECLAIM # extremely verbose -#CFLAGS+= -DLOMAC_DEBUG_LOOKUP # extremely verbose -#CFLAGS+= -DLOMAC_DEBUG_PIPE # relatively cheap -#CFLAGS+= -DLOMAC_DEBUG_RECWD # only happens once - -EXPORT_SYMS= YES # XXX evaluate - -.PATH: ${.CURDIR}/../../security/lomac - -load-all: all - @cd ${.CURDIR}/syscall_gate; ${MAKE} load - @cd ${.CURDIR}/plm; ${MAKE} load - @${MAKE} load - -kldunload-binacts: - -/sbin/kldunload linux - -/sbin/kldunload svr4 - -start: kldunload-binacts load-all - -.include "Makefile.inc" -.include diff --git a/sys/modules/lomac/Makefile.inc b/sys/modules/lomac/Makefile.inc deleted file mode 100644 index 265f86d1ed55..000000000000 --- a/sys/modules/lomac/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc" diff --git a/sys/modules/lomac/plm/Makefile b/sys/modules/lomac/plm/Makefile deleted file mode 100644 index 2dac4b871219..000000000000 --- a/sys/modules/lomac/plm/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -KMOD= lomac_plm -SRCS= vnode_if.h kernel_plm.c -CFLAGS+= -I${.CURDIR}/../../../security/lomac - -EXPORT_SYMS= lomac_node_entry_root \ - lomac_plm_init_lomacfs_vnode \ - lomac_plm_initialized - -.PATH: ${.CURDIR}/../../../security/lomac - -.include "../Makefile.inc" -.include diff --git a/sys/modules/lomac/syscall_gate/Makefile b/sys/modules/lomac/syscall_gate/Makefile deleted file mode 100644 index d74fe922468a..000000000000 --- a/sys/modules/lomac/syscall_gate/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# $FreeBSD$ - -KMOD= syscall_gate -SRCS= syscall_gate.c -CFLAGS+= -I${.CURDIR}/../../../security/lomac - -EXPORT_SYMS= syscall_gate_register \ - syscall_gate_deregister - -.PATH: ${.CURDIR}/../../../security/lomac - -.include "../Makefile.inc" -.include diff --git a/sys/security/lomac/kernel_interface.c b/sys/security/lomac/kernel_interface.c deleted file mode 100644 index c4a0c044f366..000000000000 --- a/sys/security/lomac/kernel_interface.c +++ /dev/null @@ -1,506 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kernel_interface.h" -#include "lomacfs.h" -#include "kernel_log.h" - -/* - * Reuse the eflags field of proc.p_vmspace->vm_map.header (since it is - * currently not used for anything but a placeholder, and won't change - * generally...) as storage for our process-based information. - * - * This is the only really effective way to make thread-based MAC - * easy. - */ - -#define p_eflags p_vmspace->vm_map.header.eflags -#define EF_HIGHEST_LEVEL 0x00010000 -#define EF_LOWEST_LEVEL 0x00020000 -#define EF_LEVEL_MASK 0x00030000 -#define EF_ATTR_NONETDEMOTE 0x00040000 -#define EF_ATTR_NODEMOTE 0x00080000 -#define EF_ATTR_MASK 0x000c0000 - -static u_int -level2subjectbits(level_t level) { - - switch (level) { - case LOMAC_HIGHEST_LEVEL: - return (EF_HIGHEST_LEVEL); - case LOMAC_LOWEST_LEVEL: - return (EF_LOWEST_LEVEL); - default: - panic("level2subjectbits: invalid level %d\n", level); - } -} - -static level_t -subjectbits2level(u_int flags) { - - switch (flags & EF_LEVEL_MASK) { - case EF_HIGHEST_LEVEL: - /* - * During an execve(), the kernel's original execve() creates a - * new vmspace and puts it into use before it has been initialized - * by us to contain a subject level. Since this is the only case - * when a subject may have a level not set, pretend that it - * is just a high-level file, and allow the lomacfs_open() to then - * succeed. - */ - case 0: - return (LOMAC_HIGHEST_LEVEL); - case EF_LOWEST_LEVEL: - return (LOMAC_LOWEST_LEVEL); - default: - panic("subjectbits2level: invalid flags %#x\n", flags); - } -} - -static u_int -attr2subjectbits(u_int attr) { - u_int bits = 0; - - if (attr & LOMAC_ATTR_NONETDEMOTE) - bits |= EF_ATTR_NONETDEMOTE; - if (attr & LOMAC_ATTR_NODEMOTE) - bits |= EF_ATTR_NODEMOTE; - return (bits); -} - -static u_int -subjectbits2attr(u_int bits) { - u_int attr = 0; - - if (bits & EF_ATTR_NONETDEMOTE) - attr |= LOMAC_ATTR_NONETDEMOTE; - if (bits & EF_ATTR_NODEMOTE) - attr |= LOMAC_ATTR_NODEMOTE; - return (attr); -} - -static int -subject_lock(lomac_subject_t *p, int read) { -#ifdef USES_LOCKMGR - int hadlock; - - hadlock = PROC_LOCKED(p); - if (hadlock) - PROC_UNLOCK(p); -#endif - if (read) - vm_map_lock_read(&p->p_vmspace->vm_map); - else - vm_map_lock(&p->p_vmspace->vm_map); -#ifdef USES_LOCKMGR - return (hadlock); -#else - return (0); -#endif -} - -static void -subject_unlock(lomac_subject_t *p, int read, int hadlock) { - - if (read) - vm_map_unlock_read(&p->p_vmspace->vm_map); - else - vm_map_unlock(&p->p_vmspace->vm_map); -#ifdef USES_LOCKMGR - if (hadlock) - PROC_LOCK(p); -#endif -} - - -void -init_subject_lattr(lomac_subject_t *p, lattr_t *lattr) { - int s; - - s = subject_lock(p, 0); - p->p_eflags = level2subjectbits(lattr->level) | - attr2subjectbits(lattr->flags); - subject_unlock(p, 0, s); -} - -/* - * Set/get the subject level on a process. The process must not be able - * to change, so either the process must be locked on entry or it must - * be held in exclusivity otherwise (executing on behalf of via a syscall, - * including as EITHER child or parent in a fork). - */ -void -set_subject_lattr(lomac_subject_t *p, lattr_t lattr) { - int s; - -#ifdef INVARIANTS - do { - lattr_t oslattr; - - get_subject_lattr(p, &oslattr); - if (lomac_must_demote(&lattr, &oslattr)) - panic("raising subject level"); - } while (0); -#endif /* !INVARIANTS */ - s = subject_lock(p, 0); - p->p_eflags = (p->p_eflags & ~(EF_LEVEL_MASK | EF_ATTR_MASK)) | - level2subjectbits(lattr.level) | - attr2subjectbits(lattr.flags); - subject_unlock(p, 0, s); - kernel_vm_drop_perms(curthread, &lattr); -} - -void -get_subject_lattr(lomac_subject_t *p, lattr_t *lattr) { - int s; - - s = subject_lock(p, 1); - lattr->level = subjectbits2level(p->p_eflags); - lattr->flags = subjectbits2attr(p->p_eflags); - subject_unlock(p, 1, s); -} - -static __inline u_int -level2lvnodebits(level_t level) { - - switch (level) { - case LOMAC_HIGHEST_LEVEL: - return (LN_HIGHEST_LEVEL); - case LOMAC_LOWEST_LEVEL: - return (LN_LOWEST_LEVEL); - default: - panic("level2lvnodebits: invalid level %d\n", level); - } -} - -static __inline level_t -lvnodebits2level(u_int flags) { - - switch (flags & LN_LEVEL_MASK) { - case LN_HIGHEST_LEVEL: - return (LOMAC_HIGHEST_LEVEL); - case LN_LOWEST_LEVEL: - return (LOMAC_LOWEST_LEVEL); - default: - panic("lvnodebits2level: invalid flags %#x\n", flags); - } -} - -static __inline unsigned int -attr2lvnodebits(unsigned int attr) { - unsigned int bits = 0; - - if (attr & LOMAC_ATTR_LOWWRITE) - bits |= LN_ATTR_LOWWRITE; - if (attr & LOMAC_ATTR_LOWNOOPEN) - bits |= LN_ATTR_LOWNOOPEN; - if (attr & LOMAC_ATTR_NONETDEMOTE) - bits |= LN_ATTR_NONETDEMOTE; - if (attr & LOMAC_ATTR_NODEMOTE) - bits |= LN_ATTR_NODEMOTE; - return (bits); -} - -static __inline unsigned int -lvnodebits2attr(unsigned int bits) { - unsigned int attr = 0; - - if (bits & LN_ATTR_LOWWRITE) - attr |= LOMAC_ATTR_LOWWRITE; - if (bits & LN_ATTR_LOWNOOPEN) - attr |= LOMAC_ATTR_LOWNOOPEN; - if (bits & LN_ATTR_NONETDEMOTE) - attr |= LOMAC_ATTR_NONETDEMOTE; - if (bits & LN_ATTR_NODEMOTE) - attr |= LOMAC_ATTR_NODEMOTE; - return (attr); -} - -/* - * These flags correspond to the same ones set in lomac_node{}s. - */ -#define UV_LEVEL_MASK 0x08000000 -#define UV_LOWEST_LEVEL 0x00000000 -#define UV_HIGHEST_LEVEL 0x08000000 -#define UV_ATTR_LOWWRITE 0x10000000 -#define UV_ATTR_LOWNOOPEN 0x20000000 -#define UV_ATTR_NONETDEMOTE 0x40000000 -#define UV_ATTR_NODEMOTE 0x80000000 -#define UV_ATTR_MASK 0xf0000000 - -static __inline u_int -level2uvnodebits(level_t level) { - - switch (level) { - case LOMAC_HIGHEST_LEVEL: - return (UV_HIGHEST_LEVEL); - case LOMAC_LOWEST_LEVEL: - return (UV_LOWEST_LEVEL); - default: - panic("level2uvnodebits: invalid level %d\n", level); - } -} - -static __inline level_t -uvnodebits2level(u_int flags) { - - switch (flags & UV_LEVEL_MASK) { - case UV_HIGHEST_LEVEL: - return (LOMAC_HIGHEST_LEVEL); - case UV_LOWEST_LEVEL: - return (LOMAC_LOWEST_LEVEL); - default: - panic("uvnodebits2level: invalid flags %#x\n", flags); - } -} - -static __inline u_int -attr2uvnodebits(u_int attr) { - unsigned int bits = 0; - - if (attr & LOMAC_ATTR_LOWWRITE) - bits |= UV_ATTR_LOWWRITE; - if (attr & LOMAC_ATTR_LOWNOOPEN) - bits |= UV_ATTR_LOWNOOPEN; - if (attr & LOMAC_ATTR_NONETDEMOTE) - bits |= UV_ATTR_NONETDEMOTE; - if (attr & LOMAC_ATTR_NODEMOTE) - bits |= UV_ATTR_NODEMOTE; - return (bits); -} - -static __inline u_int -uvnodebits2attr(u_int bits) { - unsigned int attr = 0; - - if (bits & UV_ATTR_LOWWRITE) - attr |= LOMAC_ATTR_LOWWRITE; - if (bits & UV_ATTR_LOWNOOPEN) - attr |= LOMAC_ATTR_LOWNOOPEN; - if (bits & UV_ATTR_NONETDEMOTE) - attr |= LOMAC_ATTR_NONETDEMOTE; - if (bits & UV_ATTR_NODEMOTE) - attr |= LOMAC_ATTR_NODEMOTE; - return (attr); -} - -#define OBJ_LOWEST_LEVEL 0x8000 /* the highest level is implicit */ - -/* - * This code marks pipes with levels. We use a previously unnused bit - * in the pipe_state field of struct pipe to store the level - * information. Bit clear means LOMAC_HIGHEST_LEVEL, bit set means - * LOMAC_LOWEST_LEVEL. Since new pipes have clear bits by default, - * using clear bit as highest causes new pipes to start at the highest - * level automatically. - */ -#define PIPE_LEVEL_LOWEST 0x10000000 - -/* This code marks sockets created by socketpair() with levels. It - * uses a previouslt unused bit in the so_state field of struct socket - * to store the level information. Bit clear means - * LOMAC_HIGHEST_LEVEL, bit set means LOMAC_LOWEST_LEVEL. Since new - * sockets have clear bits by default, using clear bit as highest - * causes new sockets to start at the highest level automatically. - */ -#define SOCKET_LEVEL_LOWEST 0x4000 - -void -set_object_lattr(lomac_object_t *obj, lattr_t lattr) { - struct vnode *vp; - struct lomac_node *ln; - vm_object_t object; - struct pipe *pipe; - struct socket *socket; - - switch (obj->lo_type) { - case LO_TYPE_LVNODE: - KASSERT(VISLOMAC(obj->lo_object.vnode), - ("not a LOMACFS vnode")); - ln = VTOLOMAC(obj->lo_object.vnode); - ln->ln_flags = - (ln->ln_flags & ~(LN_LEVEL_MASK | LN_ATTR_MASK)) | - level2lvnodebits(lattr.level) | - attr2lvnodebits(lattr.flags); - break; - case LO_TYPE_UVNODE: - vp = obj->lo_object.vnode; - KASSERT(!VISLOMAC(vp), ("is a LOMACFS vnode")); - VI_LOCK(vp); - vp->v_iflag = (vp->v_iflag & ~(UV_LEVEL_MASK | UV_ATTR_MASK)) | - level2uvnodebits(lattr.level) | - attr2uvnodebits(lattr.flags); - VI_UNLOCK(vp); - break; - case LO_TYPE_VM_OBJECT: - object = obj->lo_object.vm_object; - KASSERT(object->type != OBJT_VNODE, ("object has a vnode")); - KASSERT(object->backing_object == NULL, - ("is a backing object")); - if (lattr.level == LOMAC_HIGHEST_LEVEL) - vm_object_clear_flag(object, OBJ_LOWEST_LEVEL); - else - vm_object_set_flag(object, OBJ_LOWEST_LEVEL); - KASSERT(lattr.flags == 0, - ("cannot set attr on a vm_object")); - break; - case LO_TYPE_PIPE: - pipe = obj->lo_object.pipe; - KASSERT(pipe->pipe_peer == NULL || - (pipe->pipe_state & PIPE_LEVEL_LOWEST) == - (pipe->pipe_peer->pipe_state & PIPE_LEVEL_LOWEST), - ("pipe attrs unsynchronized")); - if (lattr.level == LOMAC_HIGHEST_LEVEL) - pipe->pipe_state &= ~PIPE_LEVEL_LOWEST; - else - pipe->pipe_state |= PIPE_LEVEL_LOWEST; - pipe = pipe->pipe_peer; - if (pipe != NULL) { - if (lattr.level == LOMAC_HIGHEST_LEVEL) - pipe->pipe_state &= ~PIPE_LEVEL_LOWEST; - else - pipe->pipe_state |= PIPE_LEVEL_LOWEST; - } - KASSERT(lattr.flags == 0, ("cannot set attr on a pipe")); - break; - case LO_TYPE_SOCKETPAIR: - socket = obj->lo_object.socket; - /* KASSERT that socket peer levels are synchronized */ - if (lattr.level == LOMAC_HIGHEST_LEVEL) - socket->so_state &= ~SOCKET_LEVEL_LOWEST; - else - socket->so_state |= SOCKET_LEVEL_LOWEST; -#ifdef NOT_YET - pipe = pipe->pipe_peer; - if (pipe != NULL) { - if (lattr.level == LOMAC_HIGHEST_LEVEL) - pipe->pipe_state &= ~PIPE_LEVEL_LOWEST; - else - pipe->pipe_state |= PIPE_LEVEL_LOWEST; - } - KASSERT(lattr.flags == 0, ("cannot set attr on a pipe")); -#endif - break; - default: - panic("set_object_lattr: invalid lo_type %d", obj->lo_type); - } -} - -void -get_object_lattr(const lomac_object_t *obj, lattr_t *lattr) { - struct vnode *vp; - struct lomac_node *ln; - vm_object_t object; - struct pipe *pipe; - struct socket *socket; - - switch (obj->lo_type) { - case LO_TYPE_LVNODE: - KASSERT(VISLOMAC(obj->lo_object.vnode), - ("not a LOMACFS vnode")); - ln = VTOLOMAC(obj->lo_object.vnode); - lattr->level = lvnodebits2level(ln->ln_flags); - lattr->flags = lvnodebits2attr(ln->ln_flags); - break; - case LO_TYPE_UVNODE: - vp = obj->lo_object.vnode; - KASSERT(!VISLOMAC(vp), ("is a LOMACFS vnode")); - VI_LOCK(vp); - lattr->level = uvnodebits2level(vp->v_iflag); - lattr->flags = uvnodebits2attr(vp->v_iflag); - VI_UNLOCK(vp); - break; - case LO_TYPE_VM_OBJECT: - object = obj->lo_object.vm_object; - KASSERT(object->type != OBJT_VNODE, ("object has a vnode")); - KASSERT(object->backing_object == NULL, - ("is a backing object")); - lattr->level = (object->flags & OBJ_LOWEST_LEVEL) ? - LOMAC_LOWEST_LEVEL : LOMAC_HIGHEST_LEVEL; - lattr->flags = 0; - break; - case LO_TYPE_PIPE: - pipe = obj->lo_object.pipe; - lattr->level = (pipe->pipe_state & PIPE_LEVEL_LOWEST) ? - LOMAC_LOWEST_LEVEL : LOMAC_HIGHEST_LEVEL; - lattr->flags = 0; - break; - case LO_TYPE_SOCKETPAIR: - socket = obj->lo_object.socket; - lattr->level = (socket->so_state & SOCKET_LEVEL_LOWEST) ? - LOMAC_LOWEST_LEVEL : LOMAC_HIGHEST_LEVEL; - lattr->flags = 0; - break; - default: - panic("get_object_level: invalid lo_type %d", obj->lo_type); - } -} - -/* - * Flag certain procs, like init(8) and kthreads, as "invincible". - */ -int -subject_do_not_demote(lomac_subject_t *subj) { - int inv = 0; - - if (subj->p_pid == 1) { - inv = 1; - } else { - int had_lock = PROC_LOCKED(subj); - - if (!had_lock) - PROC_LOCK(subj); - if (subj->p_flag & P_SYSTEM) - inv = 1; - if (!had_lock) - PROC_UNLOCK(subj); - } - return (inv); -} diff --git a/sys/security/lomac/kernel_interface.h b/sys/security/lomac/kernel_interface.h deleted file mode 100644 index 5229b424ba41..000000000000 --- a/sys/security/lomac/kernel_interface.h +++ /dev/null @@ -1,101 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef KERNEL_INTERFACE_H -#define KERNEL_INTERFACE_H - -#include -#include -#include -#include - -#include -#include - -#include "lomac.h" - - -/* - * We do not yet implement any categories. We use lattr_t's flags - * field to implement the "LOMAC_ATTR_LOWWRITE" exception. When - * this bit is set on a file, lowest-level processes can write to - * the file, regardless of the file's level. - * - * There is also the LOMAC_ATTR_LOWNOOPEN flag, which prevents the - * opening of a given object to subjects with a lower level than its - * own. - * - * LOMAC_ATTR_NONETDEMOTE is set on subjects to prevent demotion on - * network reads; LOMAC_ATTR_NODEMOTE is set on subjects to prevent - * all demotion. Both of these will effectively set a high-level - * subject as very trusted (and must be used sparingly). - */ -#define LOMAC_ATTR_LOWWRITE 0x00010000 -#define LOMAC_ATTR_LOWNOOPEN 0x00020000 -#define LOMAC_ATTR_NONETDEMOTE 0x00040000 -#define LOMAC_ATTR_NODEMOTE 0x00080000 - -typedef struct proc lomac_subject_t; -typedef struct lomac_object { - enum lomac_object_type { - LO_TYPE_LVNODE, /* LOMAC vnode */ - LO_TYPE_UVNODE, /* underlying vnode */ - LO_TYPE_VM_OBJECT, /* VM object, not OBJT_VNODE */ - LO_TYPE_PIPE, /* pipe */ - LO_TYPE_SOCKETPAIR /* local-domain socket in socketpair */ - } lo_type; - union { - struct vnode *vnode; - vm_object_t vm_object; - struct pipe *pipe; - struct socket *socket; - } lo_object; -} lomac_object_t; -typedef struct sbuf lomac_log_t; - -void init_subject_lattr(lomac_subject_t *, lattr_t *); -void set_subject_lattr(lomac_subject_t *, lattr_t); -void get_subject_lattr(lomac_subject_t *, lattr_t *); -void set_object_lattr(lomac_object_t *, lattr_t); -void get_object_lattr(const lomac_object_t *, lattr_t *); -int subject_do_not_demote(lomac_subject_t *); -#if 0 -void subject_propogate_lattr(lomac_subject_t *); -#endif -void kernel_vm_drop_perms(struct thread *, lattr_t *); - -#endif /* KERNEL_INTERFACE_H */ diff --git a/sys/security/lomac/kernel_lkm.c b/sys/security/lomac/kernel_lkm.c deleted file mode 100644 index 215c3d45b33b..000000000000 --- a/sys/security/lomac/kernel_lkm.c +++ /dev/null @@ -1,286 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kernel_interface.h" -#include "kernel_mediate.h" -#include "kernel_plm.h" -#include "kernel_util.h" -#include "kernel_pipe.h" -#include "kernel_socket.h" -#include "lomacfs.h" -#include "lomacio.h" - -static d_ioctl_t lomac_ioctl; - -#define CDEV_MAJOR 207 -#define LOMAC_MINOR 0 - -static struct cdevsw lomac_cdevsw = { - /* open */ (d_open_t *)nullop, - /* close */ (d_open_t *)nullop, - /* read */ noread, - /* write */ nowrite, - /* ioctl */ lomac_ioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ nostrategy, - /* name */ "lomac", - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ 0, -}; - -static dev_t lomac_dev = NULL; - -int -lomac_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { - struct nameidata nd; - struct proc *targp; - struct lomac_fioctl *fio; - lomac_object_t lobj; - lattr_t lattr; - int error; - - switch (cmd) { - case LIOGETPLEVEL: - targp = pfind(*(int *)data); - if (targp == NULL) - return (ESRCH); - if (p_cansee(td, targp) != 0) { - PROC_UNLOCK(targp); - return (ESRCH); - } - get_subject_lattr(targp, &lattr); - *(level_t *)data = lattr.level; - PROC_UNLOCK(targp); - return (0); - case LIOGETFLEVEL: - fio = (struct lomac_fioctl *)data; - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, - fio->path, td); - if ((error = namei(&nd)) != 0) - return (error); - if (VISLOMAC(nd.ni_vp)) - lobj.lo_type = LO_TYPE_LVNODE; - else - lobj.lo_type = LO_TYPE_UVNODE; - lobj.lo_object.vnode = nd.ni_vp; - get_object_lattr(&lobj, &lattr); - *(level_t *)&fio->level = lattr.level; - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_vp); - return (error); - case LIOGETFLATTR: - fio = (struct lomac_fioctl *)data; - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_SYSSPACE, - fio->path, td); - if ((error = namei(&nd)) != 0) - return (error); - if (VISLOMAC(nd.ni_vp)) - lobj.lo_type = LO_TYPE_LVNODE; - else - lobj.lo_type = LO_TYPE_UVNODE; - lobj.lo_object.vnode = nd.ni_vp; - get_object_lattr(&lobj, (lattr_t *)&fio->level); - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_vp); - return (error); - case LIOPMAKELOWLEVEL: - lattr.level = LOMAC_LOWEST_LEVEL; - lattr.flags = 0; - set_subject_lattr(td->td_proc, lattr); - return (0); - default: - return (ENOTTY); - } -} - -int (*old_execve)(struct proc *, void *); -#ifdef __i386__ -int (*old_sysarch)(struct proc *, void *); -#endif - -/* - * This is "borrowed" from kern_module.c and MUST be kept in synch! - */ -struct module { - TAILQ_ENTRY(module) link; /* chain together all modules */ - TAILQ_ENTRY(module) flink; /* all modules in a file */ - struct linker_file* file; /* file which contains this module */ - int refs; /* reference count */ - int id; /* unique id number */ - char *name; /* module name */ - modeventhand_t handler; /* event handler */ - void *arg; /* argument for handler */ - modspecific_t data; /* module specific data */ -}; - -static int -lomac_modevent(module_t module, int event, void *unused) { - static int initialized_procs = 0; - static int initialized_syscalls = 0; - static int initialized_pipes = 0; - static int initialized_sockets = 0; - static int initialized_vm = 0; - static linker_file_t kernlf; - int error; - - switch ((enum modeventtype)event) { - case MOD_LOAD: - if (!lomac_plm_initialized) - return (EINVAL); - kernlf = linker_kernel_file; - old_execve = - (int (*)(struct proc *, void *))linker_file_lookup_symbol( - kernlf, "execve", 1); - if (old_execve == NULL) - return (ENOENT); -#ifdef __i386__ - old_sysarch = - (int (*)(struct proc *, void *))linker_file_lookup_symbol( - kernlf, "sysarch", 1); - if (old_sysarch == NULL) - return (ENOENT); -#endif - error = lomac_initialize_procs(); - if (error) - break; - initialized_procs = 1; - error = lomac_initialize_syscalls(); - if (error) - break; - initialized_syscalls = 1; - error = lomac_initialize_pipes(); - if (error) - break; - initialized_pipes = 1; - error = lomac_initialize_sockets(); - if (error) - break; - initialized_sockets = 1; - lomac_dev = make_dev(&lomac_cdevsw, LOMAC_MINOR, UID_ROOT, - GID_WHEEL, 0666, "lomac"); - linker_kernel_file = module->file; - error = vfs_mount(curthread, "lomacfs", "/", 0, NULL); - if (error) - return (error); - error = lomac_initialize_cwds(); - if (error) - return (error); - printf("LOMAC: Low-Watermark Mandatory Access Control v2.0.0\n"); - return (error); - case MOD_UNLOAD: - /* - * It's always a bad idea to let a low-security process - * unload the module providing security. - */ - if (initialized_procs && - !mediate_subject_at_level("kldunload", curthread->td_proc, - LOMAC_HIGHEST_LEVEL)) - return (EPERM); - /* - * Unloading doesn't work well at the moment... - */ - return (EPERM); - if (initialized_sockets) { - error = lomac_uninitialize_sockets(); - if (error) - break; - initialized_sockets = 0; - } - if (initialized_pipes) { - error = lomac_uninitialize_pipes(); - if (error) - break; - initialized_pipes = 0; - } - if (initialized_syscalls) { - error = lomac_uninitialize_syscalls(); - if (error) - break; - initialized_syscalls = 0; - } - if (initialized_procs) { - error = lomac_uninitialize_procs(); - if (error) - break; - initialized_procs = 0; - } - if (initialized_vm) { - error = lomac_uninitialize_vm(); - if (error) - break; - initialized_vm = 0; - } - if (lomac_dev) { - if (count_dev(lomac_dev) != 0) - return (EBUSY); - destroy_dev(lomac_dev); - } - printf("LOMAC: unloading\n"); - linker_kernel_file = kernlf; - break; - case MOD_SHUTDOWN: - break; - } - return (0); -} - -static moduledata_t lomac_moduledata = { - "lomac", - &lomac_modevent, - NULL -}; -DECLARE_MODULE(lomac, lomac_moduledata, SI_SUB_VFS, SI_ORDER_ANY); -MODULE_VERSION(lomac, 1); -MODULE_DEPEND(lomac, syscall_gate, 1, 1, 1); -MODULE_DEPEND(lomac, lomacfs, 1, 1, 1); -MODULE_DEPEND(lomac, lomac_plm, 1, 1, 1); diff --git a/sys/security/lomac/kernel_log.c b/sys/security/lomac/kernel_log.c deleted file mode 100644 index be6f4e474564..000000000000 --- a/sys/security/lomac/kernel_log.c +++ /dev/null @@ -1,206 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "lomacfs.h" - -#include "kernel_interface.h" - -/* The following definition sets the global log verbosity level. */ -SYSCTL_NODE(_kern, OID_AUTO, lomac, CTLFLAG_RW, 0, "LOMAC"); -SYSCTL_NODE(_kern_lomac, OID_AUTO, verbose, CTLFLAG_RW, 0, "LOMAC verbosity"); -#define VERBOSITY_SETTING(level) \ - unsigned int lomac_verbose_##level = 1; \ - SYSCTL_UINT(_kern_lomac_verbose, OID_AUTO, level, \ - CTLFLAG_RW, &lomac_verbose_##level, 1, "") -#include "kernel_log.h" - -/* sbuf_start() - * - * in: nothing - * out: nothing - * return: struct sbuf * to pass to later callers - * - */ - -lomac_log_t * -log_start(void) { - struct sbuf *s; - - s = sbuf_new(NULL, NULL, PATH_MAX * 2, 0); - KASSERT(s != NULL, ("sbuf uses M_WAITOK -- must not return NULL!")); - return (s); -} /* log_start() */ - - -/* log_append_string() - * - * in: s - a struct sbuf * - * in: data_s - null-terminated string to append to log - * out: nothing, see description for side-effects - * return: nothing - * - * This function appends `data_s' to `log_s', being careful to ensure - * that there is sufficient room in `log_s' for the data and a null - * terminator. If there is insufficient room in `log_s' for the entire - * `data_s' string, this function will append only the prefix of `data_s' - * which fits. - * - */ - -void -log_append_string(lomac_log_t *s, const char *data_s) { - - (void)sbuf_cat(s, data_s); -} /* log_append_string */ - - -/* log_append_int() - * - * in: data - integer value to append to log - * out: nothing, see description for side-effects - * return: nothing - * - * This function determines the ASCII representation of the integer - * value in `data' and, if there is sufficient room, appends this - * ASCII representation to `log_s'. If there is insufficient room, - * this function behaves as log_append_string(). - * - */ - -void -log_append_int(lomac_log_t *s, int data) { - - (void)sbuf_printf(s, "%d", data); -} /* log_append_int() */ - - -/* log_append_subject_id() - * - * in: p_subject - subject whose ID we want to append to the log message - * out: nothing, see description for side-effects - * return: nothing - * - * This function appends a string describing the identity of `p_subject' - * to `log_s'. If there is insufficient room in `log_s' for the entire - * ID string, only a (possibly empty) prefix of the ID string will be - * appended. - * - */ - -void -log_append_subject_id(lomac_log_t *s, const lomac_subject_t *p_subject) { - uid_t uid; - pid_t pgid; - - PROC_LOCK(p_subject); - uid = p_subject->p_ucred->cr_uid; - pgid = p_subject->p_pgrp->pg_id; - PROC_UNLOCK(p_subject); - (void)sbuf_printf(s, "p%dg%du%d:%s", p_subject->p_pid, pgid, uid, - p_subject->p_comm); -} /* log_append_subject_id() */ - -/* log_append_object_id() - * - * in: p_object - object whose ID we want to append to the log message - * out: nothing, see description for side-effects - * return: nothing - * - * This function appends a string describing the identity of `p_object' - * to `log_s'. If there is insufficient room in `log_s' for the entire - * ID string, only a (possibly empty) prefix of the ID string will be - * appended. - * - */ - -void -log_append_object_id(lomac_log_t *s, const lomac_object_t *p_object) { - struct lomac_node *ln; - - switch (p_object->lo_type) { - case LO_TYPE_UVNODE: - (void)sbuf_printf(s, "vp %p", p_object->lo_object.vnode); - break; - case LO_TYPE_LVNODE: - ln = VTOLOMAC(p_object->lo_object.vnode); -#ifdef LOMAC_DEBUG_INCNAME - (void)sbuf_printf(s, "named \"%s\"", ln->ln_name); -#else - if (ln->ln_entry != NULL) - (void)sbuf_printf(s, "named \"%s\"", - ln->ln_entry->ln_path); - else - (void)sbuf_printf(s, "under \"%s\"", - ln->ln_underpolicy->ln_path); -#endif - break; - case LO_TYPE_PIPE: - (void)sbuf_printf(s, "pipe %p", p_object->lo_object.pipe); - break; - case LO_TYPE_SOCKETPAIR: - (void)sbuf_printf(s, "socket %p", p_object->lo_object.socket); - break; - default: - panic("invalid LOMAC object type"); - } -} /* log_append_object_id() */ - -/* log_print() - * - * in: nothing - * out: nothing - * return: nothing - * - * This function prints `log_s' to the system log. - * - */ - -void -log_print(lomac_log_t *s) { - - sbuf_finish(s); - log(LOG_INFO, "%s", sbuf_data(s)); - sbuf_delete(s); -} /* log_print() */ diff --git a/sys/security/lomac/kernel_log.h b/sys/security/lomac/kernel_log.h deleted file mode 100644 index 58dbf9801ef1..000000000000 --- a/sys/security/lomac/kernel_log.h +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef _KERNEL_LOG_H_ -#define _KERNEL_LOG_H_ - -#include "kernel_interface.h" - -/* Use this unsigned int and its constants to set the log output * - * verbosity. Use of the log_* functions should be surrounded by * - * if statements of the form "if( verbose & VERBOSE_FOO )" where * - * VERBOSE_FOO is the constant below which corresponds to the * - * type of event you're logging. */ -#define VERBOSE_NOLOG 0x00000000 /* no log output, please. */ -#define VERBOSE_DEMOTE_DENY 0x00000001 /* log demotions and access denials. */ -#define VERBOSE_PIPE 0x00000002 /* log changes to pipe "levels". */ -#define VERBOSE_LOG_SOCKETS 0x00000004 /* log UNIX domain socket setup. */ -#define VERBOSE_LOG_OBJECTS 0x00000008 /* log opening of objects. */ -#ifdef TRUST -#define VERBOSE_TRUST 0x00000020 /* log when trust stops demotion. */ -#endif - -#ifndef VERBOSITY_SETTING -#define VERBOSITY_SETTING(level) extern unsigned int lomac_verbose_##level; -#endif -VERBOSITY_SETTING(demote_deny); -VERBOSITY_SETTING(log_sockets); -VERBOSITY_SETTING(log_objects); -#ifdef LOMAC_DEBUG_PIPE -VERBOSITY_SETTING(pipe); -#endif -#ifdef TRUST -VERBOSITY_SETTING(trust); -#endif - -lomac_log_t *log_start( void ); -void log_append_string( lomac_log_t *s, const char *data_s ); -void log_append_int( lomac_log_t *s, int data ); -void log_append_subject_id( lomac_log_t *s, const lomac_subject_t *p_subject ); -void log_append_object_id( lomac_log_t *s, const lomac_object_t *p_object ); -void log_print( lomac_log_t *s ); - -#endif diff --git a/sys/security/lomac/kernel_mediate.c b/sys/security/lomac/kernel_mediate.c deleted file mode 100644 index 8a8285dd9773..000000000000 --- a/sys/security/lomac/kernel_mediate.c +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -/* - * This file contains functions that make access control decisions - * concerning wether or not given system calls should be allowed - * or denied. This activity is called "mediation". These functions - * generally consider both the parameters passed to a system call - * and the current internal state of LOMAC in the course of making - * a decision. However, they do not modify these parameters or - * LOMAC's internal state. Functions for modifying LOMAC's internal - * state can be found in lomac_monitor.c. - * - */ - -#include "kernel_interface.h" -#include "kernel_mediate.h" -#if 0 -#include "lomac_plm.h" -#endif -#include "kernel_log.h" - -/* mediate_subject_level_subject() - * - * in: op_s - name of operation to mediate - * p_subject_one - subject one (for informational purposes only) - * level_one - already-known level of the first subject - * p_subject_two - subject two - * out: nothing - * return: value condition - * ----- --------- - * 0 caller should deny operation - * 1 caller should allow operation - * - * This function returns 1 if `p_subject_one's level is at least - * as great as `p_subject_two's level. Otherwise, it logs a permission - * failure on operation `op_s' and returns 0. - * - * This function is used to mediate pgrp changes. - * - */ - -int -mediate_subject_level_subject(const char *op_s, - const lomac_subject_t *p_subject_one, level_t level_one, - lomac_subject_t *p_subject_two) { - - lattr_t lattr_two; /* lattr of `p_subject_two' */ - int ret_val; /* result to return to caller */ - -#ifdef NO_MEDIATION - ret_val = 1; /* no denials, just logging */ -#else - ret_val = 0; /* pessimistically assume deny */ -#endif - - get_subject_lattr(p_subject_two, &lattr_two); - - if (lattr_two.level <= level_one) { - ret_val = 1; /* OK, allow */ - } else if (lomac_verbose_demote_deny) { - lomac_log_t *logmsg = log_start(); - - log_append_string(logmsg, "LOMAC: denied level-"); - log_append_int(logmsg, level_one); - log_append_string(logmsg, " proc "); - log_append_subject_id(logmsg, p_subject_one); - log_append_string(logmsg, " "); - log_append_string(logmsg, op_s); - log_append_string(logmsg, " to level-"); - log_append_int(logmsg, lattr_two.level); - log_append_string(logmsg, " proc "); - log_append_subject_id(logmsg, p_subject_two); - log_print(logmsg); - } - return (ret_val); -} /* mediate_subject_subject() */ - -/* mediate_subject_object() - * - * in: op_s - string describing operation, like "write" or "writev" - * p_subject - subject trying to operate on `p_object'. - * p_object - object that `p_subject' is trying to operate on. - * out: nothing - * return: value condition - * ----- --------- - * 0 Caller should prevent operation - * 1 Caller should permit operation - * - * This function returns 1 if the level of `p_object' is less than or - * equal to the level of `p_subject'. Otherwise, it returns 0 and - * logs a permission denial on `op_s'. - * - * This function allows LOMAC to mediate write and writev system calls. - * - */ - -int -mediate_subject_object(const char *op_s, lomac_subject_t *p_subject, - const lomac_object_t *p_object) { - lattr_t subject_lattr; /* lattr of `p_subject' */ - lattr_t object_lattr; /* lattr of `p_object' */ - int ret_val; /* value to return to caller */ - -#ifdef NO_MEDIATION - ret_val = 1; /* allow operation regardless of decision */ -#else - ret_val = 0; /* pessimistically assume deny */ -#endif - - /* Get the lattrs of `p_subject' and `p_object' so we can compare them. */ - get_subject_lattr(p_subject, &subject_lattr); - get_object_lattr(p_object, &object_lattr); - - /* - * If `p_subject's level is less than `p_object's level, - * we indicate that the operation must not be allowed. - */ - - if (!lomac_must_deny(&subject_lattr, &object_lattr) || - object_lattr.flags & LOMAC_ATTR_LOWWRITE) { - ret_val = 1; /* allow operation */ - } else if (lomac_verbose_demote_deny) { - lomac_log_t *logmsg = log_start(); - log_append_string(logmsg, "LOMAC: level-"); - log_append_int(logmsg, subject_lattr.level); - log_append_string(logmsg, " proc "); - log_append_subject_id(logmsg, p_subject); - log_append_string(logmsg, " denied "); - log_append_string(logmsg, op_s); - log_append_string(logmsg, " to level-"); - log_append_int(logmsg, object_lattr.level); - log_append_string(logmsg, " object "); - log_append_object_id(logmsg, p_object); - log_append_string(logmsg, "\n"); - log_print(logmsg); - } - return (ret_val); -} /* mediate_subject_object() */ - - -/* mediate_subject_object_open() - * - * in: p_subject - subject trying to operate on `p_object'. - * p_object - object that `p_subject' is trying to operate on. - * out: nothing - * return: value condition - * ----- --------- - * 0 Caller should prevent operation - * 1 Caller should permit operation - * - * This function returns 1 if the level of `p_object' is less than or - * equal to the level of `p_subject'. Otherwise, it returns 0 and - * logs a permission denial on `op_s'. - * - * This function allows LOMAC to mediate open system calls. - * - */ - -int -mediate_subject_object_open(lomac_subject_t *p_subject, - const lomac_object_t *p_object) { - lattr_t subject_lattr; /* lattr of `p_subject' */ - lattr_t object_lattr; /* lattr of `p_object' */ - int ret_val; /* value to return to caller */ - -#ifdef NO_MEDIATION - ret_val = 1; /* allow operation regardless of decision */ -#else - ret_val = 0; /* pessimistically assume deny */ -#endif - - /* Get the lattrs of `p_subject' and `p_object' so we can compare them. */ - get_subject_lattr(p_subject, &subject_lattr); - get_object_lattr(p_object, &object_lattr); - - /* - * If `p_subject's level is less than `p_object's level, - * we must indicate that the operation should not be allowed. - */ - if (lomac_must_deny(&subject_lattr, &object_lattr) && - object_lattr.flags & LOMAC_ATTR_LOWNOOPEN) { - if (lomac_verbose_demote_deny) { - lomac_log_t *logmsg = log_start(); - - log_append_string(logmsg, "LOMAC: level-"); - log_append_int(logmsg, subject_lattr.level); - log_append_string(logmsg, " proc "); - log_append_subject_id(logmsg, p_subject); - log_append_string(logmsg, " denied open to level-"); - log_append_int(logmsg, object_lattr.level); - log_append_string(logmsg, " object "); - log_append_object_id(logmsg, p_object); - log_append_string(logmsg, "\n"); - log_print(logmsg); - } - } else { - ret_val = 1; /* allow operation */ - } /* if/else allow/deny */ - return (ret_val); -} /* mediate_subject_object() */ - - -/* mediate_subject_at_level() - * - * in: op_s - name of operation being mediated - * p_subject - subject whose level we want to check - * target_level - level to compare to `p_subject's level - * - * out: nothing - * return: value condition - * ----- --------- - * 0 `p_subject' is not at `target_level' - * 1 `p_subject' is at `target_level' - * - * This function provides a predicate for determining whether or not - * `p_subject' is at the level specified by `target_level'. This - * function compares `p_subject's level to `target_level'. If the - * levels match, it retruns 1. Otherwise, it logs a permission denial - * on `op_s' and returns 0. - * - */ - -int -mediate_subject_at_level(const char *op_s, lomac_subject_t *p_subject, - const level_t target_level) { - lattr_t subject_lattr; /* lattr of `p_subject' */ - int ret_val; /* value returned to caller */ - -#ifdef NO_MEDIATION - ret_val = 1; /* allow operation regardless of decision */ -#else - ret_val = 0; /* pessimistically assume deny */ -#endif - - /* Make `subject_lattr' the lattr of `p_subject'. */ - get_subject_lattr(p_subject, &subject_lattr); - - /* compare with `target_lattr */ - if (subject_lattr.level == target_level) { - ret_val = 1; /* allow operation */ - } else if (lomac_verbose_demote_deny) { - lomac_log_t *logmsg = log_start(); - - log_append_string(logmsg, "LOMAC: denied level-"); - log_append_int(logmsg, subject_lattr.level); - log_append_string(logmsg, " proc "); - log_append_subject_id(logmsg, p_subject); - log_append_string(logmsg, "'s "); - log_append_string(logmsg, op_s); - log_append_string(logmsg, ".\n"); - log_print(logmsg); - } - return (ret_val); -} /* mediate_subject_at_level() */ diff --git a/sys/security/lomac/kernel_mediate.h b/sys/security/lomac/kernel_mediate.h deleted file mode 100644 index 37842e64b67b..000000000000 --- a/sys/security/lomac/kernel_mediate.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef _KERNEL_MEDIATE_H_ -#define _KERNEL_MEDIATE_H_ - -#include "kernel_interface.h" - -int mediate_subject_level_subject( const char *op_s, - const lomac_subject_t *p_subject_one, - level_t level_one, - lomac_subject_t *p_subject_two ); -int mediate_subject_object( const char *op_s, lomac_subject_t *p_subject, - const lomac_object_t *p_object ); -int mediate_subject_object_open( lomac_subject_t *p_subject, - const lomac_object_t *p_object ); -#if 0 -int mediate_subject_path( const char *op_s, const lomac_subject_t *p_subject, - const char *path_s ); -int mediate_path_path( const char *op_s, const lomac_subject_t *p_subject, - const char *canabsname_one_s, - const char *canabsname_two_s ); -#endif -int mediate_subject_at_level( const char *op_s, - lomac_subject_t *p_subject, - const level_t target_level ); -#if 0 -int mediate_object_at_level( const char *op_s, - const lomac_subject_t *p_subject, - const lomac_object_t *p_object, - const level_t target_level ); -#endif - -#endif diff --git a/sys/security/lomac/kernel_mmap.c b/sys/security/lomac/kernel_mmap.c deleted file mode 100644 index 25e87920d4a6..000000000000 --- a/sys/security/lomac/kernel_mmap.c +++ /dev/null @@ -1,591 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. Neither the name of the the above entities nor the names of any - * contributors of those entities may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - */ -/* - * Copyright (c) 1988 University of Utah. - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * the Systems Programming Group of the University of Utah Computer - * Science Department. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$ - * - * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94 - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kernel_interface.h" -#include "kernel_mediate.h" -#include "kernel_monitor.h" -#include "kernel_util.h" -#include "lomacfs.h" - -extern int max_proc_mmap; - -int lomac_mmap(struct proc *, struct mmap_args *); - -/* - * Memory Map (mmap) system call. Note that the file offset - * and address are allowed to be NOT page aligned, though if - * the MAP_FIXED flag it set, both must have the same remainder - * modulo the PAGE_SIZE (POSIX 1003.1b). If the address is not - * page-aligned, the actual mapping starts at trunc_page(addr) - * and the return value is adjusted up by the page offset. - * - * Generally speaking, only character devices which are themselves - * memory-based, such as a video framebuffer, can be mmap'd. Otherwise - * there would be no cache coherency between a descriptor and a VM mapping - * both to the same character device. - * - * Block devices can be mmap'd no matter what they represent. Cache coherency - * is maintained as long as you do not write directly to the underlying - * character device. - */ -#ifndef _SYS_SYSPROTO_H_ -struct mmap_args { - void *addr; - size_t len; - int prot; - int flags; - int fd; - long pad; - off_t pos; -}; -#endif - -int -mmap(td, uap) - struct thread *td; - struct mmap_args *uap; -{ - struct proc *p = td->td_proc; - struct filedesc *fdp = p->p_fd; - struct file *fp = NULL; - struct vnode *vp, *origvp; - vm_offset_t addr; - vm_size_t size, pageoff; - vm_prot_t prot, maxprot; - void *handle; - int flags, error; - int disablexworkaround; - off_t pos; - struct vmspace *vms = p->p_vmspace; - vm_object_t obj; - lomac_object_t lobj; - - addr = (vm_offset_t) uap->addr; - size = uap->len; - prot = uap->prot & VM_PROT_ALL; - flags = uap->flags; - pos = uap->pos; - origvp = NULL; - - /* make sure mapping fits into numeric range etc */ - if ((ssize_t) uap->len < 0 || - ((flags & MAP_ANON) && uap->fd != -1)) - return (EINVAL); - - if (flags & MAP_STACK) { - if ((uap->fd != -1) || - ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) - return (EINVAL); - flags |= MAP_ANON; - pos = 0; - } - - /* - * Align the file position to a page boundary, - * and save its page offset component. - */ - pageoff = (pos & PAGE_MASK); - pos -= pageoff; - - /* Adjust size for rounding (on both ends). */ - size += pageoff; /* low end... */ - size = (vm_size_t) round_page(size); /* hi end */ - - /* - * Check for illegal addresses. Watch out for address wrap... Note - * that VM_*_ADDRESS are not constants due to casts (argh). - */ - if (flags & MAP_FIXED) { - /* - * The specified address must have the same remainder - * as the file offset taken modulo PAGE_SIZE, so it - * should be aligned after adjustment by pageoff. - */ - addr -= pageoff; - if (addr & PAGE_MASK) - return (EINVAL); - /* Address range must be all in user VM space. */ - if (VM_MAXUSER_ADDRESS > 0 && addr + size > VM_MAXUSER_ADDRESS) - return (EINVAL); -#ifndef __i386__ - if (VM_MIN_ADDRESS > 0 && addr < VM_MIN_ADDRESS) - return (EINVAL); -#endif - if (addr + size < addr) - return (EINVAL); - } - /* - * XXX for non-fixed mappings where no hint is provided or - * the hint would fall in the potential heap space, - * place it after the end of the largest possible heap. - * - * There should really be a pmap call to determine a reasonable - * location. - */ - else if (addr == 0 || - (addr >= round_page((vm_offset_t)vms->vm_taddr) && - addr < round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ))) - addr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); - - mtx_lock(&Giant); /* syscall marked mp-safe but isn't */ - if (flags & MAP_ANON) { - /* - * Mapping blank space is trivial. - */ - handle = NULL; - maxprot = VM_PROT_ALL; - pos = 0; - } else { - /* - * Mapping file, get fp for validation. Obtain vnode and make - * sure it is of appropriate type. - */ - if (((unsigned) uap->fd) >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[uap->fd]) == NULL) { - mtx_unlock(&Giant); - return (EBADF); - } - if (fp->f_type != DTYPE_VNODE) { - mtx_unlock(&Giant); - return (EINVAL); - } - - /* - * don't let the descriptor disappear on us if we block - */ - fhold(fp); - - /* - * POSIX shared-memory objects are defined to have - * kernel persistence, and are not defined to support - * read(2)/write(2) -- or even open(2). Thus, we can - * use MAP_ASYNC to trade on-disk coherence for speed. - * The shm_open(3) library routine turns on the FPOSIXSHM - * flag to request this behavior. - */ - if (fp->f_flag & FPOSIXSHM) - flags |= MAP_NOSYNC; - vp = (struct vnode *) fp->f_data; - if (vp->v_type != VREG && vp->v_type != VCHR) { - error = EINVAL; - goto done; - } - if (vp->v_type == VREG) { - /* - * Get the proper underlying object - */ - if (VOP_GETVOBJECT(vp, &obj) != 0) { - error = EINVAL; - goto done; - } - origvp = vp; - vp = (struct vnode*)obj->handle; - } - /* - * XXX hack to handle use of /dev/zero to map anon memory (ala - * SunOS). - */ - if ((vp->v_type == VCHR) && - (vp->v_rdev->si_devsw->d_flags & D_MMAP_ANON)) { - handle = NULL; - maxprot = VM_PROT_ALL; - flags |= MAP_ANON; - pos = 0; - } else { - /* - * cdevs does not provide private mappings of any kind. - */ - /* - * However, for XIG X server to continue to work, - * we should allow the superuser to do it anyway. - * We only allow it at securelevel < 1. - * (Because the XIG X server writes directly to video - * memory via /dev/mem, it should never work at any - * other securelevel. - * XXX this will have to go - */ - if (securelevel >= 1) - disablexworkaround = 1; - else - disablexworkaround = suser(td); - if (vp->v_type == VCHR && disablexworkaround && - (flags & (MAP_PRIVATE|MAP_COPY))) { - error = EINVAL; - goto done; - } - /* - * Ensure that file and memory protections are - * compatible. Note that we only worry about - * writability if mapping is shared; in this case, - * current and max prot are dictated by the open file. - * XXX use the vnode instead? Problem is: what - * credentials do we use for determination? What if - * proc does a setuid? - */ - maxprot = VM_PROT_EXECUTE; /* ??? */ - if (fp->f_flag & FREAD) { - maxprot |= VM_PROT_READ; - } else if (prot & PROT_READ) { - error = EACCES; - goto done; - } - /* - * If we are sharing potential changes (either via - * MAP_SHARED or via the implicit sharing of character - * device mappings), and we are trying to get write - * permission although we opened it without asking - * for it, bail out. Check for superuser, only if - * we're at securelevel < 1, to allow the XIG X server - * to continue to work. - */ - - if ((flags & MAP_SHARED) != 0 || - (vp->v_type == VCHR && disablexworkaround)) { - if ((fp->f_flag & FWRITE) != 0) { - struct vattr va; - if ((error = - VOP_GETATTR(vp, &va, - td->td_ucred, td))) { - goto done; - } - if ((va.va_flags & - (SF_SNAPSHOT|IMMUTABLE|APPEND)) == 0) { - maxprot |= VM_PROT_WRITE; - } else if (prot & PROT_WRITE) { - error = EPERM; - goto done; - } - } else if ((prot & PROT_WRITE) != 0) { - error = EACCES; - goto done; - } - } else { - maxprot |= VM_PROT_WRITE; - } - - handle = (void *)vp; - origvp = vp; - } - } - - /* - * Do not allow more then a certain number of vm_map_entry structures - * per process. Scale with the number of rforks sharing the map - * to make the limit reasonable for threads. - */ - if (max_proc_mmap && - vms->vm_map.nentries >= max_proc_mmap * vms->vm_refcnt) { - error = ENOMEM; - goto done; - } - - mtx_unlock(&Giant); - error = 0; - if (handle != NULL && VISLOMAC(origvp)) { - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = origvp; - if (flags & MAP_SHARED && maxprot & VM_PROT_WRITE && - !mediate_subject_object("mmap", p, &lobj)) - error = EPERM; - if (error == 0 && maxprot & VM_PROT_READ) - error = monitor_read_object(p, &lobj); - } - if (error == 0) - error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, - flags, handle, pos); - if (error == 0) - td->td_retval[0] = (register_t) (addr + pageoff); - mtx_lock(&Giant); -done: - if (fp) - fdrop(fp, td); - mtx_unlock(&Giant); - return (error); -} - -static void -vm_drop_perms_recurse(struct thread *td, struct vm_map *map, lattr_t *lattr) { - struct vm_map_entry *vme; - - for (vme = map->header.next; vme != &map->header; vme = vme->next) { - if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { - vm_map_lock_read(vme->object.sub_map); - vm_drop_perms_recurse(td, vme->object.sub_map, - lattr); - vm_map_unlock_read(vme->object.sub_map); - continue; - } - if ((vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC)) == 0 && - vme->max_protection & VM_PROT_WRITE) { - vm_object_t object; - vm_ooffset_t offset; - lomac_object_t lobj; - struct vnode *vp; - lattr_t olattr; - - offset = vme->offset; - object = vme->object.vm_object; - if (object == NULL) - continue; - while (object->backing_object) { - object = object->backing_object; - offset += object->backing_object_offset; - } - /* - * Regular objects (swap, etc.) inherit from - * their creator. Vnodes inherit from their - * underlying on-disk object. - */ - if (object->type == OBJT_DEVICE) - continue; - if (object->type == OBJT_VNODE) { - vp = lobj.lo_object.vnode = object->handle; - /* - * For the foreseeable future, an OBJT_VNODE - * is always !VISLOMAC(). - */ - lobj.lo_type = VISLOMAC(vp) ? - LO_TYPE_LVNODE : LO_TYPE_UVNODE; - } else { - vp = NULL; - lobj.lo_object.vm_object = object; - lobj.lo_type = LO_TYPE_VM_OBJECT; - } - get_object_lattr(&lobj, &olattr); - /* - * Revoke write access only to files with a higher - * level than the process or which have a possibly- - * undeterminable level (interpreted as "lowest"). - */ - if (lomac_must_deny(lattr, &olattr)) - continue; - vm_map_lock_upgrade(map); - /* - * If it's a private, non-file-backed mapping and - * not mapped anywhere else, we can just take it - * down with us. - */ - if (vp == NULL && object->flags & OBJ_ONEMAPPING) { - olattr.level = lattr->level; - set_object_lattr(&lobj, olattr); - goto downgrade; - } - if ((vme->protection & VM_PROT_WRITE) == 0) - vme->max_protection &= ~VM_PROT_WRITE; - else { - vm_object_reference(object); - if (vp != NULL) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, - td); - vm_object_page_clean(object, - OFF_TO_IDX(offset), - OFF_TO_IDX(offset + vme->end - vme->start + - PAGE_MASK), - OBJPC_SYNC); - if (vp != NULL) - VOP_UNLOCK(vp, 0, td); - vm_object_deallocate(object); - vme->eflags |= MAP_ENTRY_COW | - MAP_ENTRY_NEEDS_COPY; - pmap_protect(map->pmap, vme->start, vme->end, - vme->protection & ~VM_PROT_WRITE); - vm_map_simplify_entry(map, vme); - } - downgrade: - vm_map_lock_downgrade(map); - } - } -} - -void -kernel_vm_drop_perms(struct thread *td, lattr_t *newlattr) { - struct vm_map *map = &td->td_proc->p_vmspace->vm_map; - - mtx_lock(&Giant); - vm_map_lock_read(map); - vm_drop_perms_recurse(td, map, newlattr); - vm_map_unlock_read(map); - mtx_unlock(&Giant); -} - -/* - * Take the level of new vm_objects from the parent subject's level. - */ -static void -vm_object_init_lattr(vm_object_t object) { - lomac_object_t lobj; - lattr_t lattr; - - get_subject_lattr(curthread->td_proc, &lattr); - lattr.flags = 0; - lobj.lo_type = LO_TYPE_VM_OBJECT; - lobj.lo_object.vm_object = object; - set_object_lattr(&lobj, lattr); -} - - -#define PGO_ALLOC_REPLACEMENT(n) \ -static vm_object_t (*old_pgo_alloc_##n)(void *, vm_ooffset_t, \ - vm_prot_t, vm_ooffset_t); \ - \ -static vm_object_t \ -pgo_alloc_##n(void *handle, vm_ooffset_t size, vm_prot_t prot, \ - vm_ooffset_t off) { \ - vm_object_t newobj = NULL; \ - \ - newobj = old_pgo_alloc_##n(handle, size, prot, off); \ - if (newobj != NULL) \ - vm_object_init_lattr(newobj); \ - return (newobj); \ -} - -#define PGO_ALLOC_REPLACE(n) \ - do { \ - old_pgo_alloc_##n = pagertab[n]->pgo_alloc; \ - if (pagertab[n]->pgo_alloc != NULL) \ - pagertab[n]->pgo_alloc = pgo_alloc_##n; \ - } while (0) - -#define PGO_ALLOC_UNREPLACE(n) \ - do { \ - pagertab[n]->pgo_alloc = old_pgo_alloc_##n; \ - } while (0) - -PGO_ALLOC_REPLACEMENT(0); -PGO_ALLOC_REPLACEMENT(1); -PGO_ALLOC_REPLACEMENT(2); -PGO_ALLOC_REPLACEMENT(3); -PGO_ALLOC_REPLACEMENT(4); -PGO_ALLOC_REPLACEMENT(5); - -extern int npagers; - -int -lomac_initialize_vm(void) { - GIANT_REQUIRED; - - if (npagers != 6) { - printf("LOMAC: number of pagers %d not expected 6!\n", npagers); - return (EDOM); - } - PGO_ALLOC_REPLACE(0); - PGO_ALLOC_REPLACE(1); - PGO_ALLOC_REPLACE(2); - PGO_ALLOC_REPLACE(3); - PGO_ALLOC_REPLACE(4); - PGO_ALLOC_REPLACE(5); - return (0); -} - -int -lomac_uninitialize_vm(void) { - GIANT_REQUIRED; - - PGO_ALLOC_UNREPLACE(0); - PGO_ALLOC_UNREPLACE(1); - PGO_ALLOC_UNREPLACE(2); - PGO_ALLOC_UNREPLACE(3); - PGO_ALLOC_UNREPLACE(4); - PGO_ALLOC_UNREPLACE(5); - return (0); -} diff --git a/sys/security/lomac/kernel_monitor.c b/sys/security/lomac/kernel_monitor.c deleted file mode 100644 index 443c6095e19f..000000000000 --- a/sys/security/lomac/kernel_monitor.c +++ /dev/null @@ -1,206 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -/* - * This file contains functions which update LOMAC's internal - * state in response to system events, such as successful - * system calls. These updates allow LOMAC to keep an accurate - * picture of the kernel's state, enabling LOMAC to make reasonable - * decisions when it mediates processes' use of security-relevant - * system calls. These functions perform no mediation themselves - - * that is, they do not make access control decisions concerning - * whether a given system call should be allowed or denied. This - * mediation is handled by the functions in lomac_mediate.c. - */ - -#include "kernel_interface.h" -#include "kernel_monitor.h" -#include "kernel_log.h" - -#include "kernel_util.h" - - -/* monitor_read_object() - * - * in: p_subject - subject that read `p_object'. - * p_object - object read by `p_subject'. - * out: nothing - * return: nothing - * - * This function examines the objects read by subjects. If a subject - * reads from an object with a level lower than its own, this function - * reduces the subject's level to match the object's. This lowering - * is referred to as "demotion" in much of the LOMAC documentation. - * This function performs no mediation. - * - * This function is for the following kinds of objects: - * regular files and FIFOs. - * It is also used to monitor reads on unnamed pipes. LOMAC does not - * consider unnamed pipes to be objects, and treats them differently - * from objects such as files. However, the differences are mostly - * in the write-handling behavior. LOMAC's read-handling behavior is - * the same both for objects and unnamed pipes, so this function - * handles both cases. - */ - -int -monitor_read_object(lomac_subject_t *p_subject, lomac_object_t *p_object) { - lattr_t subject_lattr; /* lattr of `p_subject' */ - lattr_t object_lattr; /* lattr of `p_object' */ - - /* Get the lattrs of `p_subject' and `p_object' so we can compare them. */ - get_subject_lattr(p_subject, &subject_lattr); - get_object_lattr(p_object, &object_lattr); - - /* - * If `p_object's level is less than `p_subject's level, - * we must demote `p_subject'. The level may be 0 to indicate - * existence before LOMAC started. - */ - if (object_lattr.level && - lomac_must_demote(&subject_lattr, &object_lattr) && - (subject_lattr.flags & LOMAC_ATTR_NODEMOTE) == 0) { - if (subject_do_not_demote(p_subject)) - return (0); - set_subject_lattr(p_subject, object_lattr); /* demote! */ - if (lomac_verbose_demote_deny) { - lomac_log_t *s = log_start(); - - log_append_string(s, "LOMAC: level-"); - log_append_int(s, subject_lattr.level); - log_append_string(s, " subject "); - log_append_subject_id(s, p_subject); - log_append_string(s, " demoted to level "); - log_append_int(s, object_lattr.level); - log_append_string(s, " after reading "); - log_append_object_id(s, p_object); - log_append_string(s, "\n"); - log_print(s); - } - } /* if we need to demote */ - return (0); -} /* monitor_read_object() */ - - -/* monitor_pipe_write() - * - * in: p_subject - subject that just wrote to `p_pipe'. - * p_pipe - pipe `p_subject' has written to. - * out: p_pipe - pipe may have its level adjusted. - * return: 0 - * - * This function should be called after a successful write to - * `p_pipe'. If the level of `p_subject' is less than the level of - * `p_pipe', this function reduces `p_pipe's level to match - * `current's. - * - * - */ - -int -monitor_pipe_write(lomac_subject_t *p_subject, lomac_object_t *p_pipe) { - lattr_t pipe_lattr; /* lattr of `p_pipe' */ - lattr_t subject_lattr; /* lattr of `p_subject' */ - - get_subject_lattr(p_subject, &subject_lattr); - get_object_lattr(p_pipe, &pipe_lattr); - if (lomac_must_demote(&pipe_lattr, &subject_lattr)) { - subject_lattr.flags = 0; - set_object_lattr(p_pipe, subject_lattr); -#ifdef LOMAC_DEBUG_PIPE - if (lomac_verbose_pipe) { - lomac_log_t *s = log_start(); - - log_append_string(s, "LOMAC: level-"); - log_append_int(s, subject_lattr.level); - log_append_string(s, " subject "); - log_append_subject_id(s, p_subject); - log_append_string(s, " contaminated level-"); - log_append_int(s, pipe_lattr.level); - log_append_string(s, " "); - log_append_object_id(s, p_pipe); - log_append_string(s, "\n"); - log_print(s); - } -#endif /* LOMAC_DEBUG_PIPE */ - } - return (0); -} /* monitor_pipe_write() */ - - -/* monitor_read_net_socket() - * - * in: p_subject - subject that read from network socket. - * out: nothing - * return: 0 - * - * - */ - -int -monitor_read_net_socket(lomac_subject_t *p_subject) { - lattr_t subject_lattr; /* lattr of `p_subject' */ - lattr_t socket_lattr; /* lattr of socket (always lowest) */ - - socket_lattr.level = LOMAC_LOWEST_LEVEL; - socket_lattr.flags = 0; - get_subject_lattr(p_subject, &subject_lattr); - - if (lomac_must_demote(&subject_lattr, &socket_lattr) && - (subject_lattr.flags & - (LOMAC_ATTR_NODEMOTE | LOMAC_ATTR_NONETDEMOTE)) == 0) { - - if (subject_do_not_demote(p_subject)) - return (0); - socket_lattr.flags = subject_lattr.flags; - set_subject_lattr(p_subject, socket_lattr); /* demote! */ - if (lomac_verbose_demote_deny) { - lomac_log_t *s = log_start(); - - log_append_string(s, "LOMAC: level-"); - log_append_int(s, subject_lattr.level); - log_append_string(s, " subject "); - log_append_subject_id(s, p_subject); - log_append_string(s, " demoted to level "); - log_append_int(s, socket_lattr.level); - log_append_string(s, " after reading from " - "the network\n"); - log_print(s); - } - } - return (0); -} diff --git a/sys/security/lomac/kernel_monitor.h b/sys/security/lomac/kernel_monitor.h deleted file mode 100644 index e7237bf84541..000000000000 --- a/sys/security/lomac/kernel_monitor.h +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef _LOMAC_MONITOR_H_ -#define _LOMAC_MONITOR_H_ - -int monitor_read_object( lomac_subject_t *, lomac_object_t * ); -int monitor_pipe_write( lomac_subject_t *, lomac_object_t * ); -int monitor_read_net_socket( lomac_subject_t *p_subject ); - - -#if 0 -void monitor_open( lomac_subject_t *p_subject, lomac_object_t *p_object ); -void monitor_pipe_create( lomac_subject_t *p_subject, - lomac_object_t *p_pipe ); -void monitor_unix_socket_bind( lomac_subject_t *p_subject, - lomac_object_t *p_socket, - lomac_object_t *p_name ); -void monitor_unix_socket_abstract( lomac_subject_t *p_subject, - lomac_object_t *p_socket ); -void monitor_unix_socketpair( lomac_subject_t *p_subject, - lomac_object_t *p_socket1, - lomac_object_t *p_socket2 ); -void monitor_unix_socket_accept_connect( lomac_subject_t *p_subject, - lomac_object_t *p_old_socket, - lomac_object_t *p_new_socket ); -#endif -#endif diff --git a/sys/security/lomac/kernel_pipe.c b/sys/security/lomac/kernel_pipe.c deleted file mode 100644 index 3aee257587da..000000000000 --- a/sys/security/lomac/kernel_pipe.c +++ /dev/null @@ -1,241 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -/* - * This file contains part of LOMAC's interface to the kernel. This - * part allows LOMAC to monitor (unnamed) pipe read and write - * operations by interposing control on the kernel's pipeops vector. - * - * The pipeops vector is defined in kern/sys_pipe.c. - * - * USAGE: - * - * The LOMAC LKM should call lomac_initialize_pipes() at LKM load time. - * This function turns unnamed pipe interposition on by modifying - * the function addresses in pipeops. - * - * Once the LOMAC LKM turns interposition on, all reads and writes - * will pass through this file's monitoring functions. - * - * This file provides a lomac_uninitialize_pipes() function which - * turns unnamed pipe interposition off by restoring pipeops to - * its original unmodified state. Once the LOMAC LKM turns - * interposition off, subsequent unnamed pipe reads and writes - * will not pass through this file's monitoring functions. - * - * HOW LOMAC HANDLES PIPES: - * - * (This text describes how LOMAC handles (unnamed) pipes in terms of - * abstract architecture-independent concepts.) LOMAC does not treat - * pipes as objects, as it does files. When the kernel creates a new - * pipe, LOMAC assigns it the highest level. Whenever a process - * writes to the pipe, LOMAC reduces the pipe's level to match the - * level of the writing process. Whenever a process reads from a - * pipe, LOMAC reduces the level of the reading process to match the - * pipe's level. As a result, if a high-level process reads the - * output of a low-level process through a pipe, the reading process - * will wind up at the low level. - * - * It takes two `struct pipe's to make a pipe. We set the level - * information in both `struct pipes', and keep them synchronized. - * - * This code presently relies on the one-big-kernel-lock to - * synchronize its access to the `pipe_state' field of each `struct - * pipe'. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lomac.h" -#include "kernel_interface.h" -#include "kernel_monitor.h" -#include "kernel_pipe.h" - - -/* `pipeops' is the kernel's pipe operations vector for the file * - * structure. All reads and writes to pipes call through this vector. */ -extern struct fileops pipeops; /* defined in kern/sys_pipe.c */ - - -/* These vars store the original addresses of the pipeops read and * - * write operations, so we can call them, and even restore them * - * later if we want to. */ -static int (*pipe_read_orig)(struct file *, struct uio *, struct ucred *, - int, struct thread *); -static int (*pipe_write_orig)(struct file *, struct uio *, struct ucred *, - int, struct thread *); - - -/* declarations of functions private to this module: */ -static int lomac_pipe_read(struct file *, struct uio *, struct ucred *, - int, struct thread *); -static int lomac_pipe_write(struct file *, struct uio *, struct ucred *, - int, struct thread *); - -/* -------------------- public functions ---------------------------- */ - -/* lomac_initialize_pipes() - * - * in: nothing - * out: nothing - * return: 0 - * - * Turns pipe interposition on by replacing the pipe_read() and pipe_write() - * operations in the kernel's pipeops vector with lomac_pipe_read() and - * lomac_pipe_write(). Saves the addresses of the original operations - * so other functions can call them, and so pipe_interposition_off() - * can restore the pipeops vector to its original unmodified state. - * - */ - -int -lomac_initialize_pipes(void) { - - pipe_read_orig = pipeops.fo_read; - pipeops.fo_read = lomac_pipe_read; - pipe_write_orig = pipeops.fo_write; - pipeops.fo_write = lomac_pipe_write; - return (0); -} /* lomac_initialize_pipes() */ - - -/* lomac_uninitialize_pipes() - * - * in: nothing - * out: nothing - * return: 0 - * - * Turns pipe interposition off by restoring the pipeops vector to its - * original unmodified state. - * - * See note at top of file regarding this function and unloading the - * LOMAC LKM. - * - */ - -int -lomac_uninitialize_pipes(void) { - - KASSERT(pipe_read_orig, ("LOMAC:pipe interpositon off before on")); - KASSERT(pipe_write_orig, ("LOMAC:pipe interpositon off before on")); - pipeops.fo_read = pipe_read_orig; - pipeops.fo_write = pipe_write_orig; - return (0); -} /* lomac_uninitialize_pipes() */ - - - -/* ------------------- private functions --------------------------- */ - -#ifndef MIN -#define MIN(lo, mac) ((lo) < (mac) ? (lo) : (mac)) -#endif - -/* lomac_pipe_read() - * - * Passes the read operation down to pipe_read_orig(). If - * pipe_read_orig() returns success, examines the level of the pipe - * and the reading process. If the reading process has a higher - * level, reduces the level of the process to equal the pipe's level. - * - */ - -static int -lomac_pipe_read(struct file *fp, struct uio *uio, struct ucred *cred, - int flags, struct thread *td) { - lomac_object_t read_pipe; /* attrs are in read end of pipe */ - struct uio kuio; - struct iovec kiov; - void *buf; - int len; - int ret_val; /* holds return values */ - - len = MIN(uio->uio_resid, BIG_PIPE_SIZE); - kiov.iov_base = buf = malloc(len, M_TEMP, M_WAITOK); - kiov.iov_len = len; - kuio.uio_iov = &kiov; - kuio.uio_iovcnt = 1; - kuio.uio_offset = 0; - kuio.uio_resid = len; - kuio.uio_segflg = UIO_SYSSPACE; - kuio.uio_rw = UIO_READ; - kuio.uio_td = td; - ret_val = pipe_read_orig(fp, &kuio, cred, flags, td); - if (ret_val == 0) { - read_pipe.lo_type = LO_TYPE_PIPE; - read_pipe.lo_object.pipe = (struct pipe *)fp->f_data; - (void)monitor_read_object(td->td_proc, &read_pipe); - ret_val = uiomove(buf, len - kuio.uio_resid, uio); - } - free(buf, M_TEMP); - return (ret_val); -} /* lomac_pipe_read() */ - - -/* lomac_pipe_write() - * - * Passes the write operation down to pipe_write_orig(). If - * pipe_write_orig() returns success, examines the level of the pipe - * and the writing process. If the pipe has a higher level than the - * writing process, this function reduces the pipe's level to equal - * the level of the writing process. - * - */ - -static int -lomac_pipe_write(struct file *fp, struct uio *uio, struct ucred *cred, - int flags, struct thread *td) { - lomac_object_t pipe; - int ret_val; /* holds return values */ - - pipe.lo_type = LO_TYPE_PIPE; - pipe.lo_object.pipe = (struct pipe *)fp->f_data; - ret_val = monitor_pipe_write(td->td_proc, &pipe); - if (ret_val == 0) - ret_val = pipe_write_orig(fp, uio, cred, flags, td); - - return (ret_val); -} /* lomac_pipe_write() */ diff --git a/sys/security/lomac/kernel_pipe.h b/sys/security/lomac/kernel_pipe.h deleted file mode 100644 index 1dc268badb99..000000000000 --- a/sys/security/lomac/kernel_pipe.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef _KERNEL_PIPE_H_ -#define _KERNEL_PIPE_H_ - -int lomac_initialize_pipes( void ); -int lomac_uninitialize_pipes( void ); - -#endif /* _KERNEL_PIPE_H_ */ diff --git a/sys/security/lomac/kernel_plm.c b/sys/security/lomac/kernel_plm.c deleted file mode 100644 index 060f3fcedfb2..000000000000 --- a/sys/security/lomac/kernel_plm.c +++ /dev/null @@ -1,382 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kernel_interface.h" -#include "kernel_plm.h" -#include "lomacfs.h" -#include "policy_plm.h" - -MALLOC_DEFINE(M_LOMACPLM, "LOMAC_PLM", "LOMAC PLM nodes and strings"); -char *strsep(register char **stringp, register const char *delim); - -/* - * Get next token from string *stringp, where tokens are possibly-empty - * strings separated by characters from delim. - * - * Writes NULs into the string at *stringp to end tokens. - * delim need not remain constant from call to call. - * On return, *stringp points past the last NUL written (if there might - * be further tokens), or is NULL (if there are definitely no more tokens). - * - * If *stringp is NULL, strsep returns NULL. - */ -char * -strsep(stringp, delim) - register char **stringp; - register const char *delim; -{ - register char *s; - register const char *spanp; - register int c, sc; - char *tok; - - if ((s = *stringp) == NULL) - return (NULL); - for (tok = s;;) { - c = *s++; - spanp = delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringp = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ -} - -struct lomac_node_entry lomac_node_entry_root = { - SLIST_HEAD_INITIALIZER(lomac_node_entry), - { NULL }, - LN_HIGHEST_LEVEL | LN_INHERIT_HIGH, - "/" -}; - -static struct lomac_node_entry * -lomac_plm_subtree_find_cnp(struct lomac_node_entry *root, - struct componentname *cnp) { - char *nameptr = cnp->cn_nameptr; - struct lomac_node_entry *lne; - int len = cnp->cn_namelen; - - SLIST_FOREACH(lne, &root->ln_children, ln_chain) - if (strlen(lne->ln_name) == len && - bcmp(lne->ln_name, nameptr, len) == 0) - break; - - return (lne); -} - -static struct lomac_node_entry * -lomac_plm_subtree_find(struct lomac_node_entry *root, const char *name) { - struct lomac_node_entry *lne; - - SLIST_FOREACH(lne, &root->ln_children, ln_chain) - if (strcmp(name, lne->ln_name) == 0) - break; - - return (lne); -} - - -/* - * This is called from inside getnewvnode() before the vnode is in use. - */ -void -lomac_plm_init_lomacfs_vnode(struct vnode *dvp, struct vnode *vp, - struct componentname *cnp, lattr_t *subjlattr) { - struct lomac_node *ln = VTOLOMAC(vp); - struct lomac_node_entry *mlne = NULL; - - /* - * Only "/" has no parent, so inherit directly from our PLM root. - */ - if (dvp == NULL) { - ln->ln_flags = lomac_node_entry_root.ln_flags; - ln->ln_entry = ln->ln_underpolicy = &lomac_node_entry_root; - } else { - struct lomac_node *dln = VTOLOMAC(dvp); - struct lomac_node_entry *dlne = dln->ln_entry; - int fixup_inherit = 0; - - /* - * If we have no directory-specific entry, we inherit - * directly from the lomac_node's previously-inherited - * flags implicitly, otherwise we inherit explicitly - * from the corresponding lomac_node_entry. - */ - if (dlne == NULL) { - ln->ln_flags = dln->ln_flags & LN_INHERIT_MASK; - fixup_inherit = 1; - ln->ln_underpolicy = dln->ln_underpolicy; - ln->ln_entry = NULL; - } else if ((mlne = lomac_plm_subtree_find_cnp(dlne, cnp)) == - NULL) { - ln->ln_flags = dlne->ln_flags & LN_INHERIT_MASK; - fixup_inherit = 2; - ln->ln_underpolicy = dlne; - ln->ln_entry = NULL; - } else { - ln->ln_entry = ln->ln_underpolicy = mlne; - } - if (fixup_inherit) { - switch (ln->ln_flags) { - case LN_INHERIT_LOW: - ln->ln_flags |= LN_LOWEST_LEVEL; - break; - case LN_INHERIT_SUBJ: - if (subjlattr->level == LOMAC_HIGHEST_LEVEL) - ln->ln_flags |= LN_HIGHEST_LEVEL; - else { - ln->ln_flags &= ~LN_INHERIT_MASK; - ln->ln_flags |= LN_INHERIT_LOW | - LN_LOWEST_LEVEL; - } - break; - case LN_INHERIT_HIGH: - ln->ln_flags |= LN_HIGHEST_LEVEL; - break; - } - if (fixup_inherit == 2) - ln->ln_flags |= - (dlne->ln_flags & LN_CHILD_ATTR_MASK) >> - LN_CHILD_ATTR_SHIFT; - } else { - /* this is the only case where mlne != NULL */ - ln->ln_flags &= ~(LN_INHERIT_MASK | LN_ATTR_MASK); - ln->ln_flags |= mlne->ln_flags & - (LN_INHERIT_MASK | LN_ATTR_MASK); - if ((mlne->ln_flags & LN_LEVEL_MASK) == - LN_SUBJ_LEVEL) { - if (subjlattr->level == LOMAC_HIGHEST_LEVEL) - ln->ln_flags |= LN_HIGHEST_LEVEL; - else - ln->ln_flags |= LN_LOWEST_LEVEL; - } else - ln->ln_flags |= mlne->ln_flags & LN_LEVEL_MASK; - } - } - - KASSERT(ln->ln_flags & LN_LEVEL_MASK, ("lomac_node has no level")); - KASSERT(ln->ln_flags & LN_INHERIT_MASK, ("lomac_node has no inherit")); -#ifdef INVARIANTS - if (mlne != NULL) { - KASSERT(mlne->ln_flags & LN_LEVEL_MASK, - ("lomac_node_entry has no level")); - KASSERT(mlne->ln_flags & LN_INHERIT_MASK, - ("lomac_node_entry has no inherit")); - } -#endif /* INVARIANTS */ -} - -static struct lomac_node_entry * -lomac_plm_subtree_new(struct lomac_node_entry *plne, char *name) { - struct lomac_node_entry *lne; - static struct lomac_node_entry_head head_init = - SLIST_HEAD_INITIALIZER(lomac_node_entry); - - lne = malloc(sizeof(*lne), M_LOMACPLM, M_WAITOK); - bcopy(&head_init, &lne->ln_children, sizeof(head_init)); - lne->ln_name = name; - lne->ln_flags = plne->ln_flags & LN_INHERIT_MASK; - switch (lne->ln_flags) { - case LN_INHERIT_LOW: - lne->ln_flags |= LN_LOWEST_LEVEL; - break; - case LN_INHERIT_HIGH: - lne->ln_flags |= LN_HIGHEST_LEVEL; - break; - case LN_INHERIT_SUBJ: - lne->ln_flags |= LN_SUBJ_LEVEL; - break; - } - SLIST_INSERT_HEAD(&plne->ln_children, lne, ln_chain); - return (lne); -} - -static void -lomac_plm_subtree_free(struct lomac_node_entry *lneself) { - struct lomac_node_entry_head *head = &lneself->ln_children; - struct lomac_node_entry *lne; - - while (!SLIST_EMPTY(head)) { - lne = SLIST_FIRST(head); - SLIST_REMOVE_HEAD(head, ln_chain); - lomac_plm_subtree_free(lne); - } - free(lneself, M_LOMACPLM); -} - -struct string_list { - SLIST_ENTRY(string_list) entries; - char string[1]; -}; -static SLIST_HEAD(, string_list) string_list_head = - SLIST_HEAD_INITIALIZER(string_list); - -static char * -string_list_new(const char *s) { - struct string_list *sl; - - sl = malloc(sizeof(*sl) + strlen(s), M_LOMACPLM, M_WAITOK); - strcpy(sl->string, s); - SLIST_INSERT_HEAD(&string_list_head, sl, entries); - - return (sl->string); -} - -static void -lomac_plm_uninitialize(void) { - struct lomac_node_entry_head *head = &lomac_node_entry_root.ln_children; - struct lomac_node_entry *lne; - struct string_list *sl; - - while (!SLIST_EMPTY(head)) { - lne = SLIST_FIRST(head); - SLIST_REMOVE_HEAD(head, ln_chain); - lomac_plm_subtree_free(lne); - } - while (!SLIST_EMPTY(&string_list_head)) { - sl = SLIST_FIRST(&string_list_head); - SLIST_REMOVE_HEAD(&string_list_head, entries); - free(sl, M_LOMACPLM); - } -} - -static int -lomac_plm_initialize(void) { - struct lomac_node_entry *plne, *lne; - plm_rule_t *pr; - - for (pr = plm; pr->path != NULL; pr++) { - char *path; - char *comp; - int depth; - - if (*pr->path == '\0') { - printf("lomac_plm: invalid path \"%s\"\n", pr->path); - return (EINVAL); - } - path = string_list_new(pr->path); - lne = &lomac_node_entry_root; - depth = 0; - for (;; depth++) { - plne = lne; - comp = strsep(&path, "/"); - if (comp == NULL) - break; - if (depth == 0) { /* special case: beginning / */ - if (*comp == '\0') - continue; - else { - printf("lomac_plm: not absolute path " - "\"%s\"\n", pr->path); - return (EINVAL); - } - } else if (depth == 1) { /* special case: "/" */ - if (*comp == '\0' && strsep(&path, "/") == NULL) - break; - } - if (*comp == '\0' || - strcmp(comp, ".") == 0 || - strcmp(comp, "..") == 0) { - printf("lomac_plm: empty path component in " - "\"%s\"\n", pr->path); - return (EINVAL); - } - lne = lomac_plm_subtree_find(plne, comp); - if (lne == NULL) { - lne = lomac_plm_subtree_new(plne, comp); - lne->ln_path = plne->ln_path; - } - } - lne->ln_path = pr->path; - if (pr->flags == PLM_NOFLAGS) - lne->ln_flags &= ~LN_LEVEL_MASK; - else - lne->ln_flags &= ~LN_INHERIT_MASK; - lne->ln_flags |= - plm_levelflags_to_node_flags[pr->level][pr->flags]; - if (pr->flags == PLM_NOFLAGS) - lne->ln_flags |= pr->attr; - else - lne->ln_flags |= (pr->attr & LN_ATTR_MASK) - << LN_CHILD_ATTR_SHIFT; - } - return (0); -} - -int lomac_plm_initialized = 0; - -static int -lomac_plm_modevent(module_t module, int event, void *unused) { - int error = 0; - - switch ((enum modeventtype)event) { - case MOD_LOAD: - error = lomac_plm_initialize(); - if (error == 0) - lomac_plm_initialized = 1; - break; - case MOD_UNLOAD: - lomac_plm_uninitialize(); - case MOD_SHUTDOWN: - break; - } - return (error); -} - -static moduledata_t lomac_plm_moduledata = { - "lomac_plm", - &lomac_plm_modevent, - NULL -}; -DECLARE_MODULE(lomac_plm, lomac_plm_moduledata, SI_SUB_VFS, SI_ORDER_ANY); -MODULE_VERSION(lomac_plm, 1); diff --git a/sys/security/lomac/kernel_plm.h b/sys/security/lomac/kernel_plm.h deleted file mode 100644 index 2b0db12a3086..000000000000 --- a/sys/security/lomac/kernel_plm.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef KERNEL_PLM_H -#define KERNEL_PLM_H - -extern int lomac_plm_initialized; /* set to 1 if successfully initialized */ -void lomac_plm_init_lomacfs_vnode(struct vnode *dvp, struct vnode *vp, - struct componentname *cnp, lattr_t *subjlattr); - -#endif /* KERNEL_PLM_H */ diff --git a/sys/security/lomac/kernel_socket.c b/sys/security/lomac/kernel_socket.c deleted file mode 100644 index 291ccc2e97e9..000000000000 --- a/sys/security/lomac/kernel_socket.c +++ /dev/null @@ -1,813 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. Neither the name of the the above entities nor the names of any - * contributors of those entities may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - */ -/* - * Copyright (c) 1982, 1986, 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 - * $FreeBSD$ - */ - -/* - * This file implements LOMAC controls over socket operations. LOMAC - * gains control of socket operations by interposing on the `struct - * pr_usrreqs' operations vectors of each `struct protosw'. This code - * replaces each `struct pr_usrreqs' with an instance of `struct - * lomac_pr_usrreqs' containing LOMAC socket control functions. These - * socket control functions implement LOMAC's socket controls, and then - * call the corresponding socket operations from the original `struct - * pr_usrreqs'. Each instance of `struct lomac_pr_usrreqs' ends with - * a pointer to the `struct pr_usrreqs' it replaces. These pointers - * allow the LOMAC socket control functions to find their corresponding - * original `struct pr_usrreqs' functions. - * - * This file provides the function lomac_initialize_sockets() to turn - * socket interposition on. Once socket iterposition is turned on, - * the kernel will begin to call LOMAC's socket control functions. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kernel_interface.h" -#include "kernel_socket.h" -#include "kernel_mediate.h" -#include "kernel_monitor.h" -#include "lomacfs.h" - -MALLOC_DEFINE(M_LOMAC_USRREQS, "LOMAC-UR", "LOMAC usrreqs"); - -struct lomac_pr_usrreqs { - struct pr_usrreqs lomac_pr_usrreqs; /* LOMAC socket control fxns */ - struct pr_usrreqs *orig_pr_usrreqs; /* original socket op vector */ -}; - -int lomac_local_accept(struct socket *, struct sockaddr **); -int lomac_local_connect(struct socket *, struct sockaddr *, struct thread *); -int lomac_local_connect2(struct socket *, struct socket *); -int lomac_local_detach(struct socket *); -int lomac_local_send( struct socket *, int, struct mbuf *, struct sockaddr *, - struct mbuf *, struct thread * ); -int lomac_soreceive( struct socket *, struct sockaddr **, struct uio *, - struct mbuf **, struct mbuf **, int * ); -int lomac_local_soreceive( struct socket *, struct sockaddr **, struct uio *, - struct mbuf **, struct mbuf **, int * ); -static int monitored_soreceive( struct socket *, struct sockaddr **, - struct uio *, struct mbuf **, struct mbuf **, int * ); - -/* This usrreqs structure implements LOMAC's controls on local sockets */ -struct pr_usrreqs lomac_local_usrreqs = { - NULL, - lomac_local_accept, - NULL, - NULL, - lomac_local_connect, - lomac_local_connect2, - NULL, - lomac_local_detach, - NULL, - NULL, - NULL, - NULL, - NULL, - lomac_local_send, - NULL, - NULL, - NULL, - NULL, - lomac_local_soreceive, - NULL -}; - -/* This usrreqs structure implements LOMAC's controls on network sockets */ -struct pr_usrreqs lomac_net_usrreqs = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - lomac_soreceive, - NULL -}; - -static __inline struct pr_usrreqs * -orig_pr_usrreqs( struct socket *so ) { - return (((struct lomac_pr_usrreqs *)(so->so_proto->pr_usrreqs))-> - orig_pr_usrreqs); -} - -int -lomac_local_accept( struct socket *so, struct sockaddr **nam ) { - struct vnode *vp; - struct unpcb *unp; - int ret_val; /* value to return to caller */ - - unp = sotounpcb(so); - if (unp == NULL) - return (EINVAL); - if (unp->unp_conn != NULL) { - vp = unp->unp_vnode = unp->unp_conn->unp_vnode; - if (vp != NULL) - vref(vp); - } - ret_val = (*orig_pr_usrreqs(so)->pru_accept)(so, nam); - return (ret_val); -} - -int -lomac_local_connect(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - register struct sockaddr_un *soun = (struct sockaddr_un *)nam; - register struct vnode *vp; - register struct socket *so2, *so3; - struct unpcb *unp, *unp2, *unp3; - int error, len; - struct nameidata nd; - char buf[SOCK_MAXADDRLEN]; - - len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); - if (len <= 0) - return EINVAL; - strncpy(buf, soun->sun_path, len); - buf[len] = 0; - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, buf, td); - error = namei(&nd); - if (error) - goto bad2; - vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); - if (vp->v_type != VSOCK) { - error = ENOTSOCK; - goto bad; - } - error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td); - if (error) - goto bad; - so2 = vp->v_socket; - if (so2 == 0) { - error = ECONNREFUSED; - goto bad; - } - if (so->so_type != so2->so_type) { - error = EPROTOTYPE; - goto bad; - } - if (so->so_proto->pr_flags & PR_CONNREQUIRED) { - if ((so2->so_options & SO_ACCEPTCONN) == 0 || - (so3 = sonewconn(so2, 0)) == 0) { - error = ECONNREFUSED; - goto bad; - } - unp = sotounpcb(so); - unp2 = sotounpcb(so2); - unp3 = sotounpcb(so3); - if (unp2->unp_addr) - unp3->unp_addr = (struct sockaddr_un *) - dup_sockaddr((struct sockaddr *) - unp2->unp_addr, 1); - - /* - * unp_peercred management: - * - * The connecter's (client's) credentials are copied - * from its process structure at the time of connect() - * (which is now). - */ - cru2x(td->td_ucred, &unp3->unp_peercred); - unp3->unp_flags |= UNP_HAVEPC; - /* - * The receiver's (server's) credentials are copied - * from the unp_peercred member of socket on which the - * former called listen(); unp_listen() cached that - * process's credentials at that time so we can use - * them now. - */ - KASSERT(unp2->unp_flags & UNP_HAVEPCCACHED, - ("unp_connect: listener without cached peercred")); - memcpy(&unp->unp_peercred, &unp2->unp_peercred, - sizeof(unp->unp_peercred)); - unp->unp_flags |= UNP_HAVEPC; - - so2 = so3; - } - error = lomac_local_connect2(so, so2); -bad: - vput(vp); -bad2: - return (error); -} - -int -lomac_local_connect2( struct socket *so1, struct socket *so2 ) { - struct vnode *vp; - int ret_val; /* value to return to caller */ - - if (so2->so_head != NULL) { - vp = sotounpcb(so2->so_head)->unp_vnode; - if (vp != NULL) { - sotounpcb(so1)->unp_vnode = vp; - vref(vp); - } - } - ret_val = (*orig_pr_usrreqs(so1)->pru_connect2)(so1, so2); - return (ret_val); -} - -int -lomac_local_detach( struct socket *so ) { - int ret_val; /* value to return to caller */ - struct unpcb *unp = sotounpcb(so); - - if (unp == NULL) - return (EINVAL); - if (unp->unp_vnode != NULL && unp->unp_vnode->v_socket != so) { - vrele(unp->unp_vnode); - unp->unp_vnode = NULL; - } - ret_val = (*orig_pr_usrreqs(so)->pru_detach)(so); - return (ret_val); -} - -int -lomac_local_send( struct socket *so, int flags, struct mbuf *m, - struct sockaddr *addr, struct mbuf *control, struct thread *td ) { - struct vnode *vp; - struct unpcb *unp = sotounpcb(so); - int error; - - /* printf( "pid %d local send\n", p->p_pid ); */ - if (unp == NULL) { - error = EINVAL; - goto out; - } - if (so->so_type == SOCK_DGRAM) { - if (addr != NULL) { - if (unp->unp_conn != NULL) { - error = EISCONN; - goto out; - } - error = lomac_local_connect(so, addr, td); - if (error) - goto out; - } else if (unp->unp_conn == NULL) { - error = ENOTCONN; - goto out; - } - } else if ((so->so_state & SS_ISCONNECTED) == 0) { - if (addr != NULL) { - error = lomac_local_connect(so, addr, td); - if (error) - goto out; /* XXX */ - } else { - error = ENOTCONN; - goto out; - } - } - vp = unp->unp_vnode; - if (vp != NULL) { - lomac_object_t lobj; - - lobj.lo_type = VISLOMAC(vp) ? LO_TYPE_LVNODE : LO_TYPE_UVNODE; - lobj.lo_object.vnode = vp; - if (!mediate_subject_object("send", td->td_proc, &lobj)) { - error = EPERM; - goto out; - } - } else { - /* - * This is a send to a socket in a socketpair() pair. - * Mark both sockets in pair with the appropriate level. - */ - lomac_object_t lobj1, lobj2; - lattr_t lattr; - - lobj1.lo_type = LO_TYPE_SOCKETPAIR; - lobj1.lo_object.socket = so; - if ((error = monitor_pipe_write(td->td_proc, &lobj1)) != 0) - goto out; - lobj2.lo_type = LO_TYPE_SOCKETPAIR; - lobj2.lo_object.socket = unp->unp_conn->unp_socket; - get_object_lattr(&lobj1, &lattr); - set_object_lattr(&lobj2, lattr); - } - error = (*orig_pr_usrreqs(so)->pru_send)( so, flags, m, NULL, - control, td ); - if (addr != NULL && so->so_type == SOCK_DGRAM) - (*orig_pr_usrreqs(so)->pru_disconnect)(so); -out: - return (error); -} - - - -int -lomac_local_soreceive(struct socket *so, struct sockaddr **paddr, - struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp) { - lomac_object_t lobj; - struct vnode *vp; - struct unpcb *unp = sotounpcb(so); - int ret_val; /* value to return to caller */ - - if (unp == NULL) - return (EINVAL); - vp = unp->unp_vnode; - if (vp != NULL) { - lobj.lo_type = VISLOMAC(vp) ? LO_TYPE_LVNODE : LO_TYPE_UVNODE; - lobj.lo_object.vnode = vp; - ret_val = monitor_read_object(uio->uio_td->td_proc, &lobj); - if (ret_val == 0) - ret_val = (*orig_pr_usrreqs(so)->pru_soreceive)(so, - paddr, uio, mp0, controlp, flagsp); - } else { - /* - * This is a receive from a socket in a pair created by - * socketpair(). Monitor it as we would a pipe read, - * except for allowing for arbitrary numbers of sleeps. - */ - ret_val = monitored_soreceive(so, paddr, uio, mp0, controlp, - flagsp); - } - return (ret_val); -} - -int -lomac_soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio, - struct mbuf **mp0, struct mbuf **controlp, int *flagsp) { - int ret_val; /* value to return to caller */ - - (void)monitor_read_net_socket(uio->uio_td->td_proc); - ret_val = (*orig_pr_usrreqs(so)->pru_soreceive)(so, paddr, uio, mp0, - controlp, flagsp); - return (ret_val); -} - -int -lomac_initialize_sockets(void) { - struct domain *dp; /* used to traverse global `domains' list */ - struct protosw *pr; /* used to traverse each domain's protosw list */ - struct lomac_pr_usrreqs *lomac_pr_usrreqs; /* lomac usrreqs vectors */ - void (**lfuncp)(void), (**funcp)(void); - int n, nreq; - - nreq = sizeof(struct pr_usrreqs) / sizeof(void (*)(void)); - for (dp = domains; dp; dp = dp->dom_next) { - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { - - lomac_pr_usrreqs = (struct lomac_pr_usrreqs *)malloc( - sizeof(struct lomac_pr_usrreqs), M_LOMAC_USRREQS, - M_WAITOK); - - if (dp->dom_family == AF_LOCAL) - memcpy(lomac_pr_usrreqs, &lomac_local_usrreqs, - sizeof(struct pr_usrreqs)); - else - memcpy(lomac_pr_usrreqs, &lomac_net_usrreqs, - sizeof(struct pr_usrreqs)); - /* - * Do sparse allocation of user requests and only - * override the ones we need to (to reduce overhead). - */ - lfuncp = (void (**)(void))lomac_pr_usrreqs; - funcp = (void (**)(void))pr->pr_usrreqs; - for (n = 0; n < nreq; n++) { - if (lfuncp[n] == NULL) - lfuncp[n] = funcp[n]; - } - lomac_pr_usrreqs->orig_pr_usrreqs = pr->pr_usrreqs; - pr->pr_usrreqs = (struct pr_usrreqs *)lomac_pr_usrreqs; - } - } - return (0); -} - - -int -lomac_uninitialize_sockets(void) { - struct domain *dp; /* used to traverse global `domains' list */ - struct protosw *pr; /* used to traverse each domain's protosw list */ - struct lomac_pr_usrreqs *lomac_pr_usrreqs; /* lomac usrreqs vectors */ - - for (dp = domains; dp; dp = dp->dom_next) { - for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { - lomac_pr_usrreqs = (struct lomac_pr_usrreqs *) - pr->pr_usrreqs; - pr->pr_usrreqs = lomac_pr_usrreqs->orig_pr_usrreqs; - free(lomac_pr_usrreqs, M_LOMAC_USRREQS); - } - } - return (0); -} - -#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK) -/* - * Implement receive operations on a socket. - * We depend on the way that records are added to the sockbuf - * by sbappend*. In particular, each record (mbufs linked through m_next) - * must begin with an address if the protocol so specifies, - * followed by an optional mbuf or mbufs containing ancillary data, - * and then zero or more mbufs of data. - * In order to avoid blocking network interrupts for the entire time here, - * we splx() while doing the actual copy to user space. - * Although the sockbuf is locked, new data may still be appended, - * and thus we must maintain consistency of the sockbuf during that time. - * - * The caller may receive the data as a single mbuf chain by supplying - * an mbuf **mp0 for use in returning the chain. The uio is then used - * only for the count in uio_resid. - */ -static int -monitored_soreceive(so, psa, uio, mp0, controlp, flagsp) - register struct socket *so; - struct sockaddr **psa; - struct uio *uio; - struct mbuf **mp0; - struct mbuf **controlp; - int *flagsp; -{ - lomac_object_t lobj; - register struct mbuf *m, **mp; - register int flags, len, error, s, offset; - struct protosw *pr = so->so_proto; - struct mbuf *nextrecord; - struct proc *p; - int moff, type = 0; - int orig_resid = uio->uio_resid; - - mp = mp0; - if (psa) - *psa = 0; - if (controlp) - *controlp = 0; - if (flagsp) - flags = *flagsp &~ MSG_EOR; - else - flags = 0; - lobj.lo_type = LO_TYPE_SOCKETPAIR; - lobj.lo_object.socket = so; - if (uio->uio_td != NULL) /* XXX */ - p = uio->uio_td->td_proc; - else - p = curthread->td_proc; - if (flags & MSG_OOB) { - m = m_get(M_TRYWAIT, MT_DATA); - if (m == NULL) - return (ENOBUFS); - error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK); - if (error) - goto bad; - do { - monitor_read_object(p, &lobj); - error = uiomove(mtod(m, caddr_t), - (int) min(uio->uio_resid, m->m_len), uio); - m = m_free(m); - } while (uio->uio_resid && error == 0 && m); -bad: - if (m) - m_freem(m); - return (error); - } - if (mp) - *mp = (struct mbuf *)0; - if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) - (*pr->pr_usrreqs->pru_rcvd)(so, 0); - -restart: - error = sblock(&so->so_rcv, SBLOCKWAIT(flags)); - if (error) - return (error); - s = splnet(); - - m = so->so_rcv.sb_mb; - /* - * If we have less data than requested, block awaiting more - * (subject to any timeout) if: - * 1. the current count is less than the low water mark, or - * 2. MSG_WAITALL is set, and it is possible to do the entire - * receive operation at once if we block (resid <= hiwat). - * 3. MSG_DONTWAIT is not set - * If MSG_WAITALL is set but resid is larger than the receive buffer, - * we have to do the receive in sections, and thus risk returning - * a short count if a timeout or signal occurs after we start. - */ - if (m == 0 || (((flags & MSG_DONTWAIT) == 0 && - so->so_rcv.sb_cc < uio->uio_resid) && - (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || - ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) && - m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0)) { - KASSERT(m != 0 || !so->so_rcv.sb_cc, - ("receive: m == %p so->so_rcv.sb_cc == %lu", - m, so->so_rcv.sb_cc)); - if (so->so_error) { - if (m) - goto dontblock; - error = so->so_error; - if ((flags & MSG_PEEK) == 0) - so->so_error = 0; - goto release; - } - if (so->so_state & SS_CANTRCVMORE) { - if (m) - goto dontblock; - else - goto release; - } - for (; m; m = m->m_next) - if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) { - m = so->so_rcv.sb_mb; - goto dontblock; - } - if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 && - (so->so_proto->pr_flags & PR_CONNREQUIRED)) { - error = ENOTCONN; - goto release; - } - if (uio->uio_resid == 0) - goto release; - if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) { - error = EWOULDBLOCK; - goto release; - } - sbunlock(&so->so_rcv); - error = sbwait(&so->so_rcv); - splx(s); - if (error) - return (error); - goto restart; - } -dontblock: - if (uio->uio_td) - p->p_stats->p_ru.ru_msgrcv++; - nextrecord = m->m_nextpkt; - if (pr->pr_flags & PR_ADDR) { - KASSERT(m->m_type == MT_SONAME, ("receive 1a")); - orig_resid = 0; - if (psa) - *psa = dup_sockaddr(mtod(m, struct sockaddr *), - mp0 == 0); - if (flags & MSG_PEEK) { - m = m->m_next; - } else { - sbfree(&so->so_rcv, m); - so->so_rcv.sb_mb = m_free(m); - m = so->so_rcv.sb_mb; - } - } - while (m && m->m_type == MT_CONTROL && error == 0) { - if (flags & MSG_PEEK) { - if (controlp) - *controlp = m_copy(m, 0, m->m_len); - m = m->m_next; - } else { - sbfree(&so->so_rcv, m); - so->so_rcv.sb_mb = m->m_next; - m->m_next = NULL; - if (pr->pr_domain->dom_externalize) - error = - (*pr->pr_domain->dom_externalize)(m, controlp); - else if (controlp) - *controlp = m; - else - m_freem(m); - m = so->so_rcv.sb_mb; - } - if (controlp) { - orig_resid = 0; - do - controlp = &(*controlp)->m_next; - while (*controlp != NULL); - } - } - if (m) { - if ((flags & MSG_PEEK) == 0) - m->m_nextpkt = nextrecord; - type = m->m_type; - if (type == MT_OOBDATA) - flags |= MSG_OOB; - } - moff = 0; - offset = 0; - while (m && uio->uio_resid > 0 && error == 0) { - if (m->m_type == MT_OOBDATA) { - if (type != MT_OOBDATA) - break; - } else if (type == MT_OOBDATA) - break; - else - KASSERT(m->m_type == MT_DATA || m->m_type == MT_HEADER, - ("receive 3")); - so->so_state &= ~SS_RCVATMARK; - len = uio->uio_resid; - if (so->so_oobmark && len > so->so_oobmark - offset) - len = so->so_oobmark - offset; - if (len > m->m_len - moff) - len = m->m_len - moff; - /* - * If mp is set, just pass back the mbufs. - * Otherwise copy them out via the uio, then free. - * Sockbuf must be consistent here (points to current mbuf, - * it points to next record) when we drop priority; - * we must note any additions to the sockbuf when we - * block interrupts again. - */ - if (mp == 0) { - splx(s); - monitor_read_object(p, &lobj); - error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio); - s = splnet(); - if (error) - goto release; - } else - uio->uio_resid -= len; - if (len == m->m_len - moff) { - if (m->m_flags & M_EOR) - flags |= MSG_EOR; - if (flags & MSG_PEEK) { - m = m->m_next; - moff = 0; - } else { - nextrecord = m->m_nextpkt; - sbfree(&so->so_rcv, m); - if (mp) { - *mp = m; - mp = &m->m_next; - so->so_rcv.sb_mb = m = m->m_next; - *mp = (struct mbuf *)0; - } else { - so->so_rcv.sb_mb = m_free(m); - m = so->so_rcv.sb_mb; - } - if (m) - m->m_nextpkt = nextrecord; - } - } else { - if (flags & MSG_PEEK) - moff += len; - else { - if (mp) - *mp = m_copym(m, 0, len, M_TRYWAIT); - m->m_data += len; - m->m_len -= len; - so->so_rcv.sb_cc -= len; - } - } - if (so->so_oobmark) { - if ((flags & MSG_PEEK) == 0) { - so->so_oobmark -= len; - if (so->so_oobmark == 0) { - so->so_state |= SS_RCVATMARK; - break; - } - } else { - offset += len; - if (offset == so->so_oobmark) - break; - } - } - if (flags & MSG_EOR) - break; - /* - * If the MSG_WAITALL flag is set (for non-atomic socket), - * we must not quit until "uio->uio_resid == 0" or an error - * termination. If a signal/timeout occurs, return - * with a short count but without error. - * Keep sockbuf locked against other readers. - */ - while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 && - !sosendallatonce(so) && !nextrecord) { - if (so->so_error || so->so_state & SS_CANTRCVMORE) - break; - /* - * Notify the protocol that some data has been - * drained before blocking. - */ - if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) - (*pr->pr_usrreqs->pru_rcvd)(so, flags); - error = sbwait(&so->so_rcv); - if (error) { - sbunlock(&so->so_rcv); - splx(s); - return (0); - } - m = so->so_rcv.sb_mb; - if (m) - nextrecord = m->m_nextpkt; - } - } - - if (m && pr->pr_flags & PR_ATOMIC) { - flags |= MSG_TRUNC; - if ((flags & MSG_PEEK) == 0) - (void) sbdroprecord(&so->so_rcv); - } - if ((flags & MSG_PEEK) == 0) { - if (m == 0) - so->so_rcv.sb_mb = nextrecord; - if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) - (*pr->pr_usrreqs->pru_rcvd)(so, flags); - } - if (orig_resid == uio->uio_resid && orig_resid && - (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { - sbunlock(&so->so_rcv); - splx(s); - goto restart; - } - - if (flagsp) - *flagsp |= flags; -release: - sbunlock(&so->so_rcv); - splx(s); - return (error); -} diff --git a/sys/security/lomac/kernel_socket.h b/sys/security/lomac/kernel_socket.h deleted file mode 100644 index f4f7ccb360ee..000000000000 --- a/sys/security/lomac/kernel_socket.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef _KERNEL_SOCKET_H_ -#define _KERNEL_SOCKET_H_ - -int lomac_initialize_sockets( void ); -int lomac_uninitialize_sockets( void ); - -#endif /* _KERNEL_SOCKET_H_ */ - diff --git a/sys/security/lomac/kernel_util.c b/sys/security/lomac/kernel_util.c deleted file mode 100644 index 42de89947e95..000000000000 --- a/sys/security/lomac/kernel_util.c +++ /dev/null @@ -1,696 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * Copyright (c) 1982, 1986, 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kernel_interface.h" -#include "kernel_util.h" -#include "kernel_mediate.h" -#include "kernel_monitor.h" -#include "lomacfs.h" - -#include "syscall_gate.h" - -#define AS(name) (sizeof(struct name) / sizeof(register_t)) - -int -each_proc(int (*iter)(struct proc *p)) { - struct proc *p; - int error = 0; - - sx_slock(&allproc_lock); - LIST_FOREACH(p, &allproc, p_list) { - error = (*iter)(p); - if (error) - goto out; - } -out: - sx_sunlock(&allproc_lock); - return (error); -} - -static int -initialize_proc(struct proc *p) { - lattr_t lattr = { LOMAC_HIGHEST_LEVEL, 0 }; - - init_subject_lattr(p, &lattr); - return (0); -} - -static void -lomac_at_fork(struct proc *parent, struct proc *p, int flags) { - - if ((flags & RFMEM) == 0) { - lattr_t parent_lattr; - - get_subject_lattr(parent, &parent_lattr); - init_subject_lattr(p, &parent_lattr); - } -} - -static int -lomac_proc_candebug(struct proc *p1, struct proc *p2) { - lattr_t lattr; - - get_subject_lattr(p1, &lattr); - if (mediate_subject_level_subject("debug", p1, lattr.level, p2)) - return (0); - else - return (EPERM); -} - -static int -lomac_proc_cansched(struct proc *p1, struct proc *p2) { - lattr_t lattr; - - get_subject_lattr(p1, &lattr); - if (mediate_subject_level_subject("sched", p1, lattr.level, p2)) - return (0); - else - return (EPERM); -} - -static int -lomac_proc_cansignal(struct proc *p1, struct proc *p2, int signum) { - lattr_t lattr; - - get_subject_lattr(p1, &lattr); - /* - * Always allow signals to init(8) (necessary to shut down). - */ - if (p2->p_pid == 1 || - mediate_subject_level_subject("signal", p1, lattr.level, p2)) - return (0); - else - return (EPERM); -} - - -int -lomac_initialize_procs(void) { - int error; - -#ifdef P_CAN_HOOKS - can_hooks_lock(); - (void)p_candebug_hook(lomac_proc_candebug); - (void)p_cansignal_hook(lomac_proc_cansignal); - (void)p_cansched_hook(lomac_proc_cansched); - can_hooks_unlock(); -#endif - error = at_fork(lomac_at_fork); - if (error) - return (error); - return (each_proc(&initialize_proc)); -} - -int -lomac_uninitialize_procs(void) { - - rm_at_fork(lomac_at_fork); - return (0); -} - -extern int (*old_execve)(struct thread *, struct execve_args *); - -int -execve(struct thread *td, struct execve_args *uap) { - lattr_t lattr, textattr; - struct vmspace *oldvmspace; - struct proc *p; - int error; - - p = td->td_proc; - get_subject_lattr(p, &lattr); - oldvmspace = p->p_vmspace; - error = old_execve(td, uap); - if (error == 0) { - lomac_object_t lobj; - - lobj.lo_type = VISLOMAC(p->p_textvp) ? LO_TYPE_LVNODE : - LO_TYPE_UVNODE; - lobj.lo_object.vnode = p->p_textvp; - get_object_lattr(&lobj, &textattr); - /* - * Install the executable's relevant attributes into the - * process. - */ - lattr.flags |= textattr.flags & - (LOMAC_ATTR_NODEMOTE | LOMAC_ATTR_NONETDEMOTE); - if (p->p_vmspace != oldvmspace) - init_subject_lattr(p, &lattr); - else - set_subject_lattr(p, lattr); - mtx_lock(&Giant); - (void)monitor_read_object(p, &lobj); - mtx_unlock(&Giant); - } - return (error); -} - -const char *linker_basename(const char* path); -int linker_load_module(const char *kldname, const char *modname, - struct linker_file *parent, struct mod_depend *verinfo, - struct linker_file **lfpp); - -MALLOC_DECLARE(M_LINKER); - -/* - * MPSAFE - */ -int -kldload(struct thread* td, struct kldload_args* uap) -{ - char *kldname, *modname; - char *pathname = NULL; - linker_file_t lf; - int error = 0; - - td->td_retval[0] = -1; - - if (securelevel > 0) /* redundant, but that's OK */ - return EPERM; - - mtx_lock(&Giant); - - if ((error = suser(td)) != 0) - goto out; - - pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) - goto out; - if (!mediate_subject_at_level("kldload", td->td_proc, - LOMAC_HIGHEST_LEVEL)) { - error = EPERM; - goto out; - } - - /* - * If path do not contain qualified name or any dot in it (kldname.ko, or - * kldname.ver.ko) treat it as interface name. - */ - if (index(pathname, '/') || index(pathname, '.')) { - kldname = pathname; - modname = NULL; - } else { - kldname = NULL; - modname = pathname; - } - error = linker_load_module(kldname, modname, NULL, NULL, &lf); - if (error) - goto out; - - lf->userrefs++; - td->td_retval[0] = lf->id; - -out: - if (pathname) - free(pathname, M_TEMP); - mtx_unlock(&Giant); - return (error); -} - - -#ifdef __i386__ -#include - -extern int (*old_sysarch)(struct thread *, void *); - -int -sysarch(struct thread *td, struct sysarch_args *uap) { - switch (uap->op) { - case I386_SET_IOPERM: - if (!mediate_subject_at_level("ioperm", td->td_proc, - LOMAC_HIGHEST_LEVEL)) - return (EPERM); - default: - return (old_sysarch(td, uap)); - } -} -#endif - -extern int lomac_mmap(struct proc *, struct mmap_args *); - -/* - * Mount a filesystem. - */ -#ifndef _SYS_SYSPROTO_H_ -struct mount_args { - char *type; - char *path; - int flags; - caddr_t data; -}; -#endif -/* ARGSUSED */ -int -mount(td, uap) - struct thread *td; - struct mount_args /* { - syscallarg(char *) type; - syscallarg(char *) path; - syscallarg(int) flags; - syscallarg(caddr_t) data; - } */ *uap; -{ - char *fstype; - char *fspath; - int error; - - fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK | M_ZERO); - fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK | M_ZERO); - - /* - * vfs_mount() actually takes a kernel string for `type' and - * `path' now, so extract them. - */ - error = copyinstr(SCARG(uap, type), fstype, MFSNAMELEN, NULL); - if (error) - goto finish; - error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL); - if (error) - goto finish; - if (!mediate_subject_at_level("mount", td->td_proc, - LOMAC_HIGHEST_LEVEL)) { - error = EPERM; - goto finish; - } - error = vfs_mount(td, fstype, fspath, SCARG(uap, flags), - SCARG(uap, data)); -finish: - free(fstype, M_TEMP); - free(fspath, M_TEMP); - return (error); -} - -/* - * Unmount a filesystem. - * - * Note: unmount takes a path to the vnode mounted on as argument, - * not special file (as before). - */ -#ifndef _SYS_SYSPROTO_H_ -struct unmount_args { - char *path; - int flags; -}; -#endif -/* ARGSUSED */ -int -unmount(td, uap) - struct thread *td; - register struct unmount_args /* { - syscallarg(char *) path; - syscallarg(int) flags; - } */ *uap; -{ - register struct vnode *vp; - struct mount *mp; - int error; - struct nameidata nd; - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); - mp = vp->v_mount; - - /* - * Only root, or the user that did the original mount is - * permitted to unmount this filesystem. - */ - if (!mediate_subject_at_level("unmount", td->td_proc, - LOMAC_HIGHEST_LEVEL) || - ((mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) && - (error = suser(td)))) { - vput(vp); - return (error); - } - - /* - * Don't allow unmounting the root filesystem. - */ - if (mp->mnt_flag & MNT_ROOTFS) { - vput(vp); - return (EINVAL); - } - - /* - * Must be the root of the filesystem - */ - if ((vp->v_vflag & VV_ROOT) == 0) { - vput(vp); - return (EINVAL); - } - vput(vp); - return (dounmount(mp, SCARG(uap, flags), td)); -} - -static struct syscall_override { - int offset; - sy_call_t *call; - int narg; - int mpsafe; -} syscall_overrides[] = { - { SYS_mmap, (sy_call_t *)mmap, AS(mmap_args), 1 }, - { SYS_execve, (sy_call_t *)execve, AS(execve_args), 1 }, - { SYS_kldload, (sy_call_t *)kldload, AS(kldload_args), 1 }, - { SYS_mount, (sy_call_t *)mount, AS(mount_args), 0 }, - { SYS_unmount, (sy_call_t *)unmount, AS(unmount_args), 0 }, -#ifdef __i386__ - { SYS_sysarch, (sy_call_t *)sysarch, AS(sysarch_args), 1 } -#endif -}; - -int -lomac_initialize_syscalls(void) { - int error, i; - - for (i = 0; - i < sizeof(syscall_overrides) / sizeof(syscall_overrides[0]); i++) { - struct syscall_override *so = &syscall_overrides[i]; - - error = syscall_gate_register(so->offset, so->call, so->narg, - so->mpsafe); - if (error) { - while (--i >= 0) - syscall_gate_deregister( - syscall_overrides[i].offset); - return (error); - } - } - return (0); -} - -int -lomac_uninitialize_syscalls(void) { - int i; - - for (i = 0; - i < sizeof(syscall_overrides) / sizeof(syscall_overrides[0]); i++) - syscall_gate_deregister(syscall_overrides[i].offset); - return (0); -} - -/* This memory is shared by all lomac_do_recwd() calls, in sequence. */ -static char *pathmem; -#define DIRENTMEM_SIZE (64 << 10) /* 64KB is good, I guess! */ -static char *direntmem; - -static int -lomac_dirents_searchbyid(struct vnode *dvp, struct dirent *dp, - struct dirent *enddp, const struct vattr *vap, struct dirent **retdp) -{ - struct vattr pvattr; - struct componentname cnp; - struct thread *td = curthread; - struct ucred *ucred = td->td_ucred; - struct vnode *vp; - int error; - - *retdp = NULL; - for (; dp != enddp; dp = (struct dirent *)((char *)dp + dp->d_reclen)) { - cnp.cn_nameiop = LOOKUP; - cnp.cn_flags = LOCKPARENT | ISLASTCN | NOFOLLOW; - cnp.cn_thread = td; - cnp.cn_cred = ucred; - cnp.cn_nameptr = dp->d_name; - cnp.cn_namelen = dp->d_namlen; - - error = VOP_LOOKUP(dvp, &vp, &cnp); - if (error) - return (error); - error = VOP_GETATTR(vp, &pvattr, ucred, td); - if (vp != dvp) - (void)vput(vp); - else - vrele(vp); /* if looking up "." */ - if (error) - return (error); - if (pvattr.va_fsid == vap->va_fsid && - pvattr.va_fileid == vap->va_fileid) { - *retdp = dp; - break; - } - } - return (0); -} - -static int -lomac_getcwd( - struct thread *td, - char *buf, - size_t buflen, - char **bufret -) { - struct vattr cvattr; - char *bp; - int error, i, slash_prefixed; - struct filedesc *fdp; - struct vnode *vp, *startvp, *dvp; - - if (buflen < 2) - return (EINVAL); - if (buflen > MAXPATHLEN) - buflen = MAXPATHLEN; - bp = buf; - bp += buflen - 1; - *bp = '\0'; - fdp = td->td_proc->p_fd; - slash_prefixed = 0; -#if defined(LOMAC_DEBUG_RECWD) - printf("lomac_getcwd for %d:\n", td->td_proc->p_pid); -#endif - startvp = fdp->fd_cdir; - vref(startvp); - for (vp = startvp; vp != rootvnode; vp = dvp) { - struct iovec diov = { - direntmem, - DIRENTMEM_SIZE - }; - struct uio duio = { - &diov, - 1, - 0, - DIRENTMEM_SIZE, - UIO_SYSSPACE, - UIO_READ, - curthread - }; - struct dirent *dp; - int direof; - - ASSERT_VOP_LOCKED(vp, "lomac_getcwd"); - if (vp->v_vflag & VV_ROOT) { - if (vp->v_mount == NULL) /* forced unmount */ - return (EBADF); - dvp = vp->v_mount->mnt_vnodecovered; - continue; - } - dvp = vp->v_dd; - if (vp == dvp) - break; - /* - * Utilize POSIX requirement of files having same - * st_dev and st_ino to be the same file, in our - * case with vattr.va_fsid and vattr.va_fileid. - */ - error = vget(vp, LK_EXCLUSIVE, curthread); - if (error) - goto out2; - error = VOP_GETATTR(vp, &cvattr, curthread->td_ucred, - curthread); - if (error) - goto out2; - (void)vput(vp); - error = vget(dvp, LK_EXCLUSIVE, curthread); - if (error) - goto out2; - for (direof = 0; !direof;) { - error = VOP_READDIR(dvp, &duio, - curthread->td_ucred, &direof, NULL, NULL); - if (error) - break; - error = lomac_dirents_searchbyid(dvp, - (struct dirent *)direntmem, - (struct dirent *)(direntmem + - DIRENTMEM_SIZE - duio.uio_resid), - &cvattr, - &dp); - if (error) - break; - if (dp != NULL) { - (void)vput(dvp); -#if defined(LOMAC_DEBUG_RECWD) - printf("\tdirent component: \"%.*s\"\n", - dp->d_namlen, dp->d_name); -#endif - for (i = dp->d_namlen - 1; i >= 0; i--) - if (bp == buf) - return (ENOMEM); - else - *--bp = dp->d_name[i]; - goto nextcomp; - } - diov.iov_base = direntmem; - diov.iov_len = DIRENTMEM_SIZE; - duio.uio_resid = DIRENTMEM_SIZE; - } - if (direof) - error = ENOENT; - (void)vput(dvp); - out2: -#if defined(LOMAC_DEBUG_RECWD) - printf("backup dirent lookup problem: %d\n", error); -#endif - goto out; - nextcomp: - if (bp == buf) - return (ENOMEM); - *--bp = '/'; - slash_prefixed = 1; - } - if (!slash_prefixed) { - if (bp == buf) - return (ENOMEM); - *--bp = '/'; - } - error = 0; - *bufret = bp; -out: - vrele(startvp); - return (error); -} - -static int -lomac_do_recwd(struct proc *p) { - struct nameidata nd; - struct filedesc *fdp = curthread->td_proc->p_fd; - struct thread *td = FIRST_THREAD_IN_PROC(p); /* XXXKSE Only one? */ - char *nbuf; - struct vnode *cdir, *rdir, *vp; - int error; - - if (p == curthread->td_proc) - return (0); - PROC_LOCK(p); - if (p->p_flag & P_SYSTEM) { - PROC_UNLOCK(p); - return (0); - } - PROC_UNLOCK(p); - error = lomac_getcwd(td, pathmem, MAXPATHLEN, &nbuf); - if (error) { -#if defined(LOMAC_DEBUG_RECWD) - printf("lomac: recwd() failure, lomac_getcwd() == %d\n", - error); -#endif - return (0); - } - rdir = fdp->fd_rdir; - fdp->fd_rdir = rootvnode; - vref(fdp->fd_rdir); - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, - nbuf, curthread); - error = namei(&nd); - vrele(fdp->fd_rdir); - fdp->fd_rdir = rdir; - if (error == 0) { - vp = nd.ni_vp; - if (vp->v_type != VDIR) - error = ENOTDIR; - else - error = VOP_ACCESS(vp, VEXEC, td->td_ucred, curthread); - if (error) - vput(vp); - else { - NDFREE(&nd, NDF_ONLY_PNBUF); - fdp = p->p_fd; - cdir = fdp->fd_cdir; - fdp->fd_cdir = vp; - vrele(cdir); - VOP_UNLOCK(vp, 0, curthread); - } - } -#if defined(LOMAC_DEBUG_RECWD) - printf("\trecwd() to \"%.*s\" == %d\n", - MAXPATHLEN, nbuf, error); -#endif - return (0); -} - -int -lomac_initialize_cwds(void) { - int error; - - pathmem = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - direntmem = malloc(DIRENTMEM_SIZE, M_TEMP, M_WAITOK); - mtx_lock(&Giant); - error = each_proc(lomac_do_recwd); - mtx_unlock(&Giant); - free(pathmem, M_TEMP); - free(direntmem, M_TEMP); - return (error); -} diff --git a/sys/security/lomac/kernel_util.h b/sys/security/lomac/kernel_util.h deleted file mode 100644 index 9663688741e9..000000000000 --- a/sys/security/lomac/kernel_util.h +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef KERNEL_UTIL_H -#define KERNEL_UTIL_H - -/* - * Iterate through each proc, locking it and calling iter. - * Short-circuit and return an error if the iterator ever returns one. - */ -int each_proc(int (*iter)(struct proc *p)); - -/* - * Set the initial level on each proc, register at_fork(). - */ -int lomac_initialize_procs(void); - -/* - * Unregister at_fork(). - */ -int lomac_uninitialize_procs(void); - -int lomac_initialize_cwds(void); - -int lomac_initialize_syscalls(void); -int lomac_uninitialize_syscalls(void); - -int lomac_initialize_vm(void); -int lomac_uninitialize_vm(void); -#endif /* KERNEL_UTIL_H */ diff --git a/sys/security/lomac/lomac.h b/sys/security/lomac/lomac.h deleted file mode 100644 index 331a3b529218..000000000000 --- a/sys/security/lomac/lomac.h +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $FreeBSD$ - */ - -#ifndef LOMAC_H_ -#define LOMAC_H_ - -typedef enum { - LOMAC_LOWEST_LEVEL = 1, - LOMAC_HIGHEST_LEVEL = 2 -} level_t; - - -typedef struct { - level_t level; /* level (an integer range) */ - unsigned int flags; /* category flags */ -} lattr_t; /* lomac attribute structure type */ - - -/* lomac_must_demote() - * - * in: actor - attributes of a subject that has or will perform an - * operation that may require LOMAC to demote it. - * target - attributes of the object that is or was the operand. - * out: nothing - * return: value condition - * ----- --------- - * 0 LOMAC should not demote the subject - * 1 LOMAC should demote the subject - * - * This function is a predicate which decides whether or not LOMAC should - * demote the subject with attributes `actor' after it performs an operation - * (probably some kind of a read operation) on the object with attributes - * `target'. - * - */ - -static __inline int -lomac_must_demote(const lattr_t *actor, const lattr_t *target) { - return (actor->level > target->level); -} - - -/* lomac_must_deny() - * - * in: actor - attributes of a subject that wants to perform some - * operation that requires LOMAC to make an allow/deny - * decision. - * target - attributes of the subject or object the above subject - * will operate upon. - * out: nothing - * return: value condition - * ----- --------- - * 0 LOMAC should allow the operation - * 1 LOMAC should deny the operation - * - * This function is a predicate which decides whether or not LOMAC should - * allow the subject with attributes `actor' to perform some operation - * (probably some kind of write or kill operation) on the subject or object - * with attributes `target'. - * - * The flags are two words: the low word is to be used for categories, - * and the high word is meant to hold implementation-dependent flags that - * are not category-related. - * - */ - -static __inline int -lomac_must_deny(const lattr_t *actor, const lattr_t *target) { - - if (actor->level >= target->level) - return 0; /* allow */ - if (target->flags & 0xffff) { - if ((actor->flags & target->flags & 0xffff) == - (target->flags & 0xffff)) { - return 0; /* allow */ - } - } - return 1; /* deny */ -} - -#endif /* LOMAC_H */ diff --git a/sys/security/lomac/lomacfs.h b/sys/security/lomac/lomacfs.h deleted file mode 100644 index 575a98c63c10..000000000000 --- a/sys/security/lomac/lomacfs.h +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef LOMACFS_H -#define LOMACFS_H - -#include -#include -#include -#include -#include - -#include "kernel_interface.h" - -struct lomac_mount { - struct vnode *lm_rootvp; /* singly-ref'd root after mount() */ -#define LM_TOOKROOT 0x0001 - unsigned int lm_flags; -}; - -/* - * This is the structure associated with v_data on all LOMACFS vnodes. - */ -struct lomac_node { - struct vnode *ln_vp; /* vnode back-pointer */ - struct vnode *ln_lowervp; /* shadowed vnode (ref'd or NULL) */ -#define LN_LEVEL_MASK 0x0003 -#define LN_LOWEST_LEVEL 0x0001 -#define LN_SUBJ_LEVEL 0x0002 /* placeholder before inheriting */ -#define LN_HIGHEST_LEVEL 0x0003 -#define LN_INHERIT_MASK 0x001c -#define LN_INHERIT_LOW 0x0004 /* children start with a low level */ -#define LN_INHERIT_HIGH 0x0008 /* children start with a high level */ -#define LN_INHERIT_SUBJ 0x0010 /* children inherit subject's level */ -#define LN_ATTR_MASK 0x01e0 -#define LN_ATTR_LOWWRITE 0x0020 /* lower levels may write to */ -#define LN_ATTR_LOWNOOPEN 0x0040 /* lower levels may not open */ -#define LN_ATTR_NONETDEMOTE 0x0080 /* will not demote on net read */ -#define LN_ATTR_NODEMOTE 0x0100 /* subject won't demote on other read */ - u_int ln_flags; - /* What's the last node explicitly specifying policy for this? */ - struct lomac_node_entry *ln_underpolicy; - /* If non-NULL, this corresponds 1:1 to a specific PLM node entry. */ - struct lomac_node_entry *ln_entry; -#if defined(LOMAC_DEBUG_INCNAME) - char ln_name[MAXPATHLEN]; /* final component name */ -#endif -}; - -/* - * This is the "placeholder" structure initialized from the PLM that - * holds the level information for all named objects. - */ -struct lomac_node_entry { - SLIST_HEAD(lomac_node_entry_head, lomac_node_entry) ln_children; - SLIST_ENTRY(lomac_node_entry) ln_chain; /* chain of current level */ - /* continuing with the LN_* flags above */ -#define LN_CHILD_ATTR_SHIFT 4 /* lshift from attr -> child attr */ -#define LN_CHILD_ATTR_MASK 0x1e00 -#define LN_CHILD_ATTR_LOWWRITE 0x0200 /* lower levels may write to */ -#define LN_CHILD_ATTR_LOWNOOPEN 0x0400 /* lower levels may not open */ -#define LN_CHILD_ATTR_NONETDEMOTE 0x0800 /* will not demote on net read */ -#define LN_CHILD_ATTR_NODEMOTE 0x1000 /* subject won't demote on other read */ - u_int ln_flags; - char *ln_name; /* last component name (to search) */ - const char *ln_path; /* in "stable" storage */ -}; - -#define VTOLOMAC(vp) ((struct lomac_node *)(vp)->v_data) -#define VTOLVP(vp) VTOLOMAC(vp)->ln_lowervp -#define VFSTOLOMAC(mp) ((struct lomac_mount *)mp->mnt_data) -#define VISLOMAC(vp) (vp->v_op == lomacfs_vnodeop_p) - -int lomacfs_node_alloc(struct mount *mp, struct componentname *cnp, - struct vnode *dvp, struct vnode *lowervp, struct vnode **vpp); - -MALLOC_DECLARE(M_LOMACFS); -extern vop_t **lomacfs_vnodeop_p; -extern struct lomac_node_entry lomac_node_entry_root; - -#endif /* LOMACFS_H */ diff --git a/sys/security/lomac/lomacfs_subr.c b/sys/security/lomac/lomacfs_subr.c deleted file mode 100644 index 6c1850d7bfa1..000000000000 --- a/sys/security/lomac/lomacfs_subr.c +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "lomacfs.h" -#include "kernel_plm.h" - -int -lomacfs_node_alloc(struct mount *mp, struct componentname *cnp, - struct vnode *dvp, struct vnode *lowervp, struct vnode **vpp) { - lomac_object_t lobj; - struct thread *td = curthread; - struct vnode *vp; - struct lomac_node *lp; - lattr_t subjlattr, objlattr; - int error; - - KASSERT((cnp == NULL) == (dvp == NULL), - ("lomacfs_node_alloc: dvp and cnp do not match")); - lp = malloc(sizeof(*lp), M_LOMACFS, M_WAITOK); - if (dvp != NULL) { - error = cache_lookup(dvp, vpp, cnp); - if (error == -1) { /* lost the race; return EEXIST and the vp */ - vput(lowervp); - error = vget(*vpp, LK_EXCLUSIVE, td); - free(lp, M_LOMACFS); - if (error) { - *vpp = NULL; - return (error); - } else - return (EEXIST); - } - } - error = getnewvnode("lomacfs", mp, lomacfs_vnodeop_p, vpp); - if (error) { - vput(lowervp); - free(lp, M_LOMACFS); - return (error); - } - vp = *vpp; - - vp->v_type = lowervp != NULL ? lowervp->v_type : VBAD; - if (vp->v_type == VCHR) - vp->v_rdev = lowervp->v_rdev; - vp->v_data = lp; - lp->ln_vp = vp; - lp->ln_lowervp = lowervp; - if (lowervp != NULL) - vhold(lowervp); - get_subject_lattr(curthread->td_proc, &subjlattr); - lp->ln_flags = 0; - lomac_plm_init_lomacfs_vnode(dvp, vp, cnp, &subjlattr); - /* retrieve the just-initialized attributes */ - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = vp; - get_object_lattr(&lobj, &objlattr); - /* propogate the lattr to the underlying vnode */ - lobj.lo_type = LO_TYPE_UVNODE; - lobj.lo_object.vnode = lowervp; - set_object_lattr(&lobj, objlattr); -#if defined(LOMAC_DEBUG_INCNAME) - if (cnp == NULL) - strncpy(lp->ln_name, "/", sizeof(lp->ln_name)); - else { - strncpy(lp->ln_name, cnp->cn_nameptr, cnp->cn_namelen); - lp->ln_name[cnp->cn_namelen] = '\0'; - } -#endif - error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_THISLAYER, td); - if (error) - panic("lomacfs_node_alloc: can't lock new vnode\n"); - if (cnp == NULL) - vp->v_vflag |= VV_ROOT; - else if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, vp, cnp); - -#if defined(LOMAC_DEBUG_NODE_ALLOC) - printf("lomacfs: made vp %p for lvp %p \"%.*s\" in dvp %p from %s\n", - vp, lowervp, cnp ? (int)cnp->cn_namelen : 0, - cnp ? cnp->cn_nameptr : "", dvp, - lowervp != NULL ? lowervp->v_mount->mnt_stat.f_mntonname : ""); -#endif - - return (0); -} diff --git a/sys/security/lomac/lomacfs_vfsops.c b/sys/security/lomac/lomacfs_vfsops.c deleted file mode 100644 index 4df24840dd22..000000000000 --- a/sys/security/lomac/lomacfs_vfsops.c +++ /dev/null @@ -1,199 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lomacfs.h" -#include "kernel_mediate.h" - -MALLOC_DEFINE(M_LOMACFS, "LOMACFS", "LOMAC filesystem objects"); - -static int lomacfs_mount(struct mount *mp, char *path, caddr_t data, - struct nameidata *ndp, struct thread *td); -static int lomacfs_statfs(struct mount *mp, struct statfs *sbp, - struct thread *td); -static int lomacfs_unmount(struct mount *mp, int mntflags, struct thread *td); - -static int -lomacfs_mount(struct mount *mp, char *path, caddr_t data, - struct nameidata *ndp, struct thread *td) { - - if (mp->mnt_flag & MNT_UPDATE || VISLOMAC(mp->mnt_vnodecovered)) - return (EOPNOTSUPP); - - mp->mnt_flag |= MNT_LOCAL; - mp->mnt_flag &= ~MNT_RDONLY; - mp->mnt_data = malloc(sizeof(struct lomac_mount), M_LOMACFS, - M_WAITOK | M_ZERO); - vfs_getnewfsid(mp); - - strncpy(mp->mnt_stat.f_mntfromname, "lomacfs", MNAMELEN); - (void)lomacfs_statfs(mp, &mp->mnt_stat, td); - - /* - * Keep around an extra ref for dounmount() to vrele() after the - * VFS_UNMOUNT()... (who knows...) - */ - vref(mp->mnt_vnodecovered); - if (VOP_ISLOCKED(mp->mnt_vnodecovered, NULL)) - VOP_UNLOCK(mp->mnt_vnodecovered, 0, td); - - return (0); -} - -static int -lomacfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) { - struct statfs tmpstat; - int error; - - bzero(&tmpstat, sizeof(tmpstat)); - - error = VFS_STATFS(mp->mnt_vnodecovered->v_mount, &tmpstat, td); - if (error) - return (error); - - sbp->f_type = tmpstat.f_type; - sbp->f_flags = tmpstat.f_flags; - sbp->f_bsize = tmpstat.f_bsize; - sbp->f_iosize = tmpstat.f_iosize; - sbp->f_blocks = tmpstat.f_blocks; - sbp->f_bfree = tmpstat.f_bfree; - sbp->f_bavail = tmpstat.f_bavail; - sbp->f_files = tmpstat.f_files; - sbp->f_ffree = tmpstat.f_ffree; - if (sbp != &mp->mnt_stat) { - bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - } - return (0); -} - -static int -lomacfs_unmount(struct mount *mp, int mntflags, struct thread *td) { - struct vnode *crootvp = VFSTOLOMAC(mp)->lm_rootvp; - int error; - int flags = 0; - - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - - ASSERT_VOP_LOCKED(crootvp, "lomacfs_unmount"); - - if (VFSTOLOMAC(mp)->lm_flags & LM_TOOKROOT) - crootvp->v_vflag |= VV_ROOT; - - error = vflush(mp, 1, flags); /* have an extra root ref */ - if (error) - return (error); - - free(VFSTOLOMAC(mp), M_LOMACFS); - - /* bye, lomacfs. */ - return (0); -} - -static int -lomacfs_root(struct mount *mp, struct vnode **vpp) { - int error; - - if (VFSTOLOMAC(mp)->lm_rootvp == NULL) { - struct vnode *rootvp, *crootvp; - - crootvp = mp->mnt_vnodecovered; - error = lomacfs_node_alloc(mp, NULL, NULL, crootvp, &rootvp); - if (error) - return (error); - /* - * Reference twice to match the rest of the lomacfs vnodes. - */ - vref(crootvp); - vref(crootvp); - VFSTOLOMAC(mp)->lm_rootvp = rootvp; - /* - * This releases the lock on root, but it doesn't release - * the reference so that root won't "disappear" until - * unmount. - */ - error = VOP_UNLOCK(rootvp, 0, curthread); - if (error) - return (error); - /* - * This is some strange magic here... I need to pretend - * that the mounted-on directory isn't a root vnode if I - * want things like __getcwd() to just fail and not crash. - */ - mp_fixme("This code needs the vn lock, not interlock."); - mtx_lock(&crootvp->v_interlock); - if (crootvp->v_vflag & VV_ROOT && crootvp == rootvnode) { - crootvp->v_vflag &= ~VV_ROOT; - VFSTOLOMAC(mp)->lm_flags |= LM_TOOKROOT; - } - mtx_unlock(&crootvp->v_interlock); - } - *vpp = VFSTOLOMAC(mp)->lm_rootvp; - return (vget(*vpp, LK_EXCLUSIVE, curthread)); -} - -static struct vfsops lomacfs_vfsops = { - lomacfs_mount, - vfs_stdstart, - lomacfs_unmount, - lomacfs_root, - vfs_stdquotactl, - lomacfs_statfs, - vfs_stdsync, - vfs_stdvget, - vfs_stdfhtovp, - vfs_stdcheckexp, - vfs_stdvptofh, - vfs_stdinit, - vfs_stduninit, - vfs_stdextattrctl -}; -VFS_SET(lomacfs_vfsops, lomacfs, VFCF_LOOPBACK); -MODULE_VERSION(lomacfs, 1); -MODULE_DEPEND(lomacfs, lomac_plm, 1, 1, 1); diff --git a/sys/security/lomac/lomacfs_vnops.c b/sys/security/lomac/lomacfs_vnops.c deleted file mode 100644 index f30b110ed7df..000000000000 --- a/sys/security/lomac/lomacfs_vnops.c +++ /dev/null @@ -1,1151 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "lomacfs.h" -#include "kernel_mediate.h" -#include "kernel_monitor.h" - -#if defined(LOMAC_DEBUG_LOOKUPSTATS) -static unsigned int lomacfs_successful_lookups, lomacfs_failed_lookups, - lomacfs_successful_cachedlookups, lomacfs_failed_cachedlookups, - lomacfs_node_alloc_clashes, lomacfs_node_alloc_failures; - -SYSCTL_NODE(_vfs, OID_AUTO, lomacfs, CTLFLAG_RW, 0, "LOMACFS filesystem"); -SYSCTL_NODE(_vfs_lomacfs, OID_AUTO, debug, CTLFLAG_RW, 0, "debug stats"); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, successful_lookups, - CTLFLAG_RW, &lomacfs_successful_lookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, failed_lookups, - CTLFLAG_RW, &lomacfs_failed_lookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, successful_cachedlookups, - CTLFLAG_RW, &lomacfs_successful_cachedlookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, failed_cachedlookups, - CTLFLAG_RW, &lomacfs_failed_cachedlookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, node_alloc_clashes, - CTLFLAG_RW, &lomacfs_node_alloc_clashes, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, node_alloc_failures, - CTLFLAG_RW, &lomacfs_node_alloc_failures, 0, ""); -#endif - -static int -lomacfs_defaultop( - struct vop_generic_args /* { - struct vnodeop_desc *a_desc; - } */ *ap -) { - - printf("lomacfs: %s unsupported\n", ap->a_desc->vdesc_name); - return (EOPNOTSUPP); -} - -static int -lomacfs_inactive( - struct vop_inactive_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VTOLVP(vp); - struct thread *td = ap->a_td; - - KASSERT(lvp != NULL, ("inactive with NULL lowervp")); - VOP_UNLOCK(ap->a_vp, 0, td); - /* - * Temporarily drop our reference to the lower vnode, while keeping - * it held, to possibly call VOP_INACTIVE() on the lower layer. - */ - vrele(lvp); -#if defined(LOMAC_DEBUG_INACTIVE) - do { -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = VTOLOMAC(vp)->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: inactive(%p \"%s\"), lvp usecount down to %u\n", - vp, name, vrefcnt(lvp)); - } while (0); -#endif - /* - * Since the lower fs may actually remove the vnode on last - * release, destroy ourselves mostly here if that occurs. - * - * Additionally, devices should be totally freed - * on last close, not lazily. - */ - if (vrefcnt(lvp) == 0 && - (lvp->v_type != VREG && lvp->v_type != VDIR)) { - vdrop(lvp); - VTOLVP(vp) = NULL; - cache_purge(vp); - } else - vref(lvp); - return (0); -} - -static int -lomacfs_reclaim( - struct vop_reclaim_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct lomac_node *ln = VTOLOMAC(vp); - struct vnode *lvp = VTOLVP(vp); - - if (lvp != NULL) - vrele(lvp); -#if defined(LOMAC_DEBUG_RECLAIM) - if (lvp != NULL) { -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = ln->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: reclaim(%p \"%s\"), lvp usecount down to %u\n", - vp, name, vrefcnt(lvp)); - } -#endif - if (lvp != NULL) - vdrop(lvp); - vp->v_data = NULL; - vp->v_rdev = NULL; - free(ln, M_LOMACFS); - - return (0); -} - -static int -lomacfs_print( - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - - printf ("\ttag %s, vp=%p, lowervp=%p\n", vp->v_tag, vp, - VTOLVP(vp)); - return (0); -} - -static int -lomacfs_lock( - struct vop_lock_args /* { - struct vnode *a_vp; - int a_flags; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - struct thread *td = ap->a_td; - struct vnode *lvp; - int lflags = flags & ~(LK_INTERLOCK | LK_THISLAYER); - int error; - - /* - * To prevent race conditions involving doing a lookup - * on "..", we have to lock the lower node, then lock our - * node. Most of the time it won't matter that we lock our - * node (as any locking would need the lower one locked - * first). But we can LK_DRAIN the upper lock as a step - * towards decomissioning it. - */ - lvp = VTOLVP(vp); - if (lvp == NULL || flags & LK_THISLAYER) - return (lockmgr(vp->v_vnlock, flags, &vp->v_interlock, td)); - if (flags & LK_INTERLOCK) { - mtx_unlock(&vp->v_interlock); - flags &= ~LK_INTERLOCK; - } - if ((flags & LK_TYPE_MASK) == LK_DRAIN) { - error = vn_lock(lvp, - (lflags & ~LK_TYPE_MASK) | LK_EXCLUSIVE | LK_CANRECURSE, - td); - } else - error = vn_lock(lvp, lflags | LK_CANRECURSE, td); - if (error) - return (error); - error = lockmgr(vp->v_vnlock, flags, &vp->v_interlock, td); - if (error) - VOP_UNLOCK(lvp, 0, td); - return (error); -} - -/* - * We need to process our own vnode unlock and then clear the - * interlock flag as it applies only to our vnode, not the - * vnodes below us on the stack. - */ -static int -lomacfs_unlock( - struct vop_unlock_args /* { - struct vnode *a_vp; - int a_flags; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - int lflags = (ap->a_flags | LK_RELEASE) & - ~(LK_THISLAYER | LK_INTERLOCK); - struct thread *td = ap->a_td; - struct vnode *lvp = VTOLVP(vp); - int error; - - error = lockmgr(vp->v_vnlock, flags | LK_RELEASE, &vp->v_interlock, td); - if (lvp == NULL || flags & LK_THISLAYER || error) - return (error); - /* - * Hmm... in a vput(), this means we'll grab the lomacfs interlock, - * then the lower interlock. I don't think this matters, though, - * since both won't be held at the same time. - */ - if (lvp != NULL) - error = VOP_UNLOCK(lvp, lflags, td); - return (error); -} - -static int -lomacfs_islocked( - struct vop_islocked_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - - struct vnode *vp = ap->a_vp; - struct thread *td = ap->a_td; - - return (lockstatus(vp->v_vnlock, td)); -} - -static int -lomacfs_lookup( - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap -) { - int error; - - error = vfs_cache_lookup(ap); -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error == 0) - lomacfs_successful_lookups++; - else - lomacfs_failed_lookups++; -#endif -#if defined(LOMAC_DEBUG_LOOKUP) - if (error == 0 && (*ap->a_vpp)->v_mount == dvp->v_mount) { - struct vnode *vp = *ap->a_vpp; -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = VTOLOMAC(vp)->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: lookup(%p \"%s\"), lvp usecount up to %u\n", - vp, name, vrefcnt(VTOLVP(vp))); - } -#endif - return (error); -} - -static int -lomacfs_cachedlookup( - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct vnode *ldvp = VTOLVP(dvp); - struct vnode *lvp; - int makeentry; - int error; - - if (cnp->cn_flags & ISLASTCN && cnp->cn_nameiop != LOOKUP && - cnp->cn_nameiop != CREATE) { - lomac_object_t lobj = { LO_TYPE_LVNODE, { dvp } }; - const char *op; - - if (cnp->cn_nameiop == DELETE) - op = "delete"; - else - op = "rename"; - - if (!mediate_subject_object(op, curthread->td_proc, &lobj)) - return (EPERM); - } - makeentry = cnp->cn_flags & MAKEENTRY; - cnp->cn_flags &= ~makeentry; - error = VOP_LOOKUP(ldvp, &lvp, cnp); - cnp->cn_flags |= makeentry; - if ((error == 0 || error == EJUSTRETURN) && - cnp->cn_flags != (cnp->cn_flags | LOCKPARENT | ISLASTCN)) - (void)VOP_UNLOCK(dvp, LK_THISLAYER, curthread); - if (error == 0 && lvp->v_type != VSOCK) { - struct mount *mp; - - /* - * Check to see if the vnode has been mounted on; - * if so find the root of the mounted filesystem. - */ - if (lvp->v_type == VDIR && (mp = lvp->v_mountedhere) && - (cnp->cn_flags & NOCROSSMOUNT) == 0) { - struct vnode *tdp; - - if (vfs_busy(mp, 0, 0, curthread)) - goto forget_it; - VOP_UNLOCK(lvp, 0, curthread); - error = VFS_ROOT(mp, &tdp); - vfs_unbusy(mp, curthread); - if (error) { - vrele(lvp); - return (error); - } - vrele(lvp); - lvp = tdp; - } -forget_it: - /* - * For a create or for devices (dynamic things, aren't they), - * don't enter the vnode into the cache. - */ - if (cnp->cn_nameiop == CREATE || lvp->v_type == VCHR) - cnp->cn_flags &= ~makeentry; - /* - * The top half of dvp is locked, but ldvp is unlocked. - * Additionally, lvp is locked already, and - * lomacfs_node_alloc() always returns it locked. - */ - error = lomacfs_node_alloc(dvp->v_mount, cnp, - dvp, lvp, ap->a_vpp); - if (cnp->cn_nameiop == CREATE) - cnp->cn_flags |= makeentry; -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error) { - if (error != EEXIST) { - lomacfs_node_alloc_failures++; - } else { - lomacfs_node_alloc_clashes++; - error = 0; - } - } -#else - if (error == EEXIST) - error = 0; -#endif - } else if (error == 0) { - /* - * For sockets, just return the "real" thing - * after entering it into the cache. - */ - *ap->a_vpp = lvp; - if (cnp->cn_nameiop != CREATE && cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, lvp, cnp); - } - -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error == 0) - lomacfs_successful_cachedlookups++; - else - lomacfs_failed_cachedlookups++; -#endif - return (error); -} - -static int -lomacfs_getattr( - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vattr *vap = ap->a_vap; - int error; - - error = VOP_GETATTR(VTOLVP(vp), vap, ap->a_cred, ap->a_td); - if (error == 0 && vap->va_fsid == VNOVAL) - vap->va_fsid = VTOLVP(vp)->v_mount->mnt_stat.f_fsid.val[0]; - return (error); -} - -static int -lomacfs_setattr( - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - */ *ap -) { - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - if (mediate_subject_object(ap->a_desc->vdesc_name, curthread->td_proc, - &lobj)) - error = VOP_SETATTR(VTOLVP(ap->a_vp), ap->a_vap, ap->a_cred, - ap->a_td); - else - error = EPERM; - return (error); -} - -static int -lomacfs_readdir( - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; - } */ *ap -) { - - return (VOP_READDIR(VTOLVP(ap->a_vp), ap->a_uio, ap->a_cred, - ap->a_eofflag, ap->a_ncookies, ap->a_cookies)); -} - -static int -lomacfs_open( - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - int error; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object_open(ap->a_td->td_proc, &lobj)) - error = EPERM; - else - error = VOP_OPEN(VTOLVP(ap->a_vp), ap->a_mode, ap->a_cred, - ap->a_td); - return (error); -} - -static int -lomacfs_close( - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VTOLVP(vp); - int error; - - /* - * XXX - * Try to cope with the horrible semantics introduced here... - */ - vref(lvp); - error = VOP_CLOSE(lvp, ap->a_fflag, ap->a_cred, ap->a_td); - if (error == EAGAIN) - error = 0; - else - vrele(lvp); - return (error); -} - -static int -lomacfs_access( - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_ACCESS(VTOLVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_readlink( - struct vop_readlink_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - if (lvp == NULL) - return (EPERM); - return (VOP_READLINK(lvp, ap->a_uio, ap->a_cred)); -} - -static int -lomacfs_lease( - struct vop_lease_args /* { - struct vnode *a_vp; - struct thread *a_td; - struct ucred *a_cred; - int a_flag; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - return (VOP_LEASE(lvp, ap->a_td, ap->a_cred, ap->a_flag)); -} - -static int -lomacfs_read( - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - error = monitor_read_object(curthread->td_proc, &lobj); - if (error == 0) - error = VOP_READ(lvp, ap->a_uio, ap->a_ioflag, ap->a_cred); - return (error); -} - -static int -lomacfs_write( - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - if (mediate_subject_object(ap->a_desc->vdesc_name, curthread->td_proc, - &lobj)) - error = VOP_WRITE(lvp, ap->a_uio, ap->a_ioflag, ap->a_cred); - else - error = EIO; - return (error); -} - -static int -lomacfs_ioctl( - struct vop_ioctl_args /* { - struct vnode *a_vp; - u_long a_command; - caddr_t a_data; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - return (VOP_IOCTL(lvp, ap->a_command, ap->a_data, ap->a_fflag, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_muxcreate( - struct vop_create_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct vnode *ldvp = VTOLVP(dvp); - struct componentname *cnp = ap->a_cnp; - struct vattr *vap = ap->a_vap; - int makeentry = cnp->cn_flags & MAKEENTRY; - lomac_object_t lobj = { LO_TYPE_LVNODE, { dvp } }; - struct thread *td = curthread; - int error; - - if (!mediate_subject_object(ap->a_desc->vdesc_name, td->td_proc, - &lobj) || (vap->va_type == VCHR && - !mediate_subject_at_level("mknod", curthread->td_proc, - LOMAC_HIGHEST_LEVEL))) - return (EPERM); - ap->a_dvp = ldvp; - cnp->cn_flags &= ~makeentry; - error = VCALL(ldvp, ap->a_desc->vdesc_offset, ap); - if (error == 0) { - struct vnode *vp; - int issock; - - issock = vap->va_type == VSOCK; - vp = *ap->a_vpp; - *ap->a_vpp = NULL; - if (!issock) - cnp->cn_flags |= makeentry; - error = lomacfs_node_alloc(dvp->v_mount, cnp, dvp, vp, - ap->a_vpp); - if (error) - vput(vp); - else if (issock) { - /* - * I should really find a nicer way to do this. - */ - vref(vp); - vput(*ap->a_vpp); - *ap->a_vpp = vp; - (void)VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); - } - } - return (error); -} - -static int -lomacfs_muxremove( - struct vop_remove_args /* { - struct vnode *a_dvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct vnode *vp = ap->a_vp; - int error; - - ap->a_dvp = VTOLVP(dvp); - if (VISLOMAC(vp)) - ap->a_vp = VTOLVP(vp); - error = VCALL(ap->a_dvp, ap->a_desc->vdesc_offset, ap); - if (error == 0) - cache_purge(vp); - return (error); -} - -static int -lomacfs_fsync( - struct vop_fsync_args /* { - struct vnode *a_vp; - struct ucred *a_cred; - int a_waitfor; - struct thread *a_td; - } */ *ap -) { - - return (VOP_FSYNC(VTOLVP(ap->a_vp), ap->a_cred, ap->a_waitfor, - ap->a_td)); -} - -static int -lomacfs_advlock( - struct vop_advlock_args /* { - struct vnode *a_vp; - caddr_t a_id; - int a_op; - struct flock *a_fl; - int a_flags; - } */ *ap -) { - - return (VOP_ADVLOCK(VTOLVP(ap->a_vp), ap->a_id, ap->a_op, ap->a_fl, - ap->a_flags)); -} - -static int -lomacfs_whiteout( - struct vop_whiteout_args /* { - struct vnode *a_dvp; - struct componentname *a_cnp; - int a_flags; - } */ *ap -) { - - return (VOP_WHITEOUT(VTOLVP(ap->a_dvp), ap->a_cnp, ap->a_flags)); -} - -static int -lomacfs_poll( - struct vop_poll_args /* { - struct vnode *a_vp; - int a_events; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_POLL(VTOLVP(ap->a_vp), ap->a_events, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_revoke( - struct vop_revoke_args /* { - struct vnode *a_vp; - int a_flags; - } */ *ap -) { - - return (VOP_REVOKE(VTOLVP(ap->a_vp), ap->a_flags)); -} - -static int -lomacfs_link( - struct vop_link_args /* { - struct vnode *a_tdvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *tdvp = ap->a_tdvp; - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VISLOMAC(vp) ? VTOLVP(vp) : vp; - struct componentname *cnp = ap->a_cnp; - int error; - - error = VOP_LINK(VTOLVP(tdvp), lvp, cnp); - if (error == 0 && vp->v_type == VSOCK) { - cache_enter(tdvp, vp, cnp); -#if defined(LOMAC_DEBUG_LINK) - do { - struct vnode *nvp; - int nerror; - - nerror = cache_lookup(tdvp, &nvp, cnp); - printf("lomacfs: link(%p), cache_lookup() = %d (%p)\n", - vp, nerror, nvp); - } while (0); -#endif - } - return (error); -} - -static int -lomacfs_rename( - struct vop_rename_args /* { - struct vnode *a_fdvp; - struct vnode *a_fvp; - struct componentname *a_fcnp; - struct vnode *a_tdvp; - struct vnode *a_tvp; - struct componentname *a_tcnp; - } */ *ap -) { - struct vnode *fdvp = ap->a_fdvp; - struct vnode *fvp = ap->a_fvp; - struct componentname *fcnp = ap->a_fcnp; - struct vnode *tdvp = ap->a_tdvp; - struct vnode *tvp = ap->a_tvp; - struct componentname *tcnp = ap->a_tcnp; - int fvp_is_lomac = VISLOMAC(fvp); - int error; - - vref(VTOLVP(fdvp)); - /* - * Handle the case when LOMAC returns a real vnode for - * VSOCK, rather than the LOMAC covering vnode. - */ - if (fvp_is_lomac) - vref(VTOLVP(fvp)); - vref(VTOLVP(tdvp)); - if (tvp != NULL) - vref(VTOLVP(tvp)); - error = VOP_RENAME(VTOLVP(fdvp), fvp_is_lomac ? VTOLVP(fvp) : fvp, fcnp, - VTOLVP(tdvp), tvp != NULL ? VTOLVP(tvp) : NULL, tcnp); - if (fvp->v_type == VDIR) { - if (tvp != NULL && tvp->v_type == VDIR) - cache_purge(tdvp); - cache_purge(fdvp); - } - cache_purge(fvp); - if (tvp != NULL) - cache_purge(tvp); - (void)VOP_UNLOCK(tdvp, LK_THISLAYER, curthread); - vrele(fdvp); - if (fvp_is_lomac) - vrele(fvp); - vrele(tdvp); - if (tvp != NULL) { - (void)VOP_UNLOCK(tvp, LK_THISLAYER, curthread); - vrele(tvp); - } else if (tcnp->cn_nameiop == RENAME /* NOCACHE unsets MAKEENTRY */ - && fvp->v_type == VSOCK) - cache_enter(tdvp, fvp, tcnp); - return (error); -} - -static int -lomacfs_strategy( - struct vop_strategy_args /* { - struct vnode *a_vp; - struct buf *a_bp; - } */ *ap -) { - - return (VOP_STRATEGY(VTOLVP(ap->a_vp), ap->a_bp)); -} - -/* - * Let an underlying filesystem do the work of creating the "actual" - * vm_object_t, and we will reference it. - */ -static int -lomacfs_createvobject( - struct vop_createvobject_args /* { - struct vnode *vp; - struct ucred *cred; - struct proc *p; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lowervp = VTOLOMAC(vp) != NULL ? VTOLVP(vp) : NULL; - int error; - - if (vp->v_type == VNON || lowervp == NULL) - return (EINVAL); - error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_td); - if (error) - return (error); - vp->v_vflag |= VV_OBJBUF; - return (error); -} - -/* - * We need to destroy the lower vnode object only if we created it. - * XXX - I am very unsure about all of this. - */ -static int -lomacfs_destroyvobject( - struct vop_destroyvobject_args /* { - struct vnode *vp; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - - vp->v_vflag &= ~VV_OBJBUF; - return (0); -} - -static int -lomacfs_bmap( - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - int *a_runb; - } */ *ap -) { - - return (VOP_BMAP(VTOLVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp, - ap->a_runp, ap->a_runb)); -} - -static int -lomacfs_getpages( - struct vop_getpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_reqpage; - vm_ooffset_t a_offset; - } */ *ap -) { - - return (VOP_GETPAGES(VTOLVP(ap->a_vp), ap->a_m, ap->a_count, - ap->a_reqpage, ap->a_offset)); -} - -static int -lomacfs_putpages( - struct vop_putpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_sync; - int *a_rtvals; - vm_ooffset_t a_offset; - } */ *ap -) { - - return (VOP_PUTPAGES(VTOLVP(ap->a_vp), ap->a_m, ap->a_count, - ap->a_sync, ap->a_rtvals, ap->a_offset)); -} - -static int -lomacfs_getvobject( - struct vop_getvobject_args /* { - struct vnode *a_vp; - struct vm_object **a_objpp; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - if (lvp == NULL) - return EINVAL; - return (VOP_GETVOBJECT(lvp, ap->a_objpp)); -} - -static int -lomacfs_kqfilter( - struct vop_kqfilter_args /* { - struct vnode *a_vp; - struct knote *a_kn; - } */ *ap -) { - - return (VOP_KQFILTER(VTOLVP(ap->a_vp), ap->a_kn)); -} - -static int -lomacfs_pathconf( - struct vop_pathconf_args /* { - struct vnode *a_vp; - int a_name; - register_t *a_retval; - } */ *ap -) { - - return (VOP_PATHCONF(VTOLVP(ap->a_vp), ap->a_name, ap->a_retval)); -} - -static int -lomacfs_reallocblks( - struct vop_reallocblks_args /* { - struct vnode *a_vp; - struct cluster_save *a_buflist; - } */ *ap -) { - - return (VOP_REALLOCBLKS(VTOLVP(ap->a_vp), ap->a_buflist)); -} - -static int -lomacfs_freeblks( - struct vop_freeblks_args /* { - struct vnode *a_vp; - daddr_t a_addr; - daddr_t a_length; - } */ *ap -) { - - return (VOP_FREEBLKS(VTOLVP(ap->a_vp), ap->a_addr, ap->a_length)); -} - -static int -lomacfs_getacl( - struct vop_getacl_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_GETACL(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, ap->a_cred, - ap->a_td)); -} - -static int -lomacfs_setacl( - struct vop_setacl_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object("setacl", ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_SETACL(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_aclcheck( - struct vop_aclcheck_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_ACLCHECK(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_getextattr( - struct vop_getextattr_args /* { - struct vnode *a_vp; - int a_attrnamespace; - const char *a_name; - struct uio *a_uio; - size_t *a_size; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (monitor_read_object(ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_GETEXTATTR(VTOLVP(ap->a_vp), ap->a_attrnamespace, - ap->a_name, ap->a_uio, ap->a_size, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_setextattr( - struct vop_setextattr_args /* { - struct vnode *a_vp; - int a_attrnamespace; - const char *a_name; - struct uio *a_uio; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object("setextattr", ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_SETEXTATTR(VTOLVP(ap->a_vp), ap->a_attrnamespace, - ap->a_name, ap->a_uio, ap->a_cred, ap->a_td)); -} - -vop_t **lomacfs_vnodeop_p; -static struct vnodeopv_entry_desc lomacfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *)lomacfs_defaultop }, - { &vop_inactive_desc, (vop_t *)lomacfs_inactive }, - { &vop_reclaim_desc, (vop_t *)lomacfs_reclaim }, - { &vop_print_desc, (vop_t *)lomacfs_print }, - { &vop_lock_desc, (vop_t *)lomacfs_lock }, - { &vop_unlock_desc, (vop_t *)lomacfs_unlock }, - { &vop_islocked_desc, (vop_t *)lomacfs_islocked }, - { &vop_lookup_desc, (vop_t *)lomacfs_lookup }, - { &vop_setattr_desc, (vop_t *)lomacfs_setattr }, - { &vop_getattr_desc, (vop_t *)lomacfs_getattr }, - { &vop_readdir_desc, (vop_t *)lomacfs_readdir }, - { &vop_open_desc, (vop_t *)lomacfs_open }, - { &vop_close_desc, (vop_t *)lomacfs_close }, - { &vop_access_desc, (vop_t *)lomacfs_access }, - { &vop_readlink_desc, (vop_t *)lomacfs_readlink }, - { &vop_lease_desc, (vop_t *)lomacfs_lease }, - { &vop_read_desc, (vop_t *)lomacfs_read }, - { &vop_write_desc, (vop_t *)lomacfs_write }, - { &vop_ioctl_desc, (vop_t *)lomacfs_ioctl }, - { &vop_create_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_mkdir_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_mknod_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_symlink_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_remove_desc, (vop_t *)lomacfs_muxremove }, - { &vop_rmdir_desc, (vop_t *)lomacfs_muxremove }, - { &vop_fsync_desc, (vop_t *)lomacfs_fsync }, - { &vop_advlock_desc, (vop_t *)lomacfs_advlock }, - { &vop_whiteout_desc, (vop_t *)lomacfs_whiteout }, - { &vop_poll_desc, (vop_t *)lomacfs_poll }, - { &vop_link_desc, (vop_t *)lomacfs_link }, - { &vop_rename_desc, (vop_t *)lomacfs_rename }, - { &vop_revoke_desc, (vop_t *)lomacfs_revoke }, - { &vop_cachedlookup_desc, (vop_t *)lomacfs_cachedlookup }, - { &vop_lookup_desc, (vop_t *)lomacfs_lookup }, - { &vop_bmap_desc, (vop_t *)lomacfs_bmap }, - { &vop_getpages_desc, (vop_t *)lomacfs_getpages }, - { &vop_putpages_desc, (vop_t *)lomacfs_putpages }, - { &vop_strategy_desc, (vop_t *)lomacfs_strategy }, - { &vop_createvobject_desc, (vop_t *)lomacfs_createvobject }, - { &vop_destroyvobject_desc, (vop_t *)lomacfs_destroyvobject }, - { &vop_getvobject_desc, (vop_t *)lomacfs_getvobject }, - { &vop_getwritemount_desc, (vop_t *)vop_stdgetwritemount }, - { &vop_kqfilter_desc, (vop_t *)lomacfs_kqfilter }, - { &vop_pathconf_desc, (vop_t *)lomacfs_pathconf }, - { &vop_reallocblks_desc, (vop_t *)lomacfs_reallocblks }, - { &vop_freeblks_desc, (vop_t *)lomacfs_freeblks }, - { &vop_getacl_desc, (vop_t *)lomacfs_getacl }, - { &vop_setacl_desc, (vop_t *)lomacfs_setacl }, - { &vop_aclcheck_desc, (vop_t *)lomacfs_aclcheck }, - { &vop_getextattr_desc, (vop_t *)lomacfs_getextattr }, - { &vop_setextattr_desc, (vop_t *)lomacfs_setextattr }, - { NULL, NULL } -}; -static struct vnodeopv_desc lomacfs_vnodeopv_opv_desc = - { &lomacfs_vnodeop_p, lomacfs_vnodeop_entries }; -VNODEOP_SET(lomacfs_vnodeopv_opv_desc); diff --git a/sys/security/lomac/lomacio.h b/sys/security/lomac/lomacio.h deleted file mode 100644 index adce6191d0ca..000000000000 --- a/sys/security/lomac/lomacio.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef LOMACIO_H -#define LOMACIO_H - -#include -#include - -struct lomac_fioctl { - char path[MAXPATHLEN]; - int level; /* LOMAC security level */ -}; - -struct lomac_fioctl2 { - char path[MAXPATHLEN]; - int level; /* LOMAC security level */ - int flags; -}; - -#define LIOGETPLEVEL _IOWR('L', 0, int) /* get process level */ -#define LIOGETFLEVEL _IOWR('L', 1, struct lomac_fioctl) /* get file level */ -#define LIOGETFLATTR _IOWR('L', 3, struct lomac_fioctl2) /* get file level */ -#define LIOPMAKELOWLEVEL _IO('L', 2) /* lower proc's level */ -#endif /* LOMACIO_H */ diff --git a/sys/security/lomac/policy_plm.h b/sys/security/lomac/policy_plm.h deleted file mode 100644 index 5a2142ff9b1f..000000000000 --- a/sys/security/lomac/policy_plm.h +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef LOMAC_PLM_H -#define LOMAC_PLM_H - -enum plm_level { - LOW, - SUBJ, - HIGH -}; -enum plm_flags { - PLM_NOFLAGS, /* rule applies to this node and its children */ - PLM_CHILDOF /* rule applies to node's children, not the node */ -}; -#define LOWWRITE LN_ATTR_LOWWRITE -#define LOWNOOPEN LN_ATTR_LOWNOOPEN -#define NONETDEMOTE LN_ATTR_NONETDEMOTE -#define NODEMOTE LN_ATTR_NODEMOTE - -static u_int plm_levelflags_to_node_flags[3][2] = { - { LN_LOWEST_LEVEL, LN_INHERIT_LOW }, - { LN_SUBJ_LEVEL, LN_INHERIT_SUBJ }, - { LN_HIGHEST_LEVEL, LN_INHERIT_HIGH } -}; - -typedef struct plm_rule { - enum plm_level level; /* LOMAC level */ - enum plm_flags flags; /* flags for PLM evaluation */ - unsigned int attr; /* LN_ATTR_MASK of flags */ - const char *path; /* absolute path for this PLM rule */ -} plm_rule_t; - -/* The `plm' array maps levels onto all of the files in the filesystem */ -static plm_rule_t plm[] = { - { HIGH, PLM_NOFLAGS, 0, "/" }, /* everything initially inherits high level */ - { HIGH, PLM_CHILDOF, 0, "/" }, - { HIGH, PLM_NOFLAGS, NONETDEMOTE, "/sbin/dhclient" }, - { HIGH, PLM_CHILDOF, 0, "/var" }, - { HIGH, PLM_CHILDOF, LOWWRITE, "/dev" }, - { HIGH, PLM_NOFLAGS, LOWNOOPEN, "/dev/mdctl" }, - { HIGH, PLM_NOFLAGS, LOWNOOPEN, "/dev/pci" }, - { HIGH, PLM_NOFLAGS, LOWNOOPEN, "/dev/kmem" }, - { HIGH, PLM_NOFLAGS, LOWNOOPEN, "/dev/mem" }, - { HIGH, PLM_NOFLAGS, LOWNOOPEN, "/dev/io" }, - { HIGH, PLM_CHILDOF, 0, "/etc" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/tmp" }, - { SUBJ, PLM_CHILDOF, 0, "/tmp" }, - { HIGH, PLM_NOFLAGS, 0, "/tmp/.X11-unix" }, - { HIGH, PLM_CHILDOF, LOWWRITE, "/tmp/.X11-unix" }, - { SUBJ, PLM_CHILDOF, 0, "/proc" }, - { LOW, PLM_CHILDOF, 0, "/mnt" }, /* all nfs mounts are low */ - { LOW, PLM_CHILDOF, 0, "/home" }, - { HIGH, PLM_NOFLAGS, NONETDEMOTE, "/usr/bin/env-nonetdemote" }, - { HIGH, PLM_NOFLAGS, NODEMOTE, "/usr/bin/env-nodemote" }, - { LOW, PLM_CHILDOF, 0, "/usr/home" }, - { LOW, PLM_CHILDOF, 0, "/var/lib" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/var/tmp" }, - { SUBJ, PLM_CHILDOF, 0, "/var/tmp" }, - { LOW, PLM_NOFLAGS, 0, "/var/tmp/vi.recover" }, - { SUBJ, PLM_CHILDOF, 0, "/var/tmp/vi.recover" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/usr/tmp" }, - { SUBJ, PLM_CHILDOF, 0, "/usr/tmp" }, - { HIGH, PLM_NOFLAGS, 0, "/usr/tmp/.X11-unix" }, - { HIGH, PLM_CHILDOF, LOWWRITE, "/usr/tmp/.X11-unix" }, - { LOW, PLM_NOFLAGS, 0, "/var/mail" }, - { LOW, PLM_CHILDOF, 0, "/var/mail" }, - { LOW, PLM_NOFLAGS, 0, "/var/spool/mqueue" }, - { LOW, PLM_CHILDOF, 0, "/var/spool/mqueue" }, - { LOW, PLM_NOFLAGS, 0, "/dev/log" }, - { HIGH, PLM_NOFLAGS, 0, "/home/ftp" }, - { HIGH, PLM_NOFLAGS, 0, "/usr/home/ftp" }, - { HIGH, PLM_NOFLAGS, 0, "/mnt/cdrom" }, /* cdrom is high */ - { HIGH, PLM_NOFLAGS, 0, "/home/samba" }, - { HIGH, PLM_NOFLAGS, 0, "/usr/home/samba" }, - { LOW, PLM_NOFLAGS, 0, "/dev/printer" }, - { HIGH, PLM_CHILDOF, 0, "/var/log" }, - { LOW, PLM_NOFLAGS, 0, "/var/log/sendmail.st" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/var/run/utmp" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/var/log/lastlog" }, - { HIGH, PLM_NOFLAGS, LOWWRITE, "/var/log/wtmp" }, - { 0, 0, 0 } -}; - -#endif /* LOMAC_PLM_H */ diff --git a/sys/security/lomac/syscall_gate.c b/sys/security/lomac/syscall_gate.c deleted file mode 100644 index 70eb9afd8b46..000000000000 --- a/sys/security/lomac/syscall_gate.c +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "syscall_gate.h" -void syscall_gate_init(void); -int syscall_gate(struct thread *td, caddr_t params); - -static struct syscall_gate sg; - -void -syscall_gate_init(void) { - - sg.sg_table = curthread->td_proc->p_sysent->sv_table; - bzero(sg.sg_oldsyscalls, sizeof(sg.sg_oldsyscalls)); -} - -int -syscall_gate_register(int offset, sy_call_t *call, int narg, int mpsafe) { - struct sysent *se; - int error = 0; - - if (offset <= 0 || offset >= SYS_MAXSYSCALL) { - error = EINVAL; - goto out; - } - if (sg.sg_oldsyscalls[offset].sy_call != NULL) { - error = EEXIST; - goto out; - } - se = &sg.sg_table[offset]; - sg.sg_oldsyscalls[offset] = *se; - se->sy_call = (sy_call_t *)call; - se->sy_narg = narg | (mpsafe ? SYF_MPSAFE : 0); -out: - return (error); -} - -void -syscall_gate_deregister(int offset) { - KASSERT(offset > 0 && offset < SYS_MAXSYSCALL, ("syscall offset %d out of range", - offset)); - KASSERT(sg.sg_oldsyscalls[offset].sy_call != NULL, ("deregistering nonexistant syscall %d", - offset)); - sg.sg_table[offset] = sg.sg_oldsyscalls[offset]; - sg.sg_oldsyscalls[offset].sy_call = NULL; - sg.sg_oldsyscalls[offset].sy_narg = 0; -} - -static int -syscall_gate_modevent(module_t module, int event, void *unused) { - int i; - - switch ((enum modeventtype)event) { - case MOD_LOAD: - syscall_gate_init(); - break; - case MOD_UNLOAD: - for (i = 1; i < SYS_MAXSYSCALL; i++) { - struct sysent *se; - - se = &sg.sg_oldsyscalls[i]; - if (se->sy_call != NULL) - sg.sg_table[i] = *se; - } - break; - case MOD_SHUTDOWN: - break; - } - return (0); -} - -static moduledata_t syscall_gate_moduledata = { - "syscall_gate", - &syscall_gate_modevent, - NULL -}; -DECLARE_MODULE(syscall_gate, syscall_gate_moduledata, SI_SUB_DRIVERS, SI_ORDER_ANY); -MODULE_VERSION(syscall_gate, 1); diff --git a/sys/security/lomac/syscall_gate.h b/sys/security/lomac/syscall_gate.h deleted file mode 100644 index 1ee5c7439b8c..000000000000 --- a/sys/security/lomac/syscall_gate.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by NAI Labs, 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * 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. - * - * $Id$ - * $FreeBSD$ - */ - -#ifndef SYSCALL_GATE_H -#define SYSCALL_GATE_H - -#include -#include -#include - -#ifdef _KERNEL -struct syscall_gate { - struct sx sg_lock; /* syscalls entered into the kernel */ - struct sysent *sg_table; - struct sysent sg_oldsyscalls[SYS_MAXSYSCALL]; - struct sysent sg_newsyscalls[SYS_MAXSYSCALL]; -}; -#endif /* _KERNEL */ - -int syscall_gate_register(int offset, sy_call_t *func, int nargs, int mpsafe); -void syscall_gate_deregister(int offset); -#endif /* SYSCALL_GATE_H */