// SPDX-License-Identifier: GPL-2.0+
/*
 * erofs-utils/lib/xattr.c
 *
 * Originally contributed by an anonymous person,
 * heavily changed by Li Guifu <blucerlee@gmail.com>
 *                and Gao Xiang <hsiangkao@aol.com>
 */
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/xattr.h>
#ifdef HAVE_LINUX_XATTR_H
#include <linux/xattr.h>
#endif
#include <sys/stat.h>
#include <dirent.h>
#include "erofs/print.h"
#include "erofs/hashtable.h"
#include "erofs/xattr.h"
#include "erofs/cache.h"
#include "erofs/io.h"

#define EA_HASHTABLE_BITS 16

struct xattr_item {
	const char *kvbuf;
	unsigned int hash[2], len[2], count;
	int shared_xattr_id;
	u8 prefix;
	struct hlist_node node;
};

struct inode_xattr_node {
	struct list_head list;
	struct xattr_item *item;
};

static DECLARE_HASHTABLE(ea_hashtable, EA_HASHTABLE_BITS);

static LIST_HEAD(shared_xattrs_list);
static unsigned int shared_xattrs_count, shared_xattrs_size;

static struct xattr_prefix {
	const char *prefix;
	u16 prefix_len;
} xattr_types[] = {
	[EROFS_XATTR_INDEX_USER] = {
		XATTR_USER_PREFIX,
		XATTR_USER_PREFIX_LEN
	}, [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = {
		XATTR_NAME_POSIX_ACL_ACCESS,
		sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
	}, [EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = {
		XATTR_NAME_POSIX_ACL_DEFAULT,
		sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1
	}, [EROFS_XATTR_INDEX_TRUSTED] = {
		XATTR_TRUSTED_PREFIX,
		XATTR_TRUSTED_PREFIX_LEN
	}, [EROFS_XATTR_INDEX_SECURITY] = {
		XATTR_SECURITY_PREFIX,
		XATTR_SECURITY_PREFIX_LEN
	}
};

static unsigned int BKDRHash(char *str, unsigned int len)
{
	const unsigned int seed = 131313;
	unsigned int hash = 0;

	while (len) {
		hash = hash * seed + (*str++);
		--len;
	}
	return hash;
}

static unsigned int xattr_item_hash(u8 prefix, char *buf,
				    unsigned int len[2], unsigned int hash[2])
{
	hash[0] = BKDRHash(buf, len[0]);	/* key */
	hash[1] = BKDRHash(buf + len[0], len[1]);	/* value */

	return prefix ^ hash[0] ^ hash[1];
}

static unsigned int put_xattritem(struct xattr_item *item)
{
	if (item->count > 1)
		return --item->count;
	free(item);
	return 0;
}

static struct xattr_item *get_xattritem(u8 prefix, char *kvbuf,
					unsigned int len[2])
{
	struct xattr_item *item;
	unsigned int hash[2], hkey;

	hkey = xattr_item_hash(prefix, kvbuf, len, hash);

	hash_for_each_possible(ea_hashtable, item, node, hkey) {
		if (prefix == item->prefix &&
		    item->len[0] == len[0] && item->len[1] == len[1] &&
		    item->hash[0] == hash[0] && item->hash[1] == hash[1] &&
		    !memcmp(kvbuf, item->kvbuf, len[0] + len[1])) {
			free(kvbuf);
			++item->count;
			return item;
		}
	}

	item = malloc(sizeof(*item));
	if (!item) {
		free(kvbuf);
		return ERR_PTR(-ENOMEM);
	}
	INIT_HLIST_NODE(&item->node);
	item->count = 1;
	item->kvbuf = kvbuf;
	item->len[0] = len[0];
	item->len[1] = len[1];
	item->hash[0] = hash[0];
	item->hash[1] = hash[1];
	item->shared_xattr_id = -1;
	item->prefix = prefix;
	hash_add(ea_hashtable, &item->node, hkey);
	return item;
}

static bool match_prefix(const char *key, u8 *index, u16 *len)
{
	struct xattr_prefix *p;

	for (p = xattr_types; p < xattr_types + ARRAY_SIZE(xattr_types); ++p) {
		if (p->prefix && !strncmp(p->prefix, key, p->prefix_len)) {
			*len = p->prefix_len;
			*index = p - xattr_types;
			return true;
		}
	}
	return false;
}

static struct xattr_item *parse_one_xattr(const char *path, const char *key,
					  unsigned int keylen)
{
	ssize_t ret;
	u8 prefix;
	u16 prefixlen;
	unsigned int len[2];
	char *kvbuf;

	erofs_dbg("parse xattr [%s] of %s", path, key);

	if (!match_prefix(key, &prefix, &prefixlen))
		return ERR_PTR(-ENODATA);

	DBG_BUGON(keylen < prefixlen);

	/* determine length of the value */
	ret = lgetxattr(path, key, NULL, 0);
	if (ret < 0)
		return ERR_PTR(-errno);
	len[1] = ret;

	/* allocate key-value buffer */
	len[0] = keylen - prefixlen;

	kvbuf = malloc(len[0] + len[1]);
	if (!kvbuf)
		return ERR_PTR(-ENOMEM);
	memcpy(kvbuf, key + prefixlen, len[0]);
	if (len[1]) {
		/* copy value to buffer */
		ret = lgetxattr(path, key, kvbuf + len[0], len[1]);
		if (ret < 0) {
			free(kvbuf);
			return ERR_PTR(-errno);
		}
		if (len[1] != ret) {
			erofs_err("size of xattr value got changed just now (%u-> %ld)",
				  len[1], (long)ret);
			len[1] = ret;
		}
	}
	return get_xattritem(prefix, kvbuf, len);
}

static struct xattr_item *erofs_get_selabel_xattr(const char *srcpath,
						  mode_t mode)
{
#ifdef HAVE_LIBSELINUX
	if (cfg.sehnd) {
		char *secontext;
		int ret;
		unsigned int len[2];
		char *kvbuf, *fspath;

#ifdef WITH_ANDROID
		if (cfg.mount_point)
			ret = asprintf(&fspath, "/%s/%s", cfg.mount_point,
				       erofs_fspath(srcpath));
		else
#endif
		ret = asprintf(&fspath, "/%s", erofs_fspath(srcpath));
		if (ret <= 0)
			return ERR_PTR(-ENOMEM);

		ret = selabel_lookup(cfg.sehnd, &secontext, fspath, mode);
		free(fspath);

		if (ret) {
			ret = -errno;
			if (ret != -ENOENT) {
				erofs_err("failed to lookup selabel for %s: %s",
					  srcpath, erofs_strerror(ret));
				return ERR_PTR(ret);
			}
			/* secontext = "u:object_r:unlabeled:s0"; */
			return NULL;
		}

		len[0] = sizeof("selinux") - 1;
		len[1] = strlen(secontext);
		kvbuf = malloc(len[0] + len[1] + 1);
		if (!kvbuf) {
			freecon(secontext);
			return ERR_PTR(-ENOMEM);
		}
		sprintf(kvbuf, "selinux%s", secontext);
		freecon(secontext);
		return get_xattritem(EROFS_XATTR_INDEX_SECURITY, kvbuf, len);
	}
#endif
	return NULL;
}

static int inode_xattr_add(struct list_head *hlist, struct xattr_item *item)
{
	struct inode_xattr_node *node = malloc(sizeof(*node));

	if (!node)
		return -ENOMEM;
	init_list_head(&node->list);
	node->item = item;
	list_add(&node->list, hlist);
	return 0;
}

static int shared_xattr_add(struct xattr_item *item)
{
	struct inode_xattr_node *node = malloc(sizeof(*node));

	if (!node)
		return -ENOMEM;

	init_list_head(&node->list);
	node->item = item;
	list_add(&node->list, &shared_xattrs_list);

	shared_xattrs_size += sizeof(struct erofs_xattr_entry);
	shared_xattrs_size = EROFS_XATTR_ALIGN(shared_xattrs_size +
					       item->len[0] + item->len[1]);
	return ++shared_xattrs_count;
}

static int erofs_xattr_add(struct list_head *ixattrs, struct xattr_item *item)
{
	if (ixattrs)
		return inode_xattr_add(ixattrs, item);

	if (item->count == cfg.c_inline_xattr_tolerance + 1) {
		int ret = shared_xattr_add(item);

		if (ret < 0)
			return ret;
	}
	return 0;
}

static bool erofs_is_skipped_xattr(const char *key)
{
#ifdef HAVE_LIBSELINUX
	/* if sehnd is valid, selabels will be overridden */
	if (cfg.sehnd && !strcmp(key, XATTR_SECURITY_PREFIX "selinux"))
		return true;
#endif
	return false;
}

static int read_xattrs_from_file(const char *path, mode_t mode,
				 struct list_head *ixattrs)
{
	ssize_t kllen = llistxattr(path, NULL, 0);
	int ret;
	char *keylst, *key, *klend;
	unsigned int keylen;
	struct xattr_item *item;

	if (kllen < 0 && errno != ENODATA) {
		erofs_err("llistxattr to get the size of names for %s failed",
			  path);
		return -errno;
	}

	ret = 0;
	if (kllen <= 1)
		goto out;

	keylst = malloc(kllen);
	if (!keylst)
		return -ENOMEM;

	/* copy the list of attribute keys to the buffer.*/
	kllen = llistxattr(path, keylst, kllen);
	if (kllen < 0) {
		erofs_err("llistxattr to get names for %s failed", path);
		ret = -errno;
		goto err;
	}

	/*
	 * loop over the list of zero terminated strings with the
	 * attribute keys. Use the remaining buffer length to determine
	 * the end of the list.
	 */
	klend = keylst + kllen;
	ret = 0;

	for (key = keylst; key != klend; key += keylen + 1) {
		keylen = strlen(key);
		if (erofs_is_skipped_xattr(key))
			continue;

		item = parse_one_xattr(path, key, keylen);
		if (IS_ERR(item)) {
			ret = PTR_ERR(item);
			goto err;
		}

		ret = erofs_xattr_add(ixattrs, item);
		if (ret < 0)
			goto err;
	}
	free(keylst);

out:
	/* if some selabel is avilable, need to add right now */
	item = erofs_get_selabel_xattr(path, mode);
	if (IS_ERR(item))
		return PTR_ERR(item);
	if (item)
		ret = erofs_xattr_add(ixattrs, item);
	return ret;

err:
	free(keylst);
	return ret;
}

#ifdef WITH_ANDROID
static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
{
	const u64 capabilities = inode->capabilities;
	char *kvbuf;
	unsigned int len[2];
	struct vfs_cap_data caps;
	struct xattr_item *item;

	if (!capabilities)
		return 0;

	len[0] = sizeof("capability") - 1;
	len[1] = sizeof(caps);

	kvbuf = malloc(len[0] + len[1]);
	if (!kvbuf)
		return -ENOMEM;

	memcpy(kvbuf, "capability", len[0]);
	caps.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE;
	caps.data[0].permitted = (u32) capabilities;
	caps.data[0].inheritable = 0;
	caps.data[1].permitted = (u32) (capabilities >> 32);
	caps.data[1].inheritable = 0;
	memcpy(kvbuf + len[0], &caps, len[1]);

	item = get_xattritem(EROFS_XATTR_INDEX_SECURITY, kvbuf, len);
	if (IS_ERR(item))
		return PTR_ERR(item);
	if (!item)
		return 0;

	return erofs_xattr_add(&inode->i_xattrs, item);
}
#else
static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
{
	return 0;
}
#endif

int erofs_prepare_xattr_ibody(struct erofs_inode *inode)
{
	int ret;
	struct inode_xattr_node *node;
	struct list_head *ixattrs = &inode->i_xattrs;

	/* check if xattr is disabled */
	if (cfg.c_inline_xattr_tolerance < 0)
		return 0;

	ret = read_xattrs_from_file(inode->i_srcpath, inode->i_mode, ixattrs);
	if (ret < 0)
		return ret;

	ret = erofs_droid_xattr_set_caps(inode);
	if (ret < 0)
		return ret;

	if (list_empty(ixattrs))
		return 0;

	/* get xattr ibody size */
	ret = sizeof(struct erofs_xattr_ibody_header);
	list_for_each_entry(node, ixattrs, list) {
		const struct xattr_item *item = node->item;

		if (item->shared_xattr_id >= 0) {
			ret += sizeof(__le32);
			continue;
		}
		ret += sizeof(struct erofs_xattr_entry);
		ret = EROFS_XATTR_ALIGN(ret + item->len[0] + item->len[1]);
	}
	inode->xattr_isize = ret;
	return ret;
}

static int erofs_count_all_xattrs_from_path(const char *path)
{
	int ret;
	DIR *_dir;
	struct stat64 st;

	_dir = opendir(path);
	if (!_dir) {
		erofs_err("%s, failed to opendir at %s: %s",
			  __func__, path, erofs_strerror(errno));
		return -errno;
	}

	ret = 0;
	while (1) {
		struct dirent *dp;
		char buf[PATH_MAX];

		/*
		 * set errno to 0 before calling readdir() in order to
		 * distinguish end of stream and from an error.
		 */
		errno = 0;
		dp = readdir(_dir);
		if (!dp)
			break;

		if (is_dot_dotdot(dp->d_name) ||
		    !strncmp(dp->d_name, "lost+found", strlen("lost+found")))
			continue;

		ret = snprintf(buf, PATH_MAX, "%s/%s", path, dp->d_name);

		if (ret < 0 || ret >= PATH_MAX) {
			/* ignore the too long path */
			ret = -ENOMEM;
			goto fail;
		}

		ret = lstat64(buf, &st);
		if (ret) {
			ret = -errno;
			goto fail;
		}

		ret = read_xattrs_from_file(buf, st.st_mode, NULL);
		if (ret)
			goto fail;

		if (!S_ISDIR(st.st_mode))
			continue;

		ret = erofs_count_all_xattrs_from_path(buf);
		if (ret)
			goto fail;
	}

	if (errno)
		ret = -errno;

fail:
	closedir(_dir);
	return ret;
}

static void erofs_cleanxattrs(bool sharedxattrs)
{
	unsigned int i;
	struct xattr_item *item;
	struct hlist_node *tmp;

	hash_for_each_safe(ea_hashtable, i, tmp, item, node) {
		if (sharedxattrs && item->shared_xattr_id >= 0)
			continue;

		hash_del(&item->node);
		free(item);
	}

	if (sharedxattrs)
		return;

	shared_xattrs_size = shared_xattrs_count = 0;
}

static bool erofs_bh_flush_write_shared_xattrs(struct erofs_buffer_head *bh)
{
	void *buf = bh->fsprivate;
	int err = dev_write(buf, erofs_btell(bh, false), shared_xattrs_size);

	if (err)
		return false;
	free(buf);
	return erofs_bh_flush_generic_end(bh);
}

static struct erofs_bhops erofs_write_shared_xattrs_bhops = {
	.flush = erofs_bh_flush_write_shared_xattrs,
};

int erofs_build_shared_xattrs_from_path(const char *path)
{
	int ret;
	struct erofs_buffer_head *bh;
	struct inode_xattr_node *node, *n;
	char *buf;
	unsigned int p;
	erofs_off_t off;

	/* check if xattr or shared xattr is disabled */
	if (cfg.c_inline_xattr_tolerance < 0 ||
	    cfg.c_inline_xattr_tolerance == INT_MAX)
		return 0;

	if (shared_xattrs_size || shared_xattrs_count) {
		DBG_BUGON(1);
		return -EINVAL;
	}

	ret = erofs_count_all_xattrs_from_path(path);
	if (ret)
		return ret;

	if (!shared_xattrs_size)
		goto out;

	buf = calloc(1, shared_xattrs_size);
	if (!buf)
		return -ENOMEM;

	bh = erofs_balloc(XATTR, shared_xattrs_size, 0, 0);
	if (IS_ERR(bh)) {
		free(buf);
		return PTR_ERR(bh);
	}
	bh->op = &erofs_skip_write_bhops;

	erofs_mapbh(bh->block, true);
	off = erofs_btell(bh, false);

	sbi.xattr_blkaddr = off / EROFS_BLKSIZ;
	off %= EROFS_BLKSIZ;
	p = 0;

	list_for_each_entry_safe(node, n, &shared_xattrs_list, list) {
		struct xattr_item *const item = node->item;
		const struct erofs_xattr_entry entry = {
			.e_name_index = item->prefix,
			.e_name_len = item->len[0],
			.e_value_size = cpu_to_le16(item->len[1])
		};

		list_del(&node->list);

		item->shared_xattr_id = (off + p) /
			sizeof(struct erofs_xattr_entry);

		memcpy(buf + p, &entry, sizeof(entry));
		p += sizeof(struct erofs_xattr_entry);
		memcpy(buf + p, item->kvbuf, item->len[0] + item->len[1]);
		p = EROFS_XATTR_ALIGN(p + item->len[0] + item->len[1]);
		free(node);
	}
	bh->fsprivate = buf;
	bh->op = &erofs_write_shared_xattrs_bhops;
out:
	erofs_cleanxattrs(true);
	return 0;
}

char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
{
	struct inode_xattr_node *node, *n;
	struct erofs_xattr_ibody_header *header;
	LIST_HEAD(ilst);
	unsigned int p;
	char *buf = calloc(1, size);

	if (!buf)
		return ERR_PTR(-ENOMEM);

	header = (struct erofs_xattr_ibody_header *)buf;
	header->h_shared_count = 0;

	p = sizeof(struct erofs_xattr_ibody_header);
	list_for_each_entry_safe(node, n, ixattrs, list) {
		struct xattr_item *const item = node->item;

		list_del(&node->list);

		/* move inline xattrs to the onstack list */
		if (item->shared_xattr_id < 0) {
			list_add(&node->list, &ilst);
			continue;
		}

		*(__le32 *)(buf + p) = cpu_to_le32(item->shared_xattr_id);
		p += sizeof(__le32);
		++header->h_shared_count;
		free(node);
		put_xattritem(item);
	}

	list_for_each_entry_safe(node, n, &ilst, list) {
		struct xattr_item *const item = node->item;
		const struct erofs_xattr_entry entry = {
			.e_name_index = item->prefix,
			.e_name_len = item->len[0],
			.e_value_size = cpu_to_le16(item->len[1])
		};

		memcpy(buf + p, &entry, sizeof(entry));
		p += sizeof(struct erofs_xattr_entry);
		memcpy(buf + p, item->kvbuf, item->len[0] + item->len[1]);
		p = EROFS_XATTR_ALIGN(p + item->len[0] + item->len[1]);

		list_del(&node->list);
		free(node);
		put_xattritem(item);
	}
	DBG_BUGON(p > size);
	return buf;
}

