On 1/22/24 13:38, Tushar Sugandhi wrote:
The extra memory allocated for carrying the IMA measurement list across
kexec is hardcoded as half a PAGE. Make it configurable.
Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the
extra memory (in kb) to be allocated for IMA measurements added during
kexec soft reboot. Ensure the default value of the option is set such
that extra half a page of memory for additional measurements is allocated
to maintain backwards compatibility.
Update ima_add_kexec_buffer() function to allocate memory based on the
Kconfig option value, rather than the currently hardcoded one.
Signed-off-by: Tushar Sugandhi <tusharsu@xxxxxxxxxxxxxxxxxxx>
---
security/integrity/ima/Kconfig | 11 +++++++++++
security/integrity/ima/ima_kexec.c | 15 ++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 60a511c6b583..fc103288852b 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -338,3 +338,14 @@ config IMA_DISABLE_HTABLE
default n
help
This option disables htable to allow measurement of duplicate records.
+
+config IMA_KEXEC_EXTRA_MEMORY_KB
+ int
+ depends on IMA && IMA_KEXEC
+ default 0
+ help
+ IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be
+ allocated (in kb) for IMA measurements added during kexec soft reboot.
+ If set to the default value, an extra half page of memory for
+ additional measurements will be allocated to maintain backwards
+ compatibility.
Is there really an issue with 'backwards compatibility' that the user
needs to know about ? From looking at the code it seems more important
that a bit of additional memory is reserved now to fit the kexec 'load'
and 'exec' critical data events but that's not 'backwards compatibility'.
Also mention this as a guidance on either how kexec load+exec need to be
used or as a hint that it may potentially require a lot of memory? :
The amount of extra memory that is necessary to carry all measurements
across a kexec depends on memory requirements of the measurements taken
between the kexec 'load' and 'exec' stages. The more measurements are
taken, the more extra memory is required. Large amounts of extra memory
can be avoided by running kexec 'load' and 'exec' in short sequence.
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index f26b5b342d84..c126aa6494e9 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -121,6 +121,7 @@ void ima_add_kexec_buffer(struct kimage *image)
.buf_min = 0, .buf_max = ULONG_MAX,
.top_down = true };
unsigned long binary_runtime_size;
+ unsigned long extra_size;
/* use more understandable variable names than defined in kbuf */
void *kexec_buffer = NULL;
@@ -128,15 +129,19 @@ void ima_add_kexec_buffer(struct kimage *image)
int ret;
/*
- * Reserve an extra half page of memory for additional measurements
- * added during the kexec load.
+ * Reserve extra memory for measurements added during kexec.
*/
- binary_runtime_size = ima_get_binary_runtime_size();
+ if (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB <= 0)
+ extra_size = PAGE_SIZE / 2;
+ else
+ extra_size = CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024;
+ binary_runtime_size = ima_get_binary_runtime_size() + extra_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);
+ kexec_segment_size = ALIGN(binary_runtime_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");
Code LGTM