summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Pundir <amit.pundir@linaro.org>2024-01-15 14:37:20 +0530
committerAmit Pundir <amit.pundir@linaro.org>2024-01-22 11:45:08 +0530
commit6c3fdaa6b505c960767dc6df2a66dd3fa0baf884 (patch)
tree420a4ca55a68577aa97a243e1a2993f0f30708c7
parentd88aa862799a7cc8555338217f0f2ecfd0a89040 (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.rst24
-rw-r--r--fs/backing-file.c11
-rw-r--r--fs/overlayfs/copy_up.c2
-rw-r--r--fs/overlayfs/dir.c17
-rw-r--r--fs/overlayfs/file.c14
-rw-r--r--fs/overlayfs/inode.c20
-rw-r--r--fs/overlayfs/namei.c8
-rw-r--r--fs/overlayfs/overlayfs.h1
-rw-r--r--fs/overlayfs/ovl_entry.h1
-rw-r--r--fs/overlayfs/params.c10
-rw-r--r--fs/overlayfs/readdir.c8
-rw-r--r--fs/overlayfs/util.c13
-rw-r--r--fs/overlayfs/xattrs.c8
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;