// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
 */

#include <linux/errno.h>
#include <linux/verification.h>

#include "ipe.h"
#include "eval.h"
#include "fs.h"
#include "policy.h"
#include "policy_parser.h"
#include "audit.h"

/* lock for synchronizing writers across ipe policy */
DEFINE_MUTEX(ipe_policy_lock);

/**
 * ver_to_u64() - Convert an internal ipe_policy_version to a u64.
 * @p: Policy to extract the version from.
 *
 * Bits (LSB is index 0):
 *	[48,32] -> Major
 *	[32,16] -> Minor
 *	[16, 0] -> Revision
 *
 * Return: u64 version of the embedded version structure.
 */
static inline u64 ver_to_u64(const struct ipe_policy *const p)
{
	u64 r;

	r = (((u64)p->parsed->version.major) << 32)
	  | (((u64)p->parsed->version.minor) << 16)
	  | ((u64)(p->parsed->version.rev));

	return r;
}

/**
 * ipe_free_policy() - Deallocate a given IPE policy.
 * @p: Supplies the policy to free.
 *
 * Safe to call on IS_ERR/NULL.
 */
void ipe_free_policy(struct ipe_policy *p)
{
	if (IS_ERR_OR_NULL(p))
		return;

	ipe_del_policyfs_node(p);
	ipe_free_parsed_policy(p->parsed);
	/*
	 * p->text is allocated only when p->pkcs7 is not NULL
	 * otherwise it points to the plaintext data inside the pkcs7
	 */
	if (!p->pkcs7)
		kfree(p->text);
	kfree(p->pkcs7);
	kfree(p);
}

static int set_pkcs7_data(void *ctx, const void *data, size_t len,
			  size_t asn1hdrlen __always_unused)
{
	struct ipe_policy *p = ctx;

	p->text = (const char *)data;
	p->textlen = len;

	return 0;
}

/**
 * ipe_update_policy() - parse a new policy and replace old with it.
 * @root: Supplies a pointer to the securityfs inode saved the policy.
 * @text: Supplies a pointer to the plain text policy.
 * @textlen: Supplies the length of @text.
 * @pkcs7: Supplies a pointer to a buffer containing a pkcs7 message.
 * @pkcs7len: Supplies the length of @pkcs7len.
 *
 * @text/@textlen is mutually exclusive with @pkcs7/@pkcs7len - see
 * ipe_new_policy.
 *
 * Context: Requires root->i_rwsem to be held.
 * Return: %0 on success. If an error occurs, the function will return
 * the -errno.
 */
int ipe_update_policy(struct inode *root, const char *text, size_t textlen,
		      const char *pkcs7, size_t pkcs7len)
{
	struct ipe_policy *old, *ap, *new = NULL;
	int rc = 0;

	old = (struct ipe_policy *)root->i_private;
	if (!old)
		return -ENOENT;

	new = ipe_new_policy(text, textlen, pkcs7, pkcs7len);
	if (IS_ERR(new))
		return PTR_ERR(new);

	if (strcmp(new->parsed->name, old->parsed->name)) {
		rc = -EINVAL;
		goto err;
	}

	if (ver_to_u64(old) > ver_to_u64(new)) {
		rc = -EINVAL;
		goto err;
	}

	root->i_private = new;
	swap(new->policyfs, old->policyfs);
	ipe_audit_policy_load(new);

	mutex_lock(&ipe_policy_lock);
	ap = rcu_dereference_protected(ipe_active_policy,
				       lockdep_is_held(&ipe_policy_lock));
	if (old == ap) {
		rcu_assign_pointer(ipe_active_policy, new);
		mutex_unlock(&ipe_policy_lock);
		ipe_audit_policy_activation(old, new);
	} else {
		mutex_unlock(&ipe_policy_lock);
	}
	synchronize_rcu();
	ipe_free_policy(old);

	return 0;
err:
	ipe_free_policy(new);
	return rc;
}

/**
 * ipe_new_policy() - Allocate and parse an ipe_policy structure.
 *
 * @text: Supplies a pointer to the plain-text policy to parse.
 * @textlen: Supplies the length of @text.
 * @pkcs7: Supplies a pointer to a pkcs7-signed IPE policy.
 * @pkcs7len: Supplies the length of @pkcs7.
 *
 * @text/@textlen Should be NULL/0 if @pkcs7/@pkcs7len is set.
 *
 * Return:
 * * a pointer to the ipe_policy structure	- Success
 * * %-EBADMSG					- Policy is invalid
 * * %-ENOMEM					- Out of memory (OOM)
 * * %-ERANGE					- Policy version number overflow
 * * %-EINVAL					- Policy version parsing error
 */
struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
				  const char *pkcs7, size_t pkcs7len)
{
	struct ipe_policy *new = NULL;
	int rc = 0;

	new = kzalloc(sizeof(*new), GFP_KERNEL);
	if (!new)
		return ERR_PTR(-ENOMEM);

	if (!text) {
		new->pkcs7len = pkcs7len;
		new->pkcs7 = kmemdup(pkcs7, pkcs7len, GFP_KERNEL);
		if (!new->pkcs7) {
			rc = -ENOMEM;
			goto err;
		}

		rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len, NULL,
					    VERIFYING_UNSPECIFIED_SIGNATURE,
					    set_pkcs7_data, new);
		if (rc)
			goto err;
	} else {
		new->textlen = textlen;
		new->text = kstrdup(text, GFP_KERNEL);
		if (!new->text) {
			rc = -ENOMEM;
			goto err;
		}
	}

	rc = ipe_parse_policy(new);
	if (rc)
		goto err;

	return new;
err:
	ipe_free_policy(new);
	return ERR_PTR(rc);
}

/**
 * ipe_set_active_pol() - Make @p the active policy.
 * @p: Supplies a pointer to the policy to make active.
 *
 * Context: Requires root->i_rwsem, which i_private has the policy, to be held.
 * Return:
 * * %0	- Success
 * * %-EINVAL	- New active policy version is invalid
 */
int ipe_set_active_pol(const struct ipe_policy *p)
{
	struct ipe_policy *ap = NULL;

	mutex_lock(&ipe_policy_lock);

	ap = rcu_dereference_protected(ipe_active_policy,
				       lockdep_is_held(&ipe_policy_lock));
	if (ap == p) {
		mutex_unlock(&ipe_policy_lock);
		return 0;
	}
	if (ap && ver_to_u64(ap) > ver_to_u64(p)) {
		mutex_unlock(&ipe_policy_lock);
		return -EINVAL;
	}

	rcu_assign_pointer(ipe_active_policy, p);
	ipe_audit_policy_activation(ap, p);
	mutex_unlock(&ipe_policy_lock);

	return 0;
}
