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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull integrity updates from Mimi Zohar:
"Bug fixes:

- defer credentials checking from the bprm_check_security hook to the
bprm_creds_from_file security hook

- properly ignore IMA policy rules based on undefined SELinux labels

IMA policy rule extensions:

- extend IMA to limit including file hashes in the audit logs
(dont_audit action)

- define a new filesystem subtype policy option (fs_subtype)

Misc:

- extend IMA to support in-kernel module decompression by deferring
the IMA signature verification in kernel_read_file() to after the
kernel module is decompressed"

* tag 'integrity-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
ima: Handle error code returned by ima_filter_rule_match()
ima: Access decompressed kernel module to verify appended signature
ima: add fs_subtype condition for distinguishing FUSE instances
ima: add dont_audit action to suppress audit actions
ima: Attach CREDS_CHECK IMA hook to bprm_creds_from_file LSM hook

+122 -27
+2 -1
Documentation/ABI/testing/ima_policy
··· 20 20 rule format: action [condition ...] 21 21 22 22 action: measure | dont_measure | appraise | dont_appraise | 23 - audit | hash | dont_hash 23 + audit | dont_audit | hash | dont_hash 24 24 condition:= base | lsm [option] 25 25 base: [[func=] [mask=] [fsmagic=] [fsuuid=] [fsname=] 26 + [fs_subtype=] 26 27 [uid=] [euid=] [gid=] [egid=] 27 28 [fowner=] [fgroup=]] 28 29 lsm: [[subj_user=] [subj_role=] [subj_type=]
+1
include/linux/kernel_read_file.h
··· 14 14 id(KEXEC_INITRAMFS, kexec-initramfs) \ 15 15 id(POLICY, security-policy) \ 16 16 id(X509_CERTIFICATE, x509-certificate) \ 17 + id(MODULE_COMPRESSED, kernel-module-compressed) \ 17 18 id(MAX_ID, ) 18 19 19 20 #define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
+14 -3
kernel/module/main.c
··· 3675 3675 3676 3676 static int init_module_from_file(struct file *f, const char __user * uargs, int flags) 3677 3677 { 3678 + bool compressed = !!(flags & MODULE_INIT_COMPRESSED_FILE); 3678 3679 struct load_info info = { }; 3679 3680 void *buf = NULL; 3680 3681 int len; 3682 + int err; 3681 3683 3682 - len = kernel_read_file(f, 0, &buf, INT_MAX, NULL, READING_MODULE); 3684 + len = kernel_read_file(f, 0, &buf, INT_MAX, NULL, 3685 + compressed ? READING_MODULE_COMPRESSED : 3686 + READING_MODULE); 3683 3687 if (len < 0) { 3684 3688 mod_stat_inc(&failed_kreads); 3685 3689 return len; 3686 3690 } 3687 3691 3688 - if (flags & MODULE_INIT_COMPRESSED_FILE) { 3689 - int err = module_decompress(&info, buf, len); 3692 + if (compressed) { 3693 + err = module_decompress(&info, buf, len); 3690 3694 vfree(buf); /* compressed data is no longer needed */ 3691 3695 if (err) { 3692 3696 mod_stat_inc(&failed_decompress); 3693 3697 mod_stat_add_long(len, &invalid_decompress_bytes); 3698 + return err; 3699 + } 3700 + err = security_kernel_post_read_file(f, (char *)info.hdr, info.len, 3701 + READING_MODULE); 3702 + if (err) { 3703 + mod_stat_inc(&failed_kreads); 3704 + free_copy(&info, flags); 3694 3705 return err; 3695 3706 } 3696 3707 } else {
+46 -14
security/integrity/ima/ima_main.c
··· 235 235 236 236 static int process_measurement(struct file *file, const struct cred *cred, 237 237 struct lsm_prop *prop, char *buf, loff_t size, 238 - int mask, enum ima_hooks func) 238 + int mask, enum ima_hooks func, 239 + enum kernel_read_file_id read_id) 239 240 { 240 241 struct inode *real_inode, *inode = file_inode(file); 241 242 struct ima_iint_cache *iint = NULL; ··· 407 406 if (rc != 0 && rc != -EBADF && rc != -EINVAL) 408 407 goto out_locked; 409 408 409 + /* Defer measuring/appraising kernel modules to READING_MODULE */ 410 + if (read_id == READING_MODULE_COMPRESSED) { 411 + must_appraise = 0; 412 + goto out_locked; 413 + } 414 + 410 415 if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ 411 416 pathname = ima_d_path(&file->f_path, &pathbuf, filename); 412 417 ··· 493 486 494 487 if (reqprot & PROT_EXEC) { 495 488 ret = process_measurement(file, current_cred(), &prop, NULL, 496 - 0, MAY_EXEC, MMAP_CHECK_REQPROT); 489 + 0, MAY_EXEC, MMAP_CHECK_REQPROT, 0); 497 490 if (ret) 498 491 return ret; 499 492 } 500 493 501 494 if (prot & PROT_EXEC) 502 495 return process_measurement(file, current_cred(), &prop, NULL, 503 - 0, MAY_EXEC, MMAP_CHECK); 496 + 0, MAY_EXEC, MMAP_CHECK, 0); 504 497 505 498 return 0; 506 499 } ··· 580 573 */ 581 574 static int ima_bprm_check(struct linux_binprm *bprm) 582 575 { 583 - int ret; 584 576 struct lsm_prop prop; 585 577 586 578 security_current_getlsmprop_subj(&prop); 587 - ret = process_measurement(bprm->file, current_cred(), 588 - &prop, NULL, 0, MAY_EXEC, BPRM_CHECK); 589 - if (ret) 590 - return ret; 579 + return process_measurement(bprm->file, current_cred(), 580 + &prop, NULL, 0, MAY_EXEC, BPRM_CHECK, 0); 581 + } 591 582 592 - security_cred_getlsmprop(bprm->cred, &prop); 593 - return process_measurement(bprm->file, bprm->cred, &prop, NULL, 0, 594 - MAY_EXEC, CREDS_CHECK); 583 + /** 584 + * ima_creds_check - based on policy, collect/store measurement. 585 + * @bprm: contains the linux_binprm structure 586 + * @file: contains the file descriptor of the binary being executed 587 + * 588 + * The OS protects against an executable file, already open for write, 589 + * from being executed in deny_write_access() and an executable file, 590 + * already open for execute, from being modified in get_write_access(). 591 + * So we can be certain that what we verify and measure here is actually 592 + * what is being executed. 593 + * 594 + * The difference from ima_bprm_check() is that ima_creds_check() is invoked 595 + * only after determining the final binary to be executed without interpreter, 596 + * and not when searching for intermediate binaries. The reason is that since 597 + * commit 56305aa9b6fab ("exec: Compute file based creds only once"), the 598 + * credentials to be applied to the process are calculated only at that stage 599 + * (bprm_creds_from_file security hook instead of bprm_check_security). 600 + * 601 + * On success return 0. On integrity appraisal error, assuming the file 602 + * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. 603 + */ 604 + static int ima_creds_check(struct linux_binprm *bprm, const struct file *file) 605 + { 606 + struct lsm_prop prop; 607 + 608 + security_current_getlsmprop_subj(&prop); 609 + return process_measurement((struct file *)file, bprm->cred, &prop, NULL, 610 + 0, MAY_EXEC, CREDS_CHECK, 0); 595 611 } 596 612 597 613 /** ··· 662 632 security_current_getlsmprop_subj(&prop); 663 633 return process_measurement(file, current_cred(), &prop, NULL, 0, 664 634 mask & (MAY_READ | MAY_WRITE | MAY_EXEC | 665 - MAY_APPEND), FILE_CHECK); 635 + MAY_APPEND), FILE_CHECK, 0); 666 636 } 667 637 668 638 static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf, ··· 881 851 func = read_idmap[read_id] ?: FILE_CHECK; 882 852 security_current_getlsmprop_subj(&prop); 883 853 return process_measurement(file, current_cred(), &prop, NULL, 0, 884 - MAY_READ, func); 854 + MAY_READ, func, 0); 885 855 } 886 856 887 857 const int read_idmap[READING_MAX_ID] = { 888 858 [READING_FIRMWARE] = FIRMWARE_CHECK, 889 859 [READING_MODULE] = MODULE_CHECK, 860 + [READING_MODULE_COMPRESSED] = MODULE_CHECK, 890 861 [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK, 891 862 [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK, 892 863 [READING_POLICY] = POLICY_CHECK ··· 925 894 func = read_idmap[read_id] ?: FILE_CHECK; 926 895 security_current_getlsmprop_subj(&prop); 927 896 return process_measurement(file, current_cred(), &prop, buf, size, 928 - MAY_READ, func); 897 + MAY_READ, func, read_id); 929 898 } 930 899 931 900 /** ··· 1273 1242 static struct security_hook_list ima_hooks[] __ro_after_init = { 1274 1243 LSM_HOOK_INIT(bprm_check_security, ima_bprm_check), 1275 1244 LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec), 1245 + LSM_HOOK_INIT(bprm_creds_from_file, ima_creds_check), 1276 1246 LSM_HOOK_INIT(file_post_open, ima_file_check), 1277 1247 LSM_HOOK_INIT(inode_post_create_tmpfile, ima_post_create_tmpfile), 1278 1248 LSM_HOOK_INIT(file_release, ima_file_free),
+55 -7
security/integrity/ima/ima_policy.c
··· 38 38 #define IMA_GID 0x2000 39 39 #define IMA_EGID 0x4000 40 40 #define IMA_FGROUP 0x8000 41 + #define IMA_FS_SUBTYPE 0x10000 41 42 42 43 #define UNKNOWN 0 43 44 #define MEASURE 0x0001 /* same as IMA_MEASURE */ ··· 46 45 #define APPRAISE 0x0004 /* same as IMA_APPRAISE */ 47 46 #define DONT_APPRAISE 0x0008 48 47 #define AUDIT 0x0040 48 + #define DONT_AUDIT 0x0080 49 49 #define HASH 0x0100 50 50 #define DONT_HASH 0x0200 51 51 ··· 121 119 int type; /* audit type */ 122 120 } lsm[MAX_LSM_RULES]; 123 121 char *fsname; 122 + char *fs_subtype; 124 123 struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ 125 124 struct ima_rule_opt_list *label; /* Measure data grouped under this label */ 126 125 struct ima_template_desc *template; ··· 244 241 245 242 static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { 246 243 {.action = APPRAISE, .func = MODULE_CHECK, 247 - .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 244 + .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | 245 + IMA_CHECK_BLACKLIST}, 248 246 {.action = APPRAISE, .func = FIRMWARE_CHECK, 249 247 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 250 248 {.action = APPRAISE, .func = KEXEC_KERNEL_CHECK, ··· 401 397 * the defined_templates list and cannot be freed here 402 398 */ 403 399 kfree(entry->fsname); 400 + kfree(entry->fs_subtype); 404 401 ima_free_rule_opt_list(entry->keyrings); 405 402 ima_lsm_free_rule(entry); 406 403 kfree(entry); ··· 606 601 if ((rule->flags & IMA_FSNAME) 607 602 && strcmp(rule->fsname, inode->i_sb->s_type->name)) 608 603 return false; 604 + if (rule->flags & IMA_FS_SUBTYPE) { 605 + if (!inode->i_sb->s_subtype) 606 + return false; 607 + if (strcmp(rule->fs_subtype, inode->i_sb->s_subtype)) 608 + return false; 609 + } 609 610 if ((rule->flags & IMA_FSUUID) && 610 611 !uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid)) 611 612 return false; ··· 685 674 goto retry; 686 675 } 687 676 } 688 - if (!rc) { 677 + if (rc <= 0) { 689 678 result = false; 690 679 goto out; 691 680 } ··· 1075 1064 enum policy_opt { 1076 1065 Opt_measure, Opt_dont_measure, 1077 1066 Opt_appraise, Opt_dont_appraise, 1078 - Opt_audit, Opt_hash, Opt_dont_hash, 1067 + Opt_audit, Opt_dont_audit, Opt_hash, Opt_dont_hash, 1079 1068 Opt_obj_user, Opt_obj_role, Opt_obj_type, 1080 1069 Opt_subj_user, Opt_subj_role, Opt_subj_type, 1081 - Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fsuuid, 1070 + Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fs_subtype, Opt_fsuuid, 1082 1071 Opt_uid_eq, Opt_euid_eq, Opt_gid_eq, Opt_egid_eq, 1083 1072 Opt_fowner_eq, Opt_fgroup_eq, 1084 1073 Opt_uid_gt, Opt_euid_gt, Opt_gid_gt, Opt_egid_gt, ··· 1097 1086 {Opt_appraise, "appraise"}, 1098 1087 {Opt_dont_appraise, "dont_appraise"}, 1099 1088 {Opt_audit, "audit"}, 1089 + {Opt_dont_audit, "dont_audit"}, 1100 1090 {Opt_hash, "hash"}, 1101 1091 {Opt_dont_hash, "dont_hash"}, 1102 1092 {Opt_obj_user, "obj_user=%s"}, ··· 1110 1098 {Opt_mask, "mask=%s"}, 1111 1099 {Opt_fsmagic, "fsmagic=%s"}, 1112 1100 {Opt_fsname, "fsname=%s"}, 1101 + {Opt_fs_subtype, "fs_subtype=%s"}, 1113 1102 {Opt_fsuuid, "fsuuid=%s"}, 1114 1103 {Opt_uid_eq, "uid=%s"}, 1115 1104 {Opt_euid_eq, "euid=%s"}, ··· 1295 1282 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 1296 1283 IMA_UID | IMA_FOWNER | IMA_FSUUID | 1297 1284 IMA_INMASK | IMA_EUID | IMA_PCR | 1298 - IMA_FSNAME | IMA_GID | IMA_EGID | 1285 + IMA_FSNAME | IMA_FS_SUBTYPE | 1286 + IMA_GID | IMA_EGID | 1299 1287 IMA_FGROUP | IMA_DIGSIG_REQUIRED | 1300 1288 IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS | 1301 1289 IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED)) ··· 1309 1295 if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | 1310 1296 IMA_UID | IMA_FOWNER | IMA_FSUUID | 1311 1297 IMA_INMASK | IMA_EUID | IMA_PCR | 1312 - IMA_FSNAME | IMA_GID | IMA_EGID | 1298 + IMA_FSNAME | IMA_FS_SUBTYPE | 1299 + IMA_GID | IMA_EGID | 1313 1300 IMA_FGROUP | IMA_DIGSIG_REQUIRED | 1314 1301 IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED | 1315 1302 IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) ··· 1323 1308 1324 1309 if (entry->flags & ~(IMA_FUNC | IMA_FSMAGIC | IMA_UID | 1325 1310 IMA_FOWNER | IMA_FSUUID | IMA_EUID | 1326 - IMA_PCR | IMA_FSNAME | IMA_GID | IMA_EGID | 1311 + IMA_PCR | IMA_FSNAME | IMA_FS_SUBTYPE | 1312 + IMA_GID | IMA_EGID | 1327 1313 IMA_FGROUP)) 1328 1314 return false; 1329 1315 ··· 1494 1478 1495 1479 entry->action = AUDIT; 1496 1480 break; 1481 + case Opt_dont_audit: 1482 + ima_log_string(ab, "action", "dont_audit"); 1483 + 1484 + if (entry->action != UNKNOWN) 1485 + result = -EINVAL; 1486 + 1487 + entry->action = DONT_AUDIT; 1488 + break; 1497 1489 case Opt_hash: 1498 1490 ima_log_string(ab, "action", "hash"); 1499 1491 ··· 1610 1586 } 1611 1587 result = 0; 1612 1588 entry->flags |= IMA_FSNAME; 1589 + break; 1590 + case Opt_fs_subtype: 1591 + ima_log_string(ab, "fs_subtype", args[0].from); 1592 + 1593 + if (entry->fs_subtype) { 1594 + result = -EINVAL; 1595 + break; 1596 + } 1597 + 1598 + entry->fs_subtype = kstrdup(args[0].from, GFP_KERNEL); 1599 + if (!entry->fs_subtype) { 1600 + result = -ENOMEM; 1601 + break; 1602 + } 1603 + result = 0; 1604 + entry->flags |= IMA_FS_SUBTYPE; 1613 1605 break; 1614 1606 case Opt_keyrings: 1615 1607 ima_log_string(ab, "keyrings", args[0].from); ··· 2137 2097 seq_puts(m, pt(Opt_dont_appraise)); 2138 2098 if (entry->action & AUDIT) 2139 2099 seq_puts(m, pt(Opt_audit)); 2100 + if (entry->action & DONT_AUDIT) 2101 + seq_puts(m, pt(Opt_dont_audit)); 2140 2102 if (entry->action & HASH) 2141 2103 seq_puts(m, pt(Opt_hash)); 2142 2104 if (entry->action & DONT_HASH) ··· 2172 2130 if (entry->flags & IMA_FSNAME) { 2173 2131 snprintf(tbuf, sizeof(tbuf), "%s", entry->fsname); 2174 2132 seq_printf(m, pt(Opt_fsname), tbuf); 2133 + seq_puts(m, " "); 2134 + } 2135 + 2136 + if (entry->flags & IMA_FS_SUBTYPE) { 2137 + snprintf(tbuf, sizeof(tbuf), "%s", entry->fs_subtype); 2138 + seq_printf(m, pt(Opt_fs_subtype), tbuf); 2175 2139 seq_puts(m, " "); 2176 2140 } 2177 2141
+1
security/ipe/hooks.c
··· 118 118 op = IPE_OP_FIRMWARE; 119 119 break; 120 120 case READING_MODULE: 121 + case READING_MODULE_COMPRESSED: 121 122 op = IPE_OP_KERNEL_MODULE; 122 123 break; 123 124 case READING_KEXEC_INITRAMFS:
+3 -2
security/selinux/hooks.c
··· 4296 4296 { 4297 4297 int rc = 0; 4298 4298 4299 - BUILD_BUG_ON_MSG(READING_MAX_ID > 7, 4299 + BUILD_BUG_ON_MSG(READING_MAX_ID > 8, 4300 4300 "New kernel_read_file_id introduced; update SELinux!"); 4301 4301 4302 4302 switch (id) { ··· 4304 4304 rc = selinux_kernel_load_from_file(file, SYSTEM__FIRMWARE_LOAD); 4305 4305 break; 4306 4306 case READING_MODULE: 4307 + case READING_MODULE_COMPRESSED: 4307 4308 rc = selinux_kernel_load_from_file(file, SYSTEM__MODULE_LOAD); 4308 4309 break; 4309 4310 case READING_KEXEC_IMAGE: ··· 4333 4332 { 4334 4333 int rc = 0; 4335 4334 4336 - BUILD_BUG_ON_MSG(LOADING_MAX_ID > 7, 4335 + BUILD_BUG_ON_MSG(LOADING_MAX_ID > 8, 4337 4336 "New kernel_load_data_id introduced; update SELinux!"); 4338 4337 4339 4338 switch (id) {