| From 713848433e43c3b8400f9f60e6f8179b0771f23d Mon Sep 17 00:00:00 2001 |
| From: Mark Salyzyn <salyzyn@google.com> |
| Date: Mon, 4 Nov 2019 08:57:10 -0800 |
| Subject: [PATCH] FROMLIST: Add flags option to get xattr method paired to |
| __vfs_getxattr |
| |
| Add a flag option to get xattr method that could have a bit flag of |
| XATTR_NOSECURITY passed to it. XATTR_NOSECURITY is generally then |
| set in the __vfs_getxattr path when called by security |
| infrastructure. |
| |
| This handles the case of a union filesystem driver that is being |
| requested by the security layer to report back the xattr data. |
| |
| For the use case where access is to be blocked by the security layer. |
| |
| The path then could be security(dentry) -> |
| __vfs_getxattr(dentry...XATTR_NOSECURITY) -> |
| handler->get(dentry...XATTR_NOSECURITY) -> |
| __vfs_getxattr(lower_dentry...XATTR_NOSECURITY) -> |
| lower_handler->get(lower_dentry...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 the target |
| context that was blocked. |
| |
| Without the get handler flag, the path on a union filesystem would be |
| the errant security(dentry) -> __vfs_getxattr(dentry) -> |
| handler->get(dentry) -> vfs_getxattr(lower_dentry) -> nested -> |
| security(lower_dentry, log off) -> lower_handler->get(lower_dentry) |
| which would report back through the chain no data, and -EACCES. |
| |
| For selinux for both cases, this would translate to a correctly |
| determined blocked access. In the first case with this change a correct avc |
| log would be reported, in the second legacy case an incorrect avc log |
| would be reported against an uninitialized u:object_r:unlabeled:s0 |
| context making the logs cosmetically useless for audit2allow. |
| |
| This patch series is inert and is the wide-spread addition of the |
| flags option for xattr functions, and a replacement of __vfs_getxattr |
| with __vfs_getxattr(...XATTR_NOSECURITY). |
| |
| Signed-off-by: Mark Salyzyn <salyzyn@android.com> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Acked-by: Jan Kara <jack@suse.cz> |
| Acked-by: Jeff Layton <jlayton@kernel.org> |
| Acked-by: David Sterba <dsterba@suse.com> |
| Acked-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Acked-by: Mike Marshall <hubcap@omnibond.com> |
| Cc: Stephen Smalley <sds@tycho.nsa.gov> |
| Cc: linux-kernel@vger.kernel.org |
| Cc: kernel-team@android.com |
| Cc: linux-security-module@vger.kernel.org |
| |
| (cherry picked from (rejected from archive because of too many recipients)) |
| Signed-off-by: Mark Salyzyn <salyzyn@google.com> |
| Bug: 133515582 |
| Bug: 136124883 |
| Bug: 129319403 |
| Change-Id: Iabbb8771939d5f66667a26bb23ddf4c562c349a1 |
| --- |
| fs/ext4/xattr_hurd.c | 3 ++- |
| fs/nfs/nfs4proc.c | 3 ++- |
| include/linux/xattr.h | 5 +++-- |
| 3 files changed, 7 insertions(+), 4 deletions(-) |
| |
| diff --git a/fs/ext4/xattr_hurd.c b/fs/ext4/xattr_hurd.c |
| index c78df5790377..2baa505e5308 100644 |
| --- a/fs/ext4/xattr_hurd.c |
| +++ b/fs/ext4/xattr_hurd.c |
| @@ -21,7 +21,8 @@ ext4_xattr_hurd_list(struct dentry *dentry) |
| static int |
| ext4_xattr_hurd_get(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *name, void *buffer, size_t size) |
| + const char *name, void *buffer, size_t size, |
| + int flags) |
| { |
| if (!test_opt(inode->i_sb, XATTR_USER)) |
| return -EOPNOTSUPP; |
| diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c |
| index 32174a2a1a26..8f3cb98e87bd 100644 |
| --- a/fs/nfs/nfs4proc.c |
| +++ b/fs/nfs/nfs4proc.c |
| @@ -7604,7 +7604,8 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler, |
| |
| static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler, |
| struct dentry *unused, struct inode *inode, |
| - const char *key, void *buf, size_t buflen) |
| + const char *key, void *buf, size_t buflen, |
| + int flags) |
| { |
| struct nfs_access_entry cache; |
| ssize_t ret; |
| diff --git a/include/linux/xattr.h b/include/linux/xattr.h |
| index d04b68e1b0da..816b5d535a1a 100644 |
| --- a/include/linux/xattr.h |
| +++ b/include/linux/xattr.h |
| @@ -49,8 +49,9 @@ struct xattr { |
| size_t value_len; |
| }; |
| |
| -ssize_t __vfs_getxattr(struct user_namespace *, struct dentry *, struct inode *, |
| - const char *, void *, size_t); |
| +ssize_t __vfs_getxattr(struct user_namespace *mnt_userns, |
| + struct dentry *dentry, struct inode *inode, |
| + const char *name, void *buffer, size_t size, int flags); |
| ssize_t vfs_getxattr(struct user_namespace *, struct dentry *, const char *, |
| void *, size_t); |
| ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); |
| -- |
| 2.17.1 |
| |