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

#include <linux/err.h>
#include <linux/slab.h>
#include <linux/parser.h>
#include <linux/types.h>
#include <linux/ctype.h>

#include "policy.h"
#include "policy_parser.h"
#include "digest.h"

#define START_COMMENT	'#'
#define IPE_POLICY_DELIM " \t"
#define IPE_LINE_DELIM "\n\r"

/**
 * new_parsed_policy() - Allocate and initialize a parsed policy.
 *
 * Return:
 * * a pointer to the ipe_parsed_policy structure	- Success
 * * %-ENOMEM						- Out of memory (OOM)
 */
static struct ipe_parsed_policy *new_parsed_policy(void)
{
	struct ipe_parsed_policy *p = NULL;
	struct ipe_op_table *t = NULL;
	size_t i = 0;

	p = kzalloc_obj(*p);
	if (!p)
		return ERR_PTR(-ENOMEM);

	p->global_default_action = IPE_ACTION_INVALID;

	for (i = 0; i < ARRAY_SIZE(p->rules); ++i) {
		t = &p->rules[i];

		t->default_action = IPE_ACTION_INVALID;
		INIT_LIST_HEAD(&t->rules);
	}

	return p;
}

/**
 * remove_comment() - Truncate all chars following START_COMMENT in a string.
 *
 * @line: Supplies a policy line string for preprocessing.
 */
static void remove_comment(char *line)
{
	line = strchr(line, START_COMMENT);

	if (line)
		*line = '\0';
}

/**
 * remove_trailing_spaces() - Truncate all trailing spaces in a string.
 *
 * @line: Supplies a policy line string for preprocessing.
 *
 * Return: The length of truncated string.
 */
static size_t remove_trailing_spaces(char *line)
{
	size_t i = 0;

	i = strlen(line);
	while (i > 0 && isspace(line[i - 1]))
		i--;

	line[i] = '\0';

	return i;
}

/**
 * parse_version() - Parse policy version.
 * @ver: Supplies a version string to be parsed.
 * @p: Supplies the partial parsed policy.
 *
 * Return:
 * * %0		- Success
 * * %-EBADMSG	- Version string is invalid
 * * %-ERANGE	- Version number overflow
 * * %-EINVAL	- Parsing error
 */
static int parse_version(char *ver, struct ipe_parsed_policy *p)
{
	u16 *const cv[] = { &p->version.major, &p->version.minor, &p->version.rev };
	size_t sep_count = 0;
	char *token;
	int rc = 0;

	while ((token = strsep(&ver, ".")) != NULL) {
		/* prevent overflow */
		if (sep_count >= ARRAY_SIZE(cv))
			return -EBADMSG;

		rc = kstrtou16(token, 10, cv[sep_count]);
		if (rc)
			return rc;

		++sep_count;
	}

	/* prevent underflow */
	if (sep_count != ARRAY_SIZE(cv))
		return -EBADMSG;

	return 0;
}

enum header_opt {
	IPE_HEADER_POLICY_NAME = 0,
	IPE_HEADER_POLICY_VERSION,
	__IPE_HEADER_MAX
};

static const match_table_t header_tokens = {
	{IPE_HEADER_POLICY_NAME,	"policy_name=%s"},
	{IPE_HEADER_POLICY_VERSION,	"policy_version=%s"},
	{__IPE_HEADER_MAX,		NULL}
};

/**
 * parse_header() - Parse policy header information.
 * @line: Supplies header line to be parsed.
 * @p: Supplies the partial parsed policy.
 *
 * Return:
 * * %0		- Success
 * * %-EBADMSG	- Header string is invalid
 * * %-ENOMEM	- Out of memory (OOM)
 * * %-ERANGE	- Version number overflow
 * * %-EINVAL	- Version parsing error
 */
