| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: Stephen Smalley <sds@tycho.nsa.gov> |
| Date: Fri, 12 May 2017 12:41:24 -0400 |
| Subject: selinux: do not check open permission on sockets |
| |
| From: Stephen Smalley <sds@tycho.nsa.gov> |
| |
| |
| [ 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> |
| --- |
| security/selinux/hooks.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| --- a/security/selinux/hooks.c |
| +++ b/security/selinux/hooks.c |
| @@ -2033,8 +2033,9 @@ static inline u32 file_to_av(struct 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(stru |
| 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 |
| 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); |