From 06ccab87d8c415e51bcf69e34bb27712bad8398f Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 22 Dec 2015 07:43:52 +0000 Subject: [PATCH] Don't verify write permissions on lower inodes on overlayfs If a user opens a file r/w on overlayfs, and if the underlying inode is currently still on the lower fs, right now we're verifying whether selinux policy permits writes to the selinux context on the underlying inode. This is suboptimal, since we don't want confined processes to be able to write to these files if they're able to escape from a container and so don't want to permit this in policy. Have overlayfs pass down an additional flag when verifying the permission on lower inodes, and mask off the write bits in the selinux permissions check if that flag is set. --- fs/overlayfs/inode.c | 3 +++ include/linux/fs.h | 1 + security/selinux/hooks.c | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 4060ffde87225c..b6f02f2bdf6b15 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -125,6 +125,9 @@ int ovl_permission(struct inode *inode, int mask) goto out_dput; } + if (!is_upper) + mask |= MAY_OPEN_LOWER; + err = __inode_permission(realinode, mask); out_dput: dput(alias); diff --git a/include/linux/fs.h b/include/linux/fs.h index 3aa51425416148..57120135dada3b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,7 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_OPEN_LOWER 0x00000100 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e33019ebc2bedb..48746ee42f1406 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2904,6 +2904,15 @@ static int selinux_inode_permission(struct inode *inode, int mask) u32 audited, denied; from_access = mask & MAY_ACCESS; + + /* + * If we're trying to open the lower layer of an overlay mount, don't + * worry about write or append permissions - these will be verified + * against the upper context + */ + if (mask & MAY_OPEN_LOWER) + mask &= ~(MAY_WRITE|MAY_APPEND); + mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); /* No permission to check. Existence test. */