From: Lakshmi Ramasubramanian nramas@linux.microsoft.com
[ Upstream commit f31e3386a4e92ba6eda7328cb508462956c94c64 ]
IMA allocates kernel virtual memory to carry forward the measurement list, from the current kernel to the next kernel on kexec system call, in ima_add_kexec_buffer() function. This buffer is not freed before completing the kexec system call resulting in memory leak.
Add ima_buffer field in "struct kimage" to store the virtual address of the buffer allocated for the IMA measurement list. Free the memory allocated for the IMA measurement list in kimage_file_post_load_cleanup() function.
Signed-off-by: Lakshmi Ramasubramanian nramas@linux.microsoft.com Suggested-by: Tyler Hicks tyhicks@linux.microsoft.com Reviewed-by: Thiago Jung Bauermann bauerman@linux.ibm.com Reviewed-by: Tyler Hicks tyhicks@linux.microsoft.com Fixes: 7b8589cc29e7 ("ima: on soft reboot, save the measurement list") Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/kexec.h | 5 +++++ kernel/kexec_file.c | 5 +++++ security/integrity/ima/ima_kexec.c | 2 ++ 3 files changed, 12 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 1c08c925cefbb..1ce6ba5f04077 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -217,6 +217,11 @@ struct kimage { /* Information for loading purgatory */ struct purgatory_info purgatory_info; #endif + +#ifdef CONFIG_IMA_KEXEC + /* Virtual address of IMA measurement buffer for kexec syscall */ + void *ima_buffer; +#endif };
/* kexec interface functions */ diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 9f48f44122972..6d0bdedb2e207 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -95,6 +95,11 @@ void kimage_file_post_load_cleanup(struct kimage *image) vfree(pi->sechdrs); pi->sechdrs = NULL;
+#ifdef CONFIG_IMA_KEXEC + vfree(image->ima_buffer); + image->ima_buffer = NULL; +#endif /* CONFIG_IMA_KEXEC */ + /* See if architecture has anything to cleanup post load */ arch_kimage_file_post_load_cleanup(image);
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 40bc385a80768..ce30e6edfedc4 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -132,6 +132,8 @@ void ima_add_kexec_buffer(struct kimage *image) return; }
+ image->ima_buffer = kexec_buffer; + pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); }