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/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 ? "ALLOW" : "DENY") 19 20 #define IPE_AUDIT_HASH_ALG "sha256" 21 22 #define AUDIT_POLICY_LOAD_FMT "policy_name=\"%s\" policy_version=%hu.%hu.%hu "\ 23 "policy_digest=" IPE_AUDIT_HASH_ALG ":" 24 #define AUDIT_POLICY_LOAD_NULL_FMT "policy_name=? policy_version=? "\ 25 "policy_digest=?" 26 #define AUDIT_OLD_ACTIVE_POLICY_FMT "old_active_pol_name=\"%s\" "\ 27 "old_active_pol_version=%hu.%hu.%hu "\ 28 "old_policy_digest=" IPE_AUDIT_HASH_ALG ":" 29 #define AUDIT_OLD_ACTIVE_POLICY_NULL_FMT "old_active_pol_name=? "\ 30 "old_active_pol_version=? "\ 31 "old_policy_digest=?" 32 #define AUDIT_NEW_ACTIVE_POLICY_FMT "new_active_pol_name=\"%s\" "\ 33 "new_active_pol_version=%hu.%hu.%hu "\ 34 "new_policy_digest=" IPE_AUDIT_HASH_ALG ":" 35 36 static const char *const audit_op_names[__IPE_OP_MAX + 1] = { 37 "EXECUTE", 38 "FIRMWARE", 39 "KMODULE", 40 "KEXEC_IMAGE", 41 "KEXEC_INITRAMFS", 42 "POLICY", 43 "X509_CERT", 44 "UNKNOWN", 45 }; 46 47 static const char *const audit_hook_names[__IPE_HOOK_MAX] = { 48 "BPRM_CHECK", 49 "MMAP", 50 "MPROTECT", 51 "KERNEL_READ", 52 "KERNEL_LOAD", 53 }; 54 55 static const char *const audit_prop_names[__IPE_PROP_MAX] = { 56 "boot_verified=FALSE", 57 "boot_verified=TRUE", 58 "dmverity_roothash=", 59 "dmverity_signature=FALSE", 60 "dmverity_signature=TRUE", 61 "fsverity_digest=", 62 "fsverity_signature=FALSE", 63 "fsverity_signature=TRUE", 64 }; 65 66 /** 67 * audit_dmv_roothash() - audit the roothash of a dmverity_roothash property. 68 * @ab: Supplies a pointer to the audit_buffer to append to. 69 * @rh: Supplies a pointer to the digest structure. 70 */ 71 static void audit_dmv_roothash(struct audit_buffer *ab, const void *rh) 72 { 73 audit_log_format(ab, "%s", audit_prop_names[IPE_PROP_DMV_ROOTHASH]); 74 ipe_digest_audit(ab, rh); 75 } 76 77 /** 78 * audit_fsv_digest() - audit the digest of a fsverity_digest property. 79 * @ab: Supplies a pointer to the audit_buffer to append to. 80 * @d: Supplies a pointer to the digest structure. 81 */ 82 static void audit_fsv_digest(struct audit_buffer *ab, const void *d) 83 { 84 audit_log_format(ab, "%s", audit_prop_names[IPE_PROP_FSV_DIGEST]); 85 ipe_digest_audit(ab, d); 86 } 87 88 /** 89 * audit_rule() - audit an IPE policy rule. 90 * @ab: Supplies a pointer to the audit_buffer to append to. 91 * @r: Supplies a pointer to the ipe_rule to approximate a string form for. 92 */ 93 static void audit_rule(struct audit_buffer *ab, const struct ipe_rule *r) 94 { 95 const struct ipe_prop *ptr; 96 97 audit_log_format(ab, " rule=\"op=%s ", audit_op_names[r->op]); 98 99 list_for_each_entry(ptr, &r->props, next) { 100 switch (ptr->type) { 101 case IPE_PROP_DMV_ROOTHASH: 102 audit_dmv_roothash(ab, ptr->value); 103 break; 104 case IPE_PROP_FSV_DIGEST: 105 audit_fsv_digest(ab, ptr->value); 106 break; 107 default: 108 audit_log_format(ab, "%s", audit_prop_names[ptr->type]); 109 break; 110 } 111 112 audit_log_format(ab, " "); 113 } 114 115 audit_log_format(ab, "action=%s\"", ACTSTR(r->action)); 116 } 117 118 /** 119 * ipe_audit_match() - Audit a rule match in a policy evaluation. 120 * @ctx: Supplies a pointer to the evaluation context that was used in the 121 * evaluation. 122 * @match_type: Supplies the scope of the match: rule, operation default, 123 * global default. 124 * @act: Supplies the IPE's evaluation decision, deny or allow. 125 * @r: Supplies a pointer to the rule that was matched, if possible. 126 */ 127 void ipe_audit_match(const struct ipe_eval_ctx *const ctx, 128 enum ipe_match match_type, 129 enum ipe_action_type act, const struct ipe_rule *const r) 130 { 131 const char *op = audit_op_names[ctx->op]; 132 char comm[sizeof(current->comm)]; 133 struct audit_buffer *ab; 134 struct inode *inode; 135 136 if (act != IPE_ACTION_DENY && !READ_ONCE(success_audit)) 137 return; 138 139 ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN, 140 AUDIT_IPE_ACCESS); 141 if (!ab) 142 return; 143 144 audit_log_format(ab, "ipe_op=%s ipe_hook=%s enforcing=%d pid=%d comm=", 145 op, audit_hook_names[ctx->hook], READ_ONCE(enforce), 146 task_tgid_nr(current)); 147 audit_log_untrustedstring(ab, get_task_comm(comm, current)); 148 149 if (ctx->file) { 150 audit_log_d_path(ab, " path=", &ctx->file->f_path); 151 inode = file_inode(ctx->file); 152 if (inode) { 153 audit_log_format(ab, " dev="); 154 audit_log_untrustedstring(ab, inode->i_sb->s_id); 155 audit_log_format(ab, " ino=%lu", inode->i_ino); 156 } else { 157 audit_log_format(ab, " dev=? ino=?"); 158 } 159 } else { 160 audit_log_format(ab, " path=? dev=? ino=?"); 161 } 162 163 if (match_type == IPE_MATCH_RULE) 164 audit_rule(ab, r); 165 else if (match_type == IPE_MATCH_TABLE) 166 audit_log_format(ab, " rule=\"DEFAULT op=%s action=%s\"", op, 167 ACTSTR(act)); 168 else 169 audit_log_format(ab, " rule=\"DEFAULT action=%s\"", 170 ACTSTR(act)); 171 172 audit_log_end(ab); 173 } 174 175 /** 176 * audit_policy() - Audit a policy's name, version and thumbprint to @ab. 177 * @ab: Supplies a pointer to the audit buffer to append to. 178 * @audit_format: Supplies a pointer to the audit format string 179 * @p: Supplies a pointer to the policy to audit. 180 */ 181 static void audit_policy(struct audit_buffer *ab, 182 const char *audit_format, 183 const struct ipe_policy *const p) 184 { 185 SHASH_DESC_ON_STACK(desc, tfm); 186 struct crypto_shash *tfm; 187 u8 *digest = NULL; 188 189 tfm = crypto_alloc_shash(IPE_AUDIT_HASH_ALG, 0, 0); 190 if (IS_ERR(tfm)) 191 return; 192 193 desc->tfm = tfm; 194 195 digest = kzalloc(crypto_shash_digestsize(tfm), GFP_KERNEL); 196 if (!digest) 197 goto out; 198 199 if (crypto_shash_init(desc)) 200 goto out; 201 202 if (crypto_shash_update(desc, p->pkcs7, p->pkcs7len)) 203 goto out; 204 205 if (crypto_shash_final(desc, digest)) 206 goto out; 207 208 audit_log_format(ab, audit_format, p->parsed->name, 209 p->parsed->version.major, p->parsed->version.minor, 210 p->parsed->version.rev); 211 audit_log_n_hex(ab, digest, crypto_shash_digestsize(tfm)); 212 213 out: 214 kfree(digest); 215 crypto_free_shash(tfm); 216 } 217 218 /** 219 * ipe_audit_policy_activation() - Audit a policy being activated. 220 * @op: Supplies a pointer to the previously activated policy to audit. 221 * @np: Supplies a pointer to the newly activated policy to audit. 222 */ 223 void ipe_audit_policy_activation(const struct ipe_policy *const op, 224 const struct ipe_policy *const np) 225 { 226 struct audit_buffer *ab; 227 228 ab = audit_log_start(audit_context(), GFP_KERNEL, 229 AUDIT_IPE_CONFIG_CHANGE); 230 if (!ab) 231 return; 232 233 if (op) { 234 audit_policy(ab, AUDIT_OLD_ACTIVE_POLICY_FMT, op); 235 audit_log_format(ab, " "); 236 } else { 237 /* 238 * old active policy can be NULL if there is no kernel 239 * built-in policy 240 */ 241 audit_log_format(ab, AUDIT_OLD_ACTIVE_POLICY_NULL_FMT); 242 audit_log_format(ab, " "); 243 } 244 audit_policy(ab, AUDIT_NEW_ACTIVE_POLICY_FMT, np); 245 audit_log_format(ab, " auid=%u ses=%u lsm=ipe res=1", 246 from_kuid(&init_user_ns, audit_get_loginuid(current)), 247 audit_get_sessionid(current)); 248 249 audit_log_end(ab); 250 } 251 252 /** 253 * ipe_audit_policy_load() - Audit a policy loading event. 254 * @p: Supplies a pointer to the policy to audit or an error pointer. 255 */ 256 void ipe_audit_policy_load(const struct ipe_policy *const p) 257 { 258 struct audit_buffer *ab; 259 int err = 0; 260 261 ab = audit_log_start(audit_context(), GFP_KERNEL, 262 AUDIT_IPE_POLICY_LOAD); 263 if (!ab) 264 return; 265 266 if (!IS_ERR(p)) { 267 audit_policy(ab, AUDIT_POLICY_LOAD_FMT, p); 268 } else { 269 audit_log_format(ab, AUDIT_POLICY_LOAD_NULL_FMT); 270 err = PTR_ERR(p); 271 } 272 273 audit_log_format(ab, " auid=%u ses=%u lsm=ipe res=%d errno=%d", 274 from_kuid(&init_user_ns, audit_get_loginuid(current)), 275 audit_get_sessionid(current), !err, err); 276 277 audit_log_end(ab); 278 } 279 280 /** 281 * ipe_audit_enforce() - Audit a change in IPE's enforcement state. 282 * @new_enforce: The new value enforce to be set. 283 * @old_enforce: The old value currently in enforce. 284 */ 285 void ipe_audit_enforce(bool new_enforce, bool old_enforce) 286 { 287 struct audit_buffer *ab; 288 289 ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS); 290 if (!ab) 291 return; 292 293 audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS, 294 "enforcing=%d old_enforcing=%d auid=%u ses=%u" 295 " enabled=1 old-enabled=1 lsm=ipe res=1", 296 new_enforce, old_enforce, 297 from_kuid(&init_user_ns, audit_get_loginuid(current)), 298 audit_get_sessionid(current)); 299 300 audit_log_end(ab); 301 } 302