diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2017-05-12 12:41:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-04-13 19:48:04 +0200 |
commit | b983b2a5969c9ee4e2ec73ff3444ec6814441cb8 (patch) | |
tree | 7b06005a316980f3d7f299f3e2deeb3d1d1d0e82 | |
parent | 2c582b6bac13e495d6c14fdd1f866b93ff90cddc (diff) | |
download | linux-rt-b983b2a5969c9ee4e2ec73ff3444ec6814441cb8.tar.gz |
selinux: do not check open permission on sockets
[ Upstream commit ccb544781d34afdb73a9a73ae53035d824d193bf ]
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@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | security/selinux/hooks.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 17627d8d5a26..8ded80867b92 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2033,8 +2033,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; return av; @@ -3031,6 +3032,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; @@ -3046,8 +3048,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); |