Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'integrity-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity

Pull integrity updates from Mimi Zohar:
"Continuing IMA policy rule cleanup and validation in particular for
measuring keys, adding/removing/updating informational and error
messages (e.g. "ima_appraise" boot command line option), and other bug
fixes (e.g. minimal data size validation before use, return code and
NULL pointer checking)"

* tag 'integrity-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
ima: Fix NULL pointer dereference in ima_file_hash
evm: Check size of security.evm before using it
ima: Remove semicolon at the end of ima_get_binary_runtime_size()
ima: Don't ignore errors from crypto_shash_update()
ima: Use kmemdup rather than kmalloc+memcpy
integrity: include keyring name for unknown key request
ima: limit secure boot feedback scope for appraise
integrity: invalid kernel parameters feedback
ima: add check for enforced appraise option
integrity: Use current_uid() in integrity_audit_message()
ima: Fail rule parsing when asymmetric key measurement isn't supportable
ima: Pre-parse the list of keyrings in a KEY_CHECK rule

+161 -67
+8 -2
security/integrity/digsig_asymmetric.c
··· 55 55 } 56 56 57 57 if (IS_ERR(key)) { 58 - pr_err_ratelimited("Request for unknown key '%s' err %ld\n", 59 - name, PTR_ERR(key)); 58 + if (keyring) 59 + pr_err_ratelimited("Request for unknown key '%s' in '%s' keyring. err %ld\n", 60 + name, keyring->description, 61 + PTR_ERR(key)); 62 + else 63 + pr_err_ratelimited("Request for unknown key '%s' err %ld\n", 64 + name, PTR_ERR(key)); 65 + 60 66 switch (PTR_ERR(key)) { 61 67 /* Hide some search errors */ 62 68 case -EACCES:
+9
security/integrity/evm/evm_main.c
··· 59 59 { 60 60 if (strncmp(str, "fix", 3) == 0) 61 61 evm_fixmode = 1; 62 + else 63 + pr_err("invalid \"%s\" mode", str); 64 + 62 65 return 0; 63 66 } 64 67 __setup("evm=", evm_set_fixmode); ··· 184 181 break; 185 182 case EVM_IMA_XATTR_DIGSIG: 186 183 case EVM_XATTR_PORTABLE_DIGSIG: 184 + /* accept xattr with non-empty signature field */ 185 + if (xattr_len <= sizeof(struct signature_v2_hdr)) { 186 + evm_status = INTEGRITY_FAIL; 187 + goto out; 188 + } 189 + 187 190 hdr = (struct signature_v2_hdr *)xattr_data; 188 191 digest.hdr.algo = hdr->hash_algo; 189 192 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
+19 -8
security/integrity/ima/ima_appraise.c
··· 19 19 static int __init default_appraise_setup(char *str) 20 20 { 21 21 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM 22 - if (arch_ima_get_secureboot()) { 23 - pr_info("Secure boot enabled: ignoring ima_appraise=%s boot parameter option", 24 - str); 25 - return 1; 26 - } 22 + bool sb_state = arch_ima_get_secureboot(); 23 + int appraisal_state = ima_appraise; 27 24 28 25 if (strncmp(str, "off", 3) == 0) 29 - ima_appraise = 0; 26 + appraisal_state = 0; 30 27 else if (strncmp(str, "log", 3) == 0) 31 - ima_appraise = IMA_APPRAISE_LOG; 28 + appraisal_state = IMA_APPRAISE_LOG; 32 29 else if (strncmp(str, "fix", 3) == 0) 33 - ima_appraise = IMA_APPRAISE_FIX; 30 + appraisal_state = IMA_APPRAISE_FIX; 31 + else if (strncmp(str, "enforce", 7) == 0) 32 + appraisal_state = IMA_APPRAISE_ENFORCE; 33 + else 34 + pr_err("invalid \"%s\" appraise option", str); 35 + 36 + /* If appraisal state was changed, but secure boot is enabled, 37 + * keep its default */ 38 + if (sb_state) { 39 + if (!(appraisal_state & IMA_APPRAISE_ENFORCE)) 40 + pr_info("Secure boot enabled: ignoring ima_appraise=%s option", 41 + str); 42 + } else { 43 + ima_appraise = appraisal_state; 44 + } 34 45 #endif 35 46 return 1; 36 47 }
+2
security/integrity/ima/ima_crypto.c
··· 829 829 /* now accumulate with current aggregate */ 830 830 rc = crypto_shash_update(shash, d.digest, 831 831 crypto_shash_digestsize(tfm)); 832 + if (rc != 0) 833 + return rc; 832 834 } 833 835 /* 834 836 * Extend cumulative digest over TPM registers 8-9, which contain
+19 -4
security/integrity/ima/ima_main.c
··· 51 51 return 1; 52 52 53 53 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { 54 - if (strncmp(str, "sha1", 4) == 0) 54 + if (strncmp(str, "sha1", 4) == 0) { 55 55 ima_hash_algo = HASH_ALGO_SHA1; 56 - else if (strncmp(str, "md5", 3) == 0) 56 + } else if (strncmp(str, "md5", 3) == 0) { 57 57 ima_hash_algo = HASH_ALGO_MD5; 58 - else 58 + } else { 59 + pr_err("invalid hash algorithm \"%s\" for template \"%s\"", 60 + str, IMA_TEMPLATE_IMA_NAME); 59 61 return 1; 62 + } 60 63 goto out; 61 64 } 62 65 63 66 i = match_string(hash_algo_name, HASH_ALGO__LAST, str); 64 - if (i < 0) 67 + if (i < 0) { 68 + pr_err("invalid hash algorithm \"%s\"", str); 65 69 return 1; 70 + } 66 71 67 72 ima_hash_algo = i; 68 73 out: ··· 537 532 return -EOPNOTSUPP; 538 533 539 534 mutex_lock(&iint->mutex); 535 + 536 + /* 537 + * ima_file_hash can be called when ima_collect_measurement has still 538 + * not been called, we might not always have a hash. 539 + */ 540 + if (!iint->ima_hash) { 541 + mutex_unlock(&iint->mutex); 542 + return -EOPNOTSUPP; 543 + } 544 + 540 545 if (buf) { 541 546 size_t copied_size; 542 547
+102 -51
security/integrity/ima/ima_policy.c
··· 60 60 61 61 enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY }; 62 62 63 + struct ima_rule_opt_list { 64 + size_t count; 65 + char *items[]; 66 + }; 67 + 63 68 struct ima_rule_entry { 64 69 struct list_head list; 65 70 int action; ··· 84 79 int type; /* audit type */ 85 80 } lsm[MAX_LSM_RULES]; 86 81 char *fsname; 87 - char *keyrings; /* Measure keys added to these keyrings */ 82 + struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ 88 83 struct ima_template_desc *template; 89 84 }; 90 85 ··· 212 207 static LIST_HEAD(ima_temp_rules); 213 208 static struct list_head *ima_rules = &ima_default_rules; 214 209 215 - /* Pre-allocated buffer used for matching keyrings. */ 216 - static char *ima_keyrings; 217 - static size_t ima_keyrings_len; 218 - 219 210 static int ima_policy __initdata; 220 211 221 212 static int __init default_measure_policy_setup(char *str) ··· 242 241 ima_use_secure_boot = true; 243 242 else if (strcmp(p, "fail_securely") == 0) 244 243 ima_fail_unverifiable_sigs = true; 244 + else 245 + pr_err("policy \"%s\" not found", p); 245 246 } 246 247 247 248 return 1; ··· 256 253 return 1; 257 254 } 258 255 __setup("ima_appraise_tcb", default_appraise_policy_setup); 256 + 257 + static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src) 258 + { 259 + struct ima_rule_opt_list *opt_list; 260 + size_t count = 0; 261 + char *src_copy; 262 + char *cur, *next; 263 + size_t i; 264 + 265 + src_copy = match_strdup(src); 266 + if (!src_copy) 267 + return ERR_PTR(-ENOMEM); 268 + 269 + next = src_copy; 270 + while ((cur = strsep(&next, "|"))) { 271 + /* Don't accept an empty list item */ 272 + if (!(*cur)) { 273 + kfree(src_copy); 274 + return ERR_PTR(-EINVAL); 275 + } 276 + count++; 277 + } 278 + 279 + /* Don't accept an empty list */ 280 + if (!count) { 281 + kfree(src_copy); 282 + return ERR_PTR(-EINVAL); 283 + } 284 + 285 + opt_list = kzalloc(struct_size(opt_list, items, count), GFP_KERNEL); 286 + if (!opt_list) { 287 + kfree(src_copy); 288 + return ERR_PTR(-ENOMEM); 289 + } 290 + 291 + /* 292 + * strsep() has already replaced all instances of '|' with '\0', 293 + * leaving a byte sequence of NUL-terminated strings. Reference each 294 + * string with the array of items. 295 + * 296 + * IMPORTANT: Ownership of the allocated buffer is transferred from 297 + * src_copy to the first element in the items array. To free the 298 + * buffer, kfree() must only be called on the first element of the 299 + * array. 300 + */ 301 + for (i = 0, cur = src_copy; i < count; i++) { 302 + opt_list->items[i] = cur; 303 + cur = strchr(cur, '\0') + 1; 304 + } 305 + opt_list->count = count; 306 + 307 + return opt_list; 308 + } 309 + 310 + static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list) 311 + { 312 + if (!opt_list) 313 + return; 314 + 315 + if (opt_list->count) { 316 + kfree(opt_list->items[0]); 317 + opt_list->count = 0; 318 + } 319 + 320 + kfree(opt_list); 321 + } 259 322 260 323 static void ima_lsm_free_rule(struct ima_rule_entry *entry) 261 324 { ··· 344 275 * the defined_templates list and cannot be freed here 345 276 */ 346 277 kfree(entry->fsname); 347 - kfree(entry->keyrings); 278 + ima_free_rule_opt_list(entry->keyrings); 348 279 ima_lsm_free_rule(entry); 349 280 kfree(entry); 350 281 } ··· 354 285 struct ima_rule_entry *nentry; 355 286 int i; 356 287 357 - nentry = kmalloc(sizeof(*nentry), GFP_KERNEL); 358 - if (!nentry) 359 - return NULL; 360 - 361 288 /* 362 289 * Immutable elements are copied over as pointers and data; only 363 290 * lsm rules can change 364 291 */ 365 - memcpy(nentry, entry, sizeof(*nentry)); 292 + nentry = kmemdup(entry, sizeof(*nentry), GFP_KERNEL); 293 + if (!nentry) 294 + return NULL; 295 + 366 296 memset(nentry->lsm, 0, sizeof_field(struct ima_rule_entry, lsm)); 367 297 368 298 for (i = 0; i < MAX_LSM_RULES; i++) { ··· 463 395 static bool ima_match_keyring(struct ima_rule_entry *rule, 464 396 const char *keyring, const struct cred *cred) 465 397 { 466 - char *next_keyring, *keyrings_ptr; 467 398 bool matched = false; 399 + size_t i; 468 400 469 401 if ((rule->flags & IMA_UID) && !rule->uid_op(cred->uid, rule->uid)) 470 402 return false; ··· 475 407 if (!keyring) 476 408 return false; 477 409 478 - strcpy(ima_keyrings, rule->keyrings); 479 - 480 - /* 481 - * "keyrings=" is specified in the policy in the format below: 482 - * keyrings=.builtin_trusted_keys|.ima|.evm 483 - */ 484 - keyrings_ptr = ima_keyrings; 485 - while ((next_keyring = strsep(&keyrings_ptr, "|")) != NULL) { 486 - if (!strcmp(next_keyring, keyring)) { 410 + for (i = 0; i < rule->keyrings->count; i++) { 411 + if (!strcmp(rule->keyrings->items[i], keyring)) { 487 412 matched = true; 488 413 break; 489 414 } ··· 1127 1066 bool uid_token; 1128 1067 struct ima_template_desc *template_desc; 1129 1068 int result = 0; 1130 - size_t keyrings_len; 1131 1069 1132 1070 ab = integrity_audit_log_start(audit_context(), GFP_KERNEL, 1133 1071 AUDIT_INTEGRITY_POLICY_RULE); ··· 1235 1175 entry->func = POLICY_CHECK; 1236 1176 else if (strcmp(args[0].from, "KEXEC_CMDLINE") == 0) 1237 1177 entry->func = KEXEC_CMDLINE; 1238 - else if (strcmp(args[0].from, "KEY_CHECK") == 0) 1178 + else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) && 1179 + strcmp(args[0].from, "KEY_CHECK") == 0) 1239 1180 entry->func = KEY_CHECK; 1240 1181 else 1241 1182 result = -EINVAL; ··· 1293 1232 case Opt_keyrings: 1294 1233 ima_log_string(ab, "keyrings", args[0].from); 1295 1234 1296 - keyrings_len = strlen(args[0].from) + 1; 1297 - 1298 - if ((entry->keyrings) || 1299 - (keyrings_len < 2)) { 1235 + if (!IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) || 1236 + entry->keyrings) { 1300 1237 result = -EINVAL; 1301 1238 break; 1302 1239 } 1303 1240 1304 - if (keyrings_len > ima_keyrings_len) { 1305 - char *tmpbuf; 1306 - 1307 - tmpbuf = krealloc(ima_keyrings, keyrings_len, 1308 - GFP_KERNEL); 1309 - if (!tmpbuf) { 1310 - result = -ENOMEM; 1311 - break; 1312 - } 1313 - 1314 - ima_keyrings = tmpbuf; 1315 - ima_keyrings_len = keyrings_len; 1316 - } 1317 - 1318 - entry->keyrings = kstrdup(args[0].from, GFP_KERNEL); 1319 - if (!entry->keyrings) { 1320 - kfree(ima_keyrings); 1321 - ima_keyrings = NULL; 1322 - ima_keyrings_len = 0; 1323 - result = -ENOMEM; 1241 + entry->keyrings = ima_alloc_rule_opt_list(args); 1242 + if (IS_ERR(entry->keyrings)) { 1243 + result = PTR_ERR(entry->keyrings); 1244 + entry->keyrings = NULL; 1324 1245 break; 1325 1246 } 1326 - result = 0; 1247 + 1327 1248 entry->flags |= IMA_KEYRINGS; 1328 1249 break; 1329 1250 case Opt_fsuuid: ··· 1618 1575 seq_printf(m, "func=%d ", func); 1619 1576 } 1620 1577 1578 + static void ima_show_rule_opt_list(struct seq_file *m, 1579 + const struct ima_rule_opt_list *opt_list) 1580 + { 1581 + size_t i; 1582 + 1583 + for (i = 0; i < opt_list->count; i++) 1584 + seq_printf(m, "%s%s", i ? "|" : "", opt_list->items[i]); 1585 + } 1586 + 1621 1587 int ima_policy_show(struct seq_file *m, void *v) 1622 1588 { 1623 1589 struct ima_rule_entry *entry = v; ··· 1683 1631 } 1684 1632 1685 1633 if (entry->flags & IMA_KEYRINGS) { 1686 - if (entry->keyrings != NULL) 1687 - snprintf(tbuf, sizeof(tbuf), "%s", entry->keyrings); 1688 - seq_printf(m, pt(Opt_keyrings), tbuf); 1634 + seq_puts(m, "keyrings="); 1635 + ima_show_rule_opt_list(m, entry->keyrings); 1689 1636 seq_puts(m, " "); 1690 1637 } 1691 1638
+1 -1
security/integrity/ima/ima_queue.c
··· 133 133 return ULONG_MAX; 134 134 else 135 135 return binary_runtime_size + sizeof(struct ima_kexec_hdr); 136 - }; 136 + } 137 137 138 138 static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) 139 139 {
+1 -1
security/integrity/integrity_audit.c
··· 47 47 ab = audit_log_start(audit_context(), GFP_KERNEL, audit_msgno); 48 48 audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", 49 49 task_pid_nr(current), 50 - from_kuid(&init_user_ns, current_cred()->uid), 50 + from_kuid(&init_user_ns, current_uid()), 51 51 from_kuid(&init_user_ns, audit_get_loginuid(current)), 52 52 audit_get_sessionid(current)); 53 53 audit_log_task_context(ab);