1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * Copyright (C) 2020-2024 Microsoft Corporati 4 */ 5 6 #include <linux/slab.h> 7 #include <linux/audit.h> 8 #include <linux/types.h> 9 #include <crypto/hash.h> 10 11 #include "ipe.h" 12 #include "eval.h" 13 #include "hooks.h" 14 #include "policy.h" 15 #include "audit.h" 16 #include "digest.h" 17 18 #define ACTSTR(x) ((x) == IPE_ACTION_ALLOW ? " 19 20 #define IPE_AUDIT_HASH_ALG "sha256" 21 22 #define AUDIT_POLICY_LOAD_FMT "policy_name=\"% 23 "policy_digest=" 24 #define AUDIT_OLD_ACTIVE_POLICY_FMT "old_activ 25 "old_activ 26 "old_polic 27 #define AUDIT_OLD_ACTIVE_POLICY_NULL_FMT "old_ 28 "old_ 29 "old_ 30 #define AUDIT_NEW_ACTIVE_POLICY_FMT "new_activ 31 "new_activ 32 "new_polic 33 34 static const char *const audit_op_names[__IPE_ 35 "EXECUTE", 36 "FIRMWARE", 37 "KMODULE", 38 "KEXEC_IMAGE", 39 "KEXEC_INITRAMFS", 40 "POLICY", 41 "X509_CERT", 42 "UNKNOWN", 43 }; 44 45 static const char *const audit_hook_names[__IP 46 "BPRM_CHECK", 47 "MMAP", 48 "MPROTECT", 49 "KERNEL_READ", 50 "KERNEL_LOAD", 51 }; 52 53 static const char *const audit_prop_names[__IP 54 "boot_verified=FALSE", 55 "boot_verified=TRUE", 56 "dmverity_roothash=", 57 "dmverity_signature=FALSE", 58 "dmverity_signature=TRUE", 59 "fsverity_digest=", 60 "fsverity_signature=FALSE", 61 "fsverity_signature=TRUE", 62 }; 63 64 /** 65 * audit_dmv_roothash() - audit the roothash o 66 * @ab: Supplies a pointer to the audit_buffer 67 * @rh: Supplies a pointer to the digest struc 68 */ 69 static void audit_dmv_roothash(struct audit_bu 70 { 71 audit_log_format(ab, "%s", audit_prop_ 72 ipe_digest_audit(ab, rh); 73 } 74 75 /** 76 * audit_fsv_digest() - audit the digest of a 77 * @ab: Supplies a pointer to the audit_buffer 78 * @d: Supplies a pointer to the digest struct 79 */ 80 static void audit_fsv_digest(struct audit_buff 81 { 82 audit_log_format(ab, "%s", audit_prop_ 83 ipe_digest_audit(ab, d); 84 } 85 86 /** 87 * audit_rule() - audit an IPE policy rule. 88 * @ab: Supplies a pointer to the audit_buffer 89 * @r: Supplies a pointer to the ipe_rule to a 90 */ 91 static void audit_rule(struct audit_buffer *ab 92 { 93 const struct ipe_prop *ptr; 94 95 audit_log_format(ab, " rule=\"op=%s ", 96 97 list_for_each_entry(ptr, &r->props, ne 98 switch (ptr->type) { 99 case IPE_PROP_DMV_ROOTHASH: 100 audit_dmv_roothash(ab, 101 break; 102 case IPE_PROP_FSV_DIGEST: 103 audit_fsv_digest(ab, p 104 break; 105 default: 106 audit_log_format(ab, " 107 break; 108 } 109 110 audit_log_format(ab, " "); 111 } 112 113 audit_log_format(ab, "action=%s\"", AC 114 } 115 116 /** 117 * ipe_audit_match() - Audit a rule match in a 118 * @ctx: Supplies a pointer to the evaluation 119 * evaluation. 120 * @match_type: Supplies the scope of the matc 121 * global default. 122 * @act: Supplies the IPE's evaluation decisio 123 * @r: Supplies a pointer to the rule that was 124 */ 125 void ipe_audit_match(const struct ipe_eval_ctx 126 enum ipe_match match_type 127 enum ipe_action_type act, 128 { 129 const char *op = audit_op_names[ctx->o 130 char comm[sizeof(current->comm)]; 131 struct audit_buffer *ab; 132 struct inode *inode; 133 134 if (act != IPE_ACTION_DENY && !READ_ON 135 return; 136 137 ab = audit_log_start(audit_context(), 138 AUDIT_IPE_ACCESS) 139 if (!ab) 140 return; 141 142 audit_log_format(ab, "ipe_op=%s ipe_ho 143 op, audit_hook_names[ 144 task_tgid_nr(current) 145 audit_log_untrustedstring(ab, get_task 146 147 if (ctx->file) { 148 audit_log_d_path(ab, " path=", 149 inode = file_inode(ctx->file); 150 if (inode) { 151 audit_log_format(ab, " 152 audit_log_untrustedstr 153 audit_log_format(ab, " 154 } else { 155 audit_log_format(ab, " 156 } 157 } else { 158 audit_log_format(ab, " path=? 159 } 160 161 if (match_type == IPE_MATCH_RULE) 162 audit_rule(ab, r); 163 else if (match_type == IPE_MATCH_TABLE 164 audit_log_format(ab, " rule=\" 165 ACTSTR(act)); 166 else 167 audit_log_format(ab, " rule=\" 168 ACTSTR(act)); 169 170 audit_log_end(ab); 171 } 172 173 /** 174 * audit_policy() - Audit a policy's name, ver 175 * @ab: Supplies a pointer to the audit buffer 176 * @audit_format: Supplies a pointer to the au 177 * @p: Supplies a pointer to the policy to aud 178 */ 179 static void audit_policy(struct audit_buffer * 180 const char *audit_for 181 const struct ipe_poli 182 { 183 SHASH_DESC_ON_STACK(desc, tfm); 184 struct crypto_shash *tfm; 185 u8 *digest = NULL; 186 187 tfm = crypto_alloc_shash(IPE_AUDIT_HAS 188 if (IS_ERR(tfm)) 189 return; 190 191 desc->tfm = tfm; 192 193 digest = kzalloc(crypto_shash_digestsi 194 if (!digest) 195 goto out; 196 197 if (crypto_shash_init(desc)) 198 goto out; 199 200 if (crypto_shash_update(desc, p->pkcs7 201 goto out; 202 203 if (crypto_shash_final(desc, digest)) 204 goto out; 205 206 audit_log_format(ab, audit_format, p-> 207 p->parsed->version.ma 208 p->parsed->version.re 209 audit_log_n_hex(ab, digest, crypto_sha 210 211 out: 212 kfree(digest); 213 crypto_free_shash(tfm); 214 } 215 216 /** 217 * ipe_audit_policy_activation() - Audit a pol 218 * @op: Supplies a pointer to the previously a 219 * @np: Supplies a pointer to the newly activa 220 */ 221 void ipe_audit_policy_activation(const struct 222 const struct 223 { 224 struct audit_buffer *ab; 225 226 ab = audit_log_start(audit_context(), 227 AUDIT_IPE_CONFIG_ 228 if (!ab) 229 return; 230 231 if (op) { 232 audit_policy(ab, AUDIT_OLD_ACT 233 audit_log_format(ab, " "); 234 } else { 235 /* 236 * old active policy can be NU 237 * built-in policy 238 */ 239 audit_log_format(ab, AUDIT_OLD 240 audit_log_format(ab, " "); 241 } 242 audit_policy(ab, AUDIT_NEW_ACTIVE_POLI 243 audit_log_format(ab, " auid=%u ses=%u 244 from_kuid(&init_user_ 245 audit_get_sessionid(c 246 247 audit_log_end(ab); 248 } 249 250 /** 251 * ipe_audit_policy_load() - Audit a policy be 252 * @p: Supplies a pointer to the policy to aud 253 */ 254 void ipe_audit_policy_load(const struct ipe_po 255 { 256 struct audit_buffer *ab; 257 258 ab = audit_log_start(audit_context(), 259 AUDIT_IPE_POLICY_ 260 if (!ab) 261 return; 262 263 audit_policy(ab, AUDIT_POLICY_LOAD_FMT 264 audit_log_format(ab, " auid=%u ses=%u 265 from_kuid(&init_user_ 266 audit_get_sessionid(c 267 268 audit_log_end(ab); 269 } 270 271 /** 272 * ipe_audit_enforce() - Audit a change in IPE 273 * @new_enforce: The new value enforce to be s 274 * @old_enforce: The old value currently in en 275 */ 276 void ipe_audit_enforce(bool new_enforce, bool 277 { 278 struct audit_buffer *ab; 279 280 ab = audit_log_start(audit_context(), 281 if (!ab) 282 return; 283 284 audit_log(audit_context(), GFP_KERNEL, 285 "enforcing=%d old_enforcing= 286 " enabled=1 old-enabled=1 ls 287 new_enforce, old_enforce, 288 from_kuid(&init_user_ns, aud 289 audit_get_sessionid(current) 290 291 audit_log_end(ab); 292 } 293
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.