// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2017-2018 HUAWEI, Inc.
 *             https://www.huawei.com/
 * Copyright (C) 2021-2022, Alibaba Cloud
 */
#include <linux/security.h>
#include <linux/xxhash.h>
#include "xattr.h"

struct erofs_xattr_iter {
	struct super_block *sb;
	struct erofs_buf buf;
	erofs_off_t pos;
	void *kaddr;

	char *buffer;
	int buffer_size, buffer_ofs;

	/* getxattr */
	int index, infix_len;
	struct qstr name;

	/* listxattr */
	struct dentry *dentry;
};

static int erofs_init_inode_xattrs(struct inode *inode)
{
	struct erofs_inode *const vi = EROFS_I(inode);
	struct erofs_xattr_iter it;
	unsigned int i;
	struct erofs_xattr_ibody_header *ih;
	struct super_block *sb = inode->i_sb;
	int ret = 0;

	/* the most case is that xattrs of this inode are initialized. */
	if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags)) {
		/*
		 * paired with smp_mb() at the end of the function to ensure
		 * fields will only be observed after the bit is set.
		 */
		smp_mb();
		return 0;
	}

	if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_XATTR_BIT, TASK_KILLABLE))
		return -ERESTARTSYS;

	/* someone has initialized xattrs for us? */
	if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags))
		goto out_unlock;

	/*
	 * bypass all xattr operations if ->xattr_isize is not greater than
	 * sizeof(struct erofs_xattr_ibody_header), in detail:
	 * 1) it is not enough to contain erofs_xattr_ibody_header then
	 *    ->xattr_isize should be 0 (it means no xattr);
	 * 2) it is just to contain erofs_xattr_ibody_header, which is on-disk
	 *    undefined right now (maybe use later with some new sb feature).
	 */
	if (vi->xattr_isize == sizeof(struct erofs_xattr_ibody_header)) {
		erofs_err(sb,
			  "xattr_isize %d of nid %llu is not supported yet",
			  vi->xattr_isize, vi->nid);
		ret = -EOPNOTSUPP;
		goto out_unlock;
	} else if (vi->xattr_isize < sizeof(struct erofs_xattr_ibody_header)) {
		if (vi->xattr_isize) {
			erofs_err(sb, "bogus xattr ibody @ nid %llu", vi->nid);
			DBG_BUGON(1);
			ret = -EFSCORRUPTED;
			goto out_unlock;	/* xattr ondisk layout error */
		}
		ret = -ENOATTR;
		goto out_unlock;
	}

	it.buf = __EROFS_BUF_INITIALIZER;
	erofs_init_metabuf(&it.buf, sb);
	it.pos = erofs_iloc(inode) + vi->inode_isize;

	/* read in shared xattr array (non-atomic, see kmalloc below) */
	it.kaddr = erofs_bread(&it.buf, it.pos, EROFS_KMAP);
	if (IS_ERR(it.kaddr)) {
		ret = PTR_ERR(it.kaddr);
		goto out_unlock;
	}

	ih = it.kaddr;
	vi->xattr_name_filter = le32_to_cpu(ih->h_name_filter);
	vi->xattr_shared_count = ih->h_shared_count;
	vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count,
						sizeof(uint), GFP_KERNEL);
	if (!vi->xattr_shared_xattrs) {
		erofs_put_metabuf(&it.buf);
		ret = -ENOMEM;
		goto out_unlock;
	}

	/* let's skip ibody header */
	it.pos += sizeof(struct erofs_xattr_ibody_header);

	for (i = 0; i < vi->xattr_shared_count; ++i) {
		it.kaddr = erofs_bread(&it.buf, it.pos, EROFS_KMAP);
		if (IS_ERR(it.kaddr)) {
			kfree(vi->xattr_shared_xattrs);
			vi->xattr_shared_xattrs = NULL;
			ret = PTR_ERR(it.kaddr);
			goto out_unlock;
		}
		vi->xattr_shared_xattrs[i] = le32_to_cpu(*(__le32 *)it.kaddr);
		it.pos += sizeof(__le32);
	}
	erofs_put_metabuf(&it.buf);

	/* paired with smp_mb() at the beginning of the function. */
	smp_mb();
	set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);

out_unlock:
	clear_and_wake_up_bit(EROFS_I_BL_XATTR_BIT, &vi->flags);
	return ret;
}

static bool erofs_xattr_user_list(struct dentry *dentry)
{
	return test_opt(&EROFS_SB(dentry->d_sb)->opt, XATTR_USER);
}

static bool erofs_xattr_trusted_list(struct dentry *dentry)
{
	return capable(CAP_SYS_ADMIN);
}

