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

Merge branch 'measure-critical-data' into next-integrity

From "IMA: support for measuring kernel integrity critical data"
coverletter.

IMA measures files and buffer data such as keys, command-line arguments
passed to the kernel on kexec system call, etc. While these measurements
are necessary for monitoring and validating the integrity of the system,
they are not sufficient. Various data structures, policies, and states
stored in kernel memory also impact the integrity of the system.
Several kernel subsystems contain such integrity critical data -
e.g. LSMs like SELinux, AppArmor etc. or device-mapper targets like
dm-crypt, dm-verity, dm-integrity etc. These kernel subsystems help
protect the integrity of a system. Their integrity critical data is not
expected to change frequently during run-time. Some of these structures
cannot be defined as __ro_after_init, because they are initialized later.

For a given system, various external services/infrastructure tools
(including the attestation service) interact with it - both during the
setup and during rest of the system run-time. They share sensitive data
and/or execute critical workload on that system. The external services
may want to verify the current run-time state of the relevant kernel
subsystems before fully trusting the system with business critical
data/workload. For instance, verifying that SELinux is in "enforce" mode
along with the expected policy, disks are encrypted with a certain
configuration, secure boot is enabled etc.

This series provides the necessary IMA functionality for kernel
subsystems to ensure their configuration can be measured:
- by kernel subsystems themselves,
- in a tamper resistant way,
- and re-measured - triggered on state/configuration change.

This patch set:
- defines a new IMA hook ima_measure_critical_data() to measure
integrity critical data,
- limits the critical data being measured based on a label,
- defines a builtin critical data measurement policy,
- and includes an SELinux consumer of the new IMA critical data hook.

+304 -50
+4 -1
Documentation/ABI/testing/ima_policy
··· 32 32 func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK]MODULE_CHECK] 33 33 [FIRMWARE_CHECK] 34 34 [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] 35 - [KEXEC_CMDLINE] [KEY_CHECK] 35 + [KEXEC_CMDLINE] [KEY_CHECK] [CRITICAL_DATA] 36 36 mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] 37 37 [[^]MAY_EXEC] 38 38 fsmagic:= hex value ··· 52 52 template:= name of a defined IMA template type 53 53 (eg, ima-ng). Only valid when action is "measure". 54 54 pcr:= decimal value 55 + label:= [selinux]|[data_label] 56 + data_label:= a unique string used for grouping and limiting critical data. 57 + For example, "selinux" to measure critical data for SELinux. 55 58 56 59 default policy: 57 60 # PROC_SUPER_MAGIC
+4 -1
Documentation/admin-guide/kernel-parameters.txt
··· 1746 1746 ima_policy= [IMA] 1747 1747 The builtin policies to load during IMA setup. 1748 1748 Format: "tcb | appraise_tcb | secure_boot | 1749 - fail_securely" 1749 + fail_securely | critical_data" 1750 1750 1751 1751 The "tcb" policy measures all programs exec'd, files 1752 1752 mmap'd for exec, and all files opened with the read ··· 1764 1764 verification failure also on privileged mounted 1765 1765 filesystems with the SB_I_UNVERIFIABLE_SIGNATURE 1766 1766 flag. 1767 + 1768 + The "critical_data" policy measures kernel integrity 1769 + critical data. 1767 1770 1768 1771 ima_tcb [IMA] Deprecated. Use ima_policy= instead. 1769 1772 Load a policy which meets the needs of the Trusted
+10
include/linux/ima.h
··· 31 31 extern int ima_file_hash(struct file *file, char *buf, size_t buf_size); 32 32 extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size); 33 33 extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size); 34 + extern void ima_measure_critical_data(const char *event_label, 35 + const char *event_name, 36 + const void *buf, size_t buf_len, 37 + bool hash); 34 38 35 39 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM 36 40 extern void ima_appraise_parse_cmdline(void); ··· 132 128 } 133 129 134 130 static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) {} 131 + 132 + static inline void ima_measure_critical_data(const char *event_label, 133 + const char *event_name, 134 + const void *buf, size_t buf_len, 135 + bool hash) {} 136 + 135 137 #endif /* CONFIG_IMA */ 136 138 137 139 #ifndef CONFIG_IMA_KEXEC
+5 -3
security/integrity/ima/ima.h
··· 201 201 hook(POLICY_CHECK, policy) \ 202 202 hook(KEXEC_CMDLINE, kexec_cmdline) \ 203 203 hook(KEY_CHECK, key) \ 204 + hook(CRITICAL_DATA, critical_data) \ 204 205 hook(MAX_CHECK, none) 205 206 206 207 #define __ima_hook_enumify(ENUM, str) ENUM, ··· 257 256 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, 258 257 int mask, enum ima_hooks func, int *pcr, 259 258 struct ima_template_desc **template_desc, 260 - const char *keyring); 259 + const char *func_data); 261 260 int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); 262 261 int ima_collect_measurement(struct integrity_iint_cache *iint, 263 262 struct file *file, void *buf, loff_t size, ··· 269 268 struct ima_template_desc *template_desc); 270 269 void process_buffer_measurement(struct inode *inode, const void *buf, int size, 271 270 const char *eventname, enum ima_hooks func, 272 - int pcr, const char *keyring); 271 + int pcr, const char *func_data, 272 + bool buf_hash); 273 273 void ima_audit_measurement(struct integrity_iint_cache *iint, 274 274 const unsigned char *filename); 275 275 int ima_alloc_init_template(struct ima_event_data *event_data, ··· 286 284 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, 287 285 enum ima_hooks func, int mask, int flags, int *pcr, 288 286 struct ima_template_desc **template_desc, 289 - const char *keyring); 287 + const char *func_data); 290 288 void ima_init_policy(void); 291 289 void ima_update_policy(void); 292 290 void ima_update_policy_flag(void);
+4 -4
security/integrity/ima/ima_api.c
··· 170 170 * @func: caller identifier 171 171 * @pcr: pointer filled in if matched measure policy sets pcr= 172 172 * @template_desc: pointer filled in if matched measure policy sets template= 173 - * @keyring: keyring name used to determine the action 173 + * @func_data: func specific data, may be NULL 174 174 * 175 175 * The policy is defined in terms of keypairs: 176 176 * subj=, obj=, type=, func=, mask=, fsmagic= 177 177 * subj,obj, and type: are LSM specific. 178 178 * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK 179 - * | KEXEC_CMDLINE | KEY_CHECK 179 + * | KEXEC_CMDLINE | KEY_CHECK | CRITICAL_DATA 180 180 * mask: contains the permission mask 181 181 * fsmagic: hex value 182 182 * ··· 186 186 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, 187 187 int mask, enum ima_hooks func, int *pcr, 188 188 struct ima_template_desc **template_desc, 189 - const char *keyring) 189 + const char *func_data) 190 190 { 191 191 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH; 192 192 193 193 flags &= ima_policy_flag; 194 194 195 195 return ima_match_policy(inode, cred, secid, func, mask, flags, pcr, 196 - template_desc, keyring); 196 + template_desc, func_data); 197 197 } 198 198 199 199 /*
+1 -1
security/integrity/ima/ima_appraise.c
··· 352 352 if ((rc == -EPERM) && (iint->flags & IMA_MEASURE)) 353 353 process_buffer_measurement(NULL, digest, digestsize, 354 354 "blacklisted-hash", NONE, 355 - pcr, NULL); 355 + pcr, NULL, false); 356 356 } 357 357 358 358 return rc;
+1 -1
security/integrity/ima/ima_asymmetric_keys.c
··· 60 60 */ 61 61 process_buffer_measurement(NULL, payload, payload_len, 62 62 keyring->description, KEY_CHECK, 0, 63 - keyring->description); 63 + keyring->description, false); 64 64 }
+52 -7
security/integrity/ima/ima_main.c
··· 809 809 } 810 810 811 811 /* 812 - * process_buffer_measurement - Measure the buffer to ima log. 812 + * process_buffer_measurement - Measure the buffer or the buffer data hash 813 813 * @inode: inode associated with the object being measured (NULL for KEY_CHECK) 814 814 * @buf: pointer to the buffer that needs to be added to the log. 815 815 * @size: size of buffer(in bytes). 816 816 * @eventname: event name to be used for the buffer entry. 817 817 * @func: IMA hook 818 818 * @pcr: pcr to extend the measurement 819 - * @keyring: keyring name to determine the action to be performed 819 + * @func_data: func specific data, may be NULL 820 + * @buf_hash: measure buffer data hash 820 821 * 821 - * Based on policy, the buffer is measured into the ima log. 822 + * Based on policy, either the buffer data or buffer data hash is measured 822 823 */ 823 824 void process_buffer_measurement(struct inode *inode, const void *buf, int size, 824 825 const char *eventname, enum ima_hooks func, 825 - int pcr, const char *keyring) 826 + int pcr, const char *func_data, 827 + bool buf_hash) 826 828 { 827 829 int ret = 0; 828 830 const char *audit_cause = "ENOMEM"; ··· 839 837 struct ima_digest_data hdr; 840 838 char digest[IMA_MAX_DIGEST_SIZE]; 841 839 } hash = {}; 840 + char digest_hash[IMA_MAX_DIGEST_SIZE]; 841 + int digest_hash_len = hash_digest_size[ima_hash_algo]; 842 842 int violation = 0; 843 843 int action = 0; 844 844 u32 secid; ··· 865 861 if (func) { 866 862 security_task_getsecid(current, &secid); 867 863 action = ima_get_action(inode, current_cred(), secid, 0, func, 868 - &pcr, &template, keyring); 864 + &pcr, &template, func_data); 869 865 if (!(action & IMA_MEASURE)) 870 866 return; 871 867 } ··· 883 879 goto out; 884 880 } 885 881 882 + if (buf_hash) { 883 + memcpy(digest_hash, hash.hdr.digest, digest_hash_len); 884 + 885 + ret = ima_calc_buffer_hash(digest_hash, digest_hash_len, 886 + iint.ima_hash); 887 + if (ret < 0) { 888 + audit_cause = "hashing_error"; 889 + goto out; 890 + } 891 + 892 + event_data.buf = digest_hash; 893 + event_data.buf_len = digest_hash_len; 894 + } 895 + 886 896 ret = ima_alloc_init_template(&event_data, &entry, template); 887 897 if (ret < 0) { 888 898 audit_cause = "alloc_entry"; 889 899 goto out; 890 900 } 891 901 892 - ret = ima_store_template(entry, violation, NULL, buf, pcr); 902 + ret = ima_store_template(entry, violation, NULL, event_data.buf, pcr); 893 903 if (ret < 0) { 894 904 audit_cause = "store_entry"; 895 905 ima_free_template_entry(entry); ··· 938 920 return; 939 921 940 922 process_buffer_measurement(file_inode(f.file), buf, size, 941 - "kexec-cmdline", KEXEC_CMDLINE, 0, NULL); 923 + "kexec-cmdline", KEXEC_CMDLINE, 0, NULL, 924 + false); 942 925 fdput(f); 926 + } 927 + 928 + /** 929 + * ima_measure_critical_data - measure kernel integrity critical data 930 + * @event_label: unique event label for grouping and limiting critical data 931 + * @event_name: event name for the record in the IMA measurement list 932 + * @buf: pointer to buffer data 933 + * @buf_len: length of buffer data (in bytes) 934 + * @hash: measure buffer data hash 935 + * 936 + * Measure data critical to the integrity of the kernel into the IMA log 937 + * and extend the pcr. Examples of critical data could be various data 938 + * structures, policies, and states stored in kernel memory that can 939 + * impact the integrity of the system. 940 + */ 941 + void ima_measure_critical_data(const char *event_label, 942 + const char *event_name, 943 + const void *buf, size_t buf_len, 944 + bool hash) 945 + { 946 + if (!event_name || !event_label || !buf || !buf_len) 947 + return; 948 + 949 + process_buffer_measurement(NULL, buf, buf_len, event_name, 950 + CRITICAL_DATA, 0, event_label, 951 + hash); 943 952 } 944 953 945 954 static int __init init_ima(void)
+94 -21
security/integrity/ima/ima_policy.c
··· 34 34 #define IMA_PCR 0x0100 35 35 #define IMA_FSNAME 0x0200 36 36 #define IMA_KEYRINGS 0x0400 37 + #define IMA_LABEL 0x0800 37 38 38 39 #define UNKNOWN 0 39 40 #define MEASURE 0x0001 /* same as IMA_MEASURE */ ··· 86 85 } lsm[MAX_LSM_RULES]; 87 86 char *fsname; 88 87 struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */ 88 + struct ima_rule_opt_list *label; /* Measure data grouped under this label */ 89 89 struct ima_template_desc *template; 90 90 }; 91 91 ··· 206 204 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 207 205 }; 208 206 207 + static struct ima_rule_entry critical_data_rules[] __ro_after_init = { 208 + {.action = MEASURE, .func = CRITICAL_DATA, .flags = IMA_FUNC}, 209 + }; 210 + 209 211 /* An array of architecture specific rules */ 210 212 static struct ima_rule_entry *arch_policy_entry __ro_after_init; 211 213 ··· 232 226 233 227 static bool ima_use_appraise_tcb __initdata; 234 228 static bool ima_use_secure_boot __initdata; 229 + static bool ima_use_critical_data __initdata; 235 230 static bool ima_fail_unverifiable_sigs __ro_after_init; 236 231 static int __init policy_setup(char *str) 237 232 { ··· 247 240 ima_use_appraise_tcb = true; 248 241 else if (strcmp(p, "secure_boot") == 0) 249 242 ima_use_secure_boot = true; 243 + else if (strcmp(p, "critical_data") == 0) 244 + ima_use_critical_data = true; 250 245 else if (strcmp(p, "fail_securely") == 0) 251 246 ima_fail_unverifiable_sigs = true; 252 247 else ··· 462 453 } 463 454 464 455 /** 465 - * ima_match_keyring - determine whether the keyring matches the measure rule 456 + * ima_match_rule_data - determine whether func_data matches the policy rule 466 457 * @rule: a pointer to a rule 467 - * @keyring: name of the keyring to match against the measure rule 458 + * @func_data: data to match against the measure rule data 468 459 * @cred: a pointer to a credentials structure for user validation 469 460 * 470 - * Returns true if keyring matches one in the rule, false otherwise. 461 + * Returns true if func_data matches one in the rule, false otherwise. 471 462 */ 472 - static bool ima_match_keyring(struct ima_rule_entry *rule, 473 - const char *keyring, const struct cred *cred) 463 + static bool ima_match_rule_data(struct ima_rule_entry *rule, 464 + const char *func_data, 465 + const struct cred *cred) 474 466 { 467 + const struct ima_rule_opt_list *opt_list = NULL; 475 468 bool matched = false; 476 469 size_t i; 477 470 478 471 if ((rule->flags & IMA_UID) && !rule->uid_op(cred->uid, rule->uid)) 479 472 return false; 480 473 481 - if (!rule->keyrings) 482 - return true; 474 + switch (rule->func) { 475 + case KEY_CHECK: 476 + if (!rule->keyrings) 477 + return true; 483 478 484 - if (!keyring) 479 + opt_list = rule->keyrings; 480 + break; 481 + case CRITICAL_DATA: 482 + if (!rule->label) 483 + return true; 484 + 485 + opt_list = rule->label; 486 + break; 487 + default: 488 + return false; 489 + } 490 + 491 + if (!func_data) 485 492 return false; 486 493 487 - for (i = 0; i < rule->keyrings->count; i++) { 488 - if (!strcmp(rule->keyrings->items[i], keyring)) { 494 + for (i = 0; i < opt_list->count; i++) { 495 + if (!strcmp(opt_list->items[i], func_data)) { 489 496 matched = true; 490 497 break; 491 498 } ··· 518 493 * @secid: the secid of the task to be validated 519 494 * @func: LIM hook identifier 520 495 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 521 - * @keyring: keyring name to check in policy for KEY_CHECK func 496 + * @func_data: func specific data, may be NULL 522 497 * 523 498 * Returns true on rule match, false on failure. 524 499 */ 525 500 static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, 526 501 const struct cred *cred, u32 secid, 527 502 enum ima_hooks func, int mask, 528 - const char *keyring) 503 + const char *func_data) 529 504 { 530 505 int i; 531 506 532 - if (func == KEY_CHECK) { 533 - return (rule->flags & IMA_FUNC) && (rule->func == func) && 534 - ima_match_keyring(rule, keyring, cred); 535 - } 536 507 if ((rule->flags & IMA_FUNC) && 537 508 (rule->func != func && func != POST_SETATTR)) 538 509 return false; 510 + 511 + switch (func) { 512 + case KEY_CHECK: 513 + case CRITICAL_DATA: 514 + return ((rule->func == func) && 515 + ima_match_rule_data(rule, func_data, cred)); 516 + default: 517 + break; 518 + } 519 + 539 520 if ((rule->flags & IMA_MASK) && 540 521 (rule->mask != mask && func != POST_SETATTR)) 541 522 return false; ··· 641 610 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 642 611 * @pcr: set the pcr to extend 643 612 * @template_desc: the template that should be used for this rule 644 - * @keyring: the keyring name, if given, to be used to check in the policy. 645 - * keyring can be NULL if func is anything other than KEY_CHECK. 613 + * @func_data: func specific data, may be NULL 646 614 * 647 615 * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type) 648 616 * conditions. ··· 653 623 int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, 654 624 enum ima_hooks func, int mask, int flags, int *pcr, 655 625 struct ima_template_desc **template_desc, 656 - const char *keyring) 626 + const char *func_data) 657 627 { 658 628 struct ima_rule_entry *entry; 659 629 int action = 0, actmask = flags | (flags << 1); ··· 668 638 continue; 669 639 670 640 if (!ima_match_rules(entry, inode, cred, secid, func, mask, 671 - keyring)) 641 + func_data)) 672 642 continue; 673 643 674 644 action |= entry->flags & IMA_ACTION_FLAGS; ··· 878 848 ARRAY_SIZE(default_appraise_rules), 879 849 IMA_DEFAULT_POLICY); 880 850 851 + if (ima_use_critical_data) 852 + add_rules(critical_data_rules, 853 + ARRAY_SIZE(critical_data_rules), 854 + IMA_DEFAULT_POLICY); 855 + 881 856 ima_update_policy_flag(); 882 857 } 883 858 ··· 942 907 Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, 943 908 Opt_appraise_type, Opt_appraise_flag, 944 909 Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings, 945 - Opt_err 910 + Opt_label, Opt_err 946 911 }; 947 912 948 913 static const match_table_t policy_tokens = { ··· 979 944 {Opt_pcr, "pcr=%s"}, 980 945 {Opt_template, "template=%s"}, 981 946 {Opt_keyrings, "keyrings=%s"}, 947 + {Opt_label, "label=%s"}, 982 948 {Opt_err, NULL} 983 949 }; 984 950 ··· 1143 1107 return false; 1144 1108 1145 1109 break; 1110 + case CRITICAL_DATA: 1111 + if (entry->action & ~(MEASURE | DONT_MEASURE)) 1112 + return false; 1113 + 1114 + if (entry->flags & ~(IMA_FUNC | IMA_UID | IMA_PCR | 1115 + IMA_LABEL)) 1116 + return false; 1117 + 1118 + if (ima_rule_contains_lsm_cond(entry)) 1119 + return false; 1120 + 1121 + break; 1146 1122 default: 1147 1123 return false; 1148 1124 } ··· 1286 1238 else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) && 1287 1239 strcmp(args[0].from, "KEY_CHECK") == 0) 1288 1240 entry->func = KEY_CHECK; 1241 + else if (strcmp(args[0].from, "CRITICAL_DATA") == 0) 1242 + entry->func = CRITICAL_DATA; 1289 1243 else 1290 1244 result = -EINVAL; 1291 1245 if (!result) ··· 1357 1307 } 1358 1308 1359 1309 entry->flags |= IMA_KEYRINGS; 1310 + break; 1311 + case Opt_label: 1312 + ima_log_string(ab, "label", args[0].from); 1313 + 1314 + if (entry->label) { 1315 + result = -EINVAL; 1316 + break; 1317 + } 1318 + 1319 + entry->label = ima_alloc_rule_opt_list(args); 1320 + if (IS_ERR(entry->label)) { 1321 + result = PTR_ERR(entry->label); 1322 + entry->label = NULL; 1323 + break; 1324 + } 1325 + 1326 + entry->flags |= IMA_LABEL; 1360 1327 break; 1361 1328 case Opt_fsuuid: 1362 1329 ima_log_string(ab, "fsuuid", args[0].from); ··· 1752 1685 if (entry->flags & IMA_KEYRINGS) { 1753 1686 seq_puts(m, "keyrings="); 1754 1687 ima_show_rule_opt_list(m, entry->keyrings); 1688 + seq_puts(m, " "); 1689 + } 1690 + 1691 + if (entry->flags & IMA_LABEL) { 1692 + seq_puts(m, "label="); 1693 + ima_show_rule_opt_list(m, entry->label); 1755 1694 seq_puts(m, " "); 1756 1695 } 1757 1696
+2 -1
security/integrity/ima/ima_queue_keys.c
··· 162 162 entry->payload_len, 163 163 entry->keyring_name, 164 164 KEY_CHECK, 0, 165 - entry->keyring_name); 165 + entry->keyring_name, 166 + false); 166 167 list_del(&entry->list); 167 168 ima_free_key_entry(entry); 168 169 }
+2
security/selinux/Makefile
··· 16 16 17 17 selinux-$(CONFIG_SECURITY_INFINIBAND) += ibpkey.o 18 18 19 + selinux-$(CONFIG_IMA) += ima.o 20 + 19 21 ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include 20 22 21 23 $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
+44
security/selinux/ima.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (C) 2021 Microsoft Corporation 4 + * 5 + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) 6 + * 7 + * Measure critical data structures maintainted by SELinux 8 + * using IMA subsystem. 9 + */ 10 + #include <linux/vmalloc.h> 11 + #include <linux/ima.h> 12 + #include "security.h" 13 + #include "ima.h" 14 + 15 + /* 16 + * selinux_ima_measure_state - Measure hash of the SELinux policy 17 + * 18 + * @state: selinux state struct 19 + * 20 + * NOTE: This function must be called with policy_mutex held. 21 + */ 22 + void selinux_ima_measure_state(struct selinux_state *state) 23 + { 24 + void *policy = NULL; 25 + size_t policy_len; 26 + int rc = 0; 27 + 28 + /* 29 + * Measure SELinux policy only after initialization is completed. 30 + */ 31 + if (!selinux_initialized(state)) 32 + return; 33 + 34 + rc = security_read_state_kernel(state, &policy, &policy_len); 35 + if (rc) { 36 + pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc); 37 + return; 38 + } 39 + 40 + ima_measure_critical_data("selinux", "selinux-policy-hash", 41 + policy, policy_len, true); 42 + 43 + vfree(policy); 44 + }
+24
security/selinux/include/ima.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (C) 2021 Microsoft Corporation 4 + * 5 + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) 6 + * 7 + * Measure critical data structures maintainted by SELinux 8 + * using IMA subsystem. 9 + */ 10 + 11 + #ifndef _SELINUX_IMA_H_ 12 + #define _SELINUX_IMA_H_ 13 + 14 + #include "security.h" 15 + 16 + #ifdef CONFIG_IMA 17 + extern void selinux_ima_measure_state(struct selinux_state *selinux_state); 18 + #else 19 + static inline void selinux_ima_measure_state(struct selinux_state *selinux_state) 20 + { 21 + } 22 + #endif 23 + 24 + #endif /* _SELINUX_IMA_H_ */
+2 -1
security/selinux/include/security.h
··· 229 229 struct selinux_policy *policy); 230 230 int security_read_policy(struct selinux_state *state, 231 231 void **data, size_t *len); 232 - 232 + int security_read_state_kernel(struct selinux_state *state, 233 + void **data, size_t *len); 233 234 int security_policycap_supported(struct selinux_state *state, 234 235 unsigned int req_cap); 235 236
+55 -9
security/selinux/ss/services.c
··· 65 65 #include "ebitmap.h" 66 66 #include "audit.h" 67 67 #include "policycap_names.h" 68 + #include "ima.h" 68 69 69 70 /* Forward declaration. */ 70 71 static int context_struct_to_string(struct policydb *policydb, ··· 2179 2178 selinux_status_update_policyload(state, seqno); 2180 2179 selinux_netlbl_cache_invalidate(); 2181 2180 selinux_xfrm_notify_policyload(); 2181 + selinux_ima_measure_state(state); 2182 2182 } 2183 2183 2184 2184 void selinux_policy_commit(struct selinux_state *state, ··· 3876 3874 #endif /* CONFIG_NETLABEL */ 3877 3875 3878 3876 /** 3877 + * __security_read_policy - read the policy. 3878 + * @policy: SELinux policy 3879 + * @data: binary policy data 3880 + * @len: length of data in bytes 3881 + * 3882 + */ 3883 + static int __security_read_policy(struct selinux_policy *policy, 3884 + void *data, size_t *len) 3885 + { 3886 + int rc; 3887 + struct policy_file fp; 3888 + 3889 + fp.data = data; 3890 + fp.len = *len; 3891 + 3892 + rc = policydb_write(&policy->policydb, &fp); 3893 + if (rc) 3894 + return rc; 3895 + 3896 + *len = (unsigned long)fp.data - (unsigned long)data; 3897 + return 0; 3898 + } 3899 + 3900 + /** 3879 3901 * security_read_policy - read the policy. 3902 + * @state: selinux_state 3880 3903 * @data: binary policy data 3881 3904 * @len: length of data in bytes 3882 3905 * ··· 3910 3883 void **data, size_t *len) 3911 3884 { 3912 3885 struct selinux_policy *policy; 3913 - int rc; 3914 - struct policy_file fp; 3915 3886 3916 3887 policy = rcu_dereference_protected( 3917 3888 state->policy, lockdep_is_held(&state->policy_mutex)); ··· 3921 3896 if (!*data) 3922 3897 return -ENOMEM; 3923 3898 3924 - fp.data = *data; 3925 - fp.len = *len; 3899 + return __security_read_policy(policy, *data, len); 3900 + } 3926 3901 3927 - rc = policydb_write(&policy->policydb, &fp); 3928 - if (rc) 3929 - return rc; 3902 + /** 3903 + * security_read_state_kernel - read the policy. 3904 + * @state: selinux_state 3905 + * @data: binary policy data 3906 + * @len: length of data in bytes 3907 + * 3908 + * Allocates kernel memory for reading SELinux policy. 3909 + * This function is for internal use only and should not 3910 + * be used for returning data to user space. 3911 + * 3912 + * This function must be called with policy_mutex held. 3913 + */ 3914 + int security_read_state_kernel(struct selinux_state *state, 3915 + void **data, size_t *len) 3916 + { 3917 + struct selinux_policy *policy; 3930 3918 3931 - *len = (unsigned long)fp.data - (unsigned long)*data; 3932 - return 0; 3919 + policy = rcu_dereference_protected( 3920 + state->policy, lockdep_is_held(&state->policy_mutex)); 3921 + if (!policy) 3922 + return -EINVAL; 3933 3923 3924 + *len = policy->policydb.len; 3925 + *data = vmalloc(*len); 3926 + if (!*data) 3927 + return -ENOMEM; 3928 + 3929 + return __security_read_policy(policy, *data, len); 3934 3930 }