]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
UBUNTU: SAUCE: overlayfs: Propogate nosuid from lower and upper mounts
authorSeth Forshee <seth.forshee@canonical.com>
Thu, 21 Jan 2016 21:37:53 +0000 (15:37 -0600)
committerSeth Forshee <seth.forshee@canonical.com>
Tue, 5 Sep 2017 12:33:19 +0000 (07:33 -0500)
An overlayfs mount using an upper or lower directory from a
nosuid filesystem bypasses this restriction. Change this so
that if any lower or upper directory is nosuid at mount time the
overlayfs superblock is marked nosuid. This requires some
additions at the vfs level since nosuid currently only applies to
mounts, so a SB_I_NOSUID flag is added along with a helper
function to check a path for nosuid in both the mount and the
superblock.

BugLink: http://bugs.launchpad.net/bugs/1534961
BugLink: http://bugs.launchpad.net/bugs/1535150
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
fs/exec.c
fs/overlayfs/super.c
include/linux/fs.h
security/commoncap.c
security/selinux/hooks.c

index 9342e61c5fbb629b06380ff7cc33212b9edf63dc..f52e74b3c429f18d1771e50fd65efe5d0d7bf7b4 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -112,6 +112,13 @@ bool path_noexec(const struct path *path)
               (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 }
 
+bool path_nosuid(const struct path *path)
+{
+       return !mnt_may_suid(path->mnt) ||
+              (path->mnt->mnt_sb->s_iflags & SB_I_NOSUID);
+}
+EXPORT_SYMBOL(path_nosuid);
+
 #ifdef CONFIG_USELIB
 /*
  * Note that a shared library must be both readable and executable due to
@@ -1500,7 +1507,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm)
        bprm->cred->euid = current_euid();
        bprm->cred->egid = current_egid();
 
-       if (!mnt_may_suid(bprm->file->f_path.mnt))
+       if (path_nosuid(&bprm->file->f_path))
                return;
 
        if (task_no_new_privs(current))
index d86e89f972016b4046b20a7a45c2f3f436c50f02..93437856dbd95e139a182b324bf43b18ad4c8029 100644 (file)
@@ -960,6 +960,9 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
                sb->s_time_gran = ufs->upper_mnt->mnt_sb->s_time_gran;
 
+               if (ufs->upper_mnt->mnt_flags & MNT_NOSUID)
+                       sb->s_iflags |= SB_I_NOSUID;
+
                ufs->workdir = ovl_workdir_create(sb, ufs, workpath.dentry,
                                                  OVL_WORKDIR_NAME, false);
                /*
@@ -1031,6 +1034,9 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                 */
                mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
 
+               if (mnt->mnt_flags & MNT_NOSUID)
+                       sb->s_iflags |= SB_I_NOSUID;
+
                ufs->lower_mnt[ufs->numlower] = mnt;
                ufs->numlower++;
 
index cbfe127bccf8b112a2d65289a4ec7fef4809da22..f51f25aaae80acc7ab9b5b231f4d049897c99ed3 100644 (file)
@@ -1284,6 +1284,7 @@ struct mm_struct;
 #define SB_I_CGROUPWB  0x00000001      /* cgroup-aware writeback enabled */
 #define SB_I_NOEXEC    0x00000002      /* Ignore executables on this fs */
 #define SB_I_NODEV     0x00000004      /* Ignore devices on this fs */
+#define SB_I_NOSUID    0x00000008      /* Ignore suid on this fs */
 
 /* sb->s_iflags to limit user namespace mounts */
 #define SB_I_USERNS_VISIBLE            0x00000010 /* fstype already mounted */
@@ -3328,6 +3329,7 @@ static inline bool dir_relax_shared(struct inode *inode)
 }
 
 extern bool path_noexec(const struct path *path);
+extern bool path_nosuid(const struct path *path);
 extern void inode_nohighmem(struct inode *inode);
 
 #endif /* _LINUX_FS_H */
index 7abebd782d5e02d0c024ca0b2b1b189b1f4f83d1..22e14bcf75e24609155187085bf6451b2e42eaf8 100644 (file)
@@ -448,7 +448,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
        if (!file_caps_enabled)
                return 0;
 
-       if (!mnt_may_suid(bprm->file->f_path.mnt))
+       if (path_nosuid(&bprm->file->f_path))
                return 0;
 
        /*
index 33fd061305c40376c7f632ebcdf6fe5fd7b1e3fc..51d56d65d51dc79c119492fcbc70f5277a1381ac 100644 (file)
@@ -2315,7 +2315,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
                            const struct task_security_struct *new_tsec)
 {
        int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
-       int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
+       int nosuid = path_nosuid(&bprm->file->f_path);
        int rc;
 
        if (!nnp && !nosuid)