[PATCH v4 16/19] ima: support for kexec image and initramfs
Mimi Zohar
zohar at linux.vnet.ibm.com
Fri Feb 12 10:29:28 PST 2016
Add IMA policy support for measuring/appraising the kexec image and
initramfs. Two new IMA policy identifiers KEXEC_KERNEL_CHECK and
KEXEC_INITRAMFS_CHECK are defined.
Example policy rules:
measure func=KEXEC_KERNEL_CHECK
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
measure func=KEXEC_INITRAMFS_CHECK
appraise func=KEXEC_INITRAMFS_CHECK appraise_type=imasig
Moving the enumeration to the vfs layer simplified the patches, allowing
the IMA changes, for the most part, to be separated from the other
changes. Unfortunately, passing either a kernel_read_file_id or a
ima_hooks enumeration within IMA is messy.
Option 1: duplicate kernel_read_file enumeration in ima_hooks
enum kernel_read_file_id {
...
READING_KEXEC_IMAGE,
READING_KEXEC_INITRAMFS,
READING_MAX_ID
enum ima_hooks {
...
KEXEC_KERNEL_CHECK
KEXEC_INITRAMFS_CHECK
Option 2: define ima_hooks as extension of kernel_read_file
eg: enum ima_hooks {
FILE_CHECK = READING_MAX_ID,
MMAP_CHECK,
In order to pass both kernel_read_file_id and ima_hooks values, we
would need to specify a struct containing a union.
struct caller_id {
union {
enum ima_hooks func_id;
enum kernel_read_file_id read_id;
};
};
Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
perhaps changing the enumeration name.
For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in the ima_hooks.
Changelog v4:
- replaced switch statement with a kernel_read_file_id to an ima_hooks
id mapping array - Dmitry
- renamed ima_hook tokens KEXEC_CHECK and INITRAMFS_CHECK to
KEXEC_KERNEL_CHECK and KEXEC_INITRAMFS_CHECK respectively - Dave Young
Signed-off-by: Mimi Zohar <zohar at linux.vnet.ibm.com>
Acked-by: Petko Manolov <petkan at mip-labs.com>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin at huawei.com>
Cc: Dave Young <dyoung at redhat.com>
---
Documentation/ABI/testing/ima_policy | 1 +
security/integrity/ima/ima.h | 2 ++
security/integrity/ima/ima_main.c | 15 +++++++++------
security/integrity/ima/ima_policy.c | 15 ++++++++++++++-
4 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 0a378a8..bb0f9a1 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -27,6 +27,7 @@ Description:
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
[FIRMWARE_CHECK]
+ [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
[[^]MAY_EXEC]
fsmagic:= hex value
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a5d2592..bd97e0d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -147,6 +147,8 @@ enum ima_hooks {
POST_SETATTR,
MODULE_CHECK,
FIRMWARE_CHECK,
+ KEXEC_KERNEL_CHECK,
+ KEXEC_INITRAMFS_CHECK,
MAX_CHECK
};
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f6039f5..4d0bdf1 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -339,6 +339,13 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
return 0;
}
+static int read_idmap[READING_MAX_ID] = {
+ [READING_FIRMWARE] = FIRMWARE_CHECK,
+ [READING_MODULE] = MODULE_CHECK,
+ [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
+ [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
+};
+
/**
* ima_post_read_file - in memory collect/appraise/audit measurement
* @file: pointer to the file to be measured/appraised/audit
@@ -355,7 +362,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
int ima_post_read_file(struct file *file, void *buf, loff_t size,
enum kernel_read_file_id read_id)
{
- enum ima_hooks func = FILE_CHECK;
+ enum ima_hooks func;
if (!file && read_id == READING_FIRMWARE) {
if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
@@ -373,11 +380,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
return 0;
}
- if (read_id == READING_FIRMWARE)
- func = FIRMWARE_CHECK;
- else if (read_id == READING_MODULE)
- func = MODULE_CHECK;
-
+ func = read_idmap[read_id] ?: FILE_CHECK;
return process_measurement(file, buf, size, MAY_READ, func, 0);
}
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 7571ce8..5ccd3f5 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -612,6 +612,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
entry->func = MMAP_CHECK;
else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
entry->func = BPRM_CHECK;
+ else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") ==
+ 0)
+ entry->func = KEXEC_KERNEL_CHECK;
+ else if (strcmp(args[0].from, "KEXEC_INITRAMFS_CHECK")
+ == 0)
+ entry->func = KEXEC_INITRAMFS_CHECK;
else
result = -EINVAL;
if (!result)
@@ -855,7 +861,8 @@ static char *mask_tokens[] = {
enum {
func_file = 0, func_mmap, func_bprm,
- func_module, func_firmware, func_post
+ func_module, func_firmware, func_post,
+ func_kexec_kernel, func_kexec_initramfs
};
static char *func_tokens[] = {
@@ -929,6 +936,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
case POST_SETATTR:
seq_printf(m, pt(Opt_func), ft(func_post));
break;
+ case KEXEC_KERNEL_CHECK:
+ seq_printf(m, pt(Opt_func), ft(func_kexec_kernel));
+ break;
+ case KEXEC_INITRAMFS_CHECK:
+ seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs));
+ break;
default:
snprintf(tbuf, sizeof(tbuf), "%d", func);
seq_printf(m, pt(Opt_func), tbuf);
--
2.1.0
More information about the kexec
mailing list