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

Commit b50d9aa3 authored by Paul Lawrence's avatar Paul Lawrence
Browse files

ANDROID: Incremental fs: Support xattrs



To make selinux work, add xattr support. This is a bit clunky -
it seems like it would be better for the log and pending read
functionality to be ioctls rather than this mixture of real
and virtual files.

Bug: 133435829
Change-Id: I56579fabe2ae7efb88f0344553948dc9573299aa
Signed-off-by: default avatarPaul Lawrence <paullawrence@google.com>
parent 7a824723
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ void incfs_free_mount_info(struct mount_info *mi)
	mutex_destroy(&mi->mi_pending_reads_mutex);
	put_cred(mi->mi_owner);
	kfree(mi->mi_log.rl_ring_buf);
	kfree(mi->log_xattr);
	kfree(mi->pending_read_xattr);
	kfree(mi);
}

+6 −0
Original line number Diff line number Diff line
@@ -105,6 +105,12 @@ struct mount_info {

	/* Temporary buffer for read logger. */
	struct read_log mi_log;

	void *log_xattr;
	size_t log_xattr_size;

	void *pending_read_xattr;
	size_t pending_read_xattr_size;
};

struct data_file_block {
+76 −2
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ static void evict_inode(struct inode *inode);

static ssize_t incfs_getxattr(struct dentry *d, const char *name,
			void *value, size_t size);
static ssize_t incfs_setxattr(struct dentry *d, const char *name,
			const void *value, size_t size, int flags);
static ssize_t incfs_listxattr(struct dentry *d, char *list, size_t size);

static int show_options(struct seq_file *, struct dentry *);
@@ -166,9 +168,18 @@ static int incfs_handler_getxattr(const struct xattr_handler *xh,
	return incfs_getxattr(d, name, buffer, size);
}

static int incfs_handler_setxattr(const struct xattr_handler *xh,
				  struct dentry *d, struct inode *inode,
				  const char *name, const void *buffer,
				  size_t size, int flags)
{
	return incfs_setxattr(d, name, buffer, size, flags);
}

static const struct xattr_handler incfs_xattr_handler = {
	.prefix = "",	/* AKA all attributes */
	.get = incfs_handler_getxattr,
	.set = incfs_handler_setxattr,
};

static const struct xattr_handler *incfs_xattr_ops[] = {
@@ -2045,11 +2056,74 @@ static ssize_t incfs_getxattr(struct dentry *d, const char *name,
			void *value, size_t size)
{
	struct dentry_info *di = get_incfs_dentry(d);
	struct mount_info *mi = get_mount_info(d->d_sb);
	char *stored_value;
	size_t stored_size;

	if (!di || !di->backing_path.dentry)
	if (di && di->backing_path.dentry)
		return vfs_getxattr(di->backing_path.dentry, name, value, size);

	if (strcmp(name, "security.selinux"))
		return -ENODATA;

	return vfs_getxattr(di->backing_path.dentry, name, value, size);
	if (!strcmp(d->d_iname, INCFS_PENDING_READS_FILENAME)) {
		stored_value = mi->pending_read_xattr;
		stored_size = mi->pending_read_xattr_size;
	} else if (!strcmp(d->d_iname, INCFS_LOG_FILENAME)) {
		stored_value = mi->log_xattr;
		stored_size = mi->log_xattr_size;
	} else {
		return -ENODATA;
	}

	if (!stored_value)
		return -ENODATA;

	if (stored_size > size)
		return -E2BIG;

	memcpy(value, stored_value, stored_size);
	return stored_size;

}


static ssize_t incfs_setxattr(struct dentry *d, const char *name,
			const void *value, size_t size, int flags)
{
	struct dentry_info *di = get_incfs_dentry(d);
	struct mount_info *mi = get_mount_info(d->d_sb);
	void **stored_value;
	size_t *stored_size;

	if (di && di->backing_path.dentry)
		return vfs_setxattr(di->backing_path.dentry, name, value, size,
				    flags);

	if (strcmp(name, "security.selinux"))
		return -ENODATA;

	if (size > INCFS_MAX_FILE_ATTR_SIZE)
		return -E2BIG;

	if (!strcmp(d->d_iname, INCFS_PENDING_READS_FILENAME)) {
		stored_value = &mi->pending_read_xattr;
		stored_size = &mi->pending_read_xattr_size;
	} else if (!strcmp(d->d_iname, INCFS_LOG_FILENAME)) {
		stored_value = &mi->log_xattr;
		stored_size = &mi->log_xattr_size;
	} else {
		return -ENODATA;
	}

	kfree (*stored_value);
	*stored_value = kzalloc(size, GFP_NOFS);
	if (!*stored_value)
		return -ENOMEM;

	memcpy(*stored_value, value, size);
	*stored_size = size;
	return 0;
}

static ssize_t incfs_listxattr(struct dentry *d, char *list, size_t size)