static int parse_header(char *line, struct ipe_parsed_policy *p)
{
	substring_t args[MAX_OPT_ARGS];
	char *t, *ver = NULL;
	size_t idx = 0;
	int rc = 0;

	while ((t = strsep(&line, IPE_POLICY_DELIM)) != NULL) {
		int token;

		if (*t == '\0')
			continue;
		if (idx >= __IPE_HEADER_MAX) {
			rc = -EBADMSG;
			goto out;
		}

		token = match_token(t, header_tokens, args);
		if (token != idx) {
			rc = -EBADMSG;
			goto out;
		}

		switch (token) {
		case IPE_HEADER_POLICY_NAME:
			p->name = match_strdup(&args[0]);
			if (!p->name)
				rc = -ENOMEM;
			break;
		case IPE_HEADER_POLICY_VERSION:
			ver = match_strdup(&args[0]);
			if (!ver) {
				rc = -ENOMEM;
				break;
			}
			rc = parse_version(ver, p);
			break;
		default:
			rc = -EBADMSG;
		}
		if (rc)
			goto out;
		++idx;
	}

	if (idx != __IPE_HEADER_MAX)
		rc = -EBADMSG;

out:
	kfree(ver);
	return rc;
}

/**
 * token_default() - Determine if the given token is "DEFAULT".
 * @token: Supplies the token string to be compared.
 *
 * Return:
 * * %false	- The token is not "DEFAULT"
 * * %true	- The token is "DEFAULT"
 */
static bool token_default(char *token)
{
	return !strcmp(token, "DEFAULT");
}

/**
 * free_rule() - Free the supplied ipe_rule struct.
 * @r: Supplies the ipe_rule struct to be freed.
 *
 * Free a ipe_rule struct @r. Note @r must be removed from any lists before
 * calling this function.
 */
static void free_rule(struct ipe_rule *r)
{
	struct ipe_prop *p, *t;

	if (IS_ERR_OR_NULL(r))
		return;

	list_for_each_entry_safe(p, t, &r->props, next) {
		list_del(&p->next);
		ipe_digest_free(p->value);
		kfree(p);
	}

	kfree(r);
}

static const match_table_t operation_tokens = {
	{IPE_OP_EXEC,			"op=EXECUTE"},
	{IPE_OP_FIRMWARE,		"op=FIRMWARE"},
	{IPE_OP_KERNEL_MODULE,		"op=KMODULE"},
	{IPE_OP_KEXEC_IMAGE,		"op=KEXEC_IMAGE"},
	{IPE_OP_KEXEC_INITRAMFS,	"op=KEXEC_INITRAMFS"},
	{IPE_OP_POLICY,			"op=POLICY"},
	{IPE_OP_X509,			"op=X509_CERT"},
	{IPE_OP_INVALID,		NULL}
};

/**
 * parse_operation() - Parse the operation type given a token string.
 * @t: Supplies the token string to be parsed.
 *
 * Return: The parsed operation type.
 */
static enum ipe_op_type parse_operation(char *t)
{
	substring_t args[MAX_OPT_ARGS];

	return match_token(t, operation_tokens, args);
}

static const match_table_t action_tokens = {
	{IPE_ACTION_ALLOW,	"action=ALLOW"},
	{IPE_ACTION_DENY,	"action=DENY"},
	{IPE_ACTION_INVALID,	NULL}
};

/**
 * parse_action() - Parse the action type given a token string.
 * @t: Supplies the token string to be parsed.
 *
 * Return: The parsed action type.
 */
static enum ipe_action_type parse_action(char *t)
{
	substring_t args[MAX_OPT_ARGS];

	return match_token(t, action_tokens, args);
}

