summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2017-05-12 12:41:24 -0400
committerPaul Moore <paul@paul-moore.com>2017-05-23 10:23:42 -0400
commitccb544781d34afdb73a9a73ae53035d824d193bf (patch)
treea5c7f6475061a3b42f887d43870224af13373eba /security
parent3ba4bf5f1e2c58bddd84ba27c5aeaf8ca1d36bff (diff)
downloadlinux-ccb544781d34afdb73a9a73ae53035d824d193bf.tar.gz
linux-ccb544781d34afdb73a9a73ae53035d824d193bf.tar.bz2
linux-ccb544781d34afdb73a9a73ae53035d824d193bf.zip
selinux: do not check open permission on sockets
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>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e29800091e17..627f291fb6c1 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;
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);