297 lines · 6.8 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. */ #include <linux/slab.h>#include <linux/types.h>#include <linux/list.h>#include <kunit/test.h>#include "policy.h"struct policy_case {	const char *const policy;	int errno;	const char *const desc;}; static const struct policy_case policy_cases[] = {	{		"policy_name=allowall policy_version=0.0.0\n"		"DEFAULT action=ALLOW",		0,		"basic",	},	{		"policy_name=trailing_comment policy_version=152.0.0 #This is comment\n"		"DEFAULT action=ALLOW",		0,		"trailing comment",	},	{		"policy_name=allowallnewline policy_version=0.2.0\n"		"DEFAULT action=ALLOW\n"		"\n",		0,		"trailing newline",	},	{		"policy_name=carriagereturnlinefeed policy_version=0.0.1\n"		"DEFAULT action=ALLOW\n"		"\r\n",		0,		"clrf newline",	},	{		"policy_name=whitespace policy_version=0.0.0\n"		"DEFAULT\taction=ALLOW\n"		"     \t     DEFAULT \t    op=EXECUTE      action=DENY\n"		"op=EXECUTE boot_verified=TRUE action=ALLOW\n"		"# this is a\tcomment\t\t\t\t\n"		"DEFAULT \t op=KMODULE\t\t\t  action=DENY\r\n"		"op=KMODULE boot_verified=TRUE action=ALLOW\n",		0,		"various whitespaces and nested default",	},	{		"policy_name=boot_verified policy_version=-1236.0.0\n"		"DEFAULT\taction=ALLOW\n",		-EINVAL,		"negative version",	},	{		"policy_name=$@!*&^%%\\:;{}() policy_version=0.0.0\n"		"DEFAULT action=ALLOW",		0,		"special characters",	},	{		"policy_name=test policy_version=999999.0.0\n"		"DEFAULT action=ALLOW",		-ERANGE,		"overflow version",	},	{		"policy_name=test policy_version=255.0\n"		"DEFAULT action=ALLOW",		-EBADMSG,		"incomplete version",	},	{		"policy_name=test policy_version=111.0.0.0\n"		"DEFAULT action=ALLOW",		-EBADMSG,		"extra version",	},	{		"",		-EBADMSG,		"0-length policy",	},	{		"policy_name=test\0policy_version=0.0.0\n"		"DEFAULT action=ALLOW",		-EBADMSG,		"random null in header",	},	{		"policy_name=test policy_version=0.0.0\n"		"\0DEFAULT action=ALLOW",		-EBADMSG,		"incomplete policy from NULL",	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=DENY\n\0"		"op=EXECUTE dmverity_signature=TRUE action=ALLOW\n",		0,		"NULL truncates policy",	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE dmverity_signature=abc action=ALLOW",		-EBADMSG,		"invalid property type",	},	{		"DEFAULT action=ALLOW",		-EBADMSG,		"missing policy header",	},	{		"policy_name=test policy_version=0.0.0\n",		-EBADMSG,		"missing default definition",	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"dmverity_signature=TRUE op=EXECUTE action=ALLOW",		-EBADMSG,		"invalid rule ordering"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"action=ALLOW op=EXECUTE dmverity_signature=TRUE",		-EBADMSG,		"invalid rule ordering (2)",	},	{		"policy_name=test policy_version=0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE dmverity_signature=TRUE action=ALLOW",		-EBADMSG,		"invalid version",	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=UNKNOWN dmverity_signature=TRUE action=ALLOW",		-EBADMSG,		"unknown operation",	},	{		"policy_name=asdvpolicy_version=0.0.0\n"		"DEFAULT action=ALLOW\n",		-EBADMSG,		"missing space after policy name",	},	{		"policy_name=test\xFF\xEF policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE dmverity_signature=TRUE action=ALLOW",		0,		"expanded ascii",	},	{		"policy_name=test\xFF\xEF policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE dmverity_roothash=GOOD_DOG action=ALLOW",		-EBADMSG,		"invalid property value (2)",	},	{		"policy_name=test policy_version=0.0.0\n"		"policy_name=test policy_version=0.1.0\n"		"DEFAULT action=ALLOW",		-EBADMSG,		"double header"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"DEFAULT action=ALLOW\n",		-EBADMSG,		"double default"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"DEFAULT op=EXECUTE action=DENY\n"		"DEFAULT op=EXECUTE action=ALLOW\n",		-EBADMSG,		"double operation default"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"DEFAULT op=EXECUTE action=DEN\n",		-EBADMSG,		"invalid action value"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"DEFAULT op=EXECUTE action\n",		-EBADMSG,		"invalid action value (2)"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"UNKNOWN value=true\n",		-EBADMSG,		"unrecognized statement"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE dmverity_roothash=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n",		-EBADMSG,		"old-style digest"	},	{		"policy_name=test policy_version=0.0.0\n"		"DEFAULT action=ALLOW\n"		"op=EXECUTE fsverity_digest=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n",		-EBADMSG,		"old-style digest"	}}; static void pol_to_desc(const struct policy_case *c, char *desc){	strscpy(desc, c->desc, KUNIT_PARAM_DESC_SIZE);} KUNIT_ARRAY_PARAM(ipe_policies, policy_cases, pol_to_desc); /** * ipe_parser_unsigned_test - Test the parser by passing unsigned policies. * @test: Supplies a pointer to a kunit structure. * * This is called by the kunit harness. This test does not check the correctness * of the policy, but ensures that errors are handled correctly. */static void ipe_parser_unsigned_test(struct kunit *test){	const struct policy_case *p = test->param_value;	struct ipe_policy *pol; 	pol = ipe_new_policy(p->policy, strlen(p->policy), NULL, 0); 	if (p->errno) {		KUNIT_EXPECT_EQ(test, PTR_ERR(pol), p->errno);		return;	} 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pol);	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, pol->parsed);	KUNIT_EXPECT_STREQ(test, pol->text, p->policy);	KUNIT_EXPECT_PTR_EQ(test, NULL, pol->pkcs7);	KUNIT_EXPECT_EQ(test, 0, pol->pkcs7len); 	ipe_free_policy(pol);} /** * ipe_parser_widestring_test - Ensure parser fail on a wide string policy. * @test: Supplies a pointer to a kunit structure. * * This is called by the kunit harness. */static void ipe_parser_widestring_test(struct kunit *test){	const unsigned short policy[] = L"policy_name=Test policy_version=0.0.0\n"					L"DEFAULT action=ALLOW";	struct ipe_policy *pol = NULL; 	pol = ipe_new_policy((const char *)policy, (ARRAY_SIZE(policy) - 1) * 2, NULL, 0);	KUNIT_EXPECT_TRUE(test, IS_ERR_OR_NULL(pol)); 	ipe_free_policy(pol);} static struct kunit_case ipe_parser_test_cases[] = {	KUNIT_CASE_PARAM(ipe_parser_unsigned_test, ipe_policies_gen_params),	KUNIT_CASE(ipe_parser_widestring_test),	{ }}; static struct kunit_suite ipe_parser_test_suite = {	.name = "ipe-parser",	.test_cases = ipe_parser_test_cases,}; kunit_test_suite(ipe_parser_test_suite);