[PATCH v2 5/5 RFC] add the buffer to the event data in ima free entry data if store_template failed added check in templates for buffer
From: Prakhar Srivastava
Date: Tue Apr 23 2019 - 20:16:04 EST
From: Prakhar Srivastava <prsriva02@xxxxxxxxx>
Signed-off-by: Prakhar Srivastava <prsriva@xxxxxxxxxxxxx>
---
Currently for soft reboot(kexec_file_load) the kernel file and
signature is measured by IMA. The cmdline args used to load the kernel
is not measured.
The boot aggregate that gets calculated will have no change since the
EFI loader has not been triggered.
Adding the kexec cmdline args measure and kernel version will add some
attestable criteria.
This patch adds the buffer to be measured as the event data.
this also contains changes necessary for template
security/integrity/ima/ima_main.c | 36 +++++++++++++++++++++--
security/integrity/ima/ima_template_lib.c | 3 +-
security/integrity/integrity.h | 1 +
3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index da82c705a5ed..204a7a1acb86 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -14,7 +14,7 @@
*
* File: ima_main.c
* implements the IMA hooks: ima_bprm_check, ima_file_mmap,
- * and ima_file_check.
+ * ima_file_check and ima_buffer_check.
*/
#include <linux/module.h>
#include <linux/file.h>
@@ -180,16 +180,37 @@ static int process_buffer_measurement(const void *buff, int size,
struct ima_digest_data hdr;
char digest[IMA_MAX_DIGEST_SIZE];
} hash;
+ struct buffer_xattr {
+ enum evm_ima_xattr_type type;
+ u16 buff_length;
+ unsigned char buff[0];
+ };
char *name = NULL;
int violation = 0;
int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+ struct buffer_xattr *buffer_event_data = NULL;
+ int alloc_length = 0;
+ int action = 0;
if (!buff || size == 0 || !eventname)
goto err_out;
- if (ima_get_action(NULL, 0, BUFFER_CHECK, &pcr) != IMA_MEASURE)
+ action = ima_get_action(NULL, 0, BUFFER_CHECK, &pcr);
+ if (!(action & IMA_AUDIT) && !(action & IMA_MEASURE))
goto err_out;
+ alloc_length = sizeof(struct buffer_xattr) + size;
+ buffer_event_data = kzalloc(alloc_length, GFP_KERNEL);
+ if (!buffer_event_data)
+ goto err_out;
+
+ buffer_event_data->type = IMA_BUFFER_CHECK;
+ buffer_event_data->buff_length = size;
+ memcpy(buffer_event_data->buff, buff, size);
+
+ event_data.xattr_value = (struct evm_ima_xattr_data *)buffer_event_data;
+ event_data.xattr_len = alloc_length;
+
name = eventname;
memset(iint, 0, sizeof(*iint));
memset(&hash, 0, sizeof(hash));
@@ -208,16 +229,25 @@ static int process_buffer_measurement(const void *buff, int size,
if (ret < 0)
goto err_out;
- ret = ima_store_template(entry, violation, NULL,
+ if (action & IMA_MEASURE)
+ ret = ima_store_template(entry, violation, NULL,
buff, pcr);
+
if (ret < 0) {
ima_free_template_entry(entry);
goto err_out;
}
+ if (action & IMA_AUDIT)
+ ima_audit_measurement(iint, event_data.filename);
+
+ kfree(buffer_event_data);
return 0;
err_out:
+
+ kfree(buffer_event_data);
+
pr_err("Error in adding buffer measure: %d\n", ret);
return ret;
}
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index f9ba37b3928d..6050ef774355 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -322,7 +322,8 @@ int ima_eventsig_init(struct ima_event_data *event_data,
int xattr_len = event_data->xattr_len;
int rc = 0;
- if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
+ if ((!xattr_value) || !((xattr_value->type == EVM_IMA_XATTR_DIGSIG) ||
+ (xattr_value->type == IMA_BUFFER_CHECK)))
goto out;
rc = ima_write_template_field_data(xattr_value, xattr_len, fmt,
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 24520b4ef3b0..a674ae5be231 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -58,6 +58,7 @@ enum evm_ima_xattr_type {
EVM_XATTR_HMAC,
EVM_IMA_XATTR_DIGSIG,
IMA_XATTR_DIGEST_NG,
+ IMA_BUFFER_CHECK,
IMA_XATTR_LAST
};
--
2.17.1