| From c1a808b07ff2933b8129e4c3c86925bcb271a9d9 Mon Sep 17 00:00:00 2001 |
| From: Mark Salyzyn <salyzyn@android.com> |
| Date: Mon, 15 Jul 2019 15:46:45 -0700 |
| Subject: [PATCH] FROMLIST: overlayfs: handle XATTR_NOSECURITY flag for get |
| xattr method |
| |
| Because of the overlayfs getxattr recursion, the incoming inode fails |
| to update the selinux sid resulting in avc denials being reported |
| against a target context of u:object_r:unlabeled:s0. |
| |
| Solution is to respond to the XATTR_NOSECURITY flag in get xattr |
| method that calls the __vfs_getxattr handler instead so that the |
| context can be read in, rather than being denied with an -EACCES |
| when vfs_getxattr handler is called. |
| |
| For the use case where access is to be blocked by the security layer. |
| |
| The path then would be security(dentry) -> |
| __vfs_getxattr({dentry...XATTR_NOSECURITY}) -> |
| handler->get({dentry...XATTR_NOSECURITY}) -> |
| __vfs_getxattr({realdentry...XATTR_NOSECURITY}) -> |
| lower_handler->get({realdentry...XATTR_NOSECURITY}) which |
| would report back through the chain data and success as expected, |
| the logging security layer at the top would have the data to |
| determine the access permissions and report back to the logs and |
| the caller that the target context was blocked. |
| |
| For selinux this would solve the cosmetic issue of the selinux log |
| and allow audit2allow to correctly report the rule needed to address |
| the access problem. |
| |
| 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 pick from https://lore.kernel.org/lkml/20191104215253.141818-3-salyzyn@android.com/) |
| Signed-off-by: Mark Salyzyn <salyzyn@google.com> |
| Bug: 133515582 |
| Bug: 136124883 |
| Bug: 129319403 |
| Change-Id: Ia39543c5ce617976f14d790fb88e471d575ffd65 |
| |
| [rebase515(groeck): __vfs_getxattr() has an additional argument] |
| |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| |
| [rebase61(tzungbi): |
| Squashed: |
| FIXUP: FROMLIST: overlayfs: handle XATTR_NOSECURITY flag for get xattr method |
| Fixed context conflicts. |
| ] |
| Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org> |
| --- |
| fs/overlayfs/inode.c | 5 +++-- |
| fs/overlayfs/overlayfs.h | 2 +- |
| fs/overlayfs/super.c | 2 +- |
| 3 files changed, 5 insertions(+), 4 deletions(-) |
| |
| diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c |
| index 541cf3717fc2b1d1ce709d3725d9fd4307bf4cd1..797ae52cba1a9d6f740967c9ce3273d116f42f2f 100644 |
| --- a/fs/overlayfs/inode.c |
| +++ b/fs/overlayfs/inode.c |
| @@ -395,7 +395,7 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, |
| } |
| |
| int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, |
| - void *value, size_t size) |
| + void *value, size_t size, int flags) |
| { |
| ssize_t res; |
| const struct cred *old_cred; |
| @@ -403,7 +403,8 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, |
| |
| 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); |
| + res = __vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, |
| + d_inode(realpath.dentry), name, value, size, flags); |
| revert_creds(old_cred); |
| return res; |
| } |
| diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h |
| index 4d0b278f5630ea9a4d1b4f62277cb9646e128d57..1ccec5b8b6c91d25b4dfe5a3bf2c386b3338c937 100644 |
| --- a/fs/overlayfs/overlayfs.h |
| +++ b/fs/overlayfs/overlayfs.h |
| @@ -606,7 +606,7 @@ int ovl_permission(struct mnt_idmap *idmap, struct inode *inode, |
| int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, |
| const void *value, size_t size, int flags); |
| int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, |
| - void *value, size_t size); |
| + void *value, size_t size, int flags); |
| ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); |
| |
| #ifdef CONFIG_FS_POSIX_ACL |
| diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c |
| index f1d9f75f8786ce51ae60723eff63dac5b59c9f7f..d77a5381ebdf1aa5630402967877a943edd27218 100644 |
| --- a/fs/overlayfs/super.c |
| +++ b/fs/overlayfs/super.c |
| @@ -1024,7 +1024,7 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler, |
| struct dentry *dentry, struct inode *inode, |
| const char *name, void *buffer, size_t size) |
| { |
| - return ovl_xattr_get(dentry, inode, name, buffer, size); |
| + return ovl_xattr_get(dentry, inode, name, buffer, size, flags); |
| } |
| |
| static int ovl_other_xattr_set(const struct xattr_handler *handler, |
| -- |
| 2.38.3 |
| |