| 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 |
| |