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