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

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

Pull integrity updates from Mimi Zohar:
"The nicest change is the IMA policy rule checking. The other changes
include allowing the kexec boot cmdline line measure policy rules to
be defined in terms of the inode associated with the kexec kernel
image, making the IMA_APPRAISE_BOOTPARAM, which governs the IMA
appraise mode (log, fix, enforce), a runtime decision based on the
secure boot mode of the system, and including errno in the audit log"

* tag 'integrity-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
integrity: remove redundant initialization of variable ret
ima: move APPRAISE_BOOTPARAM dependency on ARCH_POLICY to runtime
ima: AppArmor satisfies the audit rule requirements
ima: Rename internal filter rule functions
ima: Support additional conditionals in the KEXEC_CMDLINE hook function
ima: Use the common function to detect LSM conditionals in a rule
ima: Move comprehensive rule validation checks out of the token parser
ima: Use correct type for the args_p member of ima_rule_entry.lsm elements
ima: Shallow copy the args_p member of ima_rule_entry.lsm elements
ima: Fail rule parsing when appraise_flag=blacklist is unsupportable
ima: Fail rule parsing when the KEY_CHECK hook is combined with an invalid cond
ima: Fail rule parsing when the KEXEC_CMDLINE hook is combined with an invalid cond
ima: Fail rule parsing when buffer hook functions have an invalid action
ima: Free the entire rule if it fails to parse
ima: Free the entire rule when deleting a list of rules
ima: Have the LSM free its audit rule
IMA: Add audit log for failure conditions
integrity: Add errno field in audit message

