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