// SPDX-License-Identifier: GPL-2.0-only

#include <linux/fs.h>
#include <linux/xattr.h>
#include "overlayfs.h"

static bool ovl_is_escaped_xattr(struct super_block *sb, const char *name)
{
	struct ovl_fs *ofs = sb->s_fs_info;

	if (ofs->config.userxattr)
		return strncmp(name, OVL_XATTR_ESCAPE_USER_PREFIX,
			       OVL_XATTR_ESCAPE_USER_PREFIX_LEN) == 0;
	else
		return strncmp(name, OVL_XATTR_ESCAPE_TRUSTED_PREFIX,
			       OVL_XATTR_ESCAPE_TRUSTED_PREFIX_LEN - 1) == 0;
}

static bool ovl_is_own_xattr(struct super_block *sb, const char *name)
{
	struct ovl_fs *ofs = OVL_FS(sb);

	if (ofs->config.userxattr)
		return strncmp(name, OVL_XATTR_USER_PREFIX,
			       OVL_XATTR_USER_PREFIX_LEN) == 0;
	else
		return strncmp(name, OVL_XATTR_TRUSTED_PREFIX,
			       OVL_XATTR_TRUSTED_PREFIX_LEN) == 0;
}

bool ovl_is_private_xattr(struct super_block *sb, const char *name)
{
	return ovl_is_own_xattr(sb, name) && !ovl_is_escaped_xattr(sb, name);
}

static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
			 const void *value, size_t size, int flags)
{
	int err;
	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
	struct dentry *upperdentry = ovl_i_dentry_upper(inode);
	struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry);
	struct path realpath;

	if (!value && !upperdentry) {
		ovl_path_lower(dentry, &realpath);
		with_ovl_creds(dentry->d_sb)
			err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0);
		if (err < 0)
			goto out;
	}

	if (!upperdentry) {
		err = ovl_copy_up(dentry);
		if (err)
			goto out;

		realdentry = ovl_dentry_upper(dentry);
	}

	err = ovl_want_write(dentry);
	if (err)
		goto out;

	with_ovl_creds(dentry->d_sb) {
		if (value) {
			err = ovl_do_setxattr(ofs, realdentry, name, value, size, flags);
		} else {
			WARN_ON(flags != XATTR_REPLACE);
			err = ovl_do_removexattr(ofs, realdentry, name);
		}
	}
	ovl_drop_write(dentry);

	/* copy c/mtime */
	ovl_copyattr(inode);
out:
	return err;
}

static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
			 void *value, size_t size)
{
	struct path realpath;

	ovl_i_path_real(inode, &realpath);
	with_ovl_creds(dentry->d_sb)
		return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size);
}

static bool ovl_can_list(struct super_block *sb, const char *s)
{
	/* Never list private (.overlay) */
	if (ovl_is_private_xattr(sb, s))
		return false;

	/* List all non-trusted xattrs */
	if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
		return true;

	/* list other trusted for superuser only */
	return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
}

ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
{
	struct dentry *realdentry = ovl_dentry_real(dentry);
	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
	ssize_t res;
	size_t len;
	char *s;
	size_t prefix_len, name_len;

	with_ovl_creds(dentry->d_sb)
		res = vfs_listxattr(realdentry, list, size);
	if (res <= 0 || size == 0)
		return res;

	prefix_len = ofs->config.userxattr ?
		OVL_XATTR_USER_PREFIX_LEN : OVL_XATTR_TRUSTED_PREFIX_LEN;

	/* filter out private xattrs */
	for (s = list, len = res; len;) {
		size_t slen = strnlen(s, len) + 1;

		/* underlying fs providing us with an broken xattr list? */
		if (WARN_ON(slen > len))
			return -EIO;

		len -= slen;
		if (!ovl_can_list(dentry->d_sb, s)) {
			res -= slen;
			memmove(s, s + slen, len);
		} else if (ovl_is_escaped_xattr(dentry->d_sb, s)) {
			res -= OVL_XATTR_ESCAPE_PREFIX_LEN;
			name_len = slen - prefix_len - OVL_XATTR_ESCAPE_PREFIX_LEN;
			s += prefix_len;
			memmove(s, s + OVL_XATTR_ESCAPE_PREFIX_LEN, name_len + len);
			s += name_len;
		} else {
			s += slen;
		}
	}

	return res;
}

static char *ovl_xattr_escape_name(const char *prefix, const char *name)
{
	size_t prefix_len = strlen(prefix);
	size_t name_len = strlen(name);
	size_t escaped_len;
	char *escaped, *s;

	escaped_len = prefix_len + OVL_XATTR_ESCAPE_PREFIX_LEN + name_len;
	if (escaped_len > XATTR_NAME_MAX)
		return ERR_PTR(-EOPNOTSUPP);

	escaped = kmalloc(escaped_len + 1, GFP_KERNEL);
	if (escaped == NULL)
		return ERR_PTR(-ENOMEM);

	s = escaped;
	memcpy(s, prefix, prefix_len);
	s += prefix_len;
	memcpy(s, OVL_XATTR_ESCAPE_PREFIX, OVL_XATTR_ESCAPE_PREFIX_LEN);
	s += OVL_XATTR_ESCAPE_PREFIX_LEN;
	memcpy(s, name, name_len + 1);

	return escaped;
}

static int ovl_own_xattr_get(const struct xattr_handler *handler,
			     struct dentry *dentry, struct inode *inode,
			     const char *name, void *buffer, size_t size)
{
	char *escaped;
	int r;

	escaped = ovl_xattr_escape_name(handler->prefix, name);
	if (IS_ERR(escaped))
		return PTR_ERR(escaped);

	r = ovl_xattr_get(dentry, inode, escaped, buffer, size);

	kfree(escaped);

	return r;
}

static int ovl_own_xattr_set(const struct xattr_handler *handler,
			     struct mnt_idmap *idmap,
			     struct dentry *dentry, struct inode *inode,
			     const char *name, const void *value,
			     size_t size, int flags)
{
	char *escaped;
	int r;

	escaped = ovl_xattr_escape_name(handler->prefix, name);
	if (IS_ERR(escaped))
		return PTR_ERR(escaped);

	r = ovl_xattr_set(dentry, inode, escaped, value, size, flags);

	kfree(escaped);

	return r;
}

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 mnt_idmap *idmap,
			       struct dentry *dentry, struct inode *inode,
			       const char *name, const void *value,
			       size_t size, int flags)
{
	return ovl_xattr_set(dentry, inode, name, value, size, flags);
}

static const struct xattr_handler ovl_own_trusted_xattr_handler = {
	.prefix	= OVL_XATTR_TRUSTED_PREFIX,
	.get = ovl_own_xattr_get,
	.set = ovl_own_xattr_set,
};

static const struct xattr_handler ovl_own_user_xattr_handler = {
	.prefix	= OVL_XATTR_USER_PREFIX,
	.get = ovl_own_xattr_get,
	.set = ovl_own_xattr_set,
};

static const struct xattr_handler ovl_other_xattr_handler = {
	.prefix	= "", /* catch all */
	.get = ovl_other_xattr_get,
	.set = ovl_other_xattr_set,
};

static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = {
	&ovl_own_trusted_xattr_handler,
	&ovl_other_xattr_handler,
	NULL
};

static const struct xattr_handler * const ovl_user_xattr_handlers[] = {
	&ovl_own_user_xattr_handler,
	&ovl_other_xattr_handler,
	NULL
};

const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs)
{
	return ofs->config.userxattr ? ovl_user_xattr_handlers :
		ovl_trusted_xattr_handlers;
}
