Skip to content

Commit 9d7ef88

Browse files
author
Baoquan He
committed
ima: kexec: skip IMA segment validation after kexec soft reboot
JIRA: https://issues.redhat.com/browse/RHEL-114162 Upstream Status: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git commit 9ee8888 Author: Steven Chen <chenste@linux.microsoft.com> Date: Mon Apr 21 15:25:10 2025 -0700 ima: kexec: skip IMA segment validation after kexec soft reboot Currently, the function kexec_calculate_store_digests() calculates and stores the digest of the segment during the kexec_file_load syscall, where the IMA segment is also allocated. Later, the IMA segment will be updated with the measurement log at the kexec execute stage when a kexec reboot is initiated. Therefore, the digests should be updated for the IMA segment in the normal case. The problem is that the content of memory segments carried over to the new kernel during the kexec systemcall can be changed at kexec 'execute' stage, but the size and the location of the memory segments cannot be changed at kexec 'execute' stage. To address this, skip the calculation and storage of the digest for the IMA segment in kexec_calculate_store_digests() so that it is not added to the purgatory_sha_regions. With this change, the IMA segment is not included in the digest calculation, storage, and verification. Cc: Eric Biederman <ebiederm@xmission.com> Cc: Baoquan He <bhe@redhat.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Dave Young <dyoung@redhat.com> 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 [zohar@linux.ibm.com: Fixed Signed-off-by tag to match author's email ] Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Baoquan He <bhe@redhat.com>
1 parent ea3b31c commit 9d7ef88

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

include/linux/kexec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ struct kimage {
369369

370370
phys_addr_t ima_buffer_addr;
371371
size_t ima_buffer_size;
372+
373+
unsigned long ima_segment_index;
374+
bool is_ima_segment_index_set;
372375
#endif
373376

374377
/* Core ELF header buffer */

kernel/kexec_file.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void)
3838
}
3939
#endif
4040

41+
#ifdef CONFIG_IMA_KEXEC
42+
static bool check_ima_segment_index(struct kimage *image, int i)
43+
{
44+
if (image->is_ima_segment_index_set && i == image->ima_segment_index)
45+
return true;
46+
else
47+
return false;
48+
}
49+
#else
50+
static bool check_ima_segment_index(struct kimage *image, int i)
51+
{
52+
return false;
53+
}
54+
#endif
55+
4156
static int kexec_calculate_store_digests(struct kimage *image);
4257

4358
/* Maximum size in bytes for kernel/initrd files. */
@@ -776,6 +791,13 @@ static int kexec_calculate_store_digests(struct kimage *image)
776791
if (ksegment->kbuf == pi->purgatory_buf)
777792
continue;
778793

794+
/*
795+
* Skip the segment if ima_segment_index is set and matches
796+
* the current index
797+
*/
798+
if (check_ima_segment_index(image, i))
799+
continue;
800+
779801
ret = crypto_shash_update(desc, ksegment->kbuf,
780802
ksegment->bufsz);
781803
if (ret)

security/integrity/ima/ima_kexec.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ void ima_add_kexec_buffer(struct kimage *image)
145145
kbuf.buffer = kexec_buffer;
146146
kbuf.bufsz = kexec_buffer_size;
147147
kbuf.memsz = kexec_segment_size;
148+
image->is_ima_segment_index_set = false;
148149
ret = kexec_add_buffer(&kbuf);
149150
if (ret) {
150151
pr_err("Error passing over kexec measurement buffer.\n");
@@ -155,6 +156,8 @@ void ima_add_kexec_buffer(struct kimage *image)
155156
image->ima_buffer_addr = kbuf.mem;
156157
image->ima_buffer_size = kexec_segment_size;
157158
image->ima_buffer = kexec_buffer;
159+
image->ima_segment_index = image->nr_segments - 1;
160+
image->is_ima_segment_index_set = true;
158161

159162
kexec_dprintk("kexec measurement buffer for the loaded kernel at 0x%lx.\n",
160163
kbuf.mem);

0 commit comments

Comments
 (0)