From f5f03ad347faca7b0cd6ca956835261fc1076c94 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 22 Feb 2019 20:40:05 +0000 Subject: [PATCH] Build break Revert "FROMLIST: BACKPORT: overlayfs: override_creds=off option bypass creator_cred" This reverts commit 3bc419d8deb2e3d76af538c2f0994676cb59e741. Reason for revert: Change-Id: I44312d18aeb84ace19f7d27ec3bcb219183d95fa --- Documentation/filesystems/overlayfs.txt | 23 ---------------- fs/overlayfs/copy_up.c | 2 +- fs/overlayfs/dir.c | 11 ++++---- fs/overlayfs/inode.c | 18 ++++++------- fs/overlayfs/overlayfs.h | 1 - fs/overlayfs/readdir.c | 2 +- fs/overlayfs/super.c | 35 +++---------------------- 7 files changed, 19 insertions(+), 73 deletions(-) diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt index 3ef85226bcce..bcbf9710e4af 100644 --- a/Documentation/filesystems/overlayfs.txt +++ b/Documentation/filesystems/overlayfs.txt @@ -82,29 +82,6 @@ Only the lists of names from directories are merged. Other content such as metadata and extended attributes are reported for the upper directory only. These attributes of the lower directory are hidden. -credentials ------------ - -By default, all access to the upper, lower and work directories is the -recorded mounter's MAC and DAC credentials. The incoming accesses are -checked against the caller's credentials. - -In the case where caller MAC or DAC credentials do not overlap, a -use case available in older versions of the driver, the -override_creds mount flag can be turned off and help when the use -pattern has caller with legitimate credentials where the mounter -does not. Several unintended side effects will occur though. The -caller without certain key capabilities or lower privilege will not -always be able to delete files or directories, create nodes, or -search some restricted directories. The ability to search and read -a directory entry is spotty as a result of the cache mechanism not -retesting the credentials because of the assumption, a privileged -caller can fill cache, then a lower privilege can read the directory -cache. The uneven security model where cache, upperdir and workdir -are opened at privilege, but accessed without creating a form of -privilege escalation, should only be used with strict understanding -of the side effects and of the security policies. - whiteouts and opaque directories -------------------------------- diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 0b71cb514031..36795eed40b0 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -421,7 +421,7 @@ int ovl_copy_up(struct dentry *dentry) dput(parent); dput(next); } - ovl_revert_creds(old_cred); + revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 57764da62332..8546384a5fdf 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -148,7 +148,7 @@ static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry, type = ovl_path_real(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getattr(&realpath, stat); - ovl_revert_creds(old_cred); + revert_creds(old_cred); if (err) return err; @@ -497,8 +497,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, override_cred->fsgid = inode->i_gid; if (!hardlink) { err = security_dentry_create_files_as(dentry, - stat->mode, &dentry->d_name, - old_cred ? old_cred : current_cred(), + stat->mode, &dentry->d_name, old_cred, override_cred); if (err) { put_cred(override_cred); @@ -516,7 +515,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, link, hardlink); } out_revert_creds: - ovl_revert_creds(old_cred); + revert_creds(old_cred); if (!err) { struct inode *realinode = d_inode(ovl_dentry_upper(dentry)); @@ -758,7 +757,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) err = ovl_remove_upper(dentry, is_dir); else err = ovl_remove_and_whiteout(dentry, is_dir); - ovl_revert_creds(old_cred); + revert_creds(old_cred); if (!err) { if (is_dir) clear_nlink(dentry->d_inode); @@ -999,7 +998,7 @@ out_dput_old: out_unlock: unlock_rename(new_upperdir, old_upperdir); out_revert_creds: - ovl_revert_creds(old_cred); + revert_creds(old_cred); out_drop_write: ovl_drop_write(old); out: diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 12c8e5e64db5..16f6db88c8e5 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -34,7 +34,7 @@ static int ovl_copy_up_truncate(struct dentry *dentry) stat.size = 0; err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat); } - ovl_revert_creds(old_cred); + revert_creds(old_cred); out_dput_parent: dput(parent); @@ -91,7 +91,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) inode_lock(upperdentry->d_inode); old_cred = ovl_override_creds(dentry->d_sb); err = notify_change(upperdentry, attr, NULL); - ovl_revert_creds(old_cred); + revert_creds(old_cred); if (!err) ovl_copyattr(upperdentry->d_inode, dentry->d_inode); inode_unlock(upperdentry->d_inode); @@ -115,7 +115,7 @@ static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry, ovl_path_real(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getattr(&realpath, stat); - ovl_revert_creds(old_cred); + revert_creds(old_cred); return err; } @@ -147,7 +147,7 @@ int ovl_permission(struct inode *inode, int mask) mask |= MAY_READ; } err = inode_permission(realinode, mask); - ovl_revert_creds(old_cred); + revert_creds(old_cred); return err; } @@ -164,7 +164,7 @@ static const char *ovl_get_link(struct dentry *dentry, old_cred = ovl_override_creds(dentry->d_sb); p = vfs_get_link(ovl_dentry_real(dentry), done); - ovl_revert_creds(old_cred); + revert_creds(old_cred); return p; } @@ -206,7 +206,7 @@ int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, WARN_ON(flags != XATTR_REPLACE); err = vfs_removexattr(realpath.dentry, name); } - ovl_revert_creds(old_cred); + revert_creds(old_cred); out_drop_write: ovl_drop_write(dentry); @@ -223,7 +223,7 @@ int ovl_xattr_get(struct dentry *dentry, const char *name, old_cred = ovl_override_creds(dentry->d_sb); res = vfs_getxattr(realdentry, name, value, size); - ovl_revert_creds(old_cred); + revert_creds(old_cred); return res; } @@ -247,7 +247,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) old_cred = ovl_override_creds(dentry->d_sb); res = vfs_listxattr(realdentry, list, size); - ovl_revert_creds(old_cred); + revert_creds(old_cred); if (res <= 0 || size == 0) return res; @@ -282,7 +282,7 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type) old_cred = ovl_override_creds(inode->i_sb); acl = get_acl(realinode, type); - ovl_revert_creds(old_cred); + revert_creds(old_cred); return acl; } diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 83f22daeeeb3..e218e741cb99 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -164,7 +164,6 @@ bool ovl_dentry_is_opaque(struct dentry *dentry); void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque); bool ovl_is_whiteout(struct dentry *dentry); const struct cred *ovl_override_creds(struct super_block *sb); -void ovl_revert_creds(const struct cred *oldcred); void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry); void ovl_inode_update(struct inode *inode, struct inode *upperinode); struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 4fcbfd0953c0..a1be6baabca3 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -223,7 +223,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd) } inode_unlock(dir->d_inode); } - ovl_revert_creds(old_cred); + revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index b31139710a23..e7c8ac41e288 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -31,7 +31,6 @@ struct ovl_config { char *upperdir; char *workdir; bool default_permissions; - bool override_creds; }; /* private information held for overlayfs's superblock */ @@ -267,17 +266,9 @@ const struct cred *ovl_override_creds(struct super_block *sb) { struct ovl_fs *ofs = sb->s_fs_info; - if (!ofs->config.override_creds) - return NULL; return override_creds(ofs->creator_cred); } -void ovl_revert_creds(const struct cred *old_cred) -{ - if (old_cred) - revert_creds(old_cred); -} - static bool ovl_is_opaquedir(struct dentry *dentry) { int res; @@ -593,7 +584,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_copyattr(realdentry->d_inode, inode); } - ovl_revert_creds(old_cred); + revert_creds(old_cred); oe->opaque = upperopaque; oe->__upperdentry = upperdentry; memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); @@ -612,7 +603,7 @@ out_put: out_put_upper: dput(upperdentry); out: - ovl_revert_creds(old_cred); + revert_creds(old_cred); return ERR_PTR(err); } @@ -665,11 +656,6 @@ static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) return err; } -static bool __read_mostly ovl_override_creds_def = true; -module_param_named(override_creds, ovl_override_creds_def, bool, 0644); -MODULE_PARM_DESC(ovl_override_creds_def, - "Use mounter's credentials for accesses"); - /** * ovl_show_options * @@ -688,9 +674,6 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry) } if (ufs->config.default_permissions) seq_puts(m, ",default_permissions"); - if (ofs->config.override_creds != ovl_override_creds_def) - seq_show_option(m, "override_creds", - ofs->config.override_creds ? "on" : "off"); return 0; } @@ -717,8 +700,6 @@ enum { OPT_UPPERDIR, OPT_WORKDIR, OPT_DEFAULT_PERMISSIONS, - OPT_OVERRIDE_CREDS_ON, - OPT_OVERRIDE_CREDS_OFF, OPT_ERR, }; @@ -727,8 +708,6 @@ static const match_table_t ovl_tokens = { {OPT_UPPERDIR, "upperdir=%s"}, {OPT_WORKDIR, "workdir=%s"}, {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, - {OPT_OVERRIDE_CREDS_ON, "override_creds=on"}, - {OPT_OVERRIDE_CREDS_OFF, "override_creds=off"}, {OPT_ERR, NULL} }; @@ -759,7 +738,6 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) { char *p; - config->override_creds = ovl_override_creds_def; while ((p = ovl_next_opt(&opt)) != NULL) { int token; substring_t args[MAX_OPT_ARGS]; @@ -794,14 +772,6 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) config->default_permissions = true; break; - case OPT_OVERRIDE_CREDS_ON: - config->override_creds = true; - break; - - case OPT_OVERRIDE_CREDS_OFF: - config->override_creds = false; - break; - default: pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); return -EINVAL; @@ -1383,6 +1353,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ovl_copyattr(realinode, d_inode(root_dentry)); sb->s_root = root_dentry; + return 0; out_free_oe: