| // 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); |