+285 -142
+2 -2
include/linux/ima.h
··· 25 25 enum kernel_read_file_id id); 26 26 extern void ima_post_path_mknod(struct dentry *dentry); 27 27 extern int ima_file_hash(struct file *file, char *buf, size_t buf_size); 28 - extern void ima_kexec_cmdline(const void *buf, int size); 28 + extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size); 29 29 30 30 #ifdef CONFIG_IMA_KEXEC 31 31 extern void ima_add_kexec_buffer(struct kimage *image); ··· 103 103 return -EOPNOTSUPP; 104 104 } 105 105 106 - static inline void ima_kexec_cmdline(const void *buf, int size) {} 106 + static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) {} 107 107 #endif /* CONFIG_IMA */ 108 108 109 109 #ifndef CONFIG_IMA_KEXEC
+1 -1
kernel/kexec_file.c
··· 265 265 goto out; 266 266 } 267 267 268 - ima_kexec_cmdline(image->cmdline_buf, 268 + ima_kexec_cmdline(kernel_fd, image->cmdline_buf, 269 269 image->cmdline_buf_len - 1); 270 270 } 271 271
+1 -1
security/integrity/digsig_asymmetric.c
··· 79 79 struct public_key_signature pks; 80 80 struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; 81 81 struct key *key; 82 - int ret = -ENOMEM; 82 + int ret; 83 83 84 84 if (siglen <= sizeof(*hdr)) 85 85 return -EBADMSG;
+2 -2
security/integrity/ima/Kconfig
··· 54 54 55 55 config IMA_LSM_RULES 56 56 bool 57 - depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK) 57 + depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) 58 58 default y 59 59 help 60 60 Disabling this option will disregard LSM based policy rules. ··· 232 232 233 233 config IMA_APPRAISE_BOOTPARAM 234 234 bool "ima_appraise boot parameter" 235 - depends on IMA_APPRAISE && !IMA_ARCH_POLICY 235 + depends on IMA_APPRAISE 236 236 default y 237 237 help 238 238 This option enables the different "ima_appraise=" modes
+44 -29
security/integrity/ima/ima.h
··· 186 186 return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE; 187 187 } 188 188 189 - #define __ima_hooks(hook) \ 190 - hook(NONE) \ 191 - hook(FILE_CHECK) \ 192 - hook(MMAP_CHECK) \ 193 - hook(BPRM_CHECK) \ 194 - hook(CREDS_CHECK) \ 195 - hook(POST_SETATTR) \ 196 - hook(MODULE_CHECK) \ 197 - hook(FIRMWARE_CHECK) \ 198 - hook(KEXEC_KERNEL_CHECK) \ 199 - hook(KEXEC_INITRAMFS_CHECK) \ 200 - hook(POLICY_CHECK) \ 201 - hook(KEXEC_CMDLINE) \ 202 - hook(KEY_CHECK) \ 203 - hook(MAX_CHECK) 204 - #define __ima_hook_enumify(ENUM) ENUM, 189 + #define __ima_hooks(hook) \ 190 + hook(NONE, none) \ 191 + hook(FILE_CHECK, file) \ 192 + hook(MMAP_CHECK, mmap) \ 193 + hook(BPRM_CHECK, bprm) \ 194 + hook(CREDS_CHECK, creds) \ 195 + hook(POST_SETATTR, post_setattr) \ 196 + hook(MODULE_CHECK, module) \ 197 + hook(FIRMWARE_CHECK, firmware) \ 198 + hook(KEXEC_KERNEL_CHECK, kexec_kernel) \ 199 + hook(KEXEC_INITRAMFS_CHECK, kexec_initramfs) \ 200 + hook(POLICY_CHECK, policy) \ 201 + hook(KEXEC_CMDLINE, kexec_cmdline) \ 202 + hook(KEY_CHECK, key) \ 203 + hook(MAX_CHECK, none) 204 + 205 + #define __ima_hook_enumify(ENUM, str) ENUM, 206 + #define __ima_stringify(arg) (#arg) 207 + #define __ima_hook_measuring_stringify(ENUM, str) \ 208 + (__ima_stringify(measuring_ ##str)), 205 209 206 210 enum ima_hooks { 207 211 __ima_hooks(__ima_hook_enumify) 208 212 }; 213 + 214 + static const char * const ima_hooks_measure_str[] = { 215 + __ima_hooks(__ima_hook_measuring_stringify) 216 + }; 217 + 218 + static inline const char *func_measure_str(enum ima_hooks func) 219 + { 220 + if (func >= MAX_CHECK) 221 + return ima_hooks_measure_str[NONE]; 222 + 223 + return ima_hooks_measure_str[func]; 224 + } 209 225 210 226 extern const char *const func_tokens[]; 211 227 ··· 265 249 struct evm_ima_xattr_data *xattr_value, 266 250 int xattr_len, const struct modsig *modsig, int pcr, 267 251 struct ima_template_desc *template_desc); 268 - void process_buffer_measurement(const void *buf, int size, 252 + void process_buffer_measurement(struct inode *inode, const void *buf, int size, 269 253 const char *eventname, enum ima_hooks func, 270 254 int pcr, const char *keyring); 271 255 void ima_audit_measurement(struct integrity_iint_cache *iint, ··· 372 356 #endif /* CONFIG_IMA_APPRAISE */ 373 357 374 358 #ifdef CONFIG_IMA_APPRAISE_MODSIG 375 - bool ima_hook_supports_modsig(enum ima_hooks func); 376 359 int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, 377 360 struct modsig **modsig); 378 361 void ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size); ··· 381 366 u32 *data_len); 382 367 void ima_free_modsig(struct modsig *modsig); 383 368 #else 384 - static inline bool ima_hook_supports_modsig(enum ima_hooks func) 385 - { 386 - return false; 387 - } 388 - 389 369 static inline int ima_read_modsig(enum ima_hooks func, const void *buf, 390 370 loff_t buf_len, struct modsig **modsig) 391 371 { ··· 413 403 /* LSM based policy rules require audit */ 414 404 #ifdef CONFIG_IMA_LSM_RULES 415 405 416 - #define security_filter_rule_init security_audit_rule_init 417 - #define security_filter_rule_match security_audit_rule_match 406 + #define ima_filter_rule_init security_audit_rule_init 407 + #define ima_filter_rule_free security_audit_rule_free 408 + #define ima_filter_rule_match security_audit_rule_match 418 409 419 410 #else 420 411 421 - static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, 422 - void **lsmrule) 412 + static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr, 413 + void **lsmrule) 423 414 { 424 415 return -EINVAL; 425 416 } 426 417 427 - static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, 428 - void *lsmrule) 418 + static inline void ima_filter_rule_free(void *lsmrule) 419 + { 420 + } 421 + 422 + static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op, 423 + void *lsmrule) 429 424 { 430 425 return -EINVAL; 431 426 }
+1 -1
security/integrity/ima/ima_api.c
··· 162 162 163 163 /** 164 164 * ima_get_action - appraise & measure decision based on policy. 165 - * @inode: pointer to inode to measure 165 + * @inode: pointer to the inode associated with the object being validated 166 166 * @cred: pointer to credentials structure to validate 167 167 * @secid: secid of the task being validated 168 168 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,
+7 -1
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 + } 27 + 22 28 if (strncmp(str, "off", 3) == 0) 23 29 ima_appraise = 0; 24 30 else if (strncmp(str, "log", 3) == 0) ··· 334 328 335 329 rc = is_binary_blacklisted(digest, digestsize); 336 330 if ((rc == -EPERM) && (iint->flags & IMA_MEASURE)) 337 - process_buffer_measurement(digest, digestsize, 331 + process_buffer_measurement(NULL, digest, digestsize, 338 332 "blacklisted-hash", NONE, 339 333 pcr, NULL); 340 334 }
+1 -1
security/integrity/ima/ima_asymmetric_keys.c
··· 58 58 * if the IMA policy is configured to measure a key linked 59 59 * to the given keyring. 60 60 */ 61 - process_buffer_measurement(payload, payload_len, 61 + process_buffer_measurement(NULL, payload, payload_len, 62 62 keyring->description, KEY_CHECK, 0, 63 63 keyring->description); 64 64 }
+30 -11
security/integrity/ima/ima_main.c
··· 726 726 727 727 /* 728 728 * process_buffer_measurement - Measure the buffer to ima log. 729 + * @inode: inode associated with the object being measured (NULL for KEY_CHECK) 729 730 * @buf: pointer to the buffer that needs to be added to the log. 730 731 * @size: size of buffer(in bytes). 731 732 * @eventname: event name to be used for the buffer entry. ··· 736 735 * 737 736 * Based on policy, the buffer is measured into the ima log. 738 737 */ 739 - void process_buffer_measurement(const void *buf, int size, 738 + void process_buffer_measurement(struct inode *inode, const void *buf, int size, 740 739 const char *eventname, enum ima_hooks func, 741 740 int pcr, const char *keyring) 742 741 { 743 742 int ret = 0; 743 + const char *audit_cause = "ENOMEM"; 744 744 struct ima_template_entry *entry = NULL; 745 745 struct integrity_iint_cache iint = {}; 746 746 struct ima_event_data event_data = {.iint = &iint, ··· 769 767 */ 770 768 if (func) { 771 769 security_task_getsecid(current, &secid); 772 - action = ima_get_action(NULL, current_cred(), secid, 0, func, 770 + action = ima_get_action(inode, current_cred(), secid, 0, func, 773 771 &pcr, &template, keyring); 774 772 if (!(action & IMA_MEASURE)) 775 773 return; ··· 796 794 iint.ima_hash->length = hash_digest_size[ima_hash_algo]; 797 795 798 796 ret = ima_calc_buffer_hash(buf, size, iint.ima_hash); 799 - if (ret < 0) 797 + if (ret < 0) { 798 + audit_cause = "hashing_error"; 800 799 goto out; 800 + } 801 801 802 802 ret = ima_alloc_init_template(&event_data, &entry, template); 803 - if (ret < 0) 803 + if (ret < 0) { 804 + audit_cause = "alloc_entry"; 804 805 goto out; 806 + } 805 807 806 808 ret = ima_store_template(entry, violation, NULL, buf, pcr); 807 - 808 - if (ret < 0) 809 + if (ret < 0) { 810 + audit_cause = "store_entry"; 809 811 ima_free_template_entry(entry); 812 + } 810 813 811 814 out: 812 815 if (ret < 0) 813 - pr_devel("%s: failed, result: %d\n", __func__, ret); 816 + integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, eventname, 817 + func_measure_str(func), 818 + audit_cause, ret, 0, ret); 814 819 815 820 return; 816 821 } 817 822 818 823 /** 819 824 * ima_kexec_cmdline - measure kexec cmdline boot args 825 + * @kernel_fd: file descriptor of the kexec kernel being loaded 820 826 * @buf: pointer to buffer 821 827 * @size: size of buffer 822 828 * 823 829 * Buffers can only be measured, not appraised. 824 830 */ 825 - void ima_kexec_cmdline(const void *buf, int size) 831 + void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) 826 832 { 827 - if (buf && size != 0) 828 - process_buffer_measurement(buf, size, "kexec-cmdline", 829 - KEXEC_CMDLINE, 0, NULL); 833 + struct fd f; 834 + 835 + if (!buf || !size) 836 + return; 837 + 838 + f = fdget(kernel_fd); 839 + if (!f.file) 840 + return; 841 + 842 + process_buffer_measurement(file_inode(f.file), buf, size, 843 + "kexec-cmdline", KEXEC_CMDLINE, 0, NULL); 844 + fdput(f); 830 845 } 831 846 832 847 static int __init init_ima(void)
-20
security/integrity/ima/ima_modsig.c
··· 32 32 u8 raw_pkcs7[]; 33 33 }; 34 34 35 - /** 36 - * ima_hook_supports_modsig - can the policy allow modsig for this hook? 37 - * 38 - * modsig is only supported by hooks using ima_post_read_file(), because only 39 - * they preload the contents of the file in a buffer. FILE_CHECK does that in 40 - * some cases, but not when reached from vfs_open(). POLICY_CHECK can support 41 - * it, but it's not useful in practice because it's a text file so deny. 42 - */ 43 - bool ima_hook_supports_modsig(enum ima_hooks func) 44 - { 45 - switch (func) { 46 - case KEXEC_KERNEL_CHECK: 47 - case KEXEC_INITRAMFS_CHECK: 48 - case MODULE_CHECK: 49 - return true; 50 - default: 51 - return false; 52 - } 53 - } 54 - 55 35 /* 56 36 * ima_read_modsig - Read modsig from buf. 57 37 *
+167 -71
security/integrity/ima/ima_policy.c
··· 74 74 int pcr; 75 75 struct { 76 76 void *rule; /* LSM file metadata specific */ 77 - void *args_p; /* audit value */ 77 + char *args_p; /* audit value */ 78 78 int type; /* audit type */ 79 79 } lsm[MAX_LSM_RULES]; 80 80 char *fsname; ··· 258 258 int i; 259 259 260 260 for (i = 0; i < MAX_LSM_RULES; i++) { 261 - kfree(entry->lsm[i].rule); 261 + ima_filter_rule_free(entry->lsm[i].rule); 262 262 kfree(entry->lsm[i].args_p); 263 263 } 264 + } 265 + 266 + static void ima_free_rule(struct ima_rule_entry *entry) 267 + { 268 + if (!entry) 269 + return; 270 + 271 + /* 272 + * entry->template->fields may be allocated in ima_parse_rule() but that 273 + * reference is owned by the corresponding ima_template_desc element in 274 + * the defined_templates list and cannot be freed here 275 + */ 276 + kfree(entry->fsname); 277 + kfree(entry->keyrings); 278 + ima_lsm_free_rule(entry); 264 279 kfree(entry); 265 280 } 266 281 ··· 300 285 continue; 301 286 302 287 nentry->lsm[i].type = entry->lsm[i].type; 303 - nentry->lsm[i].args_p = kstrdup(entry->lsm[i].args_p, 304 - GFP_KERNEL); 305 - if (!nentry->lsm[i].args_p) 306 - goto out_err; 288 + nentry->lsm[i].args_p = entry->lsm[i].args_p; 289 + /* 290 + * Remove the reference from entry so that the associated 291 + * memory will not be freed during a later call to 292 + * ima_lsm_free_rule(entry). 293 + */ 294 + entry->lsm[i].args_p = NULL; 307 295 308 - security_filter_rule_init(nentry->lsm[i].type, 309 - Audit_equal, 310 - nentry->lsm[i].args_p, 311 - &nentry->lsm[i].rule); 296 + ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, 297 + nentry->lsm[i].args_p, 298 + &nentry->lsm[i].rule); 312 299 if (!nentry->lsm[i].rule) 313 300 pr_warn("rule for LSM \'%s\' is undefined\n", 314 - (char *)entry->lsm[i].args_p); 301 + nentry->lsm[i].args_p); 315 302 } 316 303 return nentry; 317 - 318 - out_err: 319 - ima_lsm_free_rule(nentry); 320 - return NULL; 321 304 } 322 305 323 306 static int ima_lsm_update_rule(struct ima_rule_entry *entry) ··· 328 315 329 316 list_replace_rcu(&entry->list, &nentry->list); 330 317 synchronize_rcu(); 318 + /* 319 + * ima_lsm_copy_rule() shallow copied all references, except for the 320 + * LSM references, from entry to nentry so we only want to free the LSM 321 + * references and the entry itself. All other memory refrences will now 322 + * be owned by nentry. 323 + */ 331 324 ima_lsm_free_rule(entry); 325 + kfree(entry); 332 326 333 327 return 0; 328 + } 329 + 330 + static bool ima_rule_contains_lsm_cond(struct ima_rule_entry *entry) 331 + { 332 + int i; 333 + 334 + for (i = 0; i < MAX_LSM_RULES; i++) 335 + if (entry->lsm[i].args_p) 336 + return true; 337 + 338 + return false; 334 339 } 335 340 336 341 /* ··· 359 328 static void ima_lsm_update_rules(void) 360 329 { 361 330 struct ima_rule_entry *entry, *e; 362 - int i, result, needs_update; 331 + int result; 363 332 364 333 list_for_each_entry_safe(entry, e, &ima_policy_rules, list) { 365 - needs_update = 0; 366 - for (i = 0; i < MAX_LSM_RULES; i++) { 367 - if (entry->lsm[i].args_p) { 368 - needs_update = 1; 369 - break; 370 - } 371 - } 372 - if (!needs_update) 334 + if (!ima_rule_contains_lsm_cond(entry)) 373 335 continue; 374 336 375 337 result = ima_lsm_update_rule(entry); ··· 442 418 { 443 419 int i; 444 420 445 - if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) { 446 - if ((rule->flags & IMA_FUNC) && (rule->func == func)) { 447 - if (func == KEY_CHECK) 448 - return ima_match_keyring(rule, keyring, cred); 449 - return true; 450 - } 451 - return false; 421 + if (func == KEY_CHECK) { 422 + return (rule->flags & IMA_FUNC) && (rule->func == func) && 423 + ima_match_keyring(rule, keyring, cred); 452 424 } 453 425 if ((rule->flags & IMA_FUNC) && 454 426 (rule->func != func && func != POST_SETATTR)) ··· 494 474 case LSM_OBJ_ROLE: 495 475 case LSM_OBJ_TYPE: 496 476 security_inode_getsecid(inode, &osid); 497 - rc = security_filter_rule_match(osid, 498 - rule->lsm[i].type, 499 - Audit_equal, 500 - rule->lsm[i].rule); 477 + rc = ima_filter_rule_match(osid, rule->lsm[i].type, 478 + Audit_equal, 479 + rule->lsm[i].rule); 501 480 break; 502 481 case LSM_SUBJ_USER: 503 482 case LSM_SUBJ_ROLE: 504 483 case LSM_SUBJ_TYPE: 505 - rc = security_filter_rule_match(secid, 506 - rule->lsm[i].type, 507 - Audit_equal, 508 - rule->lsm[i].rule); 484 + rc = ima_filter_rule_match(secid, rule->lsm[i].type, 485 + Audit_equal, 486 + rule->lsm[i].rule); 509 487 default: 510 488 break; 511 489 } ··· 898 880 return -ENOMEM; 899 881 900 882 entry->lsm[lsm_rule].type = audit_type; 901 - result = security_filter_rule_init(entry->lsm[lsm_rule].type, 902 - Audit_equal, 903 - entry->lsm[lsm_rule].args_p, 904 - &entry->lsm[lsm_rule].rule); 883 + result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, 884 + entry->lsm[lsm_rule].args_p, 885 + &entry->lsm[lsm_rule].rule); 905 886 if (!entry->lsm[lsm_rule].rule) { 906 887 pr_warn("rule for LSM \'%s\' is undefined\n", 907 - (char *)entry->lsm[lsm_rule].args_p); 888 + entry->lsm[lsm_rule].args_p); 908 889 909 890 if (ima_rules == &ima_default_rules) { 910 891 kfree(entry->lsm[lsm_rule].args_p); 892 + entry->lsm[lsm_rule].args_p = NULL; 911 893 result = -EINVAL; 912 894 } else 913 895 result = 0; ··· 965 947 966 948 checked = true; 967 949 #undef MSG 950 + } 951 + 952 + static bool ima_validate_rule(struct ima_rule_entry *entry) 953 + { 954 + /* Ensure that the action is set and is compatible with the flags */ 955 + if (entry->action == UNKNOWN) 956 + return false; 957 + 958 + if (entry->action != MEASURE && entry->flags & IMA_PCR) 959 + return false; 960 + 961 + if (entry->action != APPRAISE && 962 + entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | IMA_CHECK_BLACKLIST)) 963 + return false; 964 + 965 + /* 966 + * The IMA_FUNC bit must be set if and only if there's a valid hook 967 + * function specified, and vice versa. Enforcing this property allows 968 + * for the NONE case below to validate a rule without an explicit hook 969 + * function. 970 + */ 971 + if (((entry->flags & IMA_FUNC) && entry->func == NONE) || 972 + (!(entry->flags & IMA_FUNC) && entry->func != NONE)) 973 + return false; 974 + 975 + /* 976 + * Ensure that the hook function is compatible with the other 977 + * components of the rule 978 + */ 979 + switch (entry->func) { 980 + case NONE: 981 + case FILE_CHECK: 982 + case MMAP_CHECK: 983 + case BPRM_CHECK: 984 + case CREDS_CHECK: 985 + case POST_SETATTR: 986 + case FIRMWARE_CHECK: 987 + case POLICY_CHECK: 988 + if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 989 + IMA_UID | IMA_FOWNER | IMA_FSUUID | 990 + IMA_INMASK | IMA_EUID | IMA_PCR | 991 + IMA_FSNAME | IMA_DIGSIG_REQUIRED | 992 + IMA_PERMIT_DIRECTIO)) 993 + return false; 994 + 995 + break; 996 + case MODULE_CHECK: 997 + case KEXEC_KERNEL_CHECK: 998 + case KEXEC_INITRAMFS_CHECK: 999 + if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 1000 + IMA_UID | IMA_FOWNER | IMA_FSUUID | 1001 + IMA_INMASK | IMA_EUID | IMA_PCR | 1002 + IMA_FSNAME | IMA_DIGSIG_REQUIRED | 1003 + IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED | 1004 + IMA_CHECK_BLACKLIST)) 1005 + return false; 1006 + 1007 + break; 1008 + case KEXEC_CMDLINE: 1009 + if (entry->action & ~(MEASURE | DONT_MEASURE)) 1010 + return false; 1011 + 1012 + if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID | 1013 + IMA_FOWNER | IMA_FSUUID | IMA_EUID | 1014 + IMA_PCR | IMA_FSNAME)) 1015 + return false; 1016 + 1017 + break; 1018 + case KEY_CHECK: 1019 + if (entry->action & ~(MEASURE | DONT_MEASURE)) 1020 + return false; 1021 + 1022 + if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR | 1023 + IMA_KEYRINGS)) 1024 + return false; 1025 + 1026 + if (ima_rule_contains_lsm_cond(entry)) 1027 + return false; 1028 + 1029 + break; 1030 + default: 1031 + return false; 1032 + } 1033 + 1034 + /* Ensure that combinations of flags are compatible with each other */ 1035 + if (entry->flags & IMA_CHECK_BLACKLIST && 1036 + !(entry->flags & IMA_MODSIG_ALLOWED)) 1037 + return false; 1038 + 1039 + return true; 968 1040 } 969 1041 970 1042 static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) ··· 1234 1126 keyrings_len = strlen(args[0].from) + 1; 1235 1127 1236 1128 if ((entry->keyrings) || 1237 - (entry->action != MEASURE) || 1238 - (entry->func != KEY_CHECK) || 1239 1129 (keyrings_len < 2)) { 1240 1130 result = -EINVAL; 1241 1131 break; ··· 1373 1267 AUDIT_SUBJ_TYPE); 1374 1268 break; 1375 1269 case Opt_appraise_type: 1376 - if (entry->action != APPRAISE) { 1377 - result = -EINVAL; 1378 - break; 1379 - } 1380 - 1381 1270 ima_log_string(ab, "appraise_type", args[0].from); 1382 1271 if ((strcmp(args[0].from, "imasig")) == 0) 1383 1272 entry->flags |= IMA_DIGSIG_REQUIRED; 1384 - else if (ima_hook_supports_modsig(entry->func) && 1273 + else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) && 1385 1274 strcmp(args[0].from, "imasig|modsig") == 0) 1386 1275 entry->flags |= IMA_DIGSIG_REQUIRED | 1387 1276 IMA_MODSIG_ALLOWED; ··· 1385 1284 break; 1386 1285 case Opt_appraise_flag: 1387 1286 ima_log_string(ab, "appraise_flag", args[0].from); 1388 - if (strstr(args[0].from, "blacklist")) 1287 + if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) && 1288 + strstr(args[0].from, "blacklist")) 1389 1289 entry->flags |= IMA_CHECK_BLACKLIST; 1290 + else 1291 + result = -EINVAL; 1390 1292 break; 1391 1293 case Opt_permit_directio: 1392 1294 entry->flags |= IMA_PERMIT_DIRECTIO; 1393 1295 break; 1394 1296 case Opt_pcr: 1395 - if (entry->action != MEASURE) { 1396 - result = -EINVAL; 1397 - break; 1398 - } 1399 1297 ima_log_string(ab, "pcr", args[0].from); 1400 1298 1401 1299 result = kstrtoint(args[0].from, 10, &entry->pcr); ··· 1432 1332 break; 1433 1333 } 1434 1334 } 1435 - if (!result && (entry->action == UNKNOWN)) 1335 + if (!result && !ima_validate_rule(entry)) 1436 1336 result = -EINVAL; 1437 1337 else if (entry->action == APPRAISE) 1438 1338 temp_ima_appraise |= ima_appraise_flag(entry->func); ··· 1481 1381 1482 1382 result = ima_parse_rule(p, entry); 1483 1383 if (result) { 1484 - kfree(entry); 1384 + ima_free_rule(entry); 1485 1385 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 1486 1386 NULL, op, "invalid-policy", result, 1487 1387 audit_info); ··· 1502 1402 void ima_delete_rules(void) 1503 1403 { 1504 1404 struct ima_rule_entry *entry, *tmp; 1505 - int i; 1506 1405 1507 1406 temp_ima_appraise = 0; 1508 1407 list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) { 1509 - for (i = 0; i < MAX_LSM_RULES; i++) 1510 - kfree(entry->lsm[i].args_p); 1511 - 1512 1408 list_del(&entry->list); 1513 - kfree(entry); 1409 + ima_free_rule(entry); 1514 1410 } 1515 1411 } 1516 1412 1517 - #define __ima_hook_stringify(str) (#str), 1413 + #define __ima_hook_stringify(func, str) (#func), 1518 1414 1519 1415 const char *const func_tokens[] = { 1520 1416 __ima_hooks(__ima_hook_stringify) ··· 1685 1589 switch (i) { 1686 1590 case LSM_OBJ_USER: 1687 1591 seq_printf(m, pt(Opt_obj_user), 1688 - (char *)entry->lsm[i].args_p); 1592 + entry->lsm[i].args_p); 1689 1593 break; 1690 1594 case LSM_OBJ_ROLE: 1691 1595 seq_printf(m, pt(Opt_obj_role), 1692 - (char *)entry->lsm[i].args_p); 1596 + entry->lsm[i].args_p); 1693 1597 break; 1694 1598 case LSM_OBJ_TYPE: 1695 1599 seq_printf(m, pt(Opt_obj_type), 1696 - (char *)entry->lsm[i].args_p); 1600 + entry->lsm[i].args_p); 1697 1601 break; 1698 1602 case LSM_SUBJ_USER: 1699 1603 seq_printf(m, pt(Opt_subj_user), 1700 - (char *)entry->lsm[i].args_p); 1604 + entry->lsm[i].args_p); 1701 1605 break; 1702 1606 case LSM_SUBJ_ROLE: 1703 1607 seq_printf(m, pt(Opt_subj_role), 1704 - (char *)entry->lsm[i].args_p); 1608 + entry->lsm[i].args_p); 1705 1609 break; 1706 1610 case LSM_SUBJ_TYPE: 1707 1611 seq_printf(m, pt(Opt_subj_type), 1708 - (char *)entry->lsm[i].args_p); 1612 + entry->lsm[i].args_p); 1709 1613 break; 1710 1614 } 1711 1615 seq_puts(m, " ");
+6 -1
security/integrity/ima/ima_queue_keys.c
··· 68 68 size_t payload_len) 69 69 { 70 70 int rc = 0; 71 + const char *audit_cause = "ENOMEM"; 71 72 struct ima_key_entry *entry; 72 73 73 74 entry = kzalloc(sizeof(*entry), GFP_KERNEL); ··· 89 88 90 89 out: 91 90 if (rc) { 91 + integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, 92 + keyring->description, 93 + func_measure_str(KEY_CHECK), 94 + audit_cause, rc, 0, rc); 92 95 ima_free_key_entry(entry); 93 96 entry = NULL; 94 97 } ··· 158 153 159 154 list_for_each_entry_safe(entry, tmp, &ima_keys, list) { 160 155 if (!timer_expired) 161 - process_buffer_measurement(entry->payload, 156 + process_buffer_measurement(NULL, entry->payload, 162 157 entry->payload_len, 163 158 entry->keyring_name, 164 159 KEY_CHECK, 0,
+13
security/integrity/integrity.h
··· 239 239 const unsigned char *fname, const char *op, 240 240 const char *cause, int result, int info); 241 241 242 + void integrity_audit_message(int audit_msgno, struct inode *inode, 243 + const unsigned char *fname, const char *op, 244 + const char *cause, int result, int info, 245 + int errno); 246 + 242 247 static inline struct audit_buffer * 243 248 integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) 244 249 { ··· 255 250 const unsigned char *fname, 256 251 const char *op, const char *cause, 257 252 int result, int info) 253 + { 254 + } 255 + 256 + static inline void integrity_audit_message(int audit_msgno, 257 + struct inode *inode, 258 + const unsigned char *fname, 259 + const char *op, const char *cause, 260 + int result, int info, int errno) 258 261 { 259 262 } 260 263
+10 -1
security/integrity/integrity_audit.c
··· 29 29 const unsigned char *fname, const char *op, 30 30 const char *cause, int result, int audit_info) 31 31 { 32 + integrity_audit_message(audit_msgno, inode, fname, op, cause, 33 + result, audit_info, 0); 34 + } 35 + 36 + void integrity_audit_message(int audit_msgno, struct inode *inode, 37 + const unsigned char *fname, const char *op, 38 + const char *cause, int result, int audit_info, 39 + int errno) 40 + { 32 41 struct audit_buffer *ab; 33 42 char name[TASK_COMM_LEN]; 34 43 ··· 62 53 audit_log_untrustedstring(ab, inode->i_sb->s_id); 63 54 audit_log_format(ab, " ino=%lu", inode->i_ino); 64 55 } 65 - audit_log_format(ab, " res=%d", !result); 56 + audit_log_format(ab, " res=%d errno=%d", !result, errno); 66 57 audit_log_end(ab); 67 58 }