Re: New LSM patch for consideration

From: Stephen Smalley (sdsat_private)
Date: Tue Jun 19 2001 - 12:23:36 PDT

  • Next message: jmjonesat_private: "Re: New LSM patch for consideration"

    On Tue, 19 Jun 2001 jmjonesat_private wrote:
    
    > I've been trying to apply it to an original 2.4.5 kernel, and 
    > get several errors.  Is it relative to 
    > 
    > 2.4.6-pre3
    > 2.4.5-original
    > 2.4.5-lsm (with the last released patch).
    
    Sorry for the confusion.  My patch was relative to the "head" of
    the WireX BitKeeper tree in order to allow them to easily integrate
    it.  The WireX BitKeeper tree is difficult to characterize -
    at one time, it was consistent with the 5/30 released patch,
    but WireX then committed several changes that never showed
    up in a released patch and WireX then merged with 2.4.6-pre3.
    Anyway, Chris Wright ended up asking for a 2.4.5-based patch 
    to allow them to create a new LSM patch based on a stable version.
    For your viewing pleasure, here is my patch relative to the 5/30
    released patch.  This includes both my changes and changes made by 
    WireX between the released patch and the 2.4.6-pre3 merge.  Oh,
    but this doesn't include my recent capabilities-related patch.
    
    > Due to licensing issues, I don't have access to the bitkeeper tree at this
    > time.  Where and how should I apply the patch to see what the results are?
    
    I don't understand why you can't use BitKeeper to access the lsm tree.
    The license shouldn't matter for just viewing the lsm tree.
    
    --
    Stephen D. Smalley, NAI Labs
    ssmalleyat_private
    
    
    
    
    
    diff -Nru lsm-wirex/arch/i386/kernel/ioport.c lsm-nailabs/arch/i386/kernel/ioport.c
    --- lsm-wirex/arch/i386/kernel/ioport.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/arch/i386/kernel/ioport.c	Mon Jun 18 13:22:04 2001
    @@ -64,8 +64,7 @@
     	if (turn_on && !capable(CAP_SYS_RAWIO))
     		return -EPERM;
     
    -	/* check that we have permission to do this */
    -	retval = security_ops->ioperm();
    +	retval = security_ops->ioperm(from, num, turn_on);
     	if (retval) {
     		return retval;
     	}
    @@ -121,9 +120,7 @@
     		if (!capable(CAP_SYS_RAWIO))
     			return -EPERM;
     	}
    -
    -	/* check that we have permission to do this */
    -	retval = security_ops->ioperm();
    +	retval = security_ops->iopl(old, level);
     	if (retval) {
     		return retval;
     	}
    diff -Nru lsm-wirex/arch/i386/kernel/ptrace.c lsm-nailabs/arch/i386/kernel/ptrace.c
    --- lsm-wirex/arch/i386/kernel/ptrace.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/arch/i386/kernel/ptrace.c	Mon Jun 18 13:22:04 2001
    @@ -147,7 +147,8 @@
     		/* are we already being traced? */
     		if (current->ptrace & PT_PTRACED)
     			goto out;
    -		if (security_ops->ptrace(current->p_pptr, current))
    +		ret = security_ops->ptrace(current->p_pptr, current);
    +		if (ret)
     			goto out;
     		/* set the ptrace bit in the process flags. */
     		current->ptrace |= PT_PTRACED;
    @@ -167,12 +168,13 @@
     	if (pid == 1)		/* you may not mess with init */
     		goto out_tsk;
     
    -	if (security_ops->ptrace(current, child))
    -		goto out_tsk;
    -
     	if (request == PTRACE_ATTACH) {
     		if (child == current)
     			goto out_tsk;
    +		ret = security_ops->ptrace(current, child);
    +		if (ret)
    +			goto out_tsk;
    +		ret = -EPERM;
     		if(((current->uid != child->euid) ||
     		    (current->uid != child->suid) ||
     		    (current->uid != child->uid) ||
    diff -Nru lsm-wirex/arch/ia64/config.in lsm-nailabs/arch/ia64/config.in
    --- lsm-wirex/arch/ia64/config.in	Tue Apr 17 20:19:24 2001
    +++ lsm-nailabs/arch/ia64/config.in	Mon Jun 18 13:38:15 2001
    @@ -281,3 +281,5 @@
     bool 'Disable VHPT' CONFIG_DISABLE_VHPT
     
     endmenu
    +
    +source security/Config.in
    diff -Nru lsm-wirex/arch/ia64/ia32/sys_ia32.c lsm-nailabs/arch/ia64/ia32/sys_ia32.c
    --- lsm-wirex/arch/ia64/ia32/sys_ia32.c	Thu Apr  5 15:51:47 2001
    +++ lsm-nailabs/arch/ia64/ia32/sys_ia32.c	Mon Jun 18 13:38:15 2001
    @@ -49,6 +49,7 @@
     #include <linux/personality.h>
     #include <linux/stat.h>
     #include <linux/ipc.h>
    +#include <linux/security.h>
     
     #include <asm/types.h>
     #include <asm/uaccess.h>
    @@ -2566,6 +2567,7 @@
     	unsigned int old;
     	unsigned long addr;
     	mm_segment_t old_fs = get_fs ();
    +	int retval;
     
     	if (level != 3)
     		return(-EINVAL);
    @@ -2574,6 +2576,10 @@
     	if (level > ((old >> 12) & 3)) {
     		if (!capable(CAP_SYS_RAWIO))
     			return -EPERM;
    +	}
    +	retval = security_ops->iopl(old, level);
    +	if (retval) {
    +		return retval;
     	}
     	set_fs(KERNEL_DS);
     	fd = sys_open("/dev/mem", O_SYNC | O_RDWR, 0);
    diff -Nru lsm-wirex/arch/ia64/kernel/ptrace.c lsm-nailabs/arch/ia64/kernel/ptrace.c
    --- lsm-wirex/arch/ia64/kernel/ptrace.c	Thu Apr  5 15:51:47 2001
    +++ lsm-nailabs/arch/ia64/kernel/ptrace.c	Mon Jun 18 13:38:15 2001
    @@ -15,6 +15,7 @@
     #include <linux/ptrace.h>
     #include <linux/smp_lock.h>
     #include <linux/user.h>
    +#include <linux/security.h>
     
     #include <asm/pgtable.h>
     #include <asm/processor.h>
    @@ -748,6 +749,9 @@
     		/* are we already being traced? */
     		if (current->ptrace & PT_PTRACED)
     			goto out;
    +		ret = security_ops->ptrace(current->p_pptr, current);
    +		if (ret)
    +			goto out;
     		current->ptrace |= PT_PTRACED;
     		ret = 0;
     		goto out;
    @@ -770,6 +774,10 @@
     	if (request == PTRACE_ATTACH) {
     		if (child == current)
     			goto out_tsk;
    +		ret = security_ops->ptrace(current, child);
    +		if (ret)
    +			goto out_tsk;
    +		ret = -EPERM;
     		if ((!child->dumpable ||
     		    (current->uid != child->euid) ||
     		    (current->uid != child->suid) ||
    diff -Nru lsm-wirex/arch/mips/kernel/irixelf.c lsm-nailabs/arch/mips/kernel/irixelf.c
    --- lsm-wirex/arch/mips/kernel/irixelf.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/arch/mips/kernel/irixelf.c	Mon Jun 11 14:21:47 2001
    @@ -29,7 +29,6 @@
     #include <linux/personality.h>
     #include <linux/elfcore.h>
     #include <linux/smp_lock.h>
    -#include <linux/security.h>
     
     #include <asm/uaccess.h>
     #include <asm/pgalloc.h>
    @@ -723,7 +722,7 @@
     	kfree(elf_phdata);
     	set_personality(PER_IRIX32);
     	set_binfmt(&irix_format);
    -	security_ops->bprm_ops->compute_creds(bprm);
    +	compute_creds(bprm);
     	current->flags &= ~PF_FORKNOEXEC;
     	bprm->p = (unsigned long) 
     	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
    diff -Nru lsm-wirex/arch/sparc64/kernel/binfmt_aout32.c lsm-nailabs/arch/sparc64/kernel/binfmt_aout32.c
    --- lsm-wirex/arch/sparc64/kernel/binfmt_aout32.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/arch/sparc64/kernel/binfmt_aout32.c	Mon Jun 11 14:21:58 2001
    @@ -27,7 +27,6 @@
     #include <linux/binfmts.h>
     #include <linux/personality.h>
     #include <linux/init.h>
    -#include <linux/security.h>
     
     #include <asm/system.h>
     #include <asm/uaccess.h>
    @@ -241,7 +240,7 @@
     
     	current->mm->rss = 0;
     	current->mm->mmap = NULL;
    -	security_ops->bprm_ops->compute_creds(bprm);
    +	compute_creds(bprm);
      	current->flags &= ~PF_FORKNOEXEC;
     	if (N_MAGIC(ex) == NMAGIC) {
     		loff_t pos = fd_offset;
    diff -Nru lsm-wirex/drivers/char/tty_io.c lsm-nailabs/drivers/char/tty_io.c
    --- lsm-wirex/drivers/char/tty_io.c	Thu Apr 26 20:35:49 2001
    +++ lsm-nailabs/drivers/char/tty_io.c	Wed Jun 13 12:20:28 2001
    @@ -1462,6 +1462,10 @@
     		if (!waitqueue_active(&tty->read_wait))
     			tty->minimum_to_wake = 1;
     		if (filp->f_owner.pid == 0) {
    +			retval = security_ops->file_ops->set_fowner(filp);
    +			if (retval)
    +				return retval;
    +
     			filp->f_owner.pid = (-tty->pgrp) ? : current->pid;
     			filp->f_owner.uid = current->uid;
     			filp->f_owner.euid = current->euid;
    diff -Nru lsm-wirex/fs/attr.c lsm-nailabs/fs/attr.c
    --- lsm-wirex/fs/attr.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/fs/attr.c	Mon Jun 18 13:22:05 2001
    @@ -124,9 +124,9 @@
     	error = security_ops->inode_ops->setattr(dentry, attr);
     	if (error)
     		goto unlock_and_out;
    -	if (inode->i_op && inode->i_op->setattr) {
    +	if (inode->i_op && inode->i_op->setattr) 
     		error = inode->i_op->setattr(dentry, attr);
    -	} else {
    +	else {
     		error = inode_change_ok(inode, attr);
     		if (!error)
     			inode_setattr(inode, attr);
    diff -Nru lsm-wirex/fs/binfmt_aout.c lsm-nailabs/fs/binfmt_aout.c
    --- lsm-wirex/fs/binfmt_aout.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/fs/binfmt_aout.c	Mon Jun 11 14:19:46 2001
    @@ -24,7 +24,6 @@
     #include <linux/binfmts.h>
     #include <linux/personality.h>
     #include <linux/init.h>
    -#include <linux/security.h>
     
     #include <asm/system.h>
     #include <asm/uaccess.h>
    @@ -304,7 +303,7 @@
     
     	current->mm->rss = 0;
     	current->mm->mmap = NULL;
    -	security_ops->bprm_ops->compute_creds(bprm);
    +	compute_creds(bprm);
      	current->flags &= ~PF_FORKNOEXEC;
     #ifdef __sparc__
     	if (N_MAGIC(ex) == NMAGIC) {
    diff -Nru lsm-wirex/fs/binfmt_elf.c lsm-nailabs/fs/binfmt_elf.c
    --- lsm-wirex/fs/binfmt_elf.c	Mon Jun 18 16:32:39 2001
    +++ lsm-nailabs/fs/binfmt_elf.c	Mon Jun 11 14:19:46 2001
    @@ -39,7 +39,6 @@
     #define DLINFO_ITEMS 13
     
     #include <linux/elf.h>
    -#include <linux/security.h>
     
     static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
     static int load_elf_library(struct file*);
    @@ -656,17 +655,6 @@
     	}
     	set_fs(old_fs);
     
    -	/* Shell scripts get checked in binfmt_script.c */
    -	if (!bprm->sh_bang) {
    -		retval = security_ops->file_ops->permission (bprm->file, MAY_EXEC);
    -		if (retval) {
    -			kfree(elf_interpreter);
    -			kfree(elf_phdata);
    -			send_sig(SIGKILL, current, 0);
    -			return retval;
    -		}
    -	}
    -
     	elf_entry += load_bias;
     	elf_bss += load_bias;
     	elf_brk += load_bias;
    @@ -703,7 +691,7 @@
     
     	set_binfmt(&elf_format);
     
    -	security_ops->bprm_ops->compute_creds(bprm);
    +	compute_creds(bprm);
     	current->flags &= ~PF_FORKNOEXEC;
     	bprm->p = (unsigned long)
     	  create_elf_tables((char *)bprm->p,
    diff -Nru lsm-wirex/fs/dnotify.c lsm-nailabs/fs/dnotify.c
    --- lsm-wirex/fs/dnotify.c	Wed Nov  8 02:27:57 2000
    +++ lsm-nailabs/fs/dnotify.c	Wed Jun 13 12:20:28 2001
    @@ -45,6 +45,7 @@
     	struct dnotify_struct **prev;
     	struct inode *inode;
     	int turning_off = (arg & ~DN_MULTISHOT) == 0;
    +	int error;
     
     	if (!turning_off && !dir_notify_enable)
     		return -EINVAL;
    @@ -75,6 +76,13 @@
     	}
     	if (turning_off)
     		goto out;
    +
    +	error = security_ops->file_ops->set_fowner(filp);
    +	if (error) {
    +		write_unlock(&dn_lock);
    +		return error;
    +	}
    +
     	filp->f_owner.pid = current->pid;
     	filp->f_owner.uid = current->uid;
     	filp->f_owner.euid = current->euid;
    diff -Nru lsm-wirex/fs/exec.c lsm-nailabs/fs/exec.c
    --- lsm-wirex/fs/exec.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/fs/exec.c	Mon Jun 18 13:38:15 2001
    @@ -36,7 +36,6 @@
     #include <linux/spinlock.h>
     #define __NO_VERSION__
     #include <linux/module.h>
    -#include <linux/security.h>
     
     #include <asm/uaccess.h>
     #include <asm/pgalloc.h>
    @@ -631,6 +630,28 @@
     			bprm->e_gid = inode->i_gid;
     	}
     
    +	/* We don't have VFS support for capabilities yet */
    +	cap_clear(bprm->cap_inheritable);
    +	cap_clear(bprm->cap_permitted);
    +	cap_clear(bprm->cap_effective);
    +
    +	/*  To support inheritance of root-permissions and suid-root
    +         *  executables under compatibility mode, we raise all three
    +         *  capability sets for the file.
    +         *
    +         *  If only the real uid is 0, we only raise the inheritable
    +         *  and permitted sets of the executable file.
    +         */
    +
    +	if (!issecure(SECURE_NOROOT)) {
    +		if (bprm->e_uid == 0 || current->uid == 0) {
    +			cap_set_full(bprm->cap_inheritable);
    +			cap_set_full(bprm->cap_permitted);
    +		}
    +		if (bprm->e_uid == 0) 
    +			cap_set_full(bprm->cap_effective);
    +	}
    +
     	/* fill in binprm security blob */
     	if (security_ops->bprm_ops->alloc_security(bprm))
     		return -EACCES;		/* hmm, is EACCES really right? */
    @@ -656,7 +677,6 @@
     
     void compute_creds(struct linux_binprm *bprm) 
     {
    -#if 0	/* pushed into security module */
     	kernel_cap_t new_permitted, working;
     	int do_unlock = 0;
     
    @@ -704,7 +724,8 @@
     	if(do_unlock)
     		unlock_kernel();
     	current->keep_capabilities = 0;
    -#endif
    +
    +	security_ops->bprm_ops->compute_creds(bprm);
     }
     
     
    diff -Nru lsm-wirex/fs/fcntl.c lsm-nailabs/fs/fcntl.c
    --- lsm-wirex/fs/fcntl.c	Tue May 22 12:26:06 2001
    +++ lsm-nailabs/fs/fcntl.c	Mon Jun 18 13:22:05 2001
    @@ -10,6 +10,7 @@
     #include <linux/dnotify.h>
     #include <linux/smp_lock.h>
     #include <linux/slab.h>
    +#include <linux/security.h>
     
     #include <asm/poll.h>
     #include <asm/siginfo.h>
    @@ -272,6 +273,13 @@
     			break;
     		case F_SETOWN:
     			lock_kernel();
    +
    +			err = security_ops->file_ops->set_fowner(filp);
    +			if (err) {
    +				unlock_kernel();
    +				break;
    +			}
    +
     			filp->f_owner.pid = arg;
     			filp->f_owner.uid = current->uid;
     			filp->f_owner.euid = current->euid;
    @@ -320,6 +328,12 @@
     	if (!filp)
     		goto out;
     
    +	err = security_ops->file_ops->fcntl(filp, cmd, arg);
    +	if (err) {
    +		fput(filp);
    +		return err;
    +	}
    +
     	err = do_fcntl(fd, cmd, arg, filp);
     
      	fput(filp);
    @@ -338,6 +352,13 @@
     	if (!filp)
     		goto out;
     
    +	err = security_ops->file_ops->fcntl64(filp, cmd, arg);
    +	if (err) {
    +		fput(filp);
    +		return err;
    +	}
    +	err = -EBADF;
    +	
     	switch (cmd) {
     		case F_GETLK64:
     			err = fcntl_getlk64(fd, (struct flock64 *) arg);
    @@ -378,6 +399,10 @@
     	    (fown->euid ^ p->suid) && (fown->euid ^ p->uid) &&
     	    (fown->uid ^ p->suid) && (fown->uid ^ p->uid))
     		return;
    +
    +	if (security_ops->file_ops->send_sigiotask(p, fown, fd, reason))
    +		return;
    +
     	switch (fown->signum) {
     		siginfo_t si;
     		default:
    diff -Nru lsm-wirex/fs/file_table.c lsm-nailabs/fs/file_table.c
    --- lsm-wirex/fs/file_table.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/fs/file_table.c	Wed Jun 13 12:20:28 2001
    @@ -41,6 +41,12 @@
     		list_del(&f->f_list);
     		files_stat.nr_free_files--;
     	new_one:
    +		if (security_ops->file_ops->alloc_security(f)) {
    +			list_add(&f->f_list, &free_list);
    +			files_stat.nr_free_files++;
    +			file_list_unlock();
    +			return NULL;
    +		}
     		memset(f, 0, sizeof(*f));
     		atomic_set(&f->f_count,1);
     		f->f_version = ++event;
    @@ -143,6 +149,7 @@
     void put_filp(struct file *file)
     {
     	if(atomic_dec_and_test(&file->f_count)) {
    +		security_ops->file_ops->free_security(file);
     		file_list_lock();
     		list_del(&file->f_list);
     		list_add(&file->f_list, &free_list);
    diff -Nru lsm-wirex/fs/ioctl.c lsm-nailabs/fs/ioctl.c
    --- lsm-wirex/fs/ioctl.c	Fri Feb  9 14:29:44 2001
    +++ lsm-nailabs/fs/ioctl.c	Wed Jun 13 11:02:02 2001
    @@ -7,6 +7,7 @@
     #include <linux/mm.h>
     #include <linux/smp_lock.h>
     #include <linux/file.h>
    +#include <linux/security.h>
     
     #include <asm/uaccess.h>
     #include <asm/ioctls.h>
    @@ -56,6 +57,14 @@
     	if (!filp)
     		goto out;
     	error = 0;
    +
    +	/* Call the Linux Security Module to perform its checks. */
    +	error = security_ops->file_ops->ioctl(filp, cmd, arg);
    +        if (error) {
    +                fput(filp);
    +                goto out;
    +        }
    +
     	lock_kernel();
     	switch (cmd) {
     		case FIOCLEX:
    diff -Nru lsm-wirex/fs/locks.c lsm-nailabs/fs/locks.c
    --- lsm-wirex/fs/locks.c	Fri Feb  9 14:29:44 2001
    +++ lsm-nailabs/fs/locks.c	Wed Jun 13 12:20:28 2001
    @@ -1269,6 +1269,11 @@
     	fl->fl_next = *before;
     	*before = fl;
     	list_add(&fl->fl_link, &file_lock_list);
    +
    +	error = security_ops->file_ops->set_fowner(filp);
    +	if (error)
    +		goto out_unlock;
    +
     	filp->f_owner.pid = current->pid;
     	filp->f_owner.uid = current->uid;
     	filp->f_owner.euid = current->euid;
    diff -Nru lsm-wirex/fs/namei.c lsm-nailabs/fs/namei.c
    --- lsm-wirex/fs/namei.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/fs/namei.c	Mon Jun 18 13:22:05 2001
    @@ -189,6 +189,9 @@
     	if (retval)
     		return retval;
     
    +	/* Ordinary permission routines do not understand MAY_APPEND. */
    +	mask &= ~MAY_APPEND;
    +
     	if (inode->i_op && inode->i_op->permission) {
     		lock_kernel();
     		retval = inode->i_op->permission(inode, mask);
    @@ -964,6 +967,11 @@
     	int count = 0;
     
     	acc_mode = ACC_MODE(flag);
    +
    +	/* Allow the LSM permission hook to distinguish append 
    +	   access from general write access. */
    +	if (flag & O_APPEND)
    +		acc_mode |= MAY_APPEND;
     
     	/*
     	 * The simplest case - just a plain lookup.
    diff -Nru lsm-wirex/fs/open.c lsm-nailabs/fs/open.c
    --- lsm-wirex/fs/open.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/fs/open.c	Wed Jun 13 12:20:28 2001
    @@ -667,10 +667,6 @@
     	}
     	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
     
    -	error = -EACCES;
    -	if (security_ops->file_ops->alloc_security (f))
    -		goto cleanup_all;
    -	
     	return f;
     
     cleanup_all:
    diff -Nru lsm-wirex/fs/super.c lsm-nailabs/fs/super.c
    --- lsm-wirex/fs/super.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/fs/super.c	Mon Jun 18 10:09:53 2001
    @@ -1346,7 +1346,7 @@
     
     	retval = security_ops->mount(dev_name, &nd, type_page, flags, data_page);
     	if (retval)
    -		goto fs_out;
    +		goto dput_out;
     
     	/* get superblock, locks mount_sem on success */
     	if (fstype->fs_flags & FS_NOMOUNT)
    diff -Nru lsm-wirex/include/linux/binfmts.h lsm-nailabs/include/linux/binfmts.h
    --- lsm-wirex/include/linux/binfmts.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/binfmts.h	Mon Jun 11 16:29:09 2001
    @@ -4,7 +4,6 @@
     #include <linux/ptrace.h>
     #include <linux/capability.h>
     
    -
     /*
      * MAX_ARG_PAGES defines the number of pages allocated for arguments
      * and envelope for the new program. 32 should suffice, this gives
    @@ -27,7 +26,8 @@
     	int sh_bang;
     	struct file * file;
     	int e_uid, e_gid;
    -	void *security;	/* was cap_inheritable, cap_permitted, cap_effective */
    +	kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
    +	void *security;
     	int argc, envc;
     	char * filename;	/* Name of binary */
     	unsigned long loader, exec;
    diff -Nru lsm-wirex/include/linux/elf.h lsm-nailabs/include/linux/elf.h
    --- lsm-wirex/include/linux/elf.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/elf.h	Mon Jun 11 14:19:59 2001
    @@ -512,7 +512,7 @@
     #define SHN_HIRESERVE	0xffff
     #define SHN_MIPS_ACCOMON	0xff00
      
    -typedef struct elf32_shdr {
    +typedef struct {
       Elf32_Word	sh_name;
       Elf32_Word	sh_type;
       Elf32_Word	sh_flags;
    @@ -599,7 +599,6 @@
     #define elfhdr		elf32_hdr
     #define elf_phdr	elf32_phdr
     #define elf_note	elf32_note
    -#define elf_shdr	elf32_shdr
     
     #else
     
    @@ -607,7 +606,6 @@
     #define elfhdr		elf64_hdr
     #define elf_phdr	elf64_phdr
     #define elf_note	elf64_note
    -#define elf_shdr	elf64_shdr
     
     #endif
     
    diff -Nru lsm-wirex/include/linux/fs.h lsm-nailabs/include/linux/fs.h
    --- lsm-wirex/include/linux/fs.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/fs.h	Mon Jun 11 16:29:09 2001
    @@ -71,6 +71,7 @@
     #define MAY_EXEC 1
     #define MAY_WRITE 2
     #define MAY_READ 4
    +#define MAY_APPEND 8
     
     #define FMODE_READ 1
     #define FMODE_WRITE 2
    @@ -486,6 +487,7 @@
     	int pid;		/* pid or -pgrp where SIGIO should be sent */
     	uid_t uid, euid;	/* uid/euid of process setting the owner */
     	int signum;		/* posix.1b rt signal to be delivered on IO */
    +	void *security;
     };
     
     struct file {
    diff -Nru lsm-wirex/include/linux/ipc.h lsm-nailabs/include/linux/ipc.h
    --- lsm-wirex/include/linux/ipc.h	Fri May 25 21:01:26 2001
    +++ lsm-nailabs/include/linux/ipc.h	Wed Jun 13 12:50:12 2001
    @@ -63,6 +63,7 @@
     	gid_t		cgid;
     	mode_t		mode; 
     	unsigned long	seq;
    +	void		*security;
     };
     
     #endif /* __KERNEL__ */
    diff -Nru lsm-wirex/include/linux/sched.h lsm-nailabs/include/linux/sched.h
    --- lsm-wirex/include/linux/sched.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/sched.h	Tue Jun 12 11:33:38 2001
    @@ -694,6 +694,7 @@
      * New privilege checks should use this interface, rather than suser() or
      * fsuser(). See include/linux/capability.h for defined capabilities.
      */
    +/* capable prototype and code moved to security.[hc] */
     #include <linux/security.h>
     #if 0
     static inline int capable(int cap)
    diff -Nru lsm-wirex/include/linux/security.h lsm-nailabs/include/linux/security.h
    --- lsm-wirex/include/linux/security.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/security.h	Mon Jun 18 13:38:15 2001
    @@ -6,6 +6,10 @@
      *      the Free Software Foundation; either version 2 of the License, or
      *      (at your option) any later version.
      *
    + * 2001_Jun_12 Stephen Smalley <sdsat_private>, NAI Labs, SELinux project
    + *      Changed all non-capable hooks to be authoritative or restrictive.
    + *      Added parameters to several of the hook functions.
    + *
      * 2001_Apr_12 greg k-h
      *	created based on original immunix.h code
      *
    @@ -23,7 +27,11 @@
     #include <linux/fs.h>
     #include <linux/binfmts.h>
     #include <linux/signal.h>
    -
    +#include <linux/resource.h>
    +#include <linux/ipc.h>
    +#include <linux/sem.h>
    +#include <linux/shm.h>
    +#include <linux/msg.h>
     
     /* Security plug operations */
     #define SECURITY_INTERFACE_VERSION	0x00000101	/* change this every time the security_operations structure changes */
    @@ -66,7 +74,7 @@
     	int (* truncate)	(struct inode *inode);
     	int (* permission)	(struct inode *inode, int mask);
     	int (* revalidate)	(struct dentry *dentry);
    -	int (* setattr)		(struct dentry *dentry, struct iattr *attr); // CAP_CHOWN
    +	int (* setattr)		(struct dentry *dentry, struct iattr *attr);
     	void (* attach_pathlabel)(struct dentry *dentry, struct vfsmount *mnt);	// DTE project needs this
     	int (* stat)		        (struct inode *inode);
     };
    @@ -79,24 +87,34 @@
     	int (* llseek)			(struct file *);
     	int (* read)			(struct file *);
     	int (* write)			(struct file *);
    -	int (* ioctl)			(struct file *);	// need more than file*
    -	int (* mmap)			(struct file *);
    +	int (* ioctl)			(struct file *, unsigned int cmd, unsigned long arg);
    +	int (* mmap)			(struct file *, unsigned long, unsigned long);
    +	int (* mprotect)		(struct vm_area_struct *, unsigned long);
     	int (* lock)			(struct file *);
     	int (* readv)			(struct file *);
     	int (* writev)			(struct file *);
    +	int (* fcntl)			(struct file *, unsigned int, unsigned long);
    +	int (* fcntl64)			(struct file *, unsigned int, unsigned long);
    +	int (* set_fowner)		(struct file *file);
    +	int (* send_sigiotask)		(struct task_struct *tsk, struct fown_struct *fown, int fd, int reason);
     };
     
     struct task_security_ops {
     	int (* create)			(void);
     	int (* alloc_security)		(struct task_struct *p);	// create per process security stuff
     	void (* free_security)		(struct task_struct *p);	// free it
    -	int (* setuid)			(void);		// CAP_SETUID
    -	int (* setgid)			(void);		// CAP_SETGID
    -	int (* setgroups)               (void);         // CAP_SETGID
    -	int (* setnice)			(struct task_struct *p, int nice); // CAP_SYS_NICE
    -	int (* setrlimit)		(unsigned int resource);	// CAP_SYS_RESOURCE
    -	int (* setscheduler)		(struct task_struct *p, int policy); // CAP_SYS_NICE
    -	int (* kill)			(struct task_struct *p, struct siginfo *info, int sig);	// CAP_KILL
    +#define LSM_SETID_ID  1 /* setuid or setgid, id0 == uid or gid */
    +#define LSM_SETID_RE  2 /* setreuid or setregid, id0 == real, id1 == eff */
    +#define LSM_SETID_RES 4 /* setresuid or setresgid, id0 == real, id1 == eff, uid2 == saved */
    +#define LSM_SETID_FS  8 /* setfsuid or setfsgid, id0 == fsuid or fsgid */
    +	int (* setuid)			(uid_t id0, uid_t id1, uid_t id2, int flags);
    +	int (* setgid)			(gid_t id0, gid_t id1, gid_t id2, int flags);
    +	int (* setgroups)               (int gidsetsize, gid_t *grouplist);
    +	int (* setnice)			(struct task_struct *p, int nice);
    +	int (* setrlimit)		(unsigned int resource, struct rlimit *new_rlim);
    +	int (* setscheduler)		(struct task_struct *p, int policy); 
    +	int (* kill)			(struct task_struct *p, struct siginfo *info, int sig);	
    +	int (* wait)			(struct task_struct *p);
     	
     	/* set and (in case of exec failure) unset security label */
     	int (* set_label)		(char *filename);
    @@ -108,48 +126,61 @@
     };
     
     struct module_security_ops {
    - 	int  (* create_module)		(const char *name_user, size_t size);			// CAP_SYS_MODULE
    - 	int  (* init_module)		(const char *name_user, struct module *mod_user);	// CAP_SYS_MODULE
    - 	int  (* delete_module)		(const char *name_user);				// CAP_SYS_MODULE
    + 	int  (* create_module)		(const char *name_user, size_t size);			
    + 	int  (* init_module)		(const char *name_user, struct module *mod_user);	
    + 	int  (* delete_module)		(const char *name_user);				
    +};
    +
    +struct ipc_security_ops {
    +	int (* permission)	(struct kern_ipc_perm *ipcp, short flag);
    +	int (* getinfo)		(int id, int cmd);
     };
     
     struct msg_queue_security_ops {
     	int (* create)			(key_t key);	// can i create
    -	int (* permission)		(void);		// CAP_SYS_ADMIN
    -	int (* setmaxqbytes)		(void);		// CAP_SYS_RESOURCE
    +	int (* permission)		(void);		
    +	int (* setmaxqbytes)		(void);		
     	int (* setattr)			(void);		// can i set attributes
     	int (* delete)			(void);		// can i delete
     };
     
     struct shm_security_ops {
    -	int (* create)		(key_t key);
    -	int (* permission)	(void);
    -	int (* setattr)		(void);
    -	int (* delete)		(void);
    +	int (* alloc_security)	(struct shmid_kernel *shp);
    +	void (* free_security)	(struct shmid_kernel *shp);
    +	int (* associate)	(struct shmid_kernel *shp, int shmid, int shmflg);
    +	int (* shmctl)		(struct shmid_kernel *shp, int shmid, int cmd);
    +	int (* shmat)		(struct shmid_kernel *shp, int shmid, char *shmaddr, int shmflg);
     };
     
    +struct sem_security_ops {
    +	int (* alloc_security)	(struct sem_array *sma);
    +	void (* free_security)	(struct sem_array *sma);
    +	int (* associate)	(struct sem_array *sma, int semid, int semflg);
    +	int (* semctl)		(struct sem_array *sma, int semid, int cmd);
    +	int (* semop)		(struct sem_array *sma, int semid, struct sembuf *sops, unsigned nsops, int alter);
    +};
     
     struct security_operations {
     	int	version;
     	
     	/* syscalls that are checked for permissions */
    -	int  (* sethostname)		(void);		// CAP_SYS_ADMIN
    -	int  (* setdomainname)		(void);		// CAP_SYS_ADMIN
    -	int  (* reboot)			(unsigned int cmd);	// CAP_SYS_BOOT
    +	int  (* sethostname)		(char *hostname);		
    +	int  (* setdomainname)		(char *domainname);
    +	int  (* reboot)			(unsigned int cmd, void *arg);	
     	int  (* mount)			(char * dev_name, struct nameidata *nd,
     					 char * type, unsigned long flags, 
    -					 void * data);			// part of CAP_SYS_ADMIN
    +					 void * data);			
     	int  (* add_vfsmnt)	        (struct nameidata *nd, struct super_block *sb, char *dev_name);
    -	int  (* umount)			(struct vfsmount *mnt, int flags);	// part of CAP_SYS_ADMIN
    +	int  (* umount)			(struct vfsmount *mnt, int flags);	
     	void (* umount_close)		(struct vfsmount *mnt);    
     	void (* umount_busy)		(struct vfsmount *mnt);    
     	int  (* remount)		(struct vfsmount *mnt, unsigned long flags, void *data);    
     	void (* post_remount)		(struct vfsmount *mnt, unsigned long flags, void *data);    
    -	int  (* ioperm)			(void);		// part of CAP_RAWIO
    -	int  (* iopl)			(void);		// part of CAP_RAWIO
    -	int  (* ptrace)			(struct task_struct *parent, struct task_struct *child);		// CAP_PTRACE
    -	int  (* setcapability)		(void);		// CAP_SETPCAP
    -	int  (* acct)			(void);		// CAP_SYS_PACCT
    +	int  (* ioperm)			(unsigned long from, unsigned long num, int turn_on);
    +	int  (* iopl)			(unsigned int old, unsigned int level);		
    +	int  (* ptrace)			(struct task_struct *parent, struct task_struct *child);		
    +	int  (* setcapability)		(void);		
    +	int  (* acct)			(struct file *file);
     	/* old capable call, catch all for capabilities. */
     	int (* capable)			(int cap); 
     
    @@ -160,12 +191,14 @@
     	struct task_security_ops	* task_ops;
     	struct socket_security_ops	* socket_ops;
     	struct module_security_ops 	* module_ops;
    +	struct ipc_security_ops		* ipc_ops;
     	struct msg_queue_security_ops	* msg_queue_ops;
     	struct shm_security_ops		* shm_ops;
    +	struct sem_security_ops		* sem_ops;
     
     	/* allow module stacking */
    -	int (* register_security)	(struct security_operations *ops);
    -	int (* unregister_security)	(struct security_operations *ops);
    +	int (* register_security)	(const char *name, struct security_operations *ops);
    +	int (* unregister_security)	(const char *name, struct security_operations *ops);
     };
     
     
    @@ -173,8 +206,8 @@
     extern int security_scaffolding_startup	(void);
     extern int register_security	(struct security_operations *ops);
     extern int unregister_security	(struct security_operations *ops);
    -extern int mod_reg_security	(struct security_operations *ops);
    -extern int mod_unreg_security	(struct security_operations *ops);
    +extern int mod_reg_security	(const char *name, struct security_operations *ops);
    +extern int mod_unreg_security	(const char *name, struct security_operations *ops);
     extern int capable		(int cap);
     
     /* global variables */
    diff -Nru lsm-wirex/include/linux/shm.h lsm-nailabs/include/linux/shm.h
    --- lsm-wirex/include/linux/shm.h	Fri May 25 21:01:26 2001
    +++ lsm-nailabs/include/linux/shm.h	Mon Jun 18 10:55:38 2001
    @@ -71,6 +71,19 @@
     };
     
     #ifdef __KERNEL__
    +struct shmid_kernel /* private to the kernel */
    +{	
    +	struct kern_ipc_perm	shm_perm;
    +	struct file *		shm_file;
    +	int			id;
    +	unsigned long		shm_nattch;
    +	unsigned long		shm_segsz;
    +	time_t			shm_atim;
    +	time_t			shm_dtim;
    +	time_t			shm_ctim;
    +	pid_t			shm_cprid;
    +	pid_t			shm_lprid;
    +};
     
     /* shm_mode upper byte flags */
     #define	SHM_DEST	01000	/* segment will be destroyed on last detach */
    diff -Nru lsm-wirex/include/linux/sysctl.h lsm-nailabs/include/linux/sysctl.h
    --- lsm-wirex/include/linux/sysctl.h	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/include/linux/sysctl.h	Mon Jun 11 14:19:58 2001
    @@ -647,8 +647,6 @@
     extern ctl_handler sysctl_intvec;
     extern ctl_handler sysctl_jiffies;
     
    -extern ctl_handler sysctl_codomain;
    -
     
     /*
      * Register a set of sysctl names by calling register_sysctl_table
    diff -Nru lsm-wirex/ipc/sem.c lsm-nailabs/ipc/sem.c
    --- lsm-wirex/ipc/sem.c	Mon Feb 19 13:18:18 2001
    +++ lsm-nailabs/ipc/sem.c	Mon Jun 18 10:55:38 2001
    @@ -60,6 +60,7 @@
     #include <linux/spinlock.h>
     #include <linux/init.h>
     #include <linux/proc_fs.h>
    +#include <linux/security.h>
     #include <asm/uaccess.h>
     #include "util.h"
     
    @@ -112,6 +113,7 @@
     static int newary (key_t key, int nsems, int semflg)
     {
     	int id;
    +	int retval;
     	struct sem_array *sma;
     	int size;
     
    @@ -126,6 +128,13 @@
     		return -ENOMEM;
     	}
     	memset (sma, 0, size);
    +
    +	retval = security_ops->sem_ops->alloc_security(sma);
    +	if (retval) {
    +		ipc_free(sma, size);
    +		return retval;
    +	}
    +
     	id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
     	if(id == -1) {
     		ipc_free(sma, size);
    @@ -171,7 +180,8 @@
     			BUG();
     		if (nsems > sma->sem_nsems)
     			err = -EINVAL;
    -		else if (ipcperms(&sma->sem_perm, semflg))
    +		else if (ipcperms(&sma->sem_perm, semflg) ||
    +			 security_ops->sem_ops->associate(sma, sem_buildid(id, sma->sem_perm.seq), semflg))
     			err = -EACCES;
     		else
     			err = sem_buildid(id, sma->sem_perm.seq);
    @@ -384,6 +394,7 @@
     	int size;
     
     	sma = sem_rmid(id);
    +	security_ops->sem_ops->free_security(sma);
     
     	/* Invalidate the existing undo structures for this semaphore set.
     	 * (They will be freed without any further action in sem_exit()
    @@ -438,6 +449,10 @@
     		struct seminfo seminfo;
     		int max_id;
     
    +		err = security_ops->ipc_ops->getinfo(semid, cmd);
    +		if (err)
    +			return err;
    +		
     		memset(&seminfo,0,sizeof(seminfo));
     		seminfo.semmni = sc_semmni;
     		seminfo.semmns = sc_semmns;
    @@ -479,6 +494,11 @@
     		err = -EACCES;
     		if (ipcperms (&sma->sem_perm, S_IRUGO))
     			goto out_unlock;
    +
    +		err = security_ops->sem_ops->semctl(sma, semid, cmd);
    +		if (err)
    +			goto out_unlock;
    +
     		id = sem_buildid(semid, sma->sem_perm.seq);
     
     		kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
    @@ -522,6 +542,11 @@
     	if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO))
     		goto out_unlock;
     
    +	err = security_ops->sem_ops->semctl(sma, semid, cmd);
    +	if (err)
    +		goto out_unlock;
    +
    +	err = -EACCES;
     	switch (cmd) {
     	case GETALL:
     	{
    @@ -712,6 +737,10 @@
     		goto out_unlock;
     	}
     
    +	err = security_ops->sem_ops->semctl(sma, semid, cmd);
    +	if (err)
    +		goto out_unlock;
    +
     	switch(cmd){
     	case IPC_RMID:
     		freeary(semid);
    @@ -869,6 +898,12 @@
     	error = -EACCES;
     	if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
     		goto out_unlock_free;
    +
    +	error = security_ops->sem_ops->semop(sma, semid, sops, nsops, alter);
    +	if (error)
    +		goto out_unlock_free;
    +	error = -EACCES;		
    +
     	if (undos) {
     		/* Make sure we have an undo structure
     		 * for this process and this semaphore set.
    diff -Nru lsm-wirex/ipc/shm.c lsm-nailabs/ipc/shm.c
    --- lsm-wirex/ipc/shm.c	Sat May 19 20:47:55 2001
    +++ lsm-nailabs/ipc/shm.c	Mon Jun 18 10:55:38 2001
    @@ -22,24 +22,11 @@
     #include <linux/file.h>
     #include <linux/mman.h>
     #include <linux/proc_fs.h>
    +#include <linux/security.h>
     #include <asm/uaccess.h>
     
     #include "util.h"
     
    -struct shmid_kernel /* private to the kernel */
    -{	
    -	struct kern_ipc_perm	shm_perm;
    -	struct file *		shm_file;
    -	int			id;
    -	unsigned long		shm_nattch;
    -	unsigned long		shm_segsz;
    -	time_t			shm_atim;
    -	time_t			shm_dtim;
    -	time_t			shm_ctim;
    -	pid_t			shm_cprid;
    -	pid_t			shm_lprid;
    -};
    -
     #define shm_flags	shm_perm.mode
     
     static struct file_operations shm_file_operations;
    @@ -191,6 +178,13 @@
     	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
     	if (!shp)
     		return -ENOMEM;
    +
    +	error = security_ops->shm_ops->alloc_security(shp);
    +	if (error) {
    +		kfree(shp);
    +		return error;
    +	}
    +
     	sprintf (name, "SYSV%08x", key);
     	file = shmem_file_setup(name, size);
     	error = PTR_ERR(file);
    @@ -245,7 +239,8 @@
     			BUG();
     		if (shp->shm_segsz < size)
     			err = -EINVAL;
    -		else if (ipcperms(&shp->shm_perm, shmflg))
    +		else if (ipcperms(&shp->shm_perm, shmflg) ||
    +			 security_ops->shm_ops->associate(shp, shm_buildid(id, shp->shm_perm.seq), shmflg))
     			err = -EACCES;
     		else
     			err = shm_buildid(id, shp->shm_perm.seq);
    @@ -384,6 +379,10 @@
     	{
     		struct shminfo64 shminfo;
     
    +		err = security_ops->ipc_ops->getinfo(shmid, cmd);
    +		if (err)
    +			return err;
    +
     		memset(&shminfo,0,sizeof(shminfo));
     		shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
     		shminfo.shmmax = shm_ctlmax;
    @@ -402,6 +401,10 @@
     	{
     		struct shm_info shm_info;
     
    +		err = security_ops->ipc_ops->getinfo(shmid, cmd);
    +		if (err)
    +			return err;
    +
     		memset(&shm_info,0,sizeof(shm_info));
     		down(&shm_ids.sem);
     		shm_lockall();
    @@ -427,6 +430,11 @@
     		shp = shm_lock(shmid);
     		if(shp==NULL)
     			return -EINVAL;
    +
    +		err = security_ops->shm_ops->shmctl(shp, shmid, cmd);
    +		if (err)
    +			goto out_unlock;
    +		
     		if(cmd==SHM_STAT) {
     			err = -EINVAL;
     			if (shmid > shm_ids.max_id)
    @@ -469,6 +477,11 @@
     		err = shm_checkid(shp,shmid);
     		if(err)
     			goto out_unlock;
    +
    +		err = security_ops->shm_ops->shmctl(shp, shmid, cmd);
    +		if (err)
    +			goto out_unlock;
    +		
     		if(cmd==SHM_LOCK) {
     			shmem_lock(shp->shm_file, 1);
     			shp->shm_flags |= SHM_LOCKED;
    @@ -499,6 +512,11 @@
     		err = shm_checkid(shp, shmid);
     		if(err)
     			goto out_unlock_up;
    +
    +		err = security_ops->shm_ops->shmctl(shp, shmid, cmd);
    +		if (err)
    +			goto out_unlock_up;
    +
     		if (current->euid != shp->shm_perm.uid &&
     		    current->euid != shp->shm_perm.cuid && 
     		    !capable(CAP_SYS_ADMIN)) {
    @@ -530,6 +548,11 @@
     		err = shm_checkid(shp,shmid);
     		if(err)
     			goto out_unlock_up;
    +
    +		err = security_ops->shm_ops->shmctl(shp, shmid, cmd);
    +		if (err)
    +			goto out_unlock_up;
    +		
     		err=-EPERM;
     		if (current->euid != shp->shm_perm.uid &&
     		    current->euid != shp->shm_perm.cuid && 
    @@ -610,6 +633,13 @@
     		shm_unlock(shmid);
     		return -EACCES;
     	}
    +
    +	err = security_ops->shm_ops->shmat(shp, shmid, shmaddr, shmflg);
    +	if (err) {
    +		shm_unlock(shmid);
    +		return err;
    +	}
    +		
     	file = shp->shm_file;
     	shp->shm_nattch++;
     	shm_unlock(shmid);
    diff -Nru lsm-wirex/ipc/util.c lsm-nailabs/ipc/util.c
    --- lsm-wirex/ipc/util.c	Mon Feb 19 13:18:18 2001
    +++ lsm-nailabs/ipc/util.c	Mon Jun 18 13:22:05 2001
    @@ -19,6 +19,7 @@
     #include <linux/vmalloc.h>
     #include <linux/slab.h>
     #include <linux/highuid.h>
    +#include <linux/security.h>
     
     #if defined(CONFIG_SYSVIPC)
     
    @@ -263,7 +264,7 @@
     	    !capable(CAP_IPC_OWNER))
     		return -1;
     
    -	return 0;
    +	return security_ops->ipc_ops->permission(ipcp, flag);
     }
     
     /*
    diff -Nru lsm-wirex/kernel/Makefile lsm-nailabs/kernel/Makefile
    --- lsm-wirex/kernel/Makefile	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/Makefile	Mon Jun 11 16:29:09 2001
    @@ -20,7 +20,6 @@
     obj-$(CONFIG_UID16) += uid16.o
     obj-$(CONFIG_MODULES) += ksyms.o
     obj-$(CONFIG_PM) += pm.o
    -obj-$(CONFIG_CAPABILITIES) += capability_plug.o
     
     ifneq ($(CONFIG_IA64),y)
     # According to Alan Modra <alanat_private>, the -fno-omit-frame-pointer is
    diff -Nru lsm-wirex/kernel/acct.c lsm-nailabs/kernel/acct.c
    --- lsm-wirex/kernel/acct.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/acct.c	Mon Jun 11 16:29:09 2001
    @@ -158,8 +158,7 @@
     	char *tmp;
     	int error;
     
    -	/* XXX may want to defer this until we have file -cmw */
    -	if (security_ops->acct());
    +	if (!capable(CAP_SYS_PACCT))
     		return -EPERM;
     
     	if (name) {
    @@ -182,6 +181,10 @@
     		if (!file->f_op->write) 
     			goto out_err;
     	}
    +
    +	error = security_ops->acct(file);
    +	if (error)
    +		goto out_err;
     
     	error = 0;
     	lock_kernel();
    diff -Nru lsm-wirex/kernel/capability_plug.c lsm-nailabs/kernel/capability_plug.c
    --- lsm-wirex/kernel/capability_plug.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/capability_plug.c	Wed Dec 31 19:00:00 1969
    @@ -1,699 +0,0 @@
    -/*
    - *  Capabilities Security plug
    - *
    - *	This program is free software; you can redistribute it and/or modify
    - *	it under the terms of the GNU General Public License as published by
    - *	the Free Software Foundation; either version 2 of the License, or
    - *	(at your option) any later version.
    - *
    - */ 
    -
    -#include <linux/config.h>
    -#include <linux/module.h>
    -#include <linux/init.h>
    -#include <linux/kernel.h>
    -#include <linux/errno.h>
    -#include <linux/security.h>
    -#include <linux/capability.h>
    -#include <linux/mm.h>
    -#include <linux/slab.h>
    -#include <linux/smp_lock.h>
    -#include <asm/uaccess.h>
    -
    -/* #define DEBUG */
    -
    -#ifdef DEBUG
    -static char *capabilities[] = { "CAP_CHOWN",
    -				"CAP_DAC_OVERRIDE",
    -				"CAP_DAC_READ_SEARCH",
    -				"CAP_FOWNER",
    -				"CAP_FSETID",
    -				"CAP_KILL",
    -				"CAP_SETGID",
    -				"CAP_SETUID",
    -				"CAP_SETPCAP",
    -				"CAP_LINUX_IMMUTABLE",
    -				"CAP_NET_BIND_SERVICE",
    -				"CAP_NET_BROADCAST",
    -				"CAP_NET_ADMIN",
    -				"CAP_NET_RAW",
    -				"CAP_IPC_LOCK",
    -				"CAP_IPC_OWNER",
    -				"CAP_SYS_MODULE",
    -				"CAP_SYS_RAWIO",
    -				"CAP_SYS_CHROOT",
    -				"CAP_SYS_PTRACE",
    -				"CAP_SYS_PACCT",
    -				"CAP_SYS_ADMIN",
    -				"CAP_SYS_BOOT",
    -				"CAP_SYS_NICE",
    -				"CAP_SYS_RESOURCE",
    -				"CAP_SYS_TIME",
    -				"CAP_SYS_TTY_CONFIG",
    -				"CAP_MKNOD",
    -				"CAP_LEASE" };
    -#endif /* DEBUG */
    -
    -/* flag to keep track of how we were registered */
    -static int secondary;
    -
    -struct cap_list {
    -	kernel_cap_t	cap_inheritable, cap_permitted, cap_effective;
    -};
    -
    -static inline int is_capable(int cap)
    -{
    -	if (current->security &&
    -	cap_raised(((struct cap_list*)(current->security))->cap_effective, cap)) {
    -		current->flags |= PF_SUPERPRIV;
    -#ifdef DEBUG
    -		printk(KERN_DEBUG " %s(%d) has %s\n", current->comm,
    -			current->pid, capabilities[cap]);
    -#endif
    -		return 1;
    -	}
    -#ifdef DEBUG
    -	printk(KERN_DEBUG " %s(%d) does not have %s\n", current->comm,
    -		current->pid, capabilities[cap]);
    -#endif
    -	return 0;
    -}
    -
    -/* assorted security operations  (mostly syscall interposition) */
    -static int cap_sethostname(void)
    -{
    -	return is_capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
    -}
    -static int cap_setdomainname(void)
    -{
    -	return is_capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
    -}
    -static int cap_reboot(unsigned int cmd)
    -{
    -	return is_capable(CAP_SYS_BOOT) ? 0 : -EPERM;
    -}
    -
    -static int cap_mount		(char * dev_name, struct nameidata *nd, char * type, unsigned long flags, void * data)	{return 0;}
    -static int cap_add_vfsmnt	(struct nameidata *nd, struct super_block *sb, char * dev_name)				{return 0;}
    -static int cap_umount		(struct vfsmount *mnt, int flags)							{return 0;}
    -static void cap_umount_close	(struct vfsmount *mnt)									{return;}
    -static void cap_umount_busy	(struct vfsmount *mnt)									{return;}
    -static int cap_remount		(struct vfsmount *mnt, unsigned long flags, void *data)					{return 0;}
    -static void cap_post_remount	(struct vfsmount *mnt, unsigned long flags, void *data)					{return;}
    -
    -static int cap_ioperm(void)
    -{
    -	return 0;
    -}
    -static int cap_iopl(void)
    -{
    -	return 0;
    -}
    -static int cap_ptrace(struct task_struct *parent, struct task_struct *child)
    -{
    -	if (current == child)	/* TRACEME */
    -		return 0;
    -	return is_capable(CAP_SYS_PTRACE) ? 0 : -EPERM;
    -}
    -static int cap_setcapablity(void)
    -{
    -	return 0;
    -}
    -static int cap_acct(void)
    -{
    -	return is_capable(CAP_SYS_PACCT) ? 0 : -EPERM;
    -}
    -static int cap_capable(int cap)
    -{
    -	return is_capable(cap) ? 0 : -EPERM;
    -}
    -
    -/* binprm security operations */
    -static int cap_bprm_alloc_security(struct linux_binprm *bprm)
    -{
    -	int rc = -1;
    -	struct cap_list *caps;
    -	caps = (struct cap_list*)kmalloc(sizeof(struct cap_list), GFP_KERNEL);
    -	if (!caps)
    -		goto out;
    -
    -	rc = 0;
    -	/* from prepare_binprm() */
    -	/* We don't have VFS support for capabilities yet */
    -	cap_clear(caps->cap_inheritable);
    -	cap_clear(caps->cap_permitted);
    -	cap_clear(caps->cap_effective);
    -
    -	/*  To support inheritance of root-permissions and suid-root
    -         *  executables under compatibility mode, we raise all three
    -         *  capability sets for the file.
    -         *
    -         *  If only the real uid is 0, we only raise the inheritable
    -         *  and permitted sets of the executable file.
    -         */
    -
    -	if (!issecure(SECURE_NOROOT)) {
    -		if (bprm->e_uid == 0 || current->uid == 0) {
    -			cap_set_full(caps->cap_inheritable);
    -			cap_set_full(caps->cap_permitted);
    -		}
    -		if (bprm->e_uid == 0) 
    -			cap_set_full(caps->cap_effective);
    -	}
    -out:
    -	bprm->security = (void *)caps;
    -	return rc;
    -}
    -static void cap_bprm_free_security(struct linux_binprm *bprm)
    -{
    -	if (bprm->security)
    -		kfree(bprm->security);
    -}
    -
    -/* stolen from fs/exec.c needed for compute_creds below */
    -static inline int must_not_trace_exec(struct task_struct * p)
    -{
    -	/* needs to be converted to use opaque security blob */
    -	return (p->ptrace & PT_PTRACED) && !cap_raised(p->p_pptr->cap_effective, CAP_SYS_PTRACE);
    -}
    -static void cap_bprm_compute_creds(struct linux_binprm *bprm)
    -{	/* from compute_creds() 
    -	 * keep_capabilities is still in current
    -	 */
    -	kernel_cap_t new_permitted, working;
    -	int do_unlock = 0;
    -	struct cap_list *bprm_cap = (struct cap_list*)(bprm->security);
    -	struct cap_list *cur_cap = (struct cap_list*)(current->security);
    -
    -	if (!bprm_cap || !cur_cap)
    -		return;
    -
    -	new_permitted = cap_intersect(bprm_cap->cap_permitted, cap_bset);
    -	working = cap_intersect(bprm_cap->cap_inheritable,
    -				cur_cap->cap_inheritable);
    -	new_permitted = cap_combine(new_permitted, working);
    -
    -	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
    -	    !cap_issubset(new_permitted, cur_cap->cap_permitted)) {
    -                current->dumpable = 0;
    -		
    -		lock_kernel();
    -		if (must_not_trace_exec(current)
    -		    || atomic_read(&current->fs->count) > 1
    -		    || atomic_read(&current->files->count) > 1
    -		    || atomic_read(&current->sig->count) > 1) {
    -			if(!is_capable(CAP_SETUID)) {
    -				bprm->e_uid = current->uid;
    -				bprm->e_gid = current->gid;
    -			}
    -			if(!is_capable(CAP_SETPCAP)) {
    -				new_permitted = cap_intersect(new_permitted,
    -							cur_cap->cap_permitted);
    -			}
    -		}
    -		do_unlock = 1;
    -	}
    -
    -
    -	/* For init, we want to retain the capabilities set
    -         * in the init_task struct. Thus we skip the usual
    -         * capability rules */
    -	if (current->pid != 1) {
    -		cur_cap->cap_permitted = new_permitted;
    -		cur_cap->cap_effective =
    -			cap_intersect(new_permitted, bprm_cap->cap_effective);
    -	}
    -	
    -        /* AUD: Audit candidate if current->cap_effective is set */
    -
    -        current->suid = current->euid = current->fsuid = bprm->e_uid;
    -        current->sgid = current->egid = current->fsgid = bprm->e_gid;
    -
    -	if(do_unlock)
    -		unlock_kernel();
    -	current->keep_capabilities = 0;
    -}
    -
    -/* super_block security operations */
    -static int cap_sb_alloc_security(struct super_block *sb)
    -{
    -	return 0;
    -}
    -static void cap_sb_free_security(struct super_block *sb)
    -{
    -	return;
    -}
    -static int cap_sb_statfs(struct super_block *sb)
    -{
    -	return 0;
    -}
    -
    -/* inode security operations */
    -static int cap_inode_alloc_security(struct inode *inode)
    -{
    -	return 0;
    -}
    -static void cap_inode_free_security(struct inode *inode)
    -{
    -	return;
    -}
    -static int cap_inode_create(struct inode *inode, struct dentry *dentry, int mask)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_create(struct inode *inode, struct dentry *dentry, int mask)
    -{
    -	return;
    -}
    -static int cap_inode_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
    -{
    -	return;
    -}
    -static int cap_inode_unlink(struct inode *inode, struct dentry *dentry)
    -{
    -	return 0;
    -}
    -static int cap_inode_symlink(struct inode *inode, struct dentry *dentry, const char *name)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_symlink(struct inode *inode, struct dentry *dentry, const char *name)
    -{
    -	return;
    -}
    -static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry, int mask)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_mkdir(struct inode *inode, struct dentry *dentry, int mask)
    -{
    -	return;
    -}
    -static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry)
    -{
    -	return 0;
    -}
    -static int cap_inode_mknod(struct inode *inode, struct dentry *dentry, int major, dev_t minor)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_mknod(struct inode *inode, struct dentry *dentry, int major, dev_t minor)
    -{
    -	return;
    -}
    -static int cap_inode_rename(struct inode *old_inode, struct dentry *old_dentry, struct inode *new_inode, struct dentry *new_dentry)
    -{
    -	return 0;
    -}
    -static void cap_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry, struct inode *new_inode, struct dentry *new_dentry)
    -{
    -	return;
    -}
    -static int cap_inode_readlink(struct dentry *dentry, char *name, int mask)
    -{
    -	return 0;
    -}
    -static int cap_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
    -{
    -	return 0;
    -}
    -static int cap_inode_truncate(struct inode *inode)
    -{
    -	return 0;
    -}
    -static int cap_inode_permission(struct inode *inode, int mask)
    -{
    -	return 0;
    -}
    -static int cap_inode_revalidate(struct dentry *inode)
    -{
    -	return 0;
    -}
    -static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr)
    -{
    -	return 0;
    -}
    -static void cap_inode_attach_pathlabel(struct dentry *dentry, struct vfsmount *mnt)
    -{
    -	return;
    -}
    -static int cap_inode_stat(struct inode *inode)
    -{
    -	return 0;
    -}
    -
    -
    -/* file security operations */
    -static int cap_file_permission(struct file *file, int mask)
    -{
    -	return 0;
    -}
    -static int cap_file_alloc_security(struct file *file)
    -{
    -	return 0;
    -}
    -static void cap_file_free_security(struct file *file)
    -{
    -	return;
    -}
    -static int cap_file_llseek(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_read(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_write(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_ioctl(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_mmap(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_lock(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_readv(struct file *file)
    -{
    -	return 0;
    -}
    -static int cap_file_writev(struct file *file)
    -{
    -	return 0;
    -}
    -
    -/* task security operations */
    -static int cap_task_create(void)
    -{
    -	return 0;
    -}
    -static int cap_task_alloc_security(struct task_struct *p)
    -{
    -	int rc = -1;
    -	struct cap_list *caps;
    -	caps = (struct cap_list *)kmalloc(sizeof(struct cap_list), GFP_KERNEL);
    -	if (!caps)
    -		goto out;
    -	rc = 0;
    -	if (current->security)
    -		/* inherit from parent, this will break when parent
    -		 * has a different security blob
    -		 */
    -		memcpy (caps, current->security, sizeof(struct cap_list));
    -out:
    -	p->security = (void *)caps;
    -	return rc;
    -}
    -static void cap_task_free_security(struct task_struct *p)
    -{
    -	if (p->security)
    -		kfree(p->security);
    -}
    -static int cap_task_setuid(void)
    -{
    -	return is_capable(CAP_SETUID) ? 0 : -EPERM;
    -}
    -static int cap_task_setgid(void)
    -{
    -	return is_capable(CAP_SETGID) ? 0 : -EPERM;
    -}
    -static int cap_task_setgroups(void)
    -{
    -	return is_capable(CAP_SETGID) ? 0 : -EPERM;
    -}
    -static int cap_task_setnice(struct task_struct *p, int nice)
    -{
    -	return is_capable(CAP_SYS_NICE) ? 0 : -EPERM;
    -}
    -static int cap_task_setrlimit(unsigned int resource)
    -{
    -	return is_capable(CAP_SYS_RESOURCE) ? 0 : -EPERM;
    -}
    -static int cap_task_setscheduler(struct task_struct *p, int policy)
    -{
    -	return is_capable(CAP_SYS_NICE) ? 0 : -EPERM;
    -}
    -static int cap_task_kill(struct task_struct *p, struct siginfo *info, int sig)
    -{
    -	return is_capable(CAP_KILL) ? 0 : -EPERM;
    -}
    -static int cap_task_set_label(char *filename)
    -{
    -	return 0;
    -}
    -static void cap_task_reset_label(void)
    -{
    -	return;
    -}
    -
    -/* module security operations */
    -static int cap_module_create_module(const char *name_user, size_t size)
    -{
    -	return is_capable(CAP_SYS_MODULE) ? 0 : -EPERM;
    -}
    -static int cap_module_init_module(const char *name_user, struct module *mod_user)
    -{
    -	return is_capable(CAP_SYS_MODULE) ? 0 : -EPERM;
    -}
    -static int cap_module_delete_module(const char *name_user)
    -{
    -	return is_capable(CAP_SYS_MODULE) ? 0 : -EPERM;
    -}
    -
    -/* message queue security operations */
    -static int cap_msg_queue_create(key_t key)
    -{
    -	return 0;
    -}
    -static int cap_msg_queue_permission(void)
    -{
    -	return 0;
    -}
    -static int cap_msg_queue_setmaxqbytes(void)
    -{
    -	return 0;
    -}
    -static int cap_msg_queue_setattr(void)
    -{
    -	return 0;
    -}
    -static int cap_msg_queue_delete(void)
    -{
    -	return 0;
    -}
    -
    -/* shared memory security operations */
    -static int cap_shm_create(key_t key)
    -{
    -	return 0;
    -}
    -static int cap_shm_permission(void)
    -{
    -	return 0;
    -}
    -static int cap_shm_setattr(void)
    -{
    -	return 0;
    -}
    -static int cap_shm_delete(void)
    -{
    -	return 0;
    -}
    -
    -/* for module stacking */
    -int cap_register_security (struct security_operations *ops)
    -{
    -	return -EPERM;
    -}
    -int cap_unregister_security (struct security_operations *ops)
    -{
    -	return -EPERM;
    -}
    -
    -
    -static struct binprm_security_ops cap_bprm_ops = {
    -	alloc_security:	cap_bprm_alloc_security,
    -	free_security:	cap_bprm_free_security,
    -	compute_creds:	cap_bprm_compute_creds,
    -};
    -static struct super_block_security_ops cap_sb_ops = {
    -	alloc_security:	cap_sb_alloc_security,
    -	free_security:	cap_sb_free_security,
    -	statfs:	        cap_sb_statfs,
    -};
    -static struct inode_security_ops cap_inode_ops = {
    -	alloc_security:	cap_inode_alloc_security,
    -	free_security:	cap_inode_free_security,
    -	create:		cap_inode_create,
    -	post_create:	cap_inode_post_create,
    -	link:		cap_inode_link,
    -	post_link:	cap_inode_post_link,
    -	unlink:		cap_inode_unlink,
    -	symlink:	cap_inode_symlink,
    -	post_symlink:	cap_inode_post_symlink,
    -	mkdir:		cap_inode_mkdir,
    -	post_mkdir:	cap_inode_post_mkdir,
    -	rmdir:		cap_inode_rmdir,
    -	mknod:		cap_inode_mknod,
    -	post_mknod:	cap_inode_post_mknod,
    -	rename:		cap_inode_rename,
    -	post_rename:	cap_inode_post_rename,
    -	readlink:	cap_inode_readlink,
    -	follow_link:	cap_inode_follow_link,
    -	truncate:	cap_inode_truncate,
    -	permission:	cap_inode_permission,
    -	revalidate:	cap_inode_revalidate,
    -	setattr:	cap_inode_setattr,
    -	attach_pathlabel:cap_inode_attach_pathlabel,
    -	stat:           cap_inode_stat,
    -};
    -
    -static struct file_security_ops	cap_file_ops = {
    -	permission:	cap_file_permission,
    -	alloc_security:	cap_file_alloc_security,
    -	free_security:	cap_file_free_security,
    -	llseek:		cap_file_llseek,
    -	read:		cap_file_read,
    -	write:		cap_file_write,
    -	ioctl:		cap_file_ioctl,
    -	mmap:		cap_file_mmap,
    -	lock:		cap_file_lock,
    -	readv:		cap_file_readv,
    -	writev:		cap_file_writev,
    -};
    -
    -static struct task_security_ops	cap_task_ops = {
    -	create:		cap_task_create,
    -	alloc_security:	cap_task_alloc_security,
    -	free_security:	cap_task_free_security,
    -	setuid:		cap_task_setuid,
    -	setgid:		cap_task_setgid,
    -	setgroups:	cap_task_setgroups,
    -	setnice:	cap_task_setnice,
    -	setrlimit:	cap_task_setrlimit,
    -	setscheduler:	cap_task_setscheduler,
    -	kill:		cap_task_kill,
    -	set_label:	cap_task_set_label,
    -	reset_label:	cap_task_reset_label,
    -};
    -
    -static struct socket_security_ops cap_socket_ops = {};
    -
    -static struct module_security_ops cap_module_ops = {
    -	create_module:	cap_module_create_module,
    -	init_module:	cap_module_init_module,
    -	delete_module:	cap_module_delete_module,
    -
    -};
    -
    -static struct msg_queue_security_ops cap_msg_queue_ops = {
    -	create:		cap_msg_queue_create,
    -	permission:	cap_msg_queue_permission,
    -	setmaxqbytes:	cap_msg_queue_setmaxqbytes,
    -	setattr:	cap_msg_queue_setattr,
    -	delete:		cap_msg_queue_delete,
    -};
    -
    -static struct shm_security_ops cap_shm_ops = {
    -	create:		cap_shm_create,
    -	permission:	cap_shm_permission,
    -	setattr:	cap_shm_setattr,
    -	delete:		cap_shm_delete,
    -};
    -
    -struct security_operations capability_ops = {
    -        version:                SECURITY_INTERFACE_VERSION,
    -
    -	sethostname:		cap_sethostname,
    -	setdomainname:		cap_setdomainname,
    -	reboot:			cap_reboot,
    -	mount:			cap_mount,
    -	add_vfsmnt:             cap_add_vfsmnt,
    -	umount:			cap_umount,
    -	umount_close:		cap_umount_close,
    -	umount_busy:		cap_umount_busy,
    -	remount:		cap_remount,
    -	post_remount:		cap_post_remount,
    -	ioperm:			cap_ioperm,
    -	iopl:			cap_iopl,
    -	ptrace:			cap_ptrace,
    -	setcapability:		cap_setcapablity,
    -	acct:			cap_acct,
    -	capable:		cap_capable,
    -
    -	bprm_ops:		&cap_bprm_ops,
    -	sb_ops:			&cap_sb_ops,
    -	inode_ops:		&cap_inode_ops,
    -	file_ops:		&cap_file_ops,
    -	task_ops:		&cap_task_ops,
    -	socket_ops:		&cap_socket_ops,
    -	module_ops:		&cap_module_ops,
    -	msg_queue_ops:		&cap_msg_queue_ops,
    -	shm_ops:		&cap_shm_ops,
    -
    -	register_security:	&cap_register_security,
    -	unregister_security:	&cap_unregister_security,
    -};
    -
    -static int __init capability_plug_init (void)
    -{
    -	/* register ourselves with the security framework */
    -	if (register_security (&capability_ops)) {
    -		printk (KERN_INFO "Failure registering capabilities with the kernel\n");
    -		/* try registering with primary module */
    -		if (mod_reg_security(&capability_ops)) {
    -			printk (KERN_INFO "Failure registering capbilities "
    -				"with primary security module.\n");
    -			return -EINVAL;
    -		}
    -		secondary = 1;
    -	}
    -#if defined(CONFIG_CAPABILITIES)  && !defined(CONFIG_CAPABILITIES_MODULE)
    -	/* hack to make this work when compiled in to kernel */
    -	if (current->pid == 1) {
    -		struct cap_list *cap;
    -		if (cap_task_alloc_security(current))
    -			panic("Couldn't allocate initial task security blob\n");
    -		cap = (struct cap_list *)current->security;
    -		cap->cap_effective = CAP_INIT_EFF_SET;
    -		cap->cap_inheritable = CAP_INIT_INH_SET;
    -		cap->cap_permitted = CAP_FULL_SET;
    -	}
    -#endif /* CONFIG_CAPABILITIES && !CONFIG_CAPABILITIES_MODULE */
    -	printk(KERN_INFO "Capability Plug initialized\n");
    -	return 0;
    -}
    -
    -
    -static void __exit capability_plug_exit (void)
    -{
    -	/* remove ourselves from the security framework */
    -	if (secondary) {
    -		if (mod_unreg_security (&capability_ops))
    -			printk (KERN_INFO "Failure unregistering capabilities "
    -				"with primary module.\n");
    -		return;
    -	}
    -
    -	if (unregister_security (&capability_ops)) {
    -		printk (KERN_INFO "Failure unregistering capabilities with the kernel\n");
    -	}
    -}
    -
    -
    -module_init (capability_plug_init);
    -module_exit (capability_plug_exit);
    -
    -EXPORT_SYMBOL(capability_ops);
    -
    diff -Nru lsm-wirex/kernel/exit.c lsm-nailabs/kernel/exit.c
    --- lsm-wirex/kernel/exit.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/exit.c	Mon Jun 11 16:29:09 2001
    @@ -524,6 +524,10 @@
     			if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
     			    && !(options & __WALL))
     				continue;
    +
    +			if (security_ops->task_ops->wait(p))
    +				continue;
    +
     			flag = 1;
     			switch (p->state) {
     			case TASK_STOPPED:
    diff -Nru lsm-wirex/kernel/module.c lsm-nailabs/kernel/module.c
    --- lsm-wirex/kernel/module.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/module.c	Mon Jun 11 16:29:09 2001
    @@ -298,6 +298,8 @@
     	struct module *mod;
     	unsigned long flags;
     
    +	if (!capable(CAP_SYS_MODULE))
    +		return -EPERM;
     	lock_kernel();
     	if ((namelen = get_mod_name(name_user, &name)) < 0) {
     		error = namelen;
    @@ -357,6 +359,8 @@
     	unsigned long mod_user_size;
     	struct module_ref *dep;
     
    +	if (!capable(CAP_SYS_MODULE))
    +		return -EPERM;
     	lock_kernel();
     	if ((namelen = get_mod_name(name_user, &name)) < 0) {
     		error = namelen;
    @@ -614,6 +618,9 @@
     	char *name;
     	long error;
     	int something_changed;
    +
    +	if (!capable(CAP_SYS_MODULE))
    +		return -EPERM;
     
     	lock_kernel();
     	if (name_user) {
    diff -Nru lsm-wirex/kernel/sched.c lsm-nailabs/kernel/sched.c
    --- lsm-wirex/kernel/sched.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/sched.c	Mon Jun 18 13:22:05 2001
    @@ -842,14 +842,19 @@
     asmlinkage long sys_nice(int increment)
     {
     	long newprio;
    +	int retval;
     
     	/*
     	 *	Setpriority might change our priority at the same moment.
     	 *	We don't have to worry. Conceptually one call occurs first
     	 *	and we have a single winner.
     	 */
    -	if (increment < -40)
    -		increment = -40;
    +	if (increment < 0) {
    +		if (!capable(CAP_SYS_NICE))
    +			return -EPERM;
    +		if (increment < -40)
    +			increment = -40;
    +	}
     	if (increment > 40)
     		increment = 40;
     
    @@ -858,10 +863,11 @@
     		newprio = -20;
     	if (newprio > 19)
     		newprio = 19;
    -	if (increment < 0) {
    -		if (security_ops->task_ops->setnice(current, newprio))
    -			return -EPERM;
    -	}
    +
    +	retval = security_ops->task_ops->setnice(current, newprio);
    +	if (retval)
    +		return retval;
    +	
     	current->nice = newprio;
     	return 0;
     }
    @@ -883,7 +889,6 @@
     	struct sched_param lp;
     	struct task_struct *p;
     	int retval;
    -	int no_sched;
     
     	retval = -EINVAL;
     	if (!param || pid < 0)
    @@ -924,13 +929,16 @@
     	if ((policy == SCHED_OTHER) != (lp.sched_priority == 0))
     		goto out_unlock;
     
    +	retval = security_ops->task_ops->setscheduler(p, policy);
    +	if (retval)
    +		goto out_unlock;
    +
     	retval = -EPERM;
    -	no_sched = security_ops->task_ops->setscheduler(p, policy);
     	if ((policy == SCHED_FIFO || policy == SCHED_RR) && 
    -	    no_sched)
    +	    !capable(CAP_SYS_NICE))
     		goto out_unlock;
     	if ((current->euid != p->euid) && (current->euid != p->uid) &&
    -	    no_sched)
    +	    !capable(CAP_SYS_NICE))
     		goto out_unlock;
     
     	retval = 0;
    diff -Nru lsm-wirex/kernel/security.c lsm-nailabs/kernel/security.c
    --- lsm-wirex/kernel/security.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/security.c	Mon Jun 18 13:38:15 2001
    @@ -6,6 +6,10 @@
      *      the Free Software Foundation; either version 2 of the License, or
      *      (at your option) any later version.
      *
    + * 2001_Jun_12 Stephen Smalley <sdsat_private>, NAI Labs, SELinux project
    + *      Changed all non-capable hooks to be authoritative or restrictive.
    + *      Added parameters to several of the hook functions.
    + *
      * 2001_Apr_18 greg k-h
      *	fleshed out with current security.h stubs
      *
    @@ -32,9 +36,9 @@
     
     
     /* Stub functions for the default security function pointers in case no security model is loaded */
    -static int dummy_sethostname	(void)	{return 0;}
    -static int dummy_setdomainname	(void)	{return 0;}
    -static int dummy_reboot		(unsigned int cmd)	{return 0;}
    +static int dummy_sethostname(char *hostname)	{return 0;}
    +static int dummy_setdomainname(char *domainname) { return 0; }	
    +static int dummy_reboot		(unsigned int cmd, void *arg) { return 0; }
     static int dummy_mount		(char * dev_name, struct nameidata *nd, char * type, unsigned long flags, void * data)	{return 0;}
     static int dummy_add_vfsmnt	(struct nameidata *nd, struct super_block *sb, char * dev_name)				{return 0;}
     static int dummy_umount		(struct vfsmount *mnt, int flags)					{return 0;}
    @@ -42,11 +46,11 @@
     static void dummy_umount_busy	(struct vfsmount *mnt)									{return;}
     static int dummy_remount	(struct vfsmount *mnt, unsigned long flags, void *data)					{return 0;}
     static void dummy_post_remount	(struct vfsmount *mnt, unsigned long flags, void *data)					{return;}
    -static int dummy_ioperm		(void)	{return 0;}
    -static int dummy_iopl		(void)	{return 0;}
    -static int dummy_ptrace		(struct task_struct *parent, struct task_struct *child)	{return 0;}
    +static int dummy_ioperm(unsigned long from, unsigned long num, int turn_on) { return 0; }
    +static int dummy_iopl(unsigned int old, unsigned int level) { return 0; }
    +static int dummy_ptrace		(struct task_struct *parent, struct task_struct *child) { return 0; }
     static int dummy_setcapablity	(void)	{return 0;}
    -static int dummy_acct		(void)	{return 0;}
    +static int dummy_acct		(struct file *file) { return 0; }
     static int dummy_capable	(int cap)	{return 0;}
     
     static int dummy_binprm_alloc_security(struct linux_binprm *bprm)	{return 0;}
    @@ -56,6 +60,7 @@
     static int dummy_sb_alloc_security(struct super_block *sb)	{return 0;}
     static void dummy_sb_free_security	(struct super_block *sb)		{return;}
     static int dummy_sb_statfs	(struct super_block *sb)		{return 0;}
    +
     static int dummy_inode_alloc_security	(struct inode *inode)	{return 0;}
     static void dummy_inode_free_security	(struct inode *inode)	{return;}
     static int dummy_inode_create		(struct inode *inode, struct dentry *dentry, int mask) {return 0;}
    @@ -75,9 +80,9 @@
     static int dummy_inode_readlink		(struct dentry *dentry, char *name, int mask) {return 0;}
     static int dummy_inode_follow_link	(struct dentry *dentry, struct nameidata *nameidata) {return 0;}
     static int dummy_inode_truncate		(struct inode *inode) {return 0;}
    -static int dummy_inode_permission	(struct inode *inode, int mask) {return 0;}
    +static int dummy_inode_permission(struct inode *inode, int mask) { return 0; }
     static int dummy_inode_revalidate	(struct dentry *inode) {return 0;}
    -static int dummy_inode_setattr		(struct dentry *dentry, struct iattr *iattr) {return 0;}
    +static int dummy_inode_setattr(struct dentry *dentry, struct iattr *iattr) { return 0; }
     static void dummy_inode_attach_pathlabel(struct dentry *dentry, struct vfsmount *mnt) {return;}
     static int dummy_inode_stat(struct inode *inode) {return 0;}
     
    @@ -87,22 +92,31 @@
     static int dummy_file_llseek		(struct file *file)	{return 0;}
     static int dummy_file_read		(struct file *file)	{return 0;}
     static int dummy_file_write		(struct file *file)	{return 0;}
    -static int dummy_file_ioctl		(struct file *file)	{return 0;}
    -static int dummy_file_mmap		(struct file *file)	{return 0;}
    +static int dummy_file_ioctl		(struct file *file, unsigned int command
    +, unsigned long arg)	{return 0;}
    +static int dummy_file_mmap		(struct file *file, unsigned long prot, unsigned long flags)	{return 0;}
    +static int dummy_file_mprotect		(struct vm_area_struct *vma, unsigned long prot)	{return 0;}
     static int dummy_file_lock		(struct file *file)	{return 0;}
     static int dummy_file_readv		(struct file *file)	{return 0;}
     static int dummy_file_writev		(struct file *file)	{return 0;}
    +static int dummy_file_fcntl		(struct file *file, unsigned int cmd, unsigned long arg)	{return 0;}
    +static int dummy_file_fcntl64		(struct file *file, unsigned int cmd, unsigned long arg)	{return 0;}
    +static int dummy_file_set_fowner	(struct file *file)	{return 0;}
    +static int dummy_file_send_sigiotask	(struct task_struct *tsk, struct fown_struct *fown, int fd, int reason) { return 0; }
     
     static int dummy_task_create		(void)	{return 0;}
     static int dummy_task_alloc_security	(struct task_struct *p)	{return 0;}
     static void dummy_task_free_security	(struct task_struct *p)	{return;}
    -static int dummy_task_setuid		(void)	{return 0;}
    -static int dummy_task_setgid		(void)	{return 0;}
    -static int dummy_task_setgroups		(void)	{return 0;}
    -static int dummy_task_setnice		(struct task_struct *p, int nice)			{return 0;}
    -static int dummy_task_setrlimit		(unsigned int resource)	{return 0;}
    -static int dummy_task_setscheduler	(struct task_struct *p, int policy)			{return 0;}
    -static int dummy_task_kill		(struct task_struct *p, struct siginfo *info, int sig)	{return 0;}
    +static int dummy_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) { return 0; }
    +static int dummy_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags) { return 0; }
    +static int dummy_task_setgroups(int gidsetsize, gid_t *grouplist) { return 0; }
    +static int dummy_task_setnice(struct task_struct *p, int nice) { return 0; }
    +static int dummy_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) { return 0; }
    +static int dummy_task_setscheduler(struct task_struct *p, int policy) { return 0; }
    +static int dummy_task_wait		(struct task_struct *p) {return 0;}
    +
    +static int dummy_task_kill		(struct task_struct *p, struct siginfo *info, int sig) { return 0; }
    +
     static int dummy_task_set_label		(char *filename)	{return 0;}
     static void dummy_task_reset_label	(void)			{return;}
     
    @@ -110,20 +124,30 @@
     static int dummy_module_init_module	(const char *name_user, struct module *mod_user)	{return 0;}
     static int dummy_module_delete_module	(const char *name_user)					{return 0;}
     
    +static int dummy_ipc_permission(struct kern_ipc_perm *ipcp, short flag) { return 0; }
    +static int dummy_ipc_getinfo(int id, int cmd) {return 0;}
    +
     static int dummy_msg_queue_create	(key_t key)	{return 0;}
     static int dummy_msg_queue_permission	(void)	{return 0;}
     static int dummy_msg_queue_setmaxqbytes	(void)	{return 0;}
     static int dummy_msg_queue_setattr	(void)	{return 0;}
     static int dummy_msg_queue_delete	(void)	{return 0;}
     
    -static int dummy_shm_create		(key_t key)	{return 0;}
    -static int dummy_shm_permission		(void)	{return 0;}
    -static int dummy_shm_setattr		(void)	{return 0;}
    -static int dummy_shm_delete		(void)	{return 0;}
    +static int dummy_shm_alloc_security(struct shmid_kernel *shp) {return 0;}
    +static void dummy_shm_free_security(struct shmid_kernel *shp) {return;}
    +static int dummy_shm_associate(struct shmid_kernel *shp, int shmid, int shmflg) {return 0;}
    +static int dummy_shm_shmctl(struct shmid_kernel *shp, int shmid, int cmd) {return 0;}
    +static int dummy_shm_shmat(struct shmid_kernel *shp, int shmid, char *shmaddr, int shmflg) {return 0;}
    +
    +static int dummy_sem_alloc_security(struct sem_array *sma) {return 0;}
    +static void dummy_sem_free_security(struct sem_array *sma) {return;}
    +static int dummy_sem_associate(struct sem_array *sma, int semid, int semflg) {return 0;}
    +static int dummy_sem_semctl(struct sem_array *sma, int semid, int cmd) {return 0;}
    +static int dummy_sem_semop(struct sem_array *sma, int semid, struct sembuf *sops, unsigned nsops, int alter) {return 0;}
     
    -static int dummy_register		(struct security_operations *ops)
    +static int dummy_register		(const char *name, struct security_operations *ops)
     {return -EINVAL;}
    -static int dummy_unregister		(struct security_operations *ops)
    +static int dummy_unregister		(const char *name, struct security_operations *ops)
     {return -EINVAL;}
     
     static struct binprm_security_ops dummy_binprm_ops = {
    @@ -172,9 +196,14 @@
     	write:		dummy_file_write,
     	ioctl:		dummy_file_ioctl,
     	mmap:		dummy_file_mmap,
    +	mprotect:	dummy_file_mprotect,
     	lock:		dummy_file_lock,
     	readv:		dummy_file_readv,
     	writev:		dummy_file_writev,
    +	fcntl:		dummy_file_fcntl,
    +	fcntl64:	dummy_file_fcntl64,
    +	set_fowner:	dummy_file_set_fowner,
    +	send_sigiotask:	dummy_file_send_sigiotask,
     };
     
     static struct task_security_ops	dummy_task_ops = {
    @@ -187,6 +216,7 @@
     	setnice:	dummy_task_setnice,
     	setrlimit:	dummy_task_setrlimit,
     	setscheduler:	dummy_task_setscheduler,
    +	wait:		dummy_task_wait,
     	kill:		dummy_task_kill,
     	set_label:	dummy_task_set_label,
     	reset_label:	dummy_task_reset_label,
    @@ -201,6 +231,11 @@
     
     };
     
    +static struct ipc_security_ops dummy_ipc_ops = {
    +	permission:	dummy_ipc_permission,
    +	getinfo:	dummy_ipc_getinfo,
    +};
    +
     static struct msg_queue_security_ops dummy_msg_queue_ops = {
     	create:		dummy_msg_queue_create,
     	permission:	dummy_msg_queue_permission,
    @@ -210,10 +245,19 @@
     };
     
     static struct shm_security_ops dummy_shm_ops = {
    -	create:		dummy_shm_create,
    -	permission:	dummy_shm_permission,
    -	setattr:	dummy_shm_setattr,
    -	delete:		dummy_shm_delete,
    +	alloc_security: dummy_shm_alloc_security,
    +	free_security:  dummy_shm_free_security,
    +	associate:	dummy_shm_associate,
    +	shmctl:		dummy_shm_shmctl,
    +	shmat:		dummy_shm_shmat,
    +};
    +
    +static struct sem_security_ops dummy_sem_ops = {
    +	alloc_security: dummy_sem_alloc_security,
    +	free_security:  dummy_sem_free_security,
    +	associate:	dummy_sem_associate,
    +	semctl:		dummy_sem_semctl,
    +	semop:		dummy_sem_semop,
     };
     
     static struct security_operations dummy_security_ops = {
    @@ -242,9 +286,11 @@
     	file_ops:		&dummy_file_ops,
     	task_ops:		&dummy_task_ops,
     	socket_ops:		&dummy_socket_ops,
    +	ipc_ops:		&dummy_ipc_ops,
     	module_ops:		&dummy_module_ops,
     	msg_queue_ops:		&dummy_msg_queue_ops,
     	shm_ops:		&dummy_shm_ops,
    +	sem_ops:		&dummy_sem_ops,
     	
     	register_security:	dummy_register,
     	unregister_security:	dummy_unregister,
    @@ -344,7 +390,7 @@
     /* mod_reg_security - this allows stacking security modules.
      * register security ops with primary security module
      */
    -int mod_reg_security(struct security_operations *ops)
    +int mod_reg_security(const char *name, struct security_operations *ops)
     {
     	if (verify(ops)) {
     		printk (KERN_INFO __FUNCTION__ " could not verify "
    @@ -358,11 +404,11 @@
     		return -EINVAL;
     	}
     
    -	return security_ops->register_security(ops);
    +	return security_ops->register_security(name, ops);
     }
     
     /* mod_unreg_security - unregister security ops from primary security module */
    -int mod_unreg_security(struct security_operations *ops)
    +int mod_unreg_security(const char *name, struct security_operations *ops)
     {
     	if (ops == security_ops) {
     		printk (KERN_INFO __FUNCTION__ " invalid attempt to unregister "
    @@ -370,12 +416,22 @@
     		return -EINVAL;
     	}
     
    -	return security_ops->unregister_security(ops);
    +	return security_ops->unregister_security(name, ops);
     }
     
     int capable (int cap)
     {
    -	return security_ops->capable(cap) ? 0 : 1;
    +	if (!cap_raised(current->cap_effective, cap))
    +		return 0;
    +
    +	if (!security_ops->capable(cap))
    +	{
    +		current->flags |= PF_SUPERPRIV;
    +		return 1;
    +	}
    +
    +	return 0;
    +
     }
     
     EXPORT_SYMBOL(register_security);
    diff -Nru lsm-wirex/kernel/signal.c lsm-nailabs/kernel/signal.c
    --- lsm-wirex/kernel/signal.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/signal.c	Mon Jun 18 13:22:05 2001
    @@ -311,7 +311,7 @@
     	    && ((sig != SIGCONT) || (current->session != t->session))
     	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
     	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
    -	    && security_ops->task_ops->kill(t, info, sig);
    +	    && !capable(CAP_KILL);
     }
     
     /*
    @@ -517,6 +517,9 @@
     	/* The somewhat baroque permissions check... */
     	ret = -EPERM;
     	if (bad_signal(sig, info, t))
    +		goto out_nolock;
    +	ret = security_ops->task_ops->kill(t, info, sig);
    +	if (ret)
     		goto out_nolock;
     
     	/* The null signal is a permissions and process existance probe.
    diff -Nru lsm-wirex/kernel/sys.c lsm-nailabs/kernel/sys.c
    --- lsm-wirex/kernel/sys.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/sys.c	Mon Jun 18 13:22:05 2001
    @@ -215,14 +215,18 @@
     		if (!proc_sel(p, which, who))
     			continue;
     		no_nice = security_ops->task_ops->setnice(p, niceval);
    +		if (no_nice) {
    +			error = no_nice;
    +			continue;
    +		}
     		if (p->uid != current->euid &&
    -			p->uid != current->uid && no_nice) {
    +			p->uid != current->uid && !capable(CAP_SYS_NICE)) {
     			error = -EPERM;
     			continue;
     		}
     		if (error == -ESRCH)
     			error = 0;
    -		if (niceval < p->nice && no_nice)
    +		if (niceval < p->nice && !capable(CAP_SYS_NICE))
     			error = -EACCES;
     		else
     			p->nice = niceval;
    @@ -272,12 +276,15 @@
     asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
     {
     	char buffer[256];
    -	int result;
    +	int retval;
     
    -	/* check that we have permission to do this */
    -	result = security_ops->reboot(cmd);
    -	if (result) {
    -		return result;
    +	/* We only trust the superuser with rebooting the system. */
    +	if (!capable(CAP_SYS_BOOT))
    +		return -EPERM;
    +
    +	retval = security_ops->reboot(cmd, arg);
    +	if (retval) {
    +		return retval;
     	}
     
     	/* For safety, we require "magic" arguments. */
    @@ -384,13 +391,16 @@
     	int old_egid = current->egid;
     	int new_rgid = old_rgid;
     	int new_egid = old_egid;
    -	int ok_to_setgid;
    +	int retval = 0;
    +
    +	retval = security_ops->task_ops->setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
    +	if (retval)
    +		return retval;
     
    -	ok_to_setgid = !(security_ops->task_ops->setgid());
     	if (rgid != (gid_t) -1) {
     		if ((old_rgid == rgid) ||
     		    (current->egid==rgid) ||
    -		    ok_to_setgid)
    +		    capable(CAP_SETGID))
     			new_rgid = rgid;
     		else
     			return -EPERM;
    @@ -399,7 +409,7 @@
     		if ((old_rgid == egid) ||
     		    (current->egid == egid) ||
     		    (current->sgid == egid) ||
    -		    ok_to_setgid)
    +		    capable(CAP_SETGID))
     			new_egid = egid;
     		else {
     			return -EPERM;
    @@ -427,8 +437,13 @@
     asmlinkage long sys_setgid(gid_t gid)
     {
     	int old_egid = current->egid;
    +	int retval;
     
    -	if (!security_ops->task_ops->setgid())
    +	retval = security_ops->task_ops->setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
    +	if (retval)
    +		return retval;
    +
    +	if (capable(CAP_SETGID))
     	{
     		if(old_egid != gid)
     		{
    @@ -542,19 +557,21 @@
     asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
     {
     	int old_ruid, old_euid, old_suid, new_ruid, new_euid;
    -	int no_setuid;
    +	int retval;
    +
    +	retval = security_ops->task_ops->setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
    +	if (retval)
    +		return retval;
     
     	new_ruid = old_ruid = current->uid;
     	new_euid = old_euid = current->euid;
     	old_suid = current->suid;
     
    -	no_setuid = security_ops->task_ops->setuid();
    -
     	if (ruid != (uid_t) -1) {
     		new_ruid = ruid;
     		if ((old_ruid != ruid) &&
     		    (current->euid != ruid) &&
    -		    no_setuid)
    +		    !capable(CAP_SETUID))
     			return -EPERM;
     	}
     
    @@ -563,7 +580,7 @@
     		if ((old_ruid != euid) &&
     		    (current->euid != euid) &&
     		    (current->suid != euid) &&
    -		    no_setuid)
    +		    !capable(CAP_SETUID))
     			return -EPERM;
     	}
     
    @@ -581,7 +598,6 @@
     		current->suid = current->euid;
     	current->fsuid = current->euid;
     
    -	/* XXX need to fold this in to LSM hook -cmw */
     	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
     		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
     	}
    @@ -606,12 +622,17 @@
     {
     	int old_euid = current->euid;
     	int old_ruid, old_suid, new_ruid, new_suid;
    +	int retval;
    +
    +	retval = security_ops->task_ops->setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
    +	if (retval)
    +		return retval;
     
     	old_ruid = new_ruid = current->uid;
     	old_suid = current->suid;
     	new_suid = old_suid;
     	
    -	if (!security_ops->task_ops->setuid()) {
    +	if (capable(CAP_SETUID)) {
     		if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
     			return -EAGAIN;
     		new_suid = uid;
    @@ -626,7 +647,6 @@
     	current->fsuid = current->euid = uid;
     	current->suid = new_suid;
     
    -	/* XXX need to fold this in to LSM hook -cmw */
     	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
     		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
     	}
    @@ -644,8 +664,13 @@
     	int old_ruid = current->uid;
     	int old_euid = current->euid;
     	int old_suid = current->suid;
    +	int retval;
    +
    +	retval = security_ops->task_ops->setuid(ruid, euid, suid, LSM_SETID_RES);
    +	if (retval)
    +		return retval;
     
    -	if (security_ops->task_ops->setuid()) {
    +	if (!capable(CAP_SETUID)) {
     		if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
     		    (ruid != current->euid) && (ruid != current->suid))
     			return -EPERM;
    @@ -672,7 +697,6 @@
     	if (suid != (uid_t) -1)
     		current->suid = suid;
     
    -	/* XXX need to fold this in to LSM hook -cmw */
     	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
     		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
     	}
    @@ -696,7 +720,13 @@
      */
     asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
     {
    -	if (security_ops->task_ops->setgid()) {
    +	int retval;
    +
    +	retval = security_ops->task_ops->setgid(rgid, egid, sgid, LSM_SETID_RES);
    +	if (retval)
    +		return retval;
    +
    +	if (!capable(CAP_SETGID)) {
     		if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
     		    (rgid != current->egid) && (rgid != current->sgid))
     			return -EPERM;
    @@ -744,11 +774,16 @@
     asmlinkage long sys_setfsuid(uid_t uid)
     {
     	int old_fsuid;
    +	int retval;
    +
    +	retval = security_ops->task_ops->setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
    +	if (retval)
    +		return retval;
     
     	old_fsuid = current->fsuid;
     	if (uid == current->uid || uid == current->euid ||
     	    uid == current->suid || uid == current->fsuid || 
    -	    !security_ops->task_ops->setuid())
    +	    capable(CAP_SETUID))
     	{
     		if (uid != old_fsuid)
     		{
    @@ -767,7 +802,6 @@
     	 *          if not, we might be a bit too harsh here.
     	 */
     	
    -	/* XXX need to fold this in to LSM hook -cmw */
     	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
     		if (old_fsuid == 0 && current->fsuid != 0) {
     			cap_t(current->cap_effective) &= ~CAP_FS_MASK;
    @@ -787,11 +821,16 @@
     asmlinkage long sys_setfsgid(gid_t gid)
     {
     	int old_fsgid;
    +	int retval;
    +
    +	retval = security_ops->task_ops->setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS);
    +	if (retval)
    +		return retval;
     
     	old_fsgid = current->fsgid;
     	if (gid == current->gid || gid == current->egid ||
     	    gid == current->sgid || gid == current->fsgid || 
    -	    !security_ops->task_ops->setgid())
    +	    capable(CAP_SETGID))
     	{
     		if (gid != old_fsgid)
     		{
    @@ -979,12 +1018,19 @@
      
     asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist)
     {
    -	if (security_ops->task_ops->setgroups())
    +	gid_t groups[NGROUPS];
    +	int retval;
    +
    +	if (!capable(CAP_SETGID))
     		return -EPERM;
     	if ((unsigned) gidsetsize > NGROUPS)
     		return -EINVAL;
    -	if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
    +	if(copy_from_user(groups, grouplist, gidsetsize * sizeof(gid_t)))
     		return -EFAULT;
    +	retval = security_ops->task_ops->setgroups(gidsetsize, groups);
    +	if (retval)
    +		return retval;
    +	memcpy(current->groups, groups, gidsetsize * sizeof(gid_t));
     	current->ngroups = gidsetsize;
     	return 0;
     }
    @@ -1039,21 +1085,25 @@
     
     asmlinkage long sys_sethostname(char *name, int len)
     {
    +	char nodename[__NEW_UTS_LEN+1];
     	int errno;
     
    -	if (security_ops->sethostname())
    +	if (!capable(CAP_SYS_ADMIN))
     		return -EPERM;
     	if (len < 0 || len > __NEW_UTS_LEN)
     		return -EINVAL;
    +	if (copy_from_user(nodename, name, len)) 
    +		return -EFAULT;
    +	nodename[len] = 0;
    +
    +	errno = security_ops->sethostname(nodename);
    +	if (errno)
    +		return errno;
     
     	down_write(&uts_sem);
    -	errno = -EFAULT;
    -	if (!copy_from_user(system_utsname.nodename, name, len)) {
    -		system_utsname.nodename[len] = 0;
    -		errno = 0;
    -	}
    +	memcpy(system_utsname.nodename, nodename, len+1);
     	up_write(&uts_sem);
    -	return errno;
    +	return 0;
     }
     
     asmlinkage long sys_gethostname(char *name, int len)
    @@ -1079,19 +1129,23 @@
      */
     asmlinkage long sys_setdomainname(char *name, int len)
     {
    +	char domainname[__NEW_UTS_LEN+1];
     	int errno;
     
    -	if (security_ops->setdomainname())
    +	if (!capable(CAP_SYS_ADMIN))
     		return -EPERM;
     	if (len < 0 || len > __NEW_UTS_LEN)
     		return -EINVAL;
    +	if (copy_from_user(domainname, name, len)) 
    +		return -EFAULT;
    +	domainname[len] = 0;
    +
    +	errno = security_ops->setdomainname(domainname);
    +	if (errno)
    +		return errno;
     
     	down_write(&uts_sem);
    -	errno = -EFAULT;
    -	if (!copy_from_user(system_utsname.domainname, name, len)) {
    -		errno = 0;
    -		system_utsname.domainname[len] = 0;
    -	}
    +	memcpy(system_utsname.domainname, domainname, len+1);
     	up_write(&uts_sem);
     	return errno;
     }
    @@ -1130,6 +1184,7 @@
     asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim)
     {
     	struct rlimit new_rlim, *old_rlim;
    +	int retval;
     
     	if (resource >= RLIM_NLIMITS)
     		return -EINVAL;
    @@ -1140,12 +1195,17 @@
     	old_rlim = current->rlim + resource;
     	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
     	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
    -	    security_ops->task_ops->setrlimit(resource))
    +	    !capable(CAP_SYS_RESOURCE))
     		return -EPERM;
     	if (resource == RLIMIT_NOFILE) {
     		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
     			return -EPERM;
     	}
    +
    +	retval = security_ops->task_ops->setrlimit(resource, &new_rlim);
    +	if (retval)
    +		return retval;
    +
     	*old_rlim = new_rlim;
     	return 0;
     }
    diff -Nru lsm-wirex/kernel/sysctl.c lsm-nailabs/kernel/sysctl.c
    --- lsm-wirex/kernel/sysctl.c	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/kernel/sysctl.c	Mon Jun 11 14:19:57 2001
    @@ -942,7 +942,6 @@
     int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
     			void *buffer, size_t *lenp)
     {
    -	/* XXX this is really capabilities specific -cmw */
     	if (!capable(CAP_SYS_MODULE)) {
     		return -EPERM;
     	}
    diff -Nru lsm-wirex/mm/mmap.c lsm-nailabs/mm/mmap.c
    --- lsm-wirex/mm/mmap.c	Thu May 24 18:20:18 2001
    +++ lsm-nailabs/mm/mmap.c	Mon Jun 11 16:29:09 2001
    @@ -13,6 +13,7 @@
     #include <linux/init.h>
     #include <linux/file.h>
     #include <linux/fs.h>
    +#include <linux/security.h>
     
     #include <asm/uaccess.h>
     #include <asm/pgalloc.h>
    @@ -251,6 +252,10 @@
     			return -EAGAIN;
     	}
     
    +	error = security_ops->file_ops->mmap(file, flags, prot);
    +	if (error)
    +		return error;
    +		
     	if (file) {
     		switch (flags & MAP_TYPE) {
     		case MAP_SHARED:
    diff -Nru lsm-wirex/mm/mprotect.c lsm-nailabs/mm/mprotect.c
    --- lsm-wirex/mm/mprotect.c	Mon Mar 19 15:35:08 2001
    +++ lsm-nailabs/mm/mprotect.c	Mon Jun 11 16:29:09 2001
    @@ -7,6 +7,7 @@
     #include <linux/smp_lock.h>
     #include <linux/shm.h>
     #include <linux/mman.h>
    +#include <linux/security.h>
     
     #include <asm/uaccess.h>
     #include <asm/pgalloc.h>
    @@ -260,6 +261,10 @@
     			error = -EACCES;
     			break;
     		}
    +
    +		error = security_ops->file_ops->mprotect(vma, prot);
    +		if (error)
    +			break;
     
     		if (vma->vm_end >= end) {
     			error = mprotect_fixup(vma, nstart, end, newflags);
    diff -Nru lsm-wirex/security/Config.in lsm-nailabs/security/Config.in
    --- lsm-wirex/security/Config.in	Mon Jun 18 16:32:40 2001
    +++ lsm-nailabs/security/Config.in	Mon Jun 11 16:29:09 2001
    @@ -3,6 +3,5 @@
     #
     mainmenu_option next_comment
     comment 'Security options'
    -tristate '  Capabilities Support' CONFIG_CAPABILITIES
     
     endmenu
    
    _______________________________________________
    linux-security-module mailing list
    linux-security-moduleat_private
    http://mail.wirex.com/mailman/listinfo/linux-security-module
    



    This archive was generated by hypermail 2b30 : Tue Jun 19 2001 - 12:34:12 PDT