summaryrefslogtreecommitdiff
path: root/sys/contrib/lomac/kernel_util.c
diff options
context:
space:
mode:
authorBrian Feldman <green@FreeBSD.org>2001-11-19 22:34:06 +0000
committerBrian Feldman <green@FreeBSD.org>2001-11-19 22:34:06 +0000
commit3795613d1d4af8aa4ba965db8d81926be7731556 (patch)
tree855390076025818f6fea90037cfe44711457356a /sys/contrib/lomac/kernel_util.c
parentae3a37e4a094b90a878ba986da79b4ba4cbd50ec (diff)
Notes
Diffstat (limited to 'sys/contrib/lomac/kernel_util.c')
-rw-r--r--sys/contrib/lomac/kernel_util.c687
1 files changed, 0 insertions, 687 deletions
diff --git a/sys/contrib/lomac/kernel_util.c b/sys/contrib/lomac/kernel_util.c
deleted file mode 100644
index 3a46070e66ab..000000000000
--- a/sys/contrib/lomac/kernel_util.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*-
- * Copyright (c) 2001 Networks Associates Technology, Inc.
- * All rights reserved.
- * Copyright (c) 1982, 1986, 1989, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * 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.
- *
- * 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: kernel_util.c,v 1.22 2001/11/15 20:51:13 bfeldman Exp $
- */
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/signalvar.h>
-#include <sys/sx.h>
-#include <sys/syscall.h>
-#include <sys/sysent.h>
-#include <sys/sysproto.h>
-#include <sys/systm.h>
-#include <sys/linker.h>
-#include <sys/mount.h>
-#include <sys/mman.h>
-#include <sys/dirent.h>
-#include <sys/namei.h>
-#include <sys/uio.h>
-#include <sys/unistd.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_kern.h>
-
-#include "kernel_interface.h"
-#include "kernel_util.h"
-#include "kernel_mediate.h"
-#include "kernel_monitor.h"
-#include "lomacfs.h"
-
-#include "syscall_gate/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(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 <machine/sysarch.h>
-
-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 file system.
- */
-#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 file system.
- *
- * 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_stat.f_owner != td->td_proc->p_ucred->cr_uid) &&
- (error = suser_td(td)))) {
- vput(vp);
- return (error);
- }
-
- /*
- * Don't allow unmounting the root file system.
- */
- if (mp->mnt_flag & MNT_ROOTFS) {
- vput(vp);
- return (EINVAL);
- }
-
- /*
- * Must be the root of the filesystem
- */
- if ((vp->v_flag & VROOT) == 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;
-
- if (vp->v_flag & VROOT) {
- 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 = &p->p_thread;
- 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_proc->p_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);
-}