Skip to content

Commit 8b66661

Browse files
author
Baoquan He
committed
ima: define and call ima_alloc_kexec_file_buf()
JIRA: https://issues.redhat.com/browse/RHEL-114162 Upstream Status: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git commit c95e1ac Author: Steven Chen <chenste@linux.microsoft.com> Date: Mon Apr 21 15:25:08 2025 -0700 ima: define and call ima_alloc_kexec_file_buf() In the current implementation, the ima_dump_measurement_list() API is called during the kexec "load" phase, where a buffer is allocated and the measurement records are copied. Due to this, new events added after kexec load but before kexec execute are not carried over to the new kernel during kexec operation Carrying the IMA measurement list across kexec requires allocating a buffer and copying the measurement records. Separate allocating the buffer and copying the measurement records into separate functions in order to allocate the buffer at kexec 'load' and copy the measurements at kexec 'execute'. After moving the vfree() here at this stage in the patch set, the IMA measurement list fails to verify when doing two consecutive "kexec -s -l" with/without a "kexec -s -u" in between. Only after "ima: kexec: move IMA log copy from kexec load to execute" the IMA measurement list verifies properly with the vfree() here. 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> Signed-off-by: Baoquan He <bhe@redhat.com>
1 parent a2bcdb8 commit 8b66661

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

security/integrity/ima/ima_kexec.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,46 @@
1515
#include "ima.h"
1616

1717
#ifdef CONFIG_IMA_KEXEC
18+
static struct seq_file ima_kexec_file;
19+
20+
static void ima_free_kexec_file_buf(struct seq_file *sf)
21+
{
22+
vfree(sf->buf);
23+
sf->buf = NULL;
24+
sf->size = 0;
25+
sf->read_pos = 0;
26+
sf->count = 0;
27+
}
28+
29+
static int ima_alloc_kexec_file_buf(size_t segment_size)
30+
{
31+
ima_free_kexec_file_buf(&ima_kexec_file);
32+
33+
/* segment size can't change between kexec load and execute */
34+
ima_kexec_file.buf = vmalloc(segment_size);
35+
if (!ima_kexec_file.buf)
36+
return -ENOMEM;
37+
38+
ima_kexec_file.size = segment_size;
39+
ima_kexec_file.read_pos = 0;
40+
ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */
41+
42+
return 0;
43+
}
44+
1845
static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
1946
unsigned long segment_size)
2047
{
21-
struct seq_file ima_kexec_file;
2248
struct ima_queue_entry *qe;
2349
struct ima_kexec_hdr khdr;
2450
int ret = 0;
2551

2652
/* segment size can't change between kexec load and execute */
27-
ima_kexec_file.buf = vmalloc(segment_size);
2853
if (!ima_kexec_file.buf) {
29-
ret = -ENOMEM;
30-
goto out;
54+
pr_err("Kexec file buf not allocated\n");
55+
return -EINVAL;
3156
}
3257

33-
ima_kexec_file.file = NULL;
34-
ima_kexec_file.size = segment_size;
35-
ima_kexec_file.read_pos = 0;
36-
ima_kexec_file.count = sizeof(khdr); /* reserved space */
37-
3858
memset(&khdr, 0, sizeof(khdr));
3959
khdr.version = 1;
4060
/* This is an append-only list, no need to hold the RCU read lock */
@@ -71,8 +91,6 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
7191
*buffer_size = ima_kexec_file.count;
7292
*buffer = ima_kexec_file.buf;
7393
out:
74-
if (ret == -EINVAL)
75-
vfree(ima_kexec_file.buf);
7694
return ret;
7795
}
7896

@@ -111,6 +129,12 @@ void ima_add_kexec_buffer(struct kimage *image)
111129
return;
112130
}
113131

132+
ret = ima_alloc_kexec_file_buf(kexec_segment_size);
133+
if (ret < 0) {
134+
pr_err("Not enough memory for the kexec measurement buffer.\n");
135+
return;
136+
}
137+
114138
ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer,
115139
kexec_segment_size);
116140
if (!kexec_buffer) {

0 commit comments

Comments
 (0)