Re: Some New Hooks

From: Chris Vance (cvanceat_private)
Date: Wed Jun 13 2001 - 09:59:04 PDT

  • Next message: Casey Schaufler: "Re: New LSM patch for consideration"

    I took another look at this and reorganized things a bit. I re-worked the
    f_owner/send_sigio hooks: 
            - Moved file_ops->alloc_security up to get_empty_filp()
            - Added file_ops->free_security to put_filp()
            - Removed fown_ops entirely (functionality moved to file_ops)
            - Created a file_ops->set_fowner call
            - Added calls to set_fowner in tty_io.c, dnotify.c, locks.c,
    	  fcntl.c
    
    Attached is a diff that should be relative to the previous one (I couldn't
    access the bk repository).  An exception is that a hook for ioctl was also
    added.
    
    chris.
    
    On Tue, 12 Jun 2001, Chris Wright wrote:
    
    > * Chris Vance (cvanceat_private) wrote:
    > > 
    > > I have added hooks in the following locations:
    > 
    > thanks again for the patch.  i finally had the time last night to review
    > the hooks.  some comments below...
    > 
    > > fcntl/fcntl64 (sys_fcntl/sys_fcntl64): Added hooks to authorize these
    > > 	operations.  Additionally, a security field was added to the
    > > 	fown_struct so that the attributes of the owning process could
    > > 	be maintained for later use in send_sigio_to_task.
    > >
    > > fcntl (send_sigio_to_task): Added hook to verify signal permissions.
    > 
    > i'm not real familiar with this code path, so please correct my
    > misunderstandings.
    > 
    > the fown_ops->alloc_security in F_SETOWN is a perfect example of needing
    > to separate allocation from setting the security blob.   i think this
    > should really be set (not alloc), as the space should have already been
    > allocated, (perhaps in get_empty_filp).  and i don't see any free (granted
    > this may be a simple 32 bit security id superimposed on the void *, but
    > we should get the chance to free in case it is actual allocated space).
    > should the blob be set when a lease is established, or directory notification
    > turned on?  since both of these actions maninpulate the f_owner.pid, and
    > these can generate io signals to be sent.  i want to make sure that the
    > send_sigiotask() check will always have a properly filled in f_owner.security
    > blob.
    > 
    > -chris
    > 
    > _______________________________________________
    > linux-security-module mailing list
    > linux-security-moduleat_private
    > http://mail.wirex.com/mailman/listinfo/linux-security-module
    > 
    
    
    Index: drivers/char/tty_io.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/drivers/char/tty_io.c,v
    retrieving revision 1.1
    retrieving revision 1.2
    diff -u -r1.1 -r1.2
    --- drivers/char/tty_io.c	2001/05/09 20:10:10	1.1
    +++ drivers/char/tty_io.c	2001/06/13 14:13:31	1.2
    @@ -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;
    Index: fs/dnotify.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/dnotify.c,v
    retrieving revision 1.1
    retrieving revision 1.2
    diff -u -r1.1 -r1.2
    --- fs/dnotify.c	2001/05/09 20:09:21	1.1
    +++ fs/dnotify.c	2001/06/13 14:13:31	1.2
    @@ -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;
    Index: fs/fcntl.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/fcntl.c,v
    retrieving revision 1.2
    retrieving revision 1.3
    diff -u -r1.2 -r1.3
    --- fs/fcntl.c	2001/06/04 17:19:28	1.2
    +++ fs/fcntl.c	2001/06/13 14:13:31	1.3
    @@ -273,15 +273,20 @@
     			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;
    -			err = 0;
    +
     			if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
     				err = sock_fcntl (filp, F_SETOWN, arg);
     
    -			if (!err)
    -				err = security_ops->fown_ops->alloc_security(&filp->f_owner);
     			unlock_kernel();
     			break;
     		case F_GETSIG:
    @@ -396,7 +401,7 @@
     	    (fown->uid ^ p->suid) && (fown->uid ^ p->uid))
     		return;
     
    -	if (security_ops->fown_ops->send_sigiotask(p, fown, fd, reason))
    +	if (security_ops->file_ops->send_sigiotask(p, fown, fd, reason))
     		return;
     
     	switch (fown->signum) {
    Index: fs/file_table.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/file_table.c,v
    retrieving revision 1.2
    retrieving revision 1.3
    diff -u -r1.2 -r1.3
    --- fs/file_table.c	2001/05/09 20:19:19	1.2
    +++ fs/file_table.c	2001/06/13 14:13:31	1.3
    @@ -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);
    Index: fs/ioctl.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/ioctl.c,v
    retrieving revision 1.1
    retrieving revision 1.2
    diff -u -r1.1 -r1.2
    --- fs/ioctl.c	2001/05/09 20:09:21	1.1
    +++ fs/ioctl.c	2001/06/13 13:49:09	1.2
    @@ -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:
    Index: fs/locks.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/locks.c,v
    retrieving revision 1.1
    retrieving revision 1.2
    diff -u -r1.1 -r1.2
    --- fs/locks.c	2001/05/09 20:09:21	1.1
    +++ fs/locks.c	2001/06/13 14:13:31	1.2
    @@ -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;
    Index: fs/open.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/fs/open.c,v
    retrieving revision 1.4
    retrieving revision 1.5
    diff -u -r1.4 -r1.5
    --- fs/open.c	2001/05/18 19:23:21	1.4
    +++ fs/open.c	2001/06/13 14:13:31	1.5
    @@ -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:
    Index: include/linux/security.h
    ===================================================================
    RCS file: /cvs/lsm/lsm/include/linux/security.h,v
    retrieving revision 1.10
    retrieving revision 1.12
    diff -u -r1.10 -r1.12
    --- include/linux/security.h	2001/06/12 15:35:07	1.10
    +++ include/linux/security.h	2001/06/13 14:13:31	1.12
    @@ -81,7 +81,7 @@
     	int (* llseek)			(struct file *);
     	int (* read)			(struct file *);
     	int (* write)			(struct file *);
    -	int (* ioctl)			(struct file *);	// need more than 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 *);
    @@ -89,11 +89,7 @@
     	int (* writev)			(struct file *);
     	int (* fcntl)			(struct file *, unsigned int, unsigned long);
     	int (* fcntl64)			(struct file *, unsigned int, unsigned long);
    -};
    -
    -struct fown_security_ops {
    -	int (* alloc_security)		(struct fown_struct *);
    -	void (* free_security)		(struct fown_struct *);
    +	int (* set_fowner)		(struct file *);
     	int (* send_sigiotask)		(struct task_struct *, struct fown_struct *, int, int);
     };
     
    @@ -180,7 +176,6 @@
     	struct super_block_security_ops	* sb_ops;
     	struct inode_security_ops	* inode_ops;
     	struct file_security_ops	* file_ops;
    -	struct fown_security_ops	* fown_ops;
     	struct task_security_ops	* task_ops;
     	struct socket_security_ops	* socket_ops;
     	struct module_security_ops 	* module_ops;
    Index: kernel/capability_plug.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/kernel/capability_plug.c,v
    retrieving revision 1.9
    retrieving revision 1.11
    diff -u -r1.9 -r1.11
    --- kernel/capability_plug.c	2001/06/12 15:35:07	1.9
    +++ kernel/capability_plug.c	2001/06/13 14:13:31	1.11
    @@ -372,7 +372,7 @@
     {
     	return 0;
     }
    -static int cap_file_ioctl(struct file *file)
    +static int cap_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
     {
     	return 0;
     }
    @@ -409,18 +409,12 @@
     	return 0;
     }
     
    -/* fown security operations */
    -static int cap_fown_alloc_security(struct fown_struct *fown)
    +static int cap_file_set_fowner(struct file *file)
     {
    -	return 0;
    -}
    -
    -static void cap_fown_free_security(struct fown_struct *fown)
    -{
     	return;
     }
     
    -static int cap_fown_send_sigiotask(struct task_struct *tsk, 
    +static int cap_file_send_sigiotask(struct task_struct *tsk, 
     				   struct fown_struct *fown, int fd, 
     				   int reason)
     {
    @@ -641,12 +635,8 @@
     	writev:		cap_file_writev,
     	fcntl:		cap_file_fcntl,
     	fcntl64:	cap_file_fcntl64,
    -};
    -
    -static struct fown_security_ops cap_fown_ops = {
    -	alloc_security:	cap_fown_alloc_security,
    -	free_security:	cap_fown_free_security,
    -	send_sigiotask:	cap_fown_send_sigiotask,
    +	set_fowner:	cap_file_set_fowner,
    +	send_sigiotask:	cap_file_send_sigiotask,
     };
     
     static struct task_security_ops	cap_task_ops = {
    @@ -725,7 +715,6 @@
     	sb_ops:			&cap_sb_ops,
     	inode_ops:		&cap_inode_ops,
     	file_ops:		&cap_file_ops,
    -	fown_ops:		&cap_fown_ops,
     	task_ops:		&cap_task_ops,
     	socket_ops:		&cap_socket_ops,
     	module_ops:		&cap_module_ops,
    Index: kernel/security.c
    ===================================================================
    RCS file: /cvs/lsm/lsm/kernel/security.c,v
    retrieving revision 1.9
    retrieving revision 1.12
    diff -u -r1.9 -r1.12
    --- kernel/security.c	2001/06/12 15:35:07	1.9
    +++ kernel/security.c	2001/06/13 14:13:31	1.12
    @@ -87,7 +87,7 @@
     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_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;}
    @@ -95,11 +95,9 @@
     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_fown_alloc_security	(struct fown_struct *fown)	{return 0;}
    -static void dummy_fown_free_security	(struct fown_struct *fown)	{return;}
    -static int dummy_fown_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;}
    @@ -194,12 +192,8 @@
     	writev:		dummy_file_writev,
     	fcntl:		dummy_file_fcntl,
     	fcntl64:	dummy_file_fcntl64,
    -};
    -
    -static struct fown_security_ops dummy_fown_ops = {
    -	alloc_security:	dummy_fown_alloc_security,
    -	free_security:	dummy_fown_free_security,
    -	send_sigiotask:	dummy_fown_send_sigiotask,
    +	set_fowner:	dummy_file_set_fowner,
    +	send_sigiotask:	dummy_file_send_sigiotask,
     };
     
     static struct task_security_ops	dummy_task_ops = {
    
    _______________________________________________
    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 : Wed Jun 13 2001 - 10:03:01 PDT