Skip to content

Commit 591683d

Browse files
Steven Chenmimizohar
authored andcommitted
ima: measure kexec load and exec events as critical data
The amount of memory allocated at kexec load, even with the extra memory allocated, might not be large enough for the entire measurement list. The indeterminate interval between kexec 'load' and 'execute' could exacerbate this problem. Define two new IMA events, 'kexec_load' and 'kexec_execute', to be measured as critical data at kexec 'load' and 'execute' respectively. Report the allocated kexec segment size, IMA binary log size and the runtime measurements count as part of those events. These events, and the values reported through them, serve as markers in the IMA log to verify the IMA events are captured during kexec soft reboot. The presence of a 'kexec_load' event in between the last two 'boot_aggregate' events in the IMA log implies this is a kexec soft reboot, and not a cold-boot. And the absence of 'kexec_execute' event after kexec soft reboot implies missing events in that window which results in inconsistency with TPM PCR quotes, necessitating a cold boot for a successful remote attestation. These critical data events are displayed as hex encoded ascii in the ascii_runtime_measurement_list. Verifying the critical data hash requires calculating the hash of the decoded ascii string. For example, to verify the 'kexec_load' data hash: sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_load | cut -d' ' -f 6 | xxd -r -p | sha256sum To verify the 'kexec_execute' data hash: sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_execute | cut -d' ' -f 6 | xxd -r -p | sha256sum Co-developed-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Steven Chen <chenste@linux.microsoft.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Acked-by: Baoquan He <bhe@redhat.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> # ppc64/kvm Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
1 parent 0ad9398 commit 591683d

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

security/integrity/ima/ima.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
244244
unsigned long flags, bool create);
245245
#endif
246246

247+
#ifdef CONFIG_IMA_KEXEC
248+
void ima_measure_kexec_event(const char *event_name);
249+
#else
250+
static inline void ima_measure_kexec_event(const char *event_name) {}
251+
#endif
252+
247253
/*
248254
* The default binary_runtime_measurements list format is defined as the
249255
* platform native format. The canonical format is defined as little-endian.

security/integrity/ima/ima_kexec.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "ima.h"
1818

1919
#ifdef CONFIG_IMA_KEXEC
20+
#define IMA_KEXEC_EVENT_LEN 256
21+
2022
static bool ima_kexec_update_registered;
2123
static struct seq_file ima_kexec_file;
2224
static size_t kexec_segment_size;
@@ -31,6 +33,24 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)
3133
sf->count = 0;
3234
}
3335

36+
void ima_measure_kexec_event(const char *event_name)
37+
{
38+
char ima_kexec_event[IMA_KEXEC_EVENT_LEN];
39+
size_t buf_size = 0;
40+
long len;
41+
int n;
42+
43+
buf_size = ima_get_binary_runtime_size();
44+
len = atomic_long_read(&ima_htable.len);
45+
46+
n = scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN,
47+
"kexec_segment_size=%lu;ima_binary_runtime_size=%lu;"
48+
"ima_runtime_measurements_count=%ld;",
49+
kexec_segment_size, buf_size, len);
50+
51+
ima_measure_critical_data("ima_kexec", event_name, ima_kexec_event, n, false, NULL, 0);
52+
}
53+
3454
static int ima_alloc_kexec_file_buf(size_t segment_size)
3555
{
3656
/*
@@ -53,6 +73,7 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)
5373
out:
5474
ima_kexec_file.read_pos = 0;
5575
ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */
76+
ima_measure_kexec_event("kexec_load");
5677

5778
return 0;
5879
}

security/integrity/ima/ima_queue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ static int ima_reboot_notifier(struct notifier_block *nb,
241241
unsigned long action,
242242
void *data)
243243
{
244+
#ifdef CONFIG_IMA_KEXEC
245+
if (action == SYS_RESTART && data && !strcmp(data, "kexec reboot"))
246+
ima_measure_kexec_event("kexec_execute");
247+
#endif
248+
244249
ima_measurements_suspend();
245250

246251
return NOTIFY_DONE;

0 commit comments

Comments
 (0)