Re: [PATCH] selinux: do not check open permission on sockets

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

 



On Thu, 2017-05-18 at 12:45 -0400, Stephen Smalley wrote:
> On Thu, 2017-05-18 at 12:04 -0400, Paul Moore wrote:
> > On Fri, May 12, 2017 at 12:41 PM, Stephen Smalley <sds@xxxxxxxxxxxx
> > v>
> > wrote:
> > > open permission is currently only defined for files in the kernel
> > > (COMMON_FILE_PERMS rather than COMMON_FILE_SOCK_PERMS).
> > > Construction of
> > > an artificial test case that tries to open a socket via
> > > /proc/pid/fd will
> > > generate a recvfrom avc denial because recvfrom and open happen
> > > to
> > > map to
> > > the same permission bit in socket vs file classes.
> > > 
> > > open of a socket via /proc/pid/fd is not supported by the kernel
> > > regardless
> > > and will ultimately return ENXIO. But we hit the permission check
> > > first and
> > > can thus produce these odd/misleading denials.  Omit the open
> > > check
> > > when
> > > operating on a socket.
> > > 
> > > Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx>
> > > ---
> > >  security/selinux/hooks.c | 10 +++++++---
> > >  1 file changed, 7 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > > index e67a526..dd356ed 100644
> > > --- a/security/selinux/hooks.c
> > > +++ b/security/selinux/hooks.c
> > > @@ -2063,8 +2063,9 @@ static inline u32 file_to_av(struct file
> > > *file)
> > >  static inline u32 open_file_to_av(struct file *file)
> > >  {
> > >         u32 av = file_to_av(file);
> > > +       struct inode *inode = file_inode(file);
> > > 
> > > -       if (selinux_policycap_openperm)
> > > +       if (selinux_policycap_openperm && inode->i_sb->s_magic !=
> > > SOCKFS_MAGIC)
> > >                 av |= FILE__OPEN;
> > 
> > No real objection to this patch, I'm just wondering if we are
> > better
> > served by only adding the open permission on a specific whitelist
> > of
> > object classes?  From a practical point of view it probably has
> > little
> > impact either way and one check to rule out sockets is arguably
> > faster
> > than checking a handful of object classes, but I wonder how likely
> > it
> > would be that we would ever see someone trying to open other non-
> > file
> > objects and hitting this code?
> 
> We only ever assign either file or socket classes to inode security
> blobs.  There are 7 distinct file classes, so we'd have to compare
> against 7 values (unless we use a range check, which would be two
> comparisons, and if we want 100% accuracy, would require tweaking the
> classmap to ensure they are all contiguous since "fd" is presently
> intermingled).  Also, we initialize isec->sclass to SECCLASS_FILE in
> inode_alloc_security() for all inodes (for some inodes, we never get
> another chance to initialize it);

Sorry, the parenthetical statement above isn't accurate; we always have
to initialize it somewhere else or we'd be left with the unlabeled SID.
 We have seen that in the past with buggy filesystems; it was
convenient to at least have the class initialized to file so that the
permissions would be displayed correctly on denials.  I suppose we
could adjust inode_alloc_security() to initialize the class to
SECCLASS_SOCKET if inode->i_sb->s_magic == SOCKFS_MAGIC so that sockets
would at least start in the generic socket class and later be refined
to a more specific class in selinux_socket_post_create().  That would
be a separate change and would require some testing to ensure it
doesn't cause side effects.  Regardless, I think the case for testing
SOCKFS_MAGIC for open is still valid.

>  sockets are later switched to their
> appropriate class in selinux_socket_post_create().  Testing for
> SOCKFS_MAGIC seems simpler, more efficient, and less prone to error. 
> Up to you, but I'm not sure we gain anything by switching to a class-
> based test.
> 
> > Also, as an aside, it seems rather odd that we don't have a macro
> > somewhere to check if an inode is a socket.  Oh well.
> 
> Smack uses this test as well in various place to see if an inode
> represents a socket.  I suspect the vfs folks would view it as a
> layering violation, but we do need to tell at times...
> 
> > 
> > >         return av;
> > > @@ -3059,6 +3060,7 @@ static int selinux_inode_permission(struct
> > > inode *inode, int mask)
> > >  static int selinux_inode_setattr(struct dentry *dentry, struct
> > > iattr *iattr)
> > >  {
> > >         const struct cred *cred = current_cred();
> > > +       struct inode *inode = d_backing_inode(dentry);
> > >         unsigned int ia_valid = iattr->ia_valid;
> > >         __u32 av = FILE__WRITE;
> > > 
> > > @@ -3074,8 +3076,10 @@ static int selinux_inode_setattr(struct
> > > dentry *dentry, struct iattr *iattr)
> > >                         ATTR_ATIME_SET | ATTR_MTIME_SET |
> > > ATTR_TIMES_SET))
> > >                 return dentry_has_perm(cred, dentry,
> > > FILE__SETATTR);
> > > 
> > > -       if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)
> > > -                       && !(ia_valid & ATTR_FILE))
> > > +       if (selinux_policycap_openperm &&
> > > +           inode->i_sb->s_magic != SOCKFS_MAGIC &&
> > > +           (ia_valid & ATTR_SIZE) &&
> > > +           !(ia_valid & ATTR_FILE))
> > >                 av |= FILE__OPEN;
> > > 
> > >         return dentry_has_perm(cred, dentry, av);
> > > --
> > > 2.9.3
> > > 
> > 
> > 



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

  Powered by Linux