From 86b4da8c0e7fcb6c217c604efcd9438ad55dd055 Mon Sep 17 00:00:00 2001 From: Prakhar Srivastava Date: Sun, 23 Jun 2019 23:23:30 -0700 Subject: IMA: Define a new template field buf A buffer(kexec boot command line arguments) measured into IMA measuremnt list cannot be appraised, without already being aware of the buffer contents. Since hashes are non-reversible, raw buffer is needed for validation or regenerating hash for appraisal/attestation. Add support to store/read the buffer contents in HEX. The kexec cmdline hash is stored in the "d-ng" field of the template data. It can be verified using sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec-cmdline | cut -d' ' -f 6 | xxd -r -p | sha256sum - Add two new fields to ima_event_data to hold the buf and buf_len - Add a new template field 'buf' to be used to store/read the buffer data. - Updated process_buffer_meaurement to add the buffer to ima_event_data. process_buffer_measurement added in "Define a new IMA hook to measure the boot command line arguments" - Add a new template policy name ima-buf to represent 'd-ng|n-ng|buf' Signed-off-by: Prakhar Srivastava Reviewed-by: Roberto Sassu Reviewed-by: James Morris Signed-off-by: Mimi Zohar --- security/integrity/ima/ima.h | 2 ++ security/integrity/ima/ima_main.c | 4 +++- security/integrity/ima/ima_template.c | 3 +++ security/integrity/ima/ima_template_lib.c | 21 +++++++++++++++++++++ security/integrity/ima/ima_template_lib.h | 4 ++++ 5 files changed, 33 insertions(+), 1 deletion(-) (limited to 'security') diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index bdca641f9e51..6aa28ab53d27 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -65,6 +65,8 @@ struct ima_event_data { struct evm_ima_xattr_data *xattr_value; int xattr_len; const char *violation; + const void *buf; + int buf_len; }; /* IMA template field data definition */ diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2507bee1b762..317c4b6f2c18 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -627,7 +627,9 @@ static void process_buffer_measurement(const void *buf, int size, struct ima_template_entry *entry = NULL; struct integrity_iint_cache iint = {}; struct ima_event_data event_data = {.iint = &iint, - .filename = eventname}; + .filename = eventname, + .buf = buf, + .buf_len = size}; struct ima_template_desc *template_desc = NULL; struct { struct ima_digest_data hdr; diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 00dd5a434689..a01a17e5c581 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -26,6 +26,7 @@ static struct ima_template_desc builtin_templates[] = { {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, {.name = "ima-ng", .fmt = "d-ng|n-ng"}, {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, + {.name = "ima-buf", .fmt = "d-ng|n-ng|buf"}, {.name = "", .fmt = ""}, /* placeholder for a custom format */ }; @@ -43,6 +44,8 @@ static const struct ima_template_field supported_fields[] = { .field_show = ima_show_template_string}, {.field_id = "sig", .field_init = ima_eventsig_init, .field_show = ima_show_template_sig}, + {.field_id = "buf", .field_init = ima_eventbuf_init, + .field_show = ima_show_template_buf}, }; #define MAX_TEMPLATE_NAME_LEN 15 diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 513b457ae900..baf4de45c5aa 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -162,6 +162,12 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data); } +void ima_show_template_buf(struct seq_file *m, enum ima_show_type show, + struct ima_field_data *field_data) +{ + ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data); +} + /** * ima_parse_buf() - Parses lengths and data from an input buffer * @bufstartp: Buffer start address. @@ -389,3 +395,18 @@ int ima_eventsig_init(struct ima_event_data *event_data, return ima_write_template_field_data(xattr_value, event_data->xattr_len, DATA_FMT_HEX, field_data); } + +/* + * ima_eventbuf_init - include the buffer(kexec-cmldine) as part of the + * template data. + */ +int ima_eventbuf_init(struct ima_event_data *event_data, + struct ima_field_data *field_data) +{ + if ((!event_data->buf) || (event_data->buf_len == 0)) + return 0; + + return ima_write_template_field_data(event_data->buf, + event_data->buf_len, DATA_FMT_HEX, + field_data); +} diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h index 6a3d8b831deb..12f1a8578b31 100644 --- a/security/integrity/ima/ima_template_lib.h +++ b/security/integrity/ima/ima_template_lib.h @@ -29,6 +29,8 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show, struct ima_field_data *field_data); void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, struct ima_field_data *field_data); +void ima_show_template_buf(struct seq_file *m, enum ima_show_type show, + struct ima_field_data *field_data); int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp, int maxfields, struct ima_field_data *fields, int *curfields, unsigned long *len_mask, int enforce_mask, char *bufname); @@ -42,4 +44,6 @@ int ima_eventname_ng_init(struct ima_event_data *event_data, struct ima_field_data *field_data); int ima_eventsig_init(struct ima_event_data *event_data, struct ima_field_data *field_data); +int ima_eventbuf_init(struct ima_event_data *event_data, + struct ima_field_data *field_data); #endif /* __LINUX_IMA_TEMPLATE_LIB_H */ -- cgit v1.2.3-59-g8ed1b