diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2018-07-13 14:06:01 -0400 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2018-07-16 15:31:57 -0400 |
commit | ef96837b0de4af47732e2a8ebf5c18e8a885ded6 (patch) | |
tree | 9a9f6481aae7a957d72fdbaf3e89d3c88847203f /security | |
parent | fed2512a7ccc8fc4b8e1de22925d127e4caac300 (diff) |
ima: add build time policy
IMA by default does not measure, appraise or audit files, but can be
enabled at runtime by specifying a builtin policy on the boot command line
or by loading a custom policy.
This patch defines a build time policy, which verifies kernel modules,
firmware, kexec image, and/or the IMA policy signatures. This build time
policy is automatically enabled at runtime and persists after loading a
custom policy.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/ima/Kconfig | 58 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 46 |
2 files changed, 101 insertions, 3 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 6a8f67714c83..004919d9bf09 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -156,6 +156,64 @@ config IMA_APPRAISE | |||
156 | <http://linux-ima.sourceforge.net> | 156 | <http://linux-ima.sourceforge.net> |
157 | If unsure, say N. | 157 | If unsure, say N. |
158 | 158 | ||
159 | config IMA_APPRAISE_BUILD_POLICY | ||
160 | bool "IMA build time configured policy rules" | ||
161 | depends on IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS | ||
162 | default n | ||
163 | help | ||
164 | This option defines an IMA appraisal policy at build time, which | ||
165 | is enforced at run time without having to specify a builtin | ||
166 | policy name on the boot command line. The build time appraisal | ||
167 | policy rules persist after loading a custom policy. | ||
168 | |||
169 | Depending on the rules configured, this policy may require kernel | ||
170 | modules, firmware, the kexec kernel image, and/or the IMA policy | ||
171 | to be signed. Unsigned files might prevent the system from | ||
172 | booting or applications from working properly. | ||
173 | |||
174 | config IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS | ||
175 | bool "Appraise firmware signatures" | ||
176 | depends on IMA_APPRAISE_BUILD_POLICY | ||
177 | default n | ||
178 | help | ||
179 | This option defines a policy requiring all firmware to be signed, | ||
180 | including the regulatory.db. If both this option and | ||
181 | CFG80211_REQUIRE_SIGNED_REGDB are enabled, then both signature | ||
182 | verification methods are necessary. | ||
183 | |||
184 | config IMA_APPRAISE_REQUIRE_KEXEC_SIGS | ||
185 | bool "Appraise kexec kernel image signatures" | ||
186 | depends on IMA_APPRAISE_BUILD_POLICY | ||
187 | default n | ||
188 | help | ||
189 | Enabling this rule will require all kexec'ed kernel images to | ||
190 | be signed and verified by a public key on the trusted IMA | ||
191 | keyring. | ||
192 | |||
193 | Kernel image signatures can not be verified by the original | ||
194 | kexec_load syscall. Enabling this rule will prevent its | ||
195 | usage. | ||
196 | |||
197 | config IMA_APPRAISE_REQUIRE_MODULE_SIGS | ||
198 | bool "Appraise kernel modules signatures" | ||
199 | depends on IMA_APPRAISE_BUILD_POLICY | ||
200 | default n | ||
201 | help | ||
202 | Enabling this rule will require all kernel modules to be signed | ||
203 | and verified by a public key on the trusted IMA keyring. | ||
204 | |||
205 | Kernel module signatures can only be verified by IMA-appraisal, | ||
206 | via the finit_module syscall. Enabling this rule will prevent | ||
207 | the usage of the init_module syscall. | ||
208 | |||
209 | config IMA_APPRAISE_REQUIRE_POLICY_SIGS | ||
210 | bool "Appraise IMA policy signature" | ||
211 | depends on IMA_APPRAISE_BUILD_POLICY | ||
212 | default n | ||
213 | help | ||
214 | Enabling this rule will require the IMA policy to be signed and | ||
215 | and verified by a key on the trusted IMA keyring. | ||
216 | |||
159 | config IMA_APPRAISE_BOOTPARAM | 217 | config IMA_APPRAISE_BOOTPARAM |
160 | bool "ima_appraise boot parameter" | 218 | bool "ima_appraise boot parameter" |
161 | depends on IMA_APPRAISE | 219 | depends on IMA_APPRAISE |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d5b4958decc5..1659abb344f9 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | int ima_policy_flag; | 50 | int ima_policy_flag; |
51 | static int temp_ima_appraise; | 51 | static int temp_ima_appraise; |
52 | static int build_ima_appraise __ro_after_init; | ||
52 | 53 | ||
53 | #define MAX_LSM_RULES 6 | 54 | #define MAX_LSM_RULES 6 |
54 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, | 55 | enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, |
@@ -162,6 +163,25 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = { | |||
162 | #endif | 163 | #endif |
163 | }; | 164 | }; |
164 | 165 | ||
166 | static struct ima_rule_entry build_appraise_rules[] __ro_after_init = { | ||
167 | #ifdef CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS | ||
168 | {.action = APPRAISE, .func = MODULE_CHECK, | ||
169 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | ||
170 | #endif | ||
171 | #ifdef CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS | ||
172 | {.action = APPRAISE, .func = FIRMWARE_CHECK, | ||
173 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | ||
174 | #endif | ||
175 | #ifdef CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS | ||
176 | {.action = APPRAISE, .func = KEXEC_KERNEL_CHECK, | ||
177 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | ||
178 | #endif | ||
179 | #ifdef CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS | ||
180 | {.action = APPRAISE, .func = POLICY_CHECK, | ||
181 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | ||
182 | #endif | ||
183 | }; | ||
184 | |||
165 | static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { | 185 | static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { |
166 | {.action = APPRAISE, .func = MODULE_CHECK, | 186 | {.action = APPRAISE, .func = MODULE_CHECK, |
167 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | 187 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, |
@@ -435,7 +455,7 @@ void ima_update_policy_flag(void) | |||
435 | ima_policy_flag |= entry->action; | 455 | ima_policy_flag |= entry->action; |
436 | } | 456 | } |
437 | 457 | ||
438 | ima_appraise |= temp_ima_appraise; | 458 | ima_appraise |= (build_ima_appraise | temp_ima_appraise); |
439 | if (!ima_appraise) | 459 | if (!ima_appraise) |
440 | ima_policy_flag &= ~IMA_APPRAISE; | 460 | ima_policy_flag &= ~IMA_APPRAISE; |
441 | } | 461 | } |
@@ -488,8 +508,8 @@ void __init ima_init_policy(void) | |||
488 | } | 508 | } |
489 | 509 | ||
490 | /* | 510 | /* |
491 | * Insert the appraise rules requiring file signatures, prior to | 511 | * Insert the builtin "secure_boot" policy rules requiring file |
492 | * any other appraise rules. | 512 | * signatures, prior to any other appraise rules. |
493 | */ | 513 | */ |
494 | for (i = 0; i < secure_boot_entries; i++) { | 514 | for (i = 0; i < secure_boot_entries; i++) { |
495 | list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); | 515 | list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); |
@@ -497,6 +517,26 @@ void __init ima_init_policy(void) | |||
497 | ima_appraise_flag(secure_boot_rules[i].func); | 517 | ima_appraise_flag(secure_boot_rules[i].func); |
498 | } | 518 | } |
499 | 519 | ||
520 | /* | ||
521 | * Insert the build time appraise rules requiring file signatures | ||
522 | * for both the initial and custom policies, prior to other appraise | ||
523 | * rules. | ||
524 | */ | ||
525 | for (i = 0; i < ARRAY_SIZE(build_appraise_rules); i++) { | ||
526 | struct ima_rule_entry *entry; | ||
527 | |||
528 | if (!secure_boot_entries) | ||
529 | list_add_tail(&build_appraise_rules[i].list, | ||
530 | &ima_default_rules); | ||
531 | |||
532 | entry = kmemdup(&build_appraise_rules[i], sizeof(*entry), | ||
533 | GFP_KERNEL); | ||
534 | if (entry) | ||
535 | list_add_tail(&entry->list, &ima_policy_rules); | ||
536 | build_ima_appraise |= | ||
537 | ima_appraise_flag(build_appraise_rules[i].func); | ||
538 | } | ||
539 | |||
500 | for (i = 0; i < appraise_entries; i++) { | 540 | for (i = 0; i < appraise_entries; i++) { |
501 | list_add_tail(&default_appraise_rules[i].list, | 541 | list_add_tail(&default_appraise_rules[i].list, |
502 | &ima_default_rules); | 542 | &ima_default_rules); |