1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. 4 */ 5 6 #include <linux/slab.h> 7 #include <linux/types.h> 8 #include <linux/list.h> 9 #include <kunit/test.h> 10 #include "policy.h" 11 struct policy_case { 12 const char *const policy; 13 int errno; 14 const char *const desc; 15 }; 16 17 static const struct policy_case policy_cases[] = { 18 { 19 "policy_name=allowall policy_version=0.0.0\n" 20 "DEFAULT action=ALLOW", 21 0, 22 "basic", 23 }, 24 { 25 "policy_name=trailing_comment policy_version=152.0.0 #This is comment\n" 26 "DEFAULT action=ALLOW", 27 0, 28 "trailing comment", 29 }, 30 { 31 "policy_name=allowallnewline policy_version=0.2.0\n" 32 "DEFAULT action=ALLOW\n" 33 "\n", 34 0, 35 "trailing newline", 36 }, 37 { 38 "policy_name=carriagereturnlinefeed policy_version=0.0.1\n" 39 "DEFAULT action=ALLOW\n" 40 "\r\n", 41 0, 42 "clrf newline", 43 }, 44 { 45 "policy_name=whitespace policy_version=0.0.0\n" 46 "DEFAULT\taction=ALLOW\n" 47 " \t DEFAULT \t op=EXECUTE action=DENY\n" 48 "op=EXECUTE boot_verified=TRUE action=ALLOW\n" 49 "# this is a\tcomment\t\t\t\t\n" 50 "DEFAULT \t op=KMODULE\t\t\t action=DENY\r\n" 51 "op=KMODULE boot_verified=TRUE action=ALLOW\n", 52 0, 53 "various whitespaces and nested default", 54 }, 55 { 56 "policy_name=boot_verified policy_version=-1236.0.0\n" 57 "DEFAULT\taction=ALLOW\n", 58 -EINVAL, 59 "negative version", 60 }, 61 { 62 "policy_name=$@!*&^%%\\:;{}() policy_version=0.0.0\n" 63 "DEFAULT action=ALLOW", 64 0, 65 "special characters", 66 }, 67 { 68 "policy_name=test policy_version=999999.0.0\n" 69 "DEFAULT action=ALLOW", 70 -ERANGE, 71 "overflow version", 72 }, 73 { 74 "policy_name=test policy_version=255.0\n" 75 "DEFAULT action=ALLOW", 76 -EBADMSG, 77 "incomplete version", 78 }, 79 { 80 "policy_name=test policy_version=111.0.0.0\n" 81 "DEFAULT action=ALLOW", 82 -EBADMSG, 83 "extra version", 84 }, 85 { 86 "", 87 -EBADMSG, 88 "0-length policy", 89 }, 90 { 91 "policy_name=test\0policy_version=0.0.0\n" 92 "DEFAULT action=ALLOW", 93 -EBADMSG, 94 "random null in header", 95 }, 96 { 97 "policy_name=test policy_version=0.0.0\n" 98 "\0DEFAULT action=ALLOW", 99 -EBADMSG, 100 "incomplete policy from NULL", 101 }, 102 { 103 "policy_name=test policy_version=0.0.0\n" 104 "DEFAULT action=DENY\n\0" 105 "op=EXECUTE dmverity_signature=TRUE action=ALLOW\n", 106 0, 107 "NULL truncates policy", 108 }, 109 { 110 "policy_name=test policy_version=0.0.0\n" 111 "DEFAULT action=ALLOW\n" 112 "op=EXECUTE dmverity_signature=abc action=ALLOW", 113 -EBADMSG, 114 "invalid property type", 115 }, 116 { 117 "DEFAULT action=ALLOW", 118 -EBADMSG, 119 "missing policy header", 120 }, 121 { 122 "policy_name=test policy_version=0.0.0\n", 123 -EBADMSG, 124 "missing default definition", 125 }, 126 { 127 "policy_name=test policy_version=0.0.0\n" 128 "DEFAULT action=ALLOW\n" 129 "dmverity_signature=TRUE op=EXECUTE action=ALLOW", 130 -EBADMSG, 131 "invalid rule ordering" 132 }, 133 { 134 "policy_name=test policy_version=0.0.0\n" 135 "DEFAULT action=ALLOW\n" 136 "action=ALLOW op=EXECUTE dmverity_signature=TRUE", 137 -EBADMSG, 138 "invalid rule ordering (2)", 139 }, 140 { 141 "policy_name=test policy_version=0.0\n" 142 "DEFAULT action=ALLOW\n" 143 "op=EXECUTE dmverity_signature=TRUE action=ALLOW", 144 -EBADMSG, 145 "invalid version", 146 }, 147 { 148 "policy_name=test policy_version=0.0.0\n" 149 "DEFAULT action=ALLOW\n" 150 "op=UNKNOWN dmverity_signature=TRUE action=ALLOW", 151 -EBADMSG, 152 "unknown operation", 153 }, 154 { 155 "policy_name=asdvpolicy_version=0.0.0\n" 156 "DEFAULT action=ALLOW\n", 157 -EBADMSG, 158 "missing space after policy name", 159 }, 160 { 161 "policy_name=test\xFF\xEF policy_version=0.0.0\n" 162 "DEFAULT action=ALLOW\n" 163 "op=EXECUTE dmverity_signature=TRUE action=ALLOW", 164 0, 165 "expanded ascii", 166 }, 167 { 168 "policy_name=test\xFF\xEF policy_version=0.0.0\n" 169 "DEFAULT action=ALLOW\n" 170 "op=EXECUTE dmverity_roothash=GOOD_DOG action=ALLOW", 171 -EBADMSG, 172 "invalid property value (2)", 173 }, 174 { 175 "policy_name=test policy_version=0.0.0\n" 176 "policy_name=test policy_version=0.1.0\n" 177 "DEFAULT action=ALLOW", 178 -EBADMSG, 179 "double header" 180 }, 181 { 182 "policy_name=test policy_version=0.0.0\n" 183 "DEFAULT action=ALLOW\n" 184 "DEFAULT action=ALLOW\n", 185 -EBADMSG, 186 "double default" 187 }, 188 { 189 "policy_name=test policy_version=0.0.0\n" 190 "DEFAULT action=ALLOW\n" 191 "DEFAULT op=EXECUTE action=DENY\n" 192 "DEFAULT op=EXECUTE action=ALLOW\n", 193 -EBADMSG, 194 "double operation default" 195 }, 196 { 197 "policy_name=test policy_version=0.0.0\n" 198 "DEFAULT action=ALLOW\n" 199 "DEFAULT op=EXECUTE action=DEN\n", 200 -EBADMSG, 201 "invalid action value" 202 }, 203 { 204 "policy_name=test policy_version=0.0.0\n" 205 "DEFAULT action=ALLOW\n" 206 "DEFAULT op=EXECUTE action\n", 207 -EBADMSG, 208 "invalid action value (2)" 209 }, 210 { 211 "policy_name=test policy_version=0.0.0\n" 212 "DEFAULT action=ALLOW\n" 213 "UNKNOWN value=true\n", 214 -EBADMSG, 215 "unrecognized statement" 216 }, 217 { 218 "policy_name=test policy_version=0.0.0\n" 219 "DEFAULT action=ALLOW\n" 220 "op=EXECUTE dmverity_roothash=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n", 221 -EBADMSG, 222 "old-style digest" 223 }, 224 { 225 "policy_name=test policy_version=0.0.0\n" 226 "DEFAULT action=ALLOW\n" 227 "op=EXECUTE fsverity_digest=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n", 228 -EBADMSG, 229 "old-style digest" 230 } 231 }; 232 233 static void pol_to_desc(const struct policy_case *c, char *desc) 234 { 235 strscpy(desc, c->desc, KUNIT_PARAM_DESC_SIZE); 236 } 237 238 KUNIT_ARRAY_PARAM(ipe_policies, policy_cases, pol_to_desc); 239 240 /** 241 * ipe_parser_unsigned_test - Test the parser by passing unsigned policies. 242 * @test: Supplies a pointer to a kunit structure. 243 * 244 * This is called by the kunit harness. This test does not check the correctness 245 * of the policy, but ensures that errors are handled correctly. 246 */ 247 static void ipe_parser_unsigned_test(struct kunit *test) 248 { 249 const struct policy_case *p = test->param_value; 250 struct ipe_policy *pol; 251 252 pol = ipe_new_policy(p->policy, strlen(p->policy), NULL, 0); 253 254 if (p->errno) { 255 KUNIT_EXPECT_EQ(test, PTR_ERR(pol), p->errno); 256 return; 257 } 258 259 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pol); 260 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, pol->parsed); 261 KUNIT_EXPECT_STREQ(test, pol->text, p->policy); 262 KUNIT_EXPECT_PTR_EQ(test, NULL, pol->pkcs7); 263 KUNIT_EXPECT_EQ(test, 0, pol->pkcs7len); 264 265 ipe_free_policy(pol); 266 } 267 268 /** 269 * ipe_parser_widestring_test - Ensure parser fail on a wide string policy. 270 * @test: Supplies a pointer to a kunit structure. 271 * 272 * This is called by the kunit harness. 273 */ 274 static void ipe_parser_widestring_test(struct kunit *test) 275 { 276 const unsigned short policy[] = L"policy_name=Test policy_version=0.0.0\n" 277 L"DEFAULT action=ALLOW"; 278 struct ipe_policy *pol = NULL; 279 280 pol = ipe_new_policy((const char *)policy, (ARRAY_SIZE(policy) - 1) * 2, NULL, 0); 281 KUNIT_EXPECT_TRUE(test, IS_ERR_OR_NULL(pol)); 282 283 ipe_free_policy(pol); 284 } 285 286 static struct kunit_case ipe_parser_test_cases[] = { 287 KUNIT_CASE_PARAM(ipe_parser_unsigned_test, ipe_policies_gen_params), 288 KUNIT_CASE(ipe_parser_widestring_test), 289 { } 290 }; 291 292 static struct kunit_suite ipe_parser_test_suite = { 293 .name = "ipe-parser", 294 .test_cases = ipe_parser_test_cases, 295 }; 296 297 kunit_test_suite(ipe_parser_test_suite); 298