Re: How to handle security_dentry_open when the open flags are 'special'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Which I think then blows up if we pass this file to another process or
if we exec something.  Uggh....

-Eric


On 3/12/08, Eric Paris <eparis@xxxxxxxxxx> wrote:
> See LKML posting http://marc.info/?l=linux-kernel&m=120534660832189&w=2
>
>  according to viro a call to sys_open like: open("/dev/null", 3) is
>  supposed to mean: check read and write but not set FMODE_READ or
>  FMODE_WRITE.  This is exactly the security check we get through the
>  security_inode_permission hook but not what happens through the
>  security_dentry_open hook.  This patch actually passes the bare flags
>  into security_dentry_open so that we can do the correct permission
>  checking there.
>
>  What do people think?
>
>  Untested, uncompiled, just thoughts and fleshing it out....
>
>  -Eric
>
>   fs/open.c                |    2 +-
>   include/linux/security.h |    6 +++---
>   security/security.c      |    4 ++--
>   security/selinux/hooks.c |   20 ++++++++++++++++++--
>   4 files changed, 24 insertions(+), 8 deletions(-)
>
>  diff --git a/fs/open.c b/fs/open.c
>  index 5419853..2560a3e 100644
>  --- a/fs/open.c
>  +++ b/fs/open.c
>  @@ -754,7 +754,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
>         f->f_op = fops_get(inode->i_fop);
>         file_move(f, &inode->i_sb->s_files);
>
>  -       error = security_dentry_open(f);
>  +       error = security_dentry_open(f, flags);
>         if (error)
>                 goto cleanup_all;
>
>  diff --git a/include/linux/security.h b/include/linux/security.h
>  index b07357c..704a5f7 100644
>  --- a/include/linux/security.h
>  +++ b/include/linux/security.h
>  @@ -1338,7 +1338,7 @@ struct security_operations {
>         int (*file_send_sigiotask) (struct task_struct * tsk,
>                                     struct fown_struct * fown, int sig);
>         int (*file_receive) (struct file * file);
>  -       int (*dentry_open)  (struct file *file);
>  +       int (*dentry_open)  (struct file *file, int flags);
>
>         int (*task_create) (unsigned long clone_flags);
>         int (*task_alloc_security) (struct task_struct * p);
>  @@ -1594,7 +1594,7 @@ int security_file_set_fowner(struct file *file);
>   int security_file_send_sigiotask(struct task_struct *tsk,
>                                   struct fown_struct *fown, int sig);
>   int security_file_receive(struct file *file);
>  -int security_dentry_open(struct file *file);
>  +int security_dentry_open(struct file *file, int flags);
>   int security_task_create(unsigned long clone_flags);
>   int security_task_alloc(struct task_struct *p);
>   void security_task_free(struct task_struct *p);
>  @@ -2086,7 +2086,7 @@ static inline int security_file_receive (struct file *file)
>         return 0;
>   }
>
>  -static inline int security_dentry_open (struct file *file)
>  +static inline int security_dentry_open (struct file *file, int flags)
>   {
>         return 0;
>   }
>  diff --git a/security/security.c b/security/security.c
>  index b1387a6..28a4f2a 100644
>  --- a/security/security.c
>  +++ b/security/security.c
>  @@ -582,9 +582,9 @@ int security_file_receive(struct file *file)
>         return security_ops->file_receive(file);
>   }
>
>  -int security_dentry_open(struct file *file)
>  +int security_dentry_open(struct file *file, int flags)
>   {
>  -       return security_ops->dentry_open(file);
>  +       return security_ops->dentry_open(file, flags);
>   }
>
>   int security_task_create(unsigned long clone_flags)
>  diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
>  index 4bf4807..1966590 100644
>  --- a/security/selinux/hooks.c
>  +++ b/security/selinux/hooks.c
>  @@ -3017,11 +3017,14 @@ static int selinux_file_receive(struct file *file)
>         return file_has_perm(current, file, file_to_av(file));
>   }
>
>  -static int selinux_dentry_open(struct file *file)
>  +static int selinux_dentry_open(struct file *file, int flags)
>   {
>         struct file_security_struct *fsec;
>         struct inode *inode;
>         struct inode_security_struct *isec;
>  +       u32 av = 0;
>  +       mode_t f_mode;
>  +
>         inode = file->f_path.dentry->d_inode;
>         fsec = file->f_security;
>         isec = inode->i_security;
>  @@ -3034,6 +3037,19 @@ static int selinux_dentry_open(struct file *file)
>          */
>         fsec->isid = isec->sid;
>         fsec->pseqno = avc_policy_seqno();
>  +
>  +       f_mode = flags & O_ACCMODE;
>  +       if ((f_mode+1) & O_ACCMODE)
>  +               f_mode++;
>  +
>  +       if (f_mode & FMODE_READ)
>  +               av |= FILE__READ;
>  +       if (f_mode & FMODE_WRITE) {
>  +               if (file->f_flags & O_APPEND)
>  +                       av |= FILE__APPEND;
>  +               else
>  +                       av |= FILE__WRITE;
>  +       }
>         /*
>          * Since the inode label or policy seqno may have changed
>          * between the selinux_inode_permission check and the saving
>  @@ -3042,7 +3058,7 @@ static int selinux_dentry_open(struct file *file)
>          * new inode label or new policy.
>          * This check is not redundant - do not remove.
>          */
>  -       return inode_has_perm(current, inode, file_to_av(file), NULL);
>  +       return inode_has_perm(current, inode, av, NULL);
>   }
>
>   /* task security operations */
>
>
>
>  --
>  To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
>  the body of a message to majordomo@xxxxxxxxxxxxxxx
>  More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux