From 75cffd7103a8018ded020b5d2a7a9f95cbf8428f Mon Sep 17 00:00:00 2001 From: Tushar Sugandhi Date: Mon, 3 Jan 2022 14:09:55 -0800 Subject: [PATCH 3/3] ima: on soft reboot, save the measurement list This patch uses the kexec buffer passing mechanism to pass the serialized IMA binary_runtime_measurements to the next kernel. Co-developed-by: Thiago Jung Bauermann Signed-off-by: Thiago Jung Bauermann Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 577462e9f9cc..84ddcf0d2673 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -12,9 +12,14 @@ #include #include #include +#include #include "ima.h" #ifdef CONFIG_IMA_KEXEC +/* Physical address of the measurement buffer in the next kernel. */ +static unsigned long kexec_buffer_load_addr; +static size_t kexec_segment_size; + static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, unsigned long segment_size) { @@ -127,19 +132,20 @@ void ima_add_kexec_buffer(struct kimage *image) /* use more understandable variable names than defined in kbuf */ void *kexec_buffer = NULL; size_t kexec_buffer_size; - size_t kexec_segment_size; int ret; + bool first_kexec_load = kexec_buffer_load_addr == 0; + /* - * Reserve an extra half page of memory for additional measurements - * added during the kexec load. + * Reserve an extra page of memory for additional measurements + * added during the kexec load + execute. */ binary_runtime_size = ima_get_binary_runtime_size(); if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE) kexec_segment_size = ULONG_MAX; else kexec_segment_size = ALIGN(ima_get_binary_runtime_size() + - PAGE_SIZE / 2, PAGE_SIZE); + PAGE_SIZE, PAGE_SIZE); if ((kexec_segment_size == ULONG_MAX) || ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) { pr_err("Binary measurement list too large.\n"); @@ -167,6 +173,11 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + kexec_buffer_load_addr = kbuf.mem; + + if (first_kexec_load) + register_reboot_notifier(&update_buffer_nb); + pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } -- 2.25.1