// 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;
	const struct cred *old_cred;

	if (!value && !upperdentry) {
		ovl_path_lower(dentry, &realpath);
		old_cred = ovl_override_creds(dentry->d_sb);
		err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0);
		revert_creds(old_cred);
		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;

	old_cred = ovl_override_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);
	}
	revert_creds(old_cred);
	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)
{
	ssize_t res;
	const struct cred *old_cred;
	struct path realpath;

	ovl_i_path_real(inode, &realpath);
	old_cred = ovl_override_creds(dentry->d_sb);
	res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size);
	revert_creds(old_cred);
	return res;
}

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;
	const struct cred *old_cred;
	size_t prefix_len, name_len;

	old_cred = ovl_override_creds(dentry->d_sb);
	res = vfs_listxattr(realdentry, list, size);
	revert_creds(old_cred);
	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;
}