static const match_table_t property_tokens = {
	{IPE_PROP_BOOT_VERIFIED_FALSE,	"boot_verified=FALSE"},
	{IPE_PROP_BOOT_VERIFIED_TRUE,	"boot_verified=TRUE"},
	{IPE_PROP_DMV_ROOTHASH,		"dmverity_roothash=%s"},
	{IPE_PROP_DMV_SIG_FALSE,	"dmverity_signature=FALSE"},
	{IPE_PROP_DMV_SIG_TRUE,		"dmverity_signature=TRUE"},
	{IPE_PROP_FSV_DIGEST,		"fsverity_digest=%s"},
	{IPE_PROP_FSV_SIG_FALSE,	"fsverity_signature=FALSE"},
	{IPE_PROP_FSV_SIG_TRUE,		"fsverity_signature=TRUE"},
	{IPE_PROP_INVALID,		NULL}
};

/**
 * parse_property() - Parse a rule property given a token string.
 * @t: Supplies the token string to be parsed.
 * @r: Supplies the ipe_rule the parsed property will be associated with.
 *
 * This function parses and associates a property with an IPE rule based
 * on a token string.
 *
 * Return:
 * * %0		- Success
 * * %-ENOMEM	- Out of memory (OOM)
 * * %-EBADMSG	- The supplied token cannot be parsed
 */
static int parse_property(char *t, struct ipe_rule *r)
{
	substring_t args[MAX_OPT_ARGS];
	struct ipe_prop *p = NULL;
	int rc = 0;
	int token;
	char *dup = NULL;

	p = kzalloc_obj(*p);
	if (!p)
		return -ENOMEM;

	token = match_token(t, property_tokens, args);

	switch (token) {
	case IPE_PROP_DMV_ROOTHASH:
	case IPE_PROP_FSV_DIGEST:
		dup = match_strdup(&args[0]);
		if (!dup) {
			rc = -ENOMEM;
			goto err;
		}
		p->value = ipe_digest_parse(dup);
		if (IS_ERR(p->value)) {
			rc = PTR_ERR(p->value);
			goto err;
		}
		fallthrough;
	case IPE_PROP_BOOT_VERIFIED_FALSE:
	case IPE_PROP_BOOT_VERIFIED_TRUE:
	case IPE_PROP_DMV_SIG_FALSE:
	case IPE_PROP_DMV_SIG_TRUE:
	case IPE_PROP_FSV_SIG_FALSE:
	case IPE_PROP_FSV_SIG_TRUE:
		p->type = token;
		break;
	default:
		rc = -EBADMSG;
		break;
	}
	if (rc)
		goto err;
	list_add_tail(&p->next, &r->props);

out:
	kfree(dup);
	return rc;
err:
	kfree(p);
	goto out;
}

/**
 * parse_rule() - parse a policy rule line.
 * @line: Supplies rule line to be parsed.
 * @p: Supplies the partial parsed policy.
 *
 * Return:
 * * 0		- Success
 * * %-ENOMEM	- Out of memory (OOM)
 * * %-EBADMSG	- Policy syntax error
 */
static int parse_rule(char *line, struct ipe_parsed_policy *p)
{
	enum ipe_action_type action = IPE_ACTION_INVALID;
	enum ipe_op_type op = IPE_OP_INVALID;
	bool is_default_rule = false;
	struct ipe_rule *r = NULL;
	bool first_token = true;
	bool op_parsed = false;
	int rc = 0;
	char *t;

	if (IS_ERR_OR_NULL(line))
		return -EBADMSG;

	r = kzalloc_obj(*r);
	if (!r)
		return -ENOMEM;

	INIT_LIST_HEAD(&r->next);
	INIT_LIST_HEAD(&r->props);

	while (t = strsep(&line, IPE_POLICY_DELIM), line) {
		if (*t == '\0')
			continue;
		if (first_token && token_default(t)) {
			is_default_rule = true;
		} else {
			if (!op_parsed) {
				op = parse_operation(t);
				if (op == IPE_OP_INVALID)
					rc = -EBADMSG;
				else
					op_parsed = true;
			} else {
				rc = parse_property(t, r);
			}
		}

		if (rc)
			goto err;
		first_token = false;
	}

	action = parse_action(t);
	if (action == IPE_ACTION_INVALID) {
		rc = -EBADMSG;
		goto err;
	}

	if (is_default_rule) {
		if (!list_empty(&r->props)) {
			rc = -EBADMSG;
		} else if (op == IPE_OP_INVALID) {
			if (p->global_default_action != IPE_ACTION_INVALID)
				rc = -EBADMSG;
			else
				p->global_default_action = action;
		} else {
			if (p->rules[op].default_action != IPE_ACTION_INVALID)
				rc = -EBADMSG;
			else
				p->rules[op].default_action = action;
		}
	} else if (op != IPE_OP_INVALID && action != IPE_ACTION_INVALID) {
		r->op = op;
		r->action = action;
	} else {
		rc = -EBADMSG;
	}

	if (rc)
		goto err;
	if (!is_default_rule)
		list_add_tail(&r->next, &p->rules[op].rules);
	else
		free_rule(r);

	return rc;
err:
	free_rule(r);
	return rc;
}

