Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18cb05fa authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

ANDROID: overlayfs: add __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 add a _get xattr method that calls the __vfs_getxattr
handler so that the context can be read in, rather than being denied
with an -EACCES when vfs_getxattr handler is called.

Signed-off-by: default avatarMark Salyzyn <salyzyn@google.com>
Bug: 133515582
Bug: 136124883
Bug: 129319403
Change-Id: Ia39543c5ce617976f14d790fb88e471d575ffd65
parent c195c04a
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -365,6 +365,21 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
	return err;
}

int __ovl_xattr_get(struct dentry *dentry, struct inode *inode,
		    const char *name, void *value, size_t size)
{
	ssize_t res;
	const struct cred *old_cred;
	struct dentry *realdentry =
		ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry);

	old_cred = ovl_override_creds(dentry->d_sb);
	res = __vfs_getxattr(realdentry, d_inode(realdentry), name, value,
			     size);
	ovl_revert_creds(old_cred);
	return res;
}

int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
		  void *value, size_t size)
{
+2 −0
Original line number Diff line number Diff line
@@ -351,6 +351,8 @@ 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);
int __ovl_xattr_get(struct dentry *dentry, struct inode *inode,
		    const char *name, void *value, size_t size);
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
struct posix_acl *ovl_get_acl(struct inode *inode, int type);
int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags);
+18 −0
Original line number Diff line number Diff line
@@ -884,6 +884,14 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
	return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
}

static int __maybe_unused
__ovl_posix_acl_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, handler->name, buffer, size);
}

static int __maybe_unused
ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
			struct dentry *dentry, struct inode *inode,
@@ -964,6 +972,13 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler,
	return ovl_xattr_get(dentry, inode, name, buffer, size);
}

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);
}

static int ovl_other_xattr_set(const struct xattr_handler *handler,
			       struct dentry *dentry, struct inode *inode,
			       const char *name, const void *value,
@@ -977,6 +992,7 @@ ovl_posix_acl_access_xattr_handler = {
	.name = XATTR_NAME_POSIX_ACL_ACCESS,
	.flags = ACL_TYPE_ACCESS,
	.get = ovl_posix_acl_xattr_get,
	.__get = __ovl_posix_acl_xattr_get,
	.set = ovl_posix_acl_xattr_set,
};

@@ -985,6 +1001,7 @@ ovl_posix_acl_default_xattr_handler = {
	.name = XATTR_NAME_POSIX_ACL_DEFAULT,
	.flags = ACL_TYPE_DEFAULT,
	.get = ovl_posix_acl_xattr_get,
	.__get = __ovl_posix_acl_xattr_get,
	.set = ovl_posix_acl_xattr_set,
};

@@ -997,6 +1014,7 @@ static const struct xattr_handler ovl_own_xattr_handler = {
static const struct xattr_handler ovl_other_xattr_handler = {
	.prefix	= "", /* catch all */
	.get = ovl_other_xattr_get,
	.__get = __ovl_other_xattr_get,
	.set = ovl_other_xattr_set,
};