ANDROID: overlayfs: internal getxattr operations without sepolicy checking
Check impure, opaque, origin & meta xattr with no sepolicy audit (using __vfs_getxattr) since these operations are internal to overlayfs operations and do not disclose any data. This became an issue for credential override off since sys_admin would have been required by the caller; whereas would have been inherently present for the creator since it performed the mount. This is a change in operations since we do not check in the new ovl_vfs_getxattr function if the credential override is off or not. Reasoning is that the sepolicy check is unnecessary overhead, especially since the check can be expensive. Signed-off-by: Mark Salyzyn <salyzyn@google.com> Bug: 133515582 Bug: 136124883 Bug: 129319403 Change-Id: I34d99cc46e9e87a79efc8d05f85980bbc137f7eb
This commit is contained in:
parent
69e51290af
commit
e2d54786e8
3 changed files with 24 additions and 14 deletions
|
@ -109,10 +109,11 @@ int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
|
|||
|
||||
static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
|
||||
{
|
||||
int res, err;
|
||||
ssize_t res;
|
||||
int err;
|
||||
struct ovl_fh *fh = NULL;
|
||||
|
||||
res = vfs_getxattr(dentry, name, NULL, 0);
|
||||
res = ovl_vfs_getxattr(dentry, name, NULL, 0);
|
||||
if (res < 0) {
|
||||
if (res == -ENODATA || res == -EOPNOTSUPP)
|
||||
return NULL;
|
||||
|
@ -126,7 +127,7 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
|
|||
if (!fh)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
res = vfs_getxattr(dentry, name, fh, res);
|
||||
res = ovl_vfs_getxattr(dentry, name, fh, res);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -144,10 +145,11 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
|
|||
return NULL;
|
||||
|
||||
fail:
|
||||
pr_warn_ratelimited("overlayfs: failed to get origin (%i)\n", res);
|
||||
pr_warn_ratelimited("overlayfs: failed to get origin (%zi)\n", res);
|
||||
goto out;
|
||||
invalid:
|
||||
pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n", res, fh);
|
||||
pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n",
|
||||
(int)res, fh);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,8 @@ void ovl_drop_write(struct dentry *dentry);
|
|||
struct dentry *ovl_workdir(struct dentry *dentry);
|
||||
const struct cred *ovl_override_creds(struct super_block *sb);
|
||||
void ovl_revert_creds(const struct cred *oldcred);
|
||||
ssize_t ovl_vfs_getxattr(struct dentry *dentry, const char *name, void *buf,
|
||||
size_t size);
|
||||
struct super_block *ovl_same_sb(struct super_block *sb);
|
||||
int ovl_can_decode_fh(struct super_block *sb);
|
||||
struct dentry *ovl_indexdir(struct super_block *sb);
|
||||
|
|
|
@ -51,6 +51,12 @@ void ovl_revert_creds(const struct cred *old_cred)
|
|||
revert_creds(old_cred);
|
||||
}
|
||||
|
||||
ssize_t ovl_vfs_getxattr(struct dentry *dentry, const char *name, void *buf,
|
||||
size_t size)
|
||||
{
|
||||
return __vfs_getxattr(dentry, d_inode(dentry), name, buf, size);
|
||||
}
|
||||
|
||||
struct super_block *ovl_same_sb(struct super_block *sb)
|
||||
{
|
||||
struct ovl_fs *ofs = sb->s_fs_info;
|
||||
|
@ -549,9 +555,9 @@ void ovl_copy_up_end(struct dentry *dentry)
|
|||
|
||||
bool ovl_check_origin_xattr(struct dentry *dentry)
|
||||
{
|
||||
int res;
|
||||
ssize_t res;
|
||||
|
||||
res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0);
|
||||
res = ovl_vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0);
|
||||
|
||||
/* Zero size value means "copied up but origin unknown" */
|
||||
if (res >= 0)
|
||||
|
@ -562,13 +568,13 @@ bool ovl_check_origin_xattr(struct dentry *dentry)
|
|||
|
||||
bool ovl_check_dir_xattr(struct dentry *dentry, const char *name)
|
||||
{
|
||||
int res;
|
||||
ssize_t res;
|
||||
char val;
|
||||
|
||||
if (!d_is_dir(dentry))
|
||||
return false;
|
||||
|
||||
res = vfs_getxattr(dentry, name, &val, 1);
|
||||
res = ovl_vfs_getxattr(dentry, name, &val, 1);
|
||||
if (res == 1 && val == 'y')
|
||||
return true;
|
||||
|
||||
|
@ -852,13 +858,13 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
|
|||
/* err < 0, 0 if no metacopy xattr, 1 if metacopy xattr found */
|
||||
int ovl_check_metacopy_xattr(struct dentry *dentry)
|
||||
{
|
||||
int res;
|
||||
ssize_t res;
|
||||
|
||||
/* Only regular files can have metacopy xattr */
|
||||
if (!S_ISREG(d_inode(dentry)->i_mode))
|
||||
return 0;
|
||||
|
||||
res = vfs_getxattr(dentry, OVL_XATTR_METACOPY, NULL, 0);
|
||||
res = ovl_vfs_getxattr(dentry, OVL_XATTR_METACOPY, NULL, 0);
|
||||
if (res < 0) {
|
||||
if (res == -ENODATA || res == -EOPNOTSUPP)
|
||||
return 0;
|
||||
|
@ -867,7 +873,7 @@ int ovl_check_metacopy_xattr(struct dentry *dentry)
|
|||
|
||||
return 1;
|
||||
out:
|
||||
pr_warn_ratelimited("overlayfs: failed to get metacopy (%i)\n", res);
|
||||
pr_warn_ratelimited("overlayfs: failed to get metacopy (%zi)\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -893,7 +899,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
|
|||
ssize_t res;
|
||||
char *buf = NULL;
|
||||
|
||||
res = vfs_getxattr(dentry, name, NULL, 0);
|
||||
res = ovl_vfs_getxattr(dentry, name, NULL, 0);
|
||||
if (res < 0) {
|
||||
if (res == -ENODATA || res == -EOPNOTSUPP)
|
||||
return -ENODATA;
|
||||
|
@ -905,7 +911,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
|
|||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
res = vfs_getxattr(dentry, name, buf, res);
|
||||
res = ovl_vfs_getxattr(dentry, name, buf, res);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue