diff options
author | James Morris <james.l.morris@oracle.com> | 2014-07-25 20:40:28 -0400 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2014-07-25 20:40:28 -0400 |
commit | f6fd5c84b9eb93ee6fbf028da87a32aeeecc5ee4 (patch) | |
tree | 1784d073fac0cb87b9811c43bde0dda3ba16d6ba | |
parent | ed3c4f8f862b9e79bafec3b85cde98c95807821e (diff) | |
parent | 5a9196d715607f76d6b7d96a0970d6065335e62b (diff) |
Merge tag 'fw-restrict-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux into next
-rw-r--r-- | Documentation/ABI/testing/ima_policy | 4 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 30 | ||||
-rw-r--r-- | include/linux/ima.h | 6 | ||||
-rw-r--r-- | include/linux/security.h | 17 | ||||
-rw-r--r-- | security/capability.c | 6 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 3 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 8 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 11 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 7 | ||||
-rw-r--r-- | security/integrity/integrity.h | 9 | ||||
-rw-r--r-- | security/security.c | 11 |
11 files changed, 104 insertions, 8 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 4c3efe434806..d0d0c578324c 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy | |||
@@ -26,6 +26,7 @@ Description: | |||
26 | option: [[appraise_type=]] [permit_directio] | 26 | option: [[appraise_type=]] [permit_directio] |
27 | 27 | ||
28 | base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] | 28 | base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] |
29 | [FIRMWARE_CHECK] | ||
29 | mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] | 30 | mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] |
30 | fsmagic:= hex value | 31 | fsmagic:= hex value |
31 | fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) | 32 | fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) |
@@ -57,7 +58,8 @@ Description: | |||
57 | measure func=BPRM_CHECK | 58 | measure func=BPRM_CHECK |
58 | measure func=FILE_MMAP mask=MAY_EXEC | 59 | measure func=FILE_MMAP mask=MAY_EXEC |
59 | measure func=FILE_CHECK mask=MAY_READ uid=0 | 60 | measure func=FILE_CHECK mask=MAY_READ uid=0 |
60 | measure func=MODULE_CHECK uid=0 | 61 | measure func=MODULE_CHECK |
62 | measure func=FIRMWARE_CHECK | ||
61 | appraise fowner=0 | 63 | appraise fowner=0 |
62 | 64 | ||
63 | The default policy measures all executables in bprm_check, | 65 | The default policy measures all executables in bprm_check, |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d276e33880be..63f165c59da8 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/suspend.h> | 28 | #include <linux/suspend.h> |
29 | #include <linux/syscore_ops.h> | 29 | #include <linux/syscore_ops.h> |
30 | #include <linux/reboot.h> | 30 | #include <linux/reboot.h> |
31 | #include <linux/security.h> | ||
31 | 32 | ||
32 | #include <generated/utsrelease.h> | 33 | #include <generated/utsrelease.h> |
33 | 34 | ||
@@ -308,12 +309,17 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | |||
308 | if (rc != size) { | 309 | if (rc != size) { |
309 | if (rc > 0) | 310 | if (rc > 0) |
310 | rc = -EIO; | 311 | rc = -EIO; |
311 | vfree(buf); | 312 | goto fail; |
312 | return rc; | ||
313 | } | 313 | } |
314 | rc = security_kernel_fw_from_file(file, buf, size); | ||
315 | if (rc) | ||
316 | goto fail; | ||
314 | fw_buf->data = buf; | 317 | fw_buf->data = buf; |
315 | fw_buf->size = size; | 318 | fw_buf->size = size; |
316 | return 0; | 319 | return 0; |
320 | fail: | ||
321 | vfree(buf); | ||
322 | return rc; | ||
317 | } | 323 | } |
318 | 324 | ||
319 | static int fw_get_filesystem_firmware(struct device *device, | 325 | static int fw_get_filesystem_firmware(struct device *device, |
@@ -617,6 +623,7 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
617 | { | 623 | { |
618 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 624 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
619 | struct firmware_buf *fw_buf; | 625 | struct firmware_buf *fw_buf; |
626 | ssize_t written = count; | ||
620 | int loading = simple_strtol(buf, NULL, 10); | 627 | int loading = simple_strtol(buf, NULL, 10); |
621 | int i; | 628 | int i; |
622 | 629 | ||
@@ -640,6 +647,8 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
640 | break; | 647 | break; |
641 | case 0: | 648 | case 0: |
642 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { | 649 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { |
650 | int rc; | ||
651 | |||
643 | set_bit(FW_STATUS_DONE, &fw_buf->status); | 652 | set_bit(FW_STATUS_DONE, &fw_buf->status); |
644 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); | 653 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); |
645 | 654 | ||
@@ -649,10 +658,23 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
649 | * see the mapped 'buf->data' once the loading | 658 | * see the mapped 'buf->data' once the loading |
650 | * is completed. | 659 | * is completed. |
651 | * */ | 660 | * */ |
652 | if (fw_map_pages_buf(fw_buf)) | 661 | rc = fw_map_pages_buf(fw_buf); |
662 | if (rc) | ||
653 | dev_err(dev, "%s: map pages failed\n", | 663 | dev_err(dev, "%s: map pages failed\n", |
654 | __func__); | 664 | __func__); |
665 | else | ||
666 | rc = security_kernel_fw_from_file(NULL, | ||
667 | fw_buf->data, fw_buf->size); | ||
668 | |||
669 | /* | ||
670 | * Same logic as fw_load_abort, only the DONE bit | ||
671 | * is ignored and we set ABORT only on failure. | ||
672 | */ | ||
655 | list_del_init(&fw_buf->pending_list); | 673 | list_del_init(&fw_buf->pending_list); |
674 | if (rc) { | ||
675 | set_bit(FW_STATUS_ABORT, &fw_buf->status); | ||
676 | written = rc; | ||
677 | } | ||
656 | complete_all(&fw_buf->completion); | 678 | complete_all(&fw_buf->completion); |
657 | break; | 679 | break; |
658 | } | 680 | } |
@@ -666,7 +688,7 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
666 | } | 688 | } |
667 | out: | 689 | out: |
668 | mutex_unlock(&fw_lock); | 690 | mutex_unlock(&fw_lock); |
669 | return count; | 691 | return written; |
670 | } | 692 | } |
671 | 693 | ||
672 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); | 694 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); |
diff --git a/include/linux/ima.h b/include/linux/ima.h index 1b7f268cddce..7cf5e9b32550 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -19,6 +19,7 @@ extern int ima_file_check(struct file *file, int mask); | |||
19 | extern void ima_file_free(struct file *file); | 19 | extern void ima_file_free(struct file *file); |
20 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 20 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
21 | extern int ima_module_check(struct file *file); | 21 | extern int ima_module_check(struct file *file); |
22 | extern int ima_fw_from_file(struct file *file, char *buf, size_t size); | ||
22 | 23 | ||
23 | #else | 24 | #else |
24 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 25 | static inline int ima_bprm_check(struct linux_binprm *bprm) |
@@ -46,6 +47,11 @@ static inline int ima_module_check(struct file *file) | |||
46 | return 0; | 47 | return 0; |
47 | } | 48 | } |
48 | 49 | ||
50 | static inline int ima_fw_from_file(struct file *file, char *buf, size_t size) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | |||
49 | #endif /* CONFIG_IMA */ | 55 | #endif /* CONFIG_IMA */ |
50 | 56 | ||
51 | #ifdef CONFIG_IMA_APPRAISE | 57 | #ifdef CONFIG_IMA_APPRAISE |
diff --git a/include/linux/security.h b/include/linux/security.h index 59820f8782a1..0ae4b147718a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -702,6 +702,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
702 | * @inode points to the inode to use as a reference. | 702 | * @inode points to the inode to use as a reference. |
703 | * The current task must be the one that nominated @inode. | 703 | * The current task must be the one that nominated @inode. |
704 | * Return 0 if successful. | 704 | * Return 0 if successful. |
705 | * @kernel_fw_from_file: | ||
706 | * Load firmware from userspace (not called for built-in firmware). | ||
707 | * @file contains the file structure pointing to the file containing | ||
708 | * the firmware to load. This argument will be NULL if the firmware | ||
709 | * was loaded via the uevent-triggered blob-based interface exposed | ||
710 | * by CONFIG_FW_LOADER_USER_HELPER. | ||
711 | * @buf pointer to buffer containing firmware contents. | ||
712 | * @size length of the firmware contents. | ||
713 | * Return 0 if permission is granted. | ||
705 | * @kernel_module_request: | 714 | * @kernel_module_request: |
706 | * Ability to trigger the kernel to automatically upcall to userspace for | 715 | * Ability to trigger the kernel to automatically upcall to userspace for |
707 | * userspace to load a kernel module with the given name. | 716 | * userspace to load a kernel module with the given name. |
@@ -1568,6 +1577,7 @@ struct security_operations { | |||
1568 | void (*cred_transfer)(struct cred *new, const struct cred *old); | 1577 | void (*cred_transfer)(struct cred *new, const struct cred *old); |
1569 | int (*kernel_act_as)(struct cred *new, u32 secid); | 1578 | int (*kernel_act_as)(struct cred *new, u32 secid); |
1570 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); | 1579 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); |
1580 | int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size); | ||
1571 | int (*kernel_module_request)(char *kmod_name); | 1581 | int (*kernel_module_request)(char *kmod_name); |
1572 | int (*kernel_module_from_file)(struct file *file); | 1582 | int (*kernel_module_from_file)(struct file *file); |
1573 | int (*task_fix_setuid) (struct cred *new, const struct cred *old, | 1583 | int (*task_fix_setuid) (struct cred *new, const struct cred *old, |
@@ -1840,6 +1850,7 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); | |||
1840 | void security_transfer_creds(struct cred *new, const struct cred *old); | 1850 | void security_transfer_creds(struct cred *new, const struct cred *old); |
1841 | int security_kernel_act_as(struct cred *new, u32 secid); | 1851 | int security_kernel_act_as(struct cred *new, u32 secid); |
1842 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); | 1852 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); |
1853 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size); | ||
1843 | int security_kernel_module_request(char *kmod_name); | 1854 | int security_kernel_module_request(char *kmod_name); |
1844 | int security_kernel_module_from_file(struct file *file); | 1855 | int security_kernel_module_from_file(struct file *file); |
1845 | int security_task_fix_setuid(struct cred *new, const struct cred *old, | 1856 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
@@ -2366,6 +2377,12 @@ static inline int security_kernel_create_files_as(struct cred *cred, | |||
2366 | return 0; | 2377 | return 0; |
2367 | } | 2378 | } |
2368 | 2379 | ||
2380 | static inline int security_kernel_fw_from_file(struct file *file, | ||
2381 | char *buf, size_t size) | ||
2382 | { | ||
2383 | return 0; | ||
2384 | } | ||
2385 | |||
2369 | static inline int security_kernel_module_request(char *kmod_name) | 2386 | static inline int security_kernel_module_request(char *kmod_name) |
2370 | { | 2387 | { |
2371 | return 0; | 2388 | return 0; |
diff --git a/security/capability.c b/security/capability.c index e76373de3129..a74fde6a7468 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -401,6 +401,11 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int cap_kernel_fw_from_file(struct file *file, char *buf, size_t size) | ||
405 | { | ||
406 | return 0; | ||
407 | } | ||
408 | |||
404 | static int cap_kernel_module_request(char *kmod_name) | 409 | static int cap_kernel_module_request(char *kmod_name) |
405 | { | 410 | { |
406 | return 0; | 411 | return 0; |
@@ -1015,6 +1020,7 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
1015 | set_to_cap_if_null(ops, cred_transfer); | 1020 | set_to_cap_if_null(ops, cred_transfer); |
1016 | set_to_cap_if_null(ops, kernel_act_as); | 1021 | set_to_cap_if_null(ops, kernel_act_as); |
1017 | set_to_cap_if_null(ops, kernel_create_files_as); | 1022 | set_to_cap_if_null(ops, kernel_create_files_as); |
1023 | set_to_cap_if_null(ops, kernel_fw_from_file); | ||
1018 | set_to_cap_if_null(ops, kernel_module_request); | 1024 | set_to_cap_if_null(ops, kernel_module_request); |
1019 | set_to_cap_if_null(ops, kernel_module_from_file); | 1025 | set_to_cap_if_null(ops, kernel_module_from_file); |
1020 | set_to_cap_if_null(ops, task_fix_setuid); | 1026 | set_to_cap_if_null(ops, task_fix_setuid); |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index c42056edfc97..57da4bd7ba0c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -158,7 +158,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); | |||
158 | struct integrity_iint_cache *integrity_iint_find(struct inode *inode); | 158 | struct integrity_iint_cache *integrity_iint_find(struct inode *inode); |
159 | 159 | ||
160 | /* IMA policy related functions */ | 160 | /* IMA policy related functions */ |
161 | enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; | 161 | enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR }; |
162 | 162 | ||
163 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | 163 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, |
164 | int flags); | 164 | int flags); |
@@ -171,6 +171,7 @@ void ima_delete_rules(void); | |||
171 | #define IMA_APPRAISE_ENFORCE 0x01 | 171 | #define IMA_APPRAISE_ENFORCE 0x01 |
172 | #define IMA_APPRAISE_FIX 0x02 | 172 | #define IMA_APPRAISE_FIX 0x02 |
173 | #define IMA_APPRAISE_MODULES 0x04 | 173 | #define IMA_APPRAISE_MODULES 0x04 |
174 | #define IMA_APPRAISE_FIRMWARE 0x08 | ||
174 | 175 | ||
175 | #ifdef CONFIG_IMA_APPRAISE | 176 | #ifdef CONFIG_IMA_APPRAISE |
176 | int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, | 177 | int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, |
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 59ac90275070..86bfd5c5df85 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
@@ -75,6 +75,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, | |||
75 | return iint->ima_bprm_status; | 75 | return iint->ima_bprm_status; |
76 | case MODULE_CHECK: | 76 | case MODULE_CHECK: |
77 | return iint->ima_module_status; | 77 | return iint->ima_module_status; |
78 | case FIRMWARE_CHECK: | ||
79 | return iint->ima_firmware_status; | ||
78 | case FILE_CHECK: | 80 | case FILE_CHECK: |
79 | default: | 81 | default: |
80 | return iint->ima_file_status; | 82 | return iint->ima_file_status; |
@@ -94,6 +96,9 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint, | |||
94 | case MODULE_CHECK: | 96 | case MODULE_CHECK: |
95 | iint->ima_module_status = status; | 97 | iint->ima_module_status = status; |
96 | break; | 98 | break; |
99 | case FIRMWARE_CHECK: | ||
100 | iint->ima_firmware_status = status; | ||
101 | break; | ||
97 | case FILE_CHECK: | 102 | case FILE_CHECK: |
98 | default: | 103 | default: |
99 | iint->ima_file_status = status; | 104 | iint->ima_file_status = status; |
@@ -113,6 +118,9 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func) | |||
113 | case MODULE_CHECK: | 118 | case MODULE_CHECK: |
114 | iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED); | 119 | iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED); |
115 | break; | 120 | break; |
121 | case FIRMWARE_CHECK: | ||
122 | iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED); | ||
123 | break; | ||
116 | case FILE_CHECK: | 124 | case FILE_CHECK: |
117 | default: | 125 | default: |
118 | iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); | 126 | iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 0d696431209c..2917f980bf30 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -319,6 +319,17 @@ int ima_module_check(struct file *file) | |||
319 | return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); | 319 | return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); |
320 | } | 320 | } |
321 | 321 | ||
322 | int ima_fw_from_file(struct file *file, char *buf, size_t size) | ||
323 | { | ||
324 | if (!file) { | ||
325 | if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && | ||
326 | (ima_appraise & IMA_APPRAISE_ENFORCE)) | ||
327 | return -EACCES; /* INTEGRITY_UNKNOWN */ | ||
328 | return 0; | ||
329 | } | ||
330 | return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK); | ||
331 | } | ||
332 | |||
322 | static int __init init_ima(void) | 333 | static int __init init_ima(void) |
323 | { | 334 | { |
324 | int error; | 335 | int error; |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index cea84d8bd7be..07099a8bc283 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -84,6 +84,7 @@ static struct ima_rule_entry default_rules[] = { | |||
84 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, | 84 | {.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID, |
85 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, | 85 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, |
86 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, | 86 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, |
87 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static struct ima_rule_entry default_appraise_rules[] = { | 90 | static struct ima_rule_entry default_appraise_rules[] = { |
@@ -241,6 +242,8 @@ static int get_subaction(struct ima_rule_entry *rule, int func) | |||
241 | return IMA_BPRM_APPRAISE; | 242 | return IMA_BPRM_APPRAISE; |
242 | case MODULE_CHECK: | 243 | case MODULE_CHECK: |
243 | return IMA_MODULE_APPRAISE; | 244 | return IMA_MODULE_APPRAISE; |
245 | case FIRMWARE_CHECK: | ||
246 | return IMA_FIRMWARE_APPRAISE; | ||
244 | case FILE_CHECK: | 247 | case FILE_CHECK: |
245 | default: | 248 | default: |
246 | return IMA_FILE_APPRAISE; | 249 | return IMA_FILE_APPRAISE; |
@@ -486,6 +489,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
486 | entry->func = FILE_CHECK; | 489 | entry->func = FILE_CHECK; |
487 | else if (strcmp(args[0].from, "MODULE_CHECK") == 0) | 490 | else if (strcmp(args[0].from, "MODULE_CHECK") == 0) |
488 | entry->func = MODULE_CHECK; | 491 | entry->func = MODULE_CHECK; |
492 | else if (strcmp(args[0].from, "FIRMWARE_CHECK") == 0) | ||
493 | entry->func = FIRMWARE_CHECK; | ||
489 | else if ((strcmp(args[0].from, "FILE_MMAP") == 0) | 494 | else if ((strcmp(args[0].from, "FILE_MMAP") == 0) |
490 | || (strcmp(args[0].from, "MMAP_CHECK") == 0)) | 495 | || (strcmp(args[0].from, "MMAP_CHECK") == 0)) |
491 | entry->func = MMAP_CHECK; | 496 | entry->func = MMAP_CHECK; |
@@ -636,6 +641,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
636 | result = -EINVAL; | 641 | result = -EINVAL; |
637 | else if (entry->func == MODULE_CHECK) | 642 | else if (entry->func == MODULE_CHECK) |
638 | ima_appraise |= IMA_APPRAISE_MODULES; | 643 | ima_appraise |= IMA_APPRAISE_MODULES; |
644 | else if (entry->func == FIRMWARE_CHECK) | ||
645 | ima_appraise |= IMA_APPRAISE_FIRMWARE; | ||
639 | audit_log_format(ab, "res=%d", !result); | 646 | audit_log_format(ab, "res=%d", !result); |
640 | audit_log_end(ab); | 647 | audit_log_end(ab); |
641 | return result; | 648 | return result; |
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 09c440d9aaee..19b8e314ca96 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -46,10 +46,14 @@ | |||
46 | #define IMA_BPRM_APPRAISED 0x00002000 | 46 | #define IMA_BPRM_APPRAISED 0x00002000 |
47 | #define IMA_MODULE_APPRAISE 0x00004000 | 47 | #define IMA_MODULE_APPRAISE 0x00004000 |
48 | #define IMA_MODULE_APPRAISED 0x00008000 | 48 | #define IMA_MODULE_APPRAISED 0x00008000 |
49 | #define IMA_FIRMWARE_APPRAISE 0x00010000 | ||
50 | #define IMA_FIRMWARE_APPRAISED 0x00020000 | ||
49 | #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ | 51 | #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ |
50 | IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE) | 52 | IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \ |
53 | IMA_FIRMWARE_APPRAISE) | ||
51 | #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ | 54 | #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ |
52 | IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED) | 55 | IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \ |
56 | IMA_FIRMWARE_APPRAISED) | ||
53 | 57 | ||
54 | enum evm_ima_xattr_type { | 58 | enum evm_ima_xattr_type { |
55 | IMA_XATTR_DIGEST = 0x01, | 59 | IMA_XATTR_DIGEST = 0x01, |
@@ -104,6 +108,7 @@ struct integrity_iint_cache { | |||
104 | enum integrity_status ima_mmap_status:4; | 108 | enum integrity_status ima_mmap_status:4; |
105 | enum integrity_status ima_bprm_status:4; | 109 | enum integrity_status ima_bprm_status:4; |
106 | enum integrity_status ima_module_status:4; | 110 | enum integrity_status ima_module_status:4; |
111 | enum integrity_status ima_firmware_status:4; | ||
107 | enum integrity_status evm_status:4; | 112 | enum integrity_status evm_status:4; |
108 | struct ima_digest_data *ima_hash; | 113 | struct ima_digest_data *ima_hash; |
109 | }; | 114 | }; |
diff --git a/security/security.c b/security/security.c index 31614e9e96e5..e41b1a8d7644 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -845,6 +845,17 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
845 | return security_ops->kernel_create_files_as(new, inode); | 845 | return security_ops->kernel_create_files_as(new, inode); |
846 | } | 846 | } |
847 | 847 | ||
848 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size) | ||
849 | { | ||
850 | int ret; | ||
851 | |||
852 | ret = security_ops->kernel_fw_from_file(file, buf, size); | ||
853 | if (ret) | ||
854 | return ret; | ||
855 | return ima_fw_from_file(file, buf, size); | ||
856 | } | ||
857 | EXPORT_SYMBOL_GPL(security_kernel_fw_from_file); | ||
858 | |||
848 | int security_kernel_module_request(char *kmod_name) | 859 | int security_kernel_module_request(char *kmod_name) |
849 | { | 860 | { |
850 | return security_ops->kernel_module_request(kmod_name); | 861 | return security_ops->kernel_module_request(kmod_name); |