/**
 * ipe_free_parsed_policy() - free a parsed policy structure.
 * @p: Supplies the parsed policy.
 */
void ipe_free_parsed_policy(struct ipe_parsed_policy *p)
{
	struct ipe_rule *pp, *t;
	size_t i = 0;

	if (IS_ERR_OR_NULL(p))
		return;

	for (i = 0; i < ARRAY_SIZE(p->rules); ++i)
		list_for_each_entry_safe(pp, t, &p->rules[i].rules, next) {
			list_del(&pp->next);
			free_rule(pp);
		}

	kfree(p->name);
	kfree(p);
}

/**
 * validate_policy() - validate a parsed policy.
 * @p: Supplies the fully parsed policy.
 *
 * Given a policy structure that was just parsed, validate that all
 * operations have their default rules or a global default rule is set.
 *
 * Return:
 * * %0		- Success
 * * %-EBADMSG	- Policy is invalid
 */
static int validate_policy(const struct ipe_parsed_policy *p)
{
	size_t i = 0;

	if (p->global_default_action != IPE_ACTION_INVALID)
		return 0;

	for (i = 0; i < ARRAY_SIZE(p->rules); ++i) {
		if (p->rules[i].default_action == IPE_ACTION_INVALID)
			return -EBADMSG;
	}

	return 0;
}

/**
 * ipe_parse_policy() - Given a string, parse the string into an IPE policy.
 * @p: partially filled ipe_policy structure to populate with the result.
 *     it must have text and textlen set.
 *
 * Return:
 * * %0		- Success
 * * %-EBADMSG	- Policy is invalid
 * * %-ENOMEM	- Out of Memory
 * * %-ERANGE	- Policy version number overflow
 * * %-EINVAL	- Policy version parsing error
 */
int ipe_parse_policy(struct ipe_policy *p)
{
	struct ipe_parsed_policy *pp = NULL;
	char *policy = NULL, *dup = NULL;
	bool header_parsed = false;
	char *line = NULL;
	size_t len;
	int rc = 0;

	if (!p->textlen)
		return -EBADMSG;

	policy = kmemdup_nul(p->text, p->textlen, GFP_KERNEL);
	if (!policy)
		return -ENOMEM;
	dup = policy;

	pp = new_parsed_policy();
	if (IS_ERR(pp)) {
		rc = PTR_ERR(pp);
		goto out;
	}

	while ((line = strsep(&policy, IPE_LINE_DELIM)) != NULL) {
		remove_comment(line);
		len = remove_trailing_spaces(line);
		if (!len)
			continue;

		if (!header_parsed) {
			rc = parse_header(line, pp);
			if (rc)
				goto err;
			header_parsed = true;
		} else {
			rc = parse_rule(line, pp);
			if (rc)
				goto err;
		}
	}

	if (!header_parsed || validate_policy(pp)) {
		rc = -EBADMSG;
		goto err;
	}

	p->parsed = pp;

out:
	kfree(dup);
	return rc;
err:
	ipe_free_parsed_policy(pp);
	goto out;
}
