[PATCH 01/10] ima: implement function to allocate buffer at kexec load
Tushar Sugandhi
tusharsu at linux.microsoft.com
Mon Jul 3 14:57:00 PDT 2023
IMA does not provide a mechanism to allocate memory for IMA log storage
during kexec operation. The function should handle the scenario where
the kexec load is called multiple times.
Implement a function to allocate buffer of size kexec_segment_size at
kexec load. If the buffer was already allocated, free that buffer and
reallocate. Finally, initialize ima_khdr struct.
The patch operates under the assumption that the segment size does not
change between kexec load and execute.
Signed-off-by: Tushar Sugandhi <tusharsu at linux.microsoft.com>
---
security/integrity/ima/ima_kexec.c | 47 ++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 419dc405c831..48a683874044 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -15,6 +15,53 @@
#include "ima.h"
#ifdef CONFIG_IMA_KEXEC
+struct seq_file ima_kexec_file;
+struct ima_kexec_hdr ima_khdr;
+static size_t kexec_segment_size;
+
+void ima_clear_kexec_file(void)
+{
+ vfree(ima_kexec_file.buf);
+ ima_kexec_file.buf = NULL;
+ ima_kexec_file.size = 0;
+ ima_kexec_file.read_pos = 0;
+ ima_kexec_file.count = 0;
+}
+
+static int ima_allocate_buf_at_kexec_load(void)
+{
+ if ((kexec_segment_size == 0) ||
+ (kexec_segment_size == ULONG_MAX) ||
+ ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
+ pr_err("%s: Invalid segment size for kexec: %zu\n",
+ __func__, kexec_segment_size);
+ return -EINVAL;
+ }
+
+ /* if kexec load was called before, clear the existing buffer
+ * before allocating a new one
+ */
+ if (ima_kexec_file.buf)
+ ima_clear_kexec_file();
+
+ /* segment size can't change between kexec load and execute */
+ ima_kexec_file.buf = vmalloc(kexec_segment_size);
+ if (!ima_kexec_file.buf) {
+ pr_err("%s: No memory for ima kexec measurement buffer\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ ima_kexec_file.size = kexec_segment_size;
+ ima_kexec_file.read_pos = 0;
+ ima_kexec_file.count = sizeof(ima_khdr); /* reserved space */
+
+ memset(&ima_khdr, 0, sizeof(ima_khdr));
+ ima_khdr.version = 1;
+
+ return 0;
+}
+
static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
unsigned long segment_size)
{
--
2.25.1
More information about the kexec
mailing list