static int erofs_xattr_generic_get(const struct xattr_handler *handler,
				   struct dentry *unused, struct inode *inode,
				   const char *name, void *buffer, size_t size)
{
	if (handler->flags == EROFS_XATTR_INDEX_USER &&
	    !test_opt(&EROFS_I_SB(inode)->opt, XATTR_USER))
		return -EOPNOTSUPP;

	return erofs_getxattr(inode, handler->flags, name, buffer, size);
}

const struct xattr_handler erofs_xattr_user_handler = {
	.prefix	= XATTR_USER_PREFIX,
	.flags	= EROFS_XATTR_INDEX_USER,
	.list	= erofs_xattr_user_list,
	.get	= erofs_xattr_generic_get,
};

const struct xattr_handler erofs_xattr_trusted_handler = {
	.prefix	= XATTR_TRUSTED_PREFIX,
	.flags	= EROFS_XATTR_INDEX_TRUSTED,
	.list	= erofs_xattr_trusted_list,
	.get	= erofs_xattr_generic_get,
};

#ifdef CONFIG_EROFS_FS_SECURITY
const struct xattr_handler __maybe_unused erofs_xattr_security_handler = {
	.prefix	= XATTR_SECURITY_PREFIX,
	.flags	= EROFS_XATTR_INDEX_SECURITY,
	.get	= erofs_xattr_generic_get,
};
#endif

const struct xattr_handler * const erofs_xattr_handlers[] = {
	&erofs_xattr_user_handler,
	&erofs_xattr_trusted_handler,
#ifdef CONFIG_EROFS_FS_SECURITY
	&erofs_xattr_security_handler,
#endif
	NULL,
};

static int erofs_xattr_copy_to_buffer(struct erofs_xattr_iter *it,
				      unsigned int len)
{
	unsigned int slice, processed;
	struct super_block *sb = it->sb;
	void *src;

	for (processed = 0; processed < len; processed += slice) {
		it->kaddr = erofs_bread(&it->buf, it->pos, EROFS_KMAP);
		if (IS_ERR(it->kaddr))
			return PTR_ERR(it->kaddr);

		src = it->kaddr;
		slice = min_t(unsigned int, sb->s_blocksize -
				erofs_blkoff(sb, it->pos), len - processed);
		memcpy(it->buffer + it->buffer_ofs, src, slice);
		it->buffer_ofs += slice;
		it->pos += slice;
	}
	return 0;
}

static int erofs_listxattr_foreach(struct erofs_xattr_iter *it)
{
	struct erofs_xattr_entry entry;
	unsigned int base_index, name_total, prefix_len, infix_len = 0;
	const char *prefix, *infix = NULL;
	int err;

	/* 1. handle xattr entry */
	entry = *(struct erofs_xattr_entry *)it->kaddr;
	it->pos += sizeof(struct erofs_xattr_entry);

	base_index = entry.e_name_index;
	if (entry.e_name_index & EROFS_XATTR_LONG_PREFIX) {
		struct erofs_sb_info *sbi = EROFS_SB(it->sb);
		struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
			(entry.e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);

		if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
			return 0;
		infix = pf->prefix->infix;
		infix_len = pf->infix_len;
		base_index = pf->prefix->base_index;
	}

	prefix = erofs_xattr_prefix(base_index, it->dentry);
	if (!prefix)
		return 0;
	prefix_len = strlen(prefix);
	name_total = prefix_len + infix_len + entry.e_name_len + 1;

	if (!it->buffer) {
		it->buffer_ofs += name_total;
		return 0;
	}

	if (it->buffer_ofs + name_total > it->buffer_size)
		return -ERANGE;

	memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len);
	memcpy(it->buffer + it->buffer_ofs + prefix_len, infix, infix_len);
	it->buffer_ofs += prefix_len + infix_len;

	/* 2. handle xattr name */
	err = erofs_xattr_copy_to_buffer(it, entry.e_name_len);
	if (err)
		return err;

	it->buffer[it->buffer_ofs++] = '\0';
	return 0;
}

