blob: 0a87fa5dca24e1901ccaa047d219b1b6f8db205e [file] [log] [blame]
From b92eb605a86f85be9d7d441c935c4a4cda903df2 Mon Sep 17 00:00:00 2001
From: Mark Salyzyn <salyzyn@android.com>
Date: Tue, 23 Jul 2019 13:53:48 -0700
Subject: [PATCH] FROMLIST: 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_do_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.
Because for override credentials off, this affects _everyone_ that
underneath performs private xattr calls without the appropriate
sepolicy permissions and sys_admin capability. Providing blanket
support for sys_admin would be bad for all possible callers.
For the override credentials on, this will affect only the mounter,
should it lack sepolicy permissions. Not considered a security
problem since mounting by definition has sys_admin capabilities,
but sepolicy contexts would still need to be crafted.
It should be noted that there is precedence, __vfs_getxattr is used
in other filesystems for their own internal trusted xattr management.
Signed-off-by: Mark Salyzyn <salyzyn@android.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: linux-unionfs@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: kernel-team@android.com
Cc: linux-security-module@vger.kernel.org
(cherry picked from https://lore.kernel.org/lkml/20191104215253.141818-4-salyzyn@android.com/)
Signed-off-by: Mark Salyzyn <salyzyn@google.com>
Bug: 133515582
Bug: 136124883
Bug: 129319403
Change-Id: I34d99cc46e9e87a79efc8d05f85980bbc137f7eb
[maennich: folded 8d5dc2cf06e9 ("ANDROID: overlayfs: fixup after upstream merge")]
Signed-off-by: Matthias Maennich <maennich@google.com>
[rebase515(groeck): __vfs_getxattr() has an additional argument]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase61(tzungbi):
Squashed:
FIXUP: FROMLIST: overlayfs: internal getxattr operations without sepolicy checking
]
Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org>
---
fs/overlayfs/namei.c | 7 ++++---
fs/overlayfs/overlayfs.h | 4 ++--
fs/overlayfs/util.c | 8 ++++----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index cfb3420b7df0e3314a560677626c7435218e7507..f66b66b7f4cf587a57eee42496351e25e9bfd822 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -109,7 +109,8 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len)
static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *upperdentry,
enum ovl_xattr ox)
{
- int res, err;
+ ssize_t res;
+ int err;
struct ovl_fh *fh = NULL;
res = ovl_getxattr_upper(ofs, upperdentry, ox, NULL, 0);
@@ -144,10 +145,10 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *upperdentry,
return NULL;
fail:
- pr_warn_ratelimited("failed to get origin (%i)\n", res);
+ pr_warn_ratelimited("failed to get origin (%zi)\n", res);
goto out;
invalid:
- pr_warn_ratelimited("invalid origin (%*phN)\n", res, fh);
+ pr_warn_ratelimited("invalid origin (%*phN)\n", (int)res, fh);
goto out;
}
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 1ccec5b8b6c91d25b4dfe5a3bf2c386b3338c937..865327e158dbadeb95a482278ffbb5fd072ea4be 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -214,12 +214,12 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs,
static inline ssize_t ovl_do_getxattr(const struct path *path, const char *name,
void *value, size_t size)
{
+ struct inode *ip = d_inode(path->dentry);
int err, len;
WARN_ON(path->dentry->d_sb != path->mnt->mnt_sb);
- err = vfs_getxattr(mnt_idmap(path->mnt), path->dentry,
- name, value, size);
+ err = __vfs_getxattr(mnt_idmap(path->mnt), path->dentry, ip, name, value, size, XATTR_NOSECURITY);
len = (value && err > 0) ? err : 0;
pr_debug("getxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n",
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 923d66d131c16cc5511af31f1f776a1668437dbd..1d982c61efa652f7c2cf79d33039163e85315d3e 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -578,7 +578,7 @@ void ovl_copy_up_end(struct dentry *dentry)
bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, const struct path *path)
{
- int res;
+ ssize_t res;
res = ovl_path_getxattr(ofs, path, OVL_XATTR_ORIGIN, NULL, 0);
@@ -592,7 +592,7 @@ bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, const struct path *path)
bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, const struct path *path,
enum ovl_xattr ox)
{
- int res;
+ ssize_t res;
char val;
if (!d_is_dir(path->dentry))
@@ -971,7 +971,7 @@ 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 ovl_fs *ofs, const struct path *path)
{
- int res;
+ ssize_t res;
/* Only regular files can have metacopy xattr */
if (!S_ISREG(d_inode(path->dentry)->i_mode))
@@ -993,7 +993,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, const struct path *path)
return 1;
out:
- pr_warn_ratelimited("failed to get metacopy (%i)\n", res);
+ pr_warn_ratelimited("failed to get metacopy (%zi)\n", res);
return res;
}
--
2.38.3