diff options
author | Amit Pundir <amit.pundir@linaro.org> | 2024-01-15 14:37:20 +0530 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2024-01-22 11:45:08 +0530 |
commit | 6c3fdaa6b505c960767dc6df2a66dd3fa0baf884 (patch) | |
tree | 420a4ca55a68577aa97a243e1a2993f0f30708c7 | |
parent | d88aa862799a7cc8555338217f0f2ecfd0a89040 (diff) |
Revert "ANDROID: overlayfs: override_creds=off option bypass creator_cred"rbX-6.8-rc1
This reverts commit fc6f370400e94a947610fa9d1c49401a52e072a8.
-rw-r--r-- | Documentation/filesystems/overlayfs.rst | 24 | ||||
-rw-r--r-- | fs/backing-file.c | 11 | ||||
-rw-r--r-- | fs/overlayfs/copy_up.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/dir.c | 17 | ||||
-rw-r--r-- | fs/overlayfs/file.c | 14 | ||||
-rw-r--r-- | fs/overlayfs/inode.c | 20 | ||||
-rw-r--r-- | fs/overlayfs/namei.c | 8 | ||||
-rw-r--r-- | fs/overlayfs/overlayfs.h | 1 | ||||
-rw-r--r-- | fs/overlayfs/ovl_entry.h | 1 | ||||
-rw-r--r-- | fs/overlayfs/params.c | 10 | ||||
-rw-r--r-- | fs/overlayfs/readdir.c | 8 | ||||
-rw-r--r-- | fs/overlayfs/util.c | 13 | ||||
-rw-r--r-- | fs/overlayfs/xattrs.c | 8 |
13 files changed, 44 insertions, 93 deletions
diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 58574e08a841..1c244866041a 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -323,30 +323,6 @@ and:: The resulting access permissions should be the same. The difference is in the time of copy (on-demand vs. up-front). -### Non overlapping credentials - -As noted above, 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 the mounter, a -use case available in older versions of the driver, the override_creds mount -flag can be turned off. For when the use pattern has caller with legitimate -credentials where the mounter does not. For example init may have been the -mounter, but the caller would have execute or read MAC permissions where -init would not. override_creds off means all access, incoming, upper, lower -or working, will be tested against the caller. - -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 re-testing 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. Multiple lower layers --------------------- diff --git a/fs/backing-file.c b/fs/backing-file.c index e8fc78b40556..a681f38d84d8 100644 --- a/fs/backing-file.c +++ b/fs/backing-file.c @@ -14,7 +14,6 @@ #include <linux/mm.h> #include "internal.h" -extern void ovl_revert_creds(struct super_block *sb, const struct cred *oldcred); /** * backing_file_open - open a backing file for kernel internal use @@ -175,7 +174,7 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, backing_aio_cleanup(aio, ret); } out: - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); if (ctx->accessed) ctx->accessed(ctx->user_file); @@ -242,7 +241,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, backing_aio_cleanup(aio, ret); } out: - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); return ret; } @@ -261,7 +260,7 @@ ssize_t backing_file_splice_read(struct file *in, loff_t *ppos, old_cred = override_creds(ctx->cred); ret = vfs_splice_read(in, ppos, pipe, len, flags); - ovl_revert_creds(file_inode(in)->i_sb, old_cred); + revert_creds(old_cred); if (ctx->accessed) ctx->accessed(ctx->user_file); @@ -289,7 +288,7 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, file_start_write(out); ret = iter_file_splice_write(pipe, out, ppos, len, flags); file_end_write(out); - ovl_revert_creds(file_inode(out)->i_sb, old_cred); + revert_creds(old_cred); if (ctx->end_write) ctx->end_write(ctx->user_file); @@ -315,7 +314,7 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma, old_cred = override_creds(ctx->cred); ret = call_mmap(vma->vm_file, vma); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); if (ctx->accessed) ctx->accessed(ctx->user_file); diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index d7904ea2b386..b8e25ca51016 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -1227,7 +1227,7 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags) dput(parent); dput(next); } - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 9c2e8538f1ab..0f8b4a719237 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -555,7 +555,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, struct ovl_cattr *attr, bool origin) { int err; - const struct cred *old_cred, *hold_cred = NULL; + const struct cred *old_cred; struct cred *override_cred; struct dentry *parent = dentry->d_parent; @@ -592,14 +592,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, override_cred->fsuid = inode->i_uid; override_cred->fsgid = inode->i_gid; err = security_dentry_create_files_as(dentry, - attr->mode, &dentry->d_name, - old_cred ? old_cred : current_cred(), + attr->mode, &dentry->d_name, old_cred, override_cred); if (err) { put_cred(override_cred); goto out_revert_creds; } - hold_cred = override_creds(override_cred); + put_cred(override_creds(override_cred)); put_cred(override_cred); } @@ -609,9 +608,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode, err = ovl_create_over_whiteout(dentry, inode, attr); out_revert_creds: - ovl_revert_creds(dentry->d_sb, old_cred ?: hold_cred); - if (old_cred && hold_cred) - put_cred(hold_cred); + revert_creds(old_cred); return err; } @@ -692,7 +689,7 @@ static int ovl_set_link_redirect(struct dentry *dentry) old_cred = ovl_override_creds(dentry->d_sb); err = ovl_set_redirect(dentry, false); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return err; } @@ -902,7 +899,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) err = ovl_remove_upper(dentry, is_dir, &list); else err = ovl_remove_and_whiteout(dentry, &list); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (!err) { if (is_dir) clear_nlink(dentry->d_inode); @@ -1282,7 +1279,7 @@ out_dput_old: out_unlock: unlock_rename(new_upperdir, old_upperdir); out_revert_creds: - ovl_revert_creds(old->d_sb, old_cred); + revert_creds(old_cred); if (update_nlink) ovl_nlink_end(new); else diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 6f5b26881dd5..05536964d37f 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -54,7 +54,7 @@ static struct file *ovl_open_realfile(const struct file *file, realfile = backing_file_open(&file->f_path, flags, realpath, current_cred()); } - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n", file, file, ovl_whatisit(inode, realinode), file->f_flags, @@ -216,7 +216,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) old_cred = ovl_override_creds(inode->i_sb); ret = vfs_llseek(real.file, offset, whence); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); file->f_pos = real.file->f_pos; ovl_inode_unlock(inode); @@ -403,7 +403,7 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) { old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fsync_range(real.file, start, end, datasync); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); } fdput(real); @@ -443,7 +443,7 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fallocate(real.file, mode, offset, len); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); /* Update size */ ovl_file_modified(file); @@ -468,7 +468,7 @@ static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice) old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fadvise(real.file, offset, len, advice); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); fdput(real); @@ -527,7 +527,7 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, flags); break; } - ovl_revert_creds(file_inode(file_out)->i_sb, old_cred); + revert_creds(old_cred); /* Update size */ ovl_file_modified(file_out); @@ -589,7 +589,7 @@ static int ovl_flush(struct file *file, fl_owner_t id) if (real.file->f_op->flush) { old_cred = ovl_override_creds(file_inode(file)->i_sb); err = real.file->f_op->flush(real.file, id); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); } fdput(real); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index fb29df12e515..c63b31a460be 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -81,7 +81,7 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, inode_lock(upperdentry->d_inode); old_cred = ovl_override_creds(dentry->d_sb); err = ovl_do_notify_change(ofs, upperdentry, attr); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (!err) ovl_copyattr(dentry->d_inode); inode_unlock(upperdentry->d_inode); @@ -281,7 +281,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, stat->nlink = dentry->d_inode->i_nlink; out: - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return err; } @@ -318,7 +318,7 @@ int ovl_permission(struct mnt_idmap *idmap, mask |= MAY_READ; } err = inode_permission(mnt_idmap(realpath.mnt), realinode, mask); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); return err; } @@ -335,7 +335,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(dentry->d_sb, old_cred); + revert_creds(old_cred); return p; } @@ -470,7 +470,7 @@ struct posix_acl *do_ovl_get_acl(struct mnt_idmap *idmap, old_cred = ovl_override_creds(inode->i_sb); acl = ovl_get_acl_path(&realpath, posix_acl_xattr_name(type), noperm); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); } return acl; @@ -499,7 +499,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, old_cred = ovl_override_creds(dentry->d_sb); real_acl = vfs_get_acl(mnt_idmap(realpath.mnt), realdentry, acl_name); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (IS_ERR(real_acl)) { err = PTR_ERR(real_acl); goto out; @@ -524,7 +524,7 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, err = ovl_do_set_acl(ofs, realdentry, acl_name, acl); else err = ovl_do_remove_acl(ofs, realdentry, acl_name); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); ovl_drop_write(dentry); /* copy c/mtime */ @@ -601,7 +601,7 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, old_cred = ovl_override_creds(inode->i_sb); err = realinode->i_op->fiemap(realinode, fieinfo, start, len); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); return err; } @@ -672,7 +672,7 @@ int ovl_fileattr_set(struct mnt_idmap *idmap, err = ovl_set_protattr(inode, upperpath.dentry, fa); if (!err) err = ovl_real_fileattr_set(&upperpath, fa); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); ovl_drop_write(dentry); /* @@ -734,7 +734,7 @@ int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa) old_cred = ovl_override_creds(inode->i_sb); err = ovl_real_fileattr_get(&realpath, fa); ovl_fileattr_prot_flags(inode, fa); - ovl_revert_creds(inode->i_sb, old_cred); + revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 68729e88122d..984ffdaeed6c 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -986,7 +986,7 @@ static int ovl_maybe_lookup_lowerdata(struct dentry *dentry) old_cred = ovl_override_creds(dentry->d_sb); err = ovl_lookup_data_layers(dentry, redirect, &datapath); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (err) goto out_err; @@ -1331,7 +1331,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_dentry_init_reval(dentry, upperdentry, OVL_I_E(inode)); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (origin_path) { dput(origin_path->dentry); kfree(origin_path); @@ -1355,7 +1355,7 @@ out_put_upper: kfree(upperredirect); out: kfree(d.redirect); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return ERR_PTR(err); } @@ -1412,7 +1412,7 @@ bool ovl_lower_positive(struct dentry *dentry) dput(this); } } - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return positive; } diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 43e228b5353c..5ba11eb43767 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -431,7 +431,6 @@ static inline const struct cred *ovl_creds(struct super_block *sb) return OVL_FS(sb)->creator_cred; } -void ovl_revert_creds(struct super_block *sb, const struct cred *oldcred); int ovl_can_decode_fh(struct super_block *sb); struct dentry *ovl_indexdir(struct super_block *sb); bool ovl_index_all(struct super_block *sb); diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index ce200f9c04f3..5fa9c58af65f 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -19,7 +19,6 @@ struct ovl_config { bool metacopy; bool userxattr; bool ovl_volatile; - bool override_creds; }; struct ovl_sb { diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index 7b8fe64b2b98..112b4b12f825 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -43,11 +43,6 @@ module_param_named(metacopy, ovl_metacopy_def, bool, 0644); MODULE_PARM_DESC(metacopy, "Default to on or off for the metadata only copy up feature"); -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"); - enum ovl_opt { Opt_lowerdir, Opt_lowerdir_add, @@ -64,7 +59,6 @@ enum ovl_opt { Opt_metacopy, Opt_verity, Opt_volatile, - Opt_override_creds, }; static const struct constant_table ovl_parameter_bool[] = { @@ -165,7 +159,6 @@ const struct fs_parameter_spec ovl_parameter_spec[] = { fsparam_enum("metacopy", Opt_metacopy, ovl_parameter_bool), fsparam_enum("verity", Opt_verity, ovl_parameter_verity), fsparam_flag("volatile", Opt_volatile), - fsparam_enum("override_creds", Opt_override_creds, ovl_parameter_bool), {} }; @@ -626,9 +619,6 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param) case Opt_userxattr: config->userxattr = true; break; - case Opt_override_creds: - config->override_creds = result.uint_32; - break; default: pr_err("unrecognized mount option \"%s\" or missing value\n", param->key); diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 0b2bcb2ad4ef..e71156baa7bc 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -290,7 +290,7 @@ static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data } inode_unlock(dir->d_inode); } - ovl_revert_creds(rdd->dentry->d_sb, old_cred); + revert_creds(old_cred); return err; } @@ -807,7 +807,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) } err = 0; out: - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return err; } @@ -859,7 +859,7 @@ static struct file *ovl_dir_open_realfile(const struct file *file, old_cred = ovl_override_creds(file_inode(file)->i_sb); res = ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE)); - ovl_revert_creds(file_inode(file)->i_sb, old_cred); + revert_creds(old_cred); return res; } @@ -986,7 +986,7 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) old_cred = ovl_override_creds(dentry->d_sb); err = ovl_dir_read_merged(dentry, list, &root); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (err) return err; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 9665d6d3cb7f..0217094c23ea 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -65,18 +65,9 @@ const struct cred *ovl_override_creds(struct super_block *sb) { struct ovl_fs *ofs = OVL_FS(sb); - if (!ofs->config.override_creds) - return NULL; return override_creds(ofs->creator_cred); } -void ovl_revert_creds(struct super_block *sb, const struct cred *old_cred) -{ - if (old_cred) - revert_creds(old_cred); -} - - /* * Check if underlying fs supports file handles and try to determine encoding * type, in order to deduce maximum inode number used by fs. @@ -1174,7 +1165,7 @@ int ovl_nlink_start(struct dentry *dentry) * value relative to the upper inode nlink in an upper inode xattr. */ err = ovl_set_nlink_upper(dentry); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (err) goto out_drop_write; @@ -1199,7 +1190,7 @@ void ovl_nlink_end(struct dentry *dentry) old_cred = ovl_override_creds(dentry->d_sb); ovl_cleanup_index(dentry); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); } ovl_inode_unlock(inode); diff --git a/fs/overlayfs/xattrs.c b/fs/overlayfs/xattrs.c index 0be45ed8fad3..383978e4663c 100644 --- a/fs/overlayfs/xattrs.c +++ b/fs/overlayfs/xattrs.c @@ -47,7 +47,7 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char ovl_path_lower(dentry, &realpath); old_cred = ovl_override_creds(dentry->d_sb); err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); if (err < 0) goto out; } @@ -72,7 +72,7 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char WARN_ON(flags != XATTR_REPLACE); err = ovl_do_removexattr(ofs, realdentry, name); } - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); ovl_drop_write(dentry); /* copy c/mtime */ @@ -91,7 +91,7 @@ static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char ovl_i_path_real(inode, &realpath); old_cred = ovl_override_creds(dentry->d_sb); res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); - ovl_revert_creds(dentry->d_sb, old_cred); + revert_creds(old_cred); return res; } @@ -121,7 +121,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(dentry->d_sb, old_cred); + revert_creds(old_cred); if (res <= 0 || size == 0) return res; |