static int erofs_getxattr_foreach(struct erofs_xattr_iter *it)
{
	struct super_block *sb = it->sb;
	struct erofs_xattr_entry entry;
	unsigned int slice, processed, value_sz;

	/* 1. handle xattr entry */
	entry = *(struct erofs_xattr_entry *)it->kaddr;
	it->pos += sizeof(struct erofs_xattr_entry);
	value_sz = le16_to_cpu(entry.e_value_size);

	/* should also match the infix for long name prefixes */
	if (entry.e_name_index & EROFS_XATTR_LONG_PREFIX) {
		struct erofs_sb_info *sbi = EROFS_SB(sb);
		struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
			(entry.e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);

		if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
			return -ENOATTR;

		if (it->index != pf->prefix->base_index ||
		    it->name.len != entry.e_name_len + pf->infix_len)
			return -ENOATTR;

		if (memcmp(it->name.name, pf->prefix->infix, pf->infix_len))
			return -ENOATTR;

		it->infix_len = pf->infix_len;
	} else {
		if (it->index != entry.e_name_index ||
		    it->name.len != entry.e_name_len)
			return -ENOATTR;

		it->infix_len = 0;
	}

	/* 2. handle xattr name */
	for (processed = 0; processed < entry.e_name_len; processed += slice) {
		it->kaddr = erofs_bread(&it->buf, it->pos, EROFS_KMAP);
		if (IS_ERR(it->kaddr))
			return PTR_ERR(it->kaddr);

		slice = min_t(unsigned int,
				sb->s_blocksize - erofs_blkoff(sb, it->pos),
				entry.e_name_len - processed);
		if (memcmp(it->name.name + it->infix_len + processed,
			   it->kaddr, slice))
			return -ENOATTR;
		it->pos += slice;
	}

	/* 3. handle xattr value */
	if (!it->buffer) {
		it->buffer_ofs = value_sz;
		return 0;
	}

	if (it->buffer_size < value_sz)
		return -ERANGE;

	return erofs_xattr_copy_to_buffer(it, value_sz);
}

static int erofs_xattr_iter_inline(struct erofs_xattr_iter *it,
				   struct inode *inode, bool getxattr)
{
	struct erofs_inode *const vi = EROFS_I(inode);
	unsigned int xattr_header_sz, remaining, entry_sz;
	erofs_off_t next_pos;
	int ret;

	xattr_header_sz = sizeof(struct erofs_xattr_ibody_header) +
			  sizeof(u32) * vi->xattr_shared_count;
	if (xattr_header_sz >= vi->xattr_isize) {
		DBG_BUGON(xattr_header_sz > vi->xattr_isize);
		return -ENOATTR;
	}

	remaining = vi->xattr_isize - xattr_header_sz;
	it->pos = erofs_iloc(inode) + vi->inode_isize + xattr_header_sz;

	while (remaining) {
		it->kaddr = erofs_bread(&it->buf, it->pos, EROFS_KMAP);
		if (IS_ERR(it->kaddr))
			return PTR_ERR(it->kaddr);

		entry_sz = erofs_xattr_entry_size(it->kaddr);
		/* xattr on-disk corruption: xattr entry beyond xattr_isize */
		if (remaining < entry_sz) {
			DBG_BUGON(1);
			return -EFSCORRUPTED;
		}
		remaining -= entry_sz;
		next_pos = it->pos + entry_sz;

		if (getxattr)
			ret = erofs_getxattr_foreach(it);
		else
			ret = erofs_listxattr_foreach(it);
		if ((getxattr && ret != -ENOATTR) || (!getxattr && ret))
			break;

		it->pos = next_pos;
	}
	return ret;
}

static int erofs_xattr_iter_shared(struct erofs_xattr_iter *it,
				   struct inode *inode, bool getxattr)
{
	struct erofs_inode *const vi = EROFS_I(inode);
	struct super_block *const sb = it->sb;
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	unsigned int i;
	int ret = -ENOATTR;

	for (i = 0; i < vi->xattr_shared_count; ++i) {
		it->pos = erofs_pos(sb, sbi->xattr_blkaddr) +
				vi->xattr_shared_xattrs[i] * sizeof(__le32);
		it->kaddr = erofs_bread(&it->buf, it->pos, EROFS_KMAP);
		if (IS_ERR(it->kaddr))
			return PTR_ERR(it->kaddr);

		if (getxattr)
			ret = erofs_getxattr_foreach(it);
		else
			ret = erofs_listxattr_foreach(it);
		if ((getxattr && ret != -ENOATTR) || (!getxattr && ret))
			break;
	}
	return ret;
}

int erofs_getxattr(struct inode *inode, int index, const char *name,
		   void *buffer, size_t buffer_size)
{
	int ret;
	unsigned int hashbit;
	struct erofs_xattr_iter it;
	struct erofs_inode *vi = EROFS_I(inode);
	struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);

	if (!name)
		return -EINVAL;

	ret = erofs_init_inode_xattrs(inode);
	if (ret)
		return ret;

	/* reserved flag is non-zero if there's any change of on-disk format */
	if (erofs_sb_has_xattr_filter(sbi) && !sbi->xattr_filter_reserved) {
		hashbit = xxh32(name, strlen(name),
				EROFS_XATTR_FILTER_SEED + index);
		hashbit &= EROFS_XATTR_FILTER_BITS - 1;
		if (vi->xattr_name_filter & (1U << hashbit))
			return -ENOATTR;
	}

	it.index = index;
	it.name = QSTR(name);
	if (it.name.len > EROFS_NAME_LEN)
		return -ERANGE;

	it.sb = inode->i_sb;
	it.buf = __EROFS_BUF_INITIALIZER;
	erofs_init_metabuf(&it.buf, it.sb);
	it.buffer = buffer;
	it.buffer_size = buffer_size;
	it.buffer_ofs = 0;

	ret = erofs_xattr_iter_inline(&it, inode, true);
	if (ret == -ENOATTR)
		ret = erofs_xattr_iter_shared(&it, inode, true);
	erofs_put_metabuf(&it.buf);
	return ret ? ret : it.buffer_ofs;
}

ssize_t erofs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{
	int ret;
	struct erofs_xattr_iter it;
	struct inode *inode = d_inode(dentry);

	ret = erofs_init_inode_xattrs(inode);
	if (ret == -ENOATTR)
		return 0;
	if (ret)
		return ret;

	it.sb = dentry->d_sb;
	it.buf = __EROFS_BUF_INITIALIZER;
	erofs_init_metabuf(&it.buf, it.sb);
	it.dentry = dentry;
	it.buffer = buffer;
	it.buffer_size = buffer_size;
	it.buffer_ofs = 0;

	ret = erofs_xattr_iter_inline(&it, inode, false);
	if (!ret || ret == -ENOATTR)
		ret = erofs_xattr_iter_shared(&it, inode, false);
	if (ret == -ENOATTR)
		ret = 0;
	erofs_put_metabuf(&it.buf);
	return ret ? ret : it.buffer_ofs;
}

void erofs_xattr_prefixes_cleanup(struct super_block *sb)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	int i;

	if (sbi->xattr_prefixes) {
		for (i = 0; i < sbi->xattr_prefix_count; i++)
			kfree(sbi->xattr_prefixes[i].prefix);
		kfree(sbi->xattr_prefixes);
		sbi->xattr_prefixes = NULL;
	}
}

int erofs_xattr_prefixes_init(struct super_block *sb)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
	erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
	struct erofs_xattr_prefix_item *pfs;
	int ret = 0, i, len;

	if (!sbi->xattr_prefix_count)
		return 0;

	pfs = kzalloc(sbi->xattr_prefix_count * sizeof(*pfs), GFP_KERNEL);
	if (!pfs)
		return -ENOMEM;

	if (sbi->packed_inode)
		buf.mapping = sbi->packed_inode->i_mapping;
	else
		erofs_init_metabuf(&buf, sb);

	for (i = 0; i < sbi->xattr_prefix_count; i++) {
		void *ptr = erofs_read_metadata(sb, &buf, &pos, &len);

		if (IS_ERR(ptr)) {
			ret = PTR_ERR(ptr);
			break;
		} else if (len < sizeof(*pfs->prefix) ||
			   len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
			kfree(ptr);
			ret = -EFSCORRUPTED;
			break;
		}
		pfs[i].prefix = ptr;
		pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
	}

	erofs_put_metabuf(&buf);
	sbi->xattr_prefixes = pfs;
	if (ret)
		erofs_xattr_prefixes_cleanup(sb);
	return ret;
}

#ifdef CONFIG_EROFS_FS_POSIX_ACL
struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
{
	struct posix_acl *acl;
	int prefix, rc;
	char *value = NULL;

	if (rcu)
		return ERR_PTR(-ECHILD);

	switch (type) {
	case ACL_TYPE_ACCESS:
		prefix = EROFS_XATTR_INDEX_POSIX_ACL_ACCESS;
		break;
	case ACL_TYPE_DEFAULT:
		prefix = EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT;
		break;
	default:
		return ERR_PTR(-EINVAL);
	}

	rc = erofs_getxattr(inode, prefix, "", NULL, 0);
	if (rc > 0) {
		value = kmalloc(rc, GFP_KERNEL);
		if (!value)
			return ERR_PTR(-ENOMEM);
		rc = erofs_getxattr(inode, prefix, "", value, rc);
	}

	if (rc == -ENOATTR)
		acl = NULL;
	else if (rc < 0)
		acl = ERR_PTR(rc);
	else
		acl = posix_acl_from_xattr(&init_user_ns, value, rc);
	kfree(value);
	return acl;
}
#endif
