ima: kexec: measure events between kexec load and execute
Subsystems (7)
v11 cover ima: kexec: measure events between kexec load and execute
The current kernel behavior is IMA measurements snapshot is taken at kexec 'load' and not at kexec 'execute'. IMA log is then carried over to the new kernel after kexec 'execute'.
Currently, the kernel behavior during kexec load is to fetch the IMA measurements log from TPM PCRs and store it in a buffer. When a kexec reboot is triggered, this stored log buffer is carried over to the second kernel. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel. This results in mismatch between TPM PCR quotes and the actual IMA measurements list after kexec soft reboot, which in turn results in remote attestation failure.
To solve this problem -
- allocate the necessary buffer at kexec 'load' time,
- populate the buffer with the IMA measurements at kexec 'execute' time,
- and measure two new IMA events 'kexec_load' and 'kexec_execute' as critical data to help detect missing events after kexec soft reboot.
The solution details include:
- refactoring the existing code to allocate a buffer to hold IMA measurements at kexec 'load', and dump the measurements at kexec 'execute'
- kexec functionality for mapping the segments from the current kernel to the subsequent one,
- necessary changes to the kexec_file_load syscall, enabling it to call the ima functions,
- registering a reboot notifier which gets called during kexec 'execute',
- introducing a new Kconfig option to configure the extra memory to be allocated for passing IMA log from the current Kernel to the next,
- introducing two new events to be measured by IMA during kexec, to help diagnose if the IMA log was copied fully or partially, from the current Kernel to the next,
- excluding IMA segment while calculating and storing digest in function kexec_calculate_store_digests(), since IMA segment can be modified after the digest is computed during kexec 'load'. This will ensure that the segment is not added to the 'purgatory_sha_regions', and thus not verified by verify_sha256_digest().
The changes proposed in this series ensure the integrity of the IMA measurements is preserved across kexec soft reboots, thus significantly improving the security of the kernel post kexec soft reboots.
There were previous attempts to fix this issue [1], [2], [3]. But they were not merged into the mainline kernel.
We took inspiration from the past work [1] and [2] while working on this patch series.
V4 of this series is available here[6] for reference.
V5 of this series is available here[7] for reference.
V6 of this series is available here[8] for reference.
V7 of this series is available here[9] for reference.
V8 of this series is available here[10] for reference.
V9 of this series is available here[11] for reference.
V10 of this series is available here[12] for reference.
References:
-----------
[1] [PATHC v2 5/9] ima: on soft reboot, save the measurement list
https://lore.kernel.org/lkml/[email protected]/
[2] PATCH v2 4/6] kexec_file: Add mechanism to update kexec segments.
https://lkml.org/lkml/2016/8/16/577
[3] [PATCH 1/6] kexec_file: Add buffer hand-over support
https://lore.kernel.org/linuxppc-dev/[email protected]/T/
[4] [PATCH v2 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[5] [PATCH v3 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[6] [PATCH v4 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[7] [PATCH v5 0/8] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[8] [PATCH v6 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[9] [PATCH v7 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[10] [PATCH v8 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[11] [PATCH v9 0/7] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
[12] [PATCH v10 0/8] ima: kexec: measure events between kexec load and execute
https://lore.kernel.org/all/[email protected]/
Change Log v11:
- Incorporated feedback from the community (Mimi Zohar and Baoquan He) on v10 of this series[12].
- [PATCH V10 2/8] was splited into two [PATCH V11 2/9] and [PATCH V11 7/9]. Per Mimi comment on [PATCH V10 2/8].
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
- Updated patch descriptions as necessary.
Change Log v10:
- Incorporated feedback from the community (Mimi Zohar, Baoquan He, and kernel test robot) on v9 of this series[11].
- [PATCH V9 1/7] was splited into two [PATCH V10 1/8] and [PATCH V10 2/8]. Per Mimi comment on [PATCH V9 1/7].
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
Change Log v9:
- Incorporated feedback from the community (Stefan Berger, Mimi Zohar, and kernel test robot) on v8 of this series[10].
- Rebased the patch series to mainline 6.14.0-rc3.
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
Change Log v8:
- Incorporated feedback from the community (Stefan Berger, Mimi Zohar) on v7 of this series[9].
- Rebased the patch series to mainline 6.14.0-rc1.
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
Change Log v7:
- Incorporated feedback from the community (Stefan Berger, Tyler Hicks) on v6 of this series[8].
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
Change Log v6:
- Incorporated feedback from the community (Stefan Berger, Mimi Zohar, and Petr Tesařík) on v5 of this series[7].
- Rebased the patch series to mainline 6.12.0.
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
- Compared the memory size allocated with memory size of the entire measurement record. If there is not enough memory, it will copy as many IMA measurement records as possible, and this situation will result in a failure of remote attestation.
- [PATCH V5 6/8] was removed. Per petr comment on [PATCH V5 6/8], during the handover, other CPUs are taken offline (look for migrate_to_reboot_cpu() in kernel/kexec_core.c) and even the reboot CPU will be sufficiently shut down as not to be able to add any more measurements.
Change Log v5:
- Incorporated feedback from the community (Stefan Berger and Mimi Zohar) on v4 of this series[6].
- Rebased the patch series to mainline 6.8.0-rc1.
- Verified all the patches are bisect-safe by booting into each patch and verifying multiple kexec 'load' operations work, and also verifying kexec soft reboot works, and IMA log gets carried over for each patch.
- Divided the patch #4 in the v4 of the series[6] into two separate patches. One to setup the infrastructure/stub functions to prepare the IMA log copy from Kexec 'load' to 'execute', and another one to actually copy the log.
- Updated the config description for IMA_KEXEC_EXTRA_MEMORY_KB to remove unnecessary references related to backwards compatibility.
- Fixed a typo in log message/removed an extra line etc.
- Updated patch descriptions as necessary.
Change Log v4:
- Incorporated feedback from the community (Stefan Berger and Mimi Zohar) on v3 of this series[5].
- Rearranged patches so that they remain bisect-safe i.e. the system can go through kexec soft reboot, and IMA log is carried over after each patch.
- Verified all the patches are bisect-safe by booting into each patch and verifying kexec soft reboot works, and IMA log gets carried over.
- Suspend-resume measurements is now a separate patch (patch #5) and all the relevant code is part of the same patch.
- Excluding IMA segment from segment digest verification is now a separate patch. (patch #3).
- Registering reboot notifier and functions related to move ima log copy from kexec load to execute are now part of the same patch (patch #4) to protect bisect-safeness of the series.
- Updated the title of patch #6 as per the feedback.
- The default value of kexec extra memory for IMA measurements is set to half the PAGESIZE to maintain backwards compatibility.
- Added number of IMA measurement records as part of 'kexec_load' and 'kexec_execute' IMA critical data events.
- Updated patch descriptions as necessary.
Change Log v3:
- Incorporated feedback from the community (Stefan Berger and Mimi Zohar) on v2 of this series[4].
- Renamed functions and removed extraneous checks and code comments.
- Updated patch descriptions and titles as necessary.
- Updated kexec_calculate_store_digests() in patch 2/7 to exclude ima segment from calculating and storing digest.
- Updated patch 3/7 to use kmalloc_array instead of kmalloc and freed memory early to avoid potential memory leak.
- Updated patch 6/7 to change Kconfig option IMA_KEXEC_EXTRA_PAGES to IMA_KEXEC_EXTRA_MEMORY_KB to allocate the memory in kb rather than in number of pages.
- Optimized patch 7/7 not to free and alloc memory if the buffer size hasn't changed during multiple kexec 'load' operations.
- Fixed a bug in patch 7/7 to measure multiple 'kexec_load' events even if buffer size hasn't changed.
- Verified the patches are bisect-safe by compiling and booting into each patch individually.
Change Log v2:
- Incorporated feedback from the community on v1 series.
- Refactored the existing ima_dump_measurement_list to move buffer allocation functionality to ima_alloc_kexec_buf() function.
- Introduced a new Kconfig option to configure the memory.
- Updated the logic to copy the IMA log only in case of kexec soft reboot, and not on kexec crash.
- Updated the logic to copy as many IMA events as possible in case of memory constraint, rather than just bailing out.
- Introduced two new events to be measured by IMA during kexec, to help diagnose if the IMA log was copied fully or partially from the current Kernel to the next.
- Refactored patches to ensure no warnings during individual patch compilation.
- Used virt_to_page instead of phys_to_page.
- Updated patch descriptions as necessary.
steven chen (9):
ima: rename variable the set_file "file" to "ima_kexec_file"
ima: define and call ima_alloc_kexec_file_buf()
kexec: define functions to map and unmap segments
ima: kexec: skip IMA segment validation after kexec soft reboot
ima: kexec: define functions to copy IMA log at soft boot
ima: kexec: move IMA log copy from kexec load to execute
ima: verify if the segment size has changed
ima: make the kexec extra memory configurable
ima: measure kexec load and exec events as critical data
include/linux/ima.h | 3 + include/linux/kexec.h | 9 ++ kernel/kexec_core.c | 54 ++++++++ kernel/kexec_file.c | 33 ++++- security/integrity/ima/Kconfig | 10 ++ security/integrity/ima/ima.h | 6 + security/integrity/ima/ima_kexec.c | 193 ++++++++++++++++++++++++----- security/integrity/ima/ima_queue.c | 5 + 8 files changed, 279 insertions(+), 34 deletions(-)
Signature · 1 line
2.25.1
PATCH v11 1/9 ima: rename variable the set_file "file" to "ima_kexec_file"
The current kernel behavior is IMA measurements snapshot is taken at kexec 'load' and not at kexec 'execute'. IMA log is then carried over to the new kernel after kexec 'execute'. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel.
To address the above, the following approach is proposed:
- Allocate the necessary buffer during the kexec load phase.
- Populate this buffer with the IMA measurements during the kexec execute phase.
In the current implementation, a local variable "file" of type seq_file is used in the API ima_dump_measurement_list() to store the IMA measurements to be carried over across kexec system call. To make this buffer accessible at kexec 'execute' time, rename it to "ima_kexec_file" before making it a file variable to better reflect its purpose.
Renaming the local variable "file" of type seq_file defined in the ima_dump_measurement_list function to "ima_kexec_file" will improve code readability and maintainability by making the variable's role more explicit.
--- security/integrity/ima/ima_kexec.c | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
security/integrity/ima/ima_kexec.c +16 -15
@@ -18,30 +18,30 @@static int ima_dump_measurement_list (unsigned long *buffer_size,void **buffer,unsigned long segment_size) { +struct seq_file ima_kexec_file;struct ima_queue_entry *qe; -struct seq_file file;struct ima_kexec_hdr khdr;int ret =0 ;/* segment size can't change between kexec load and execute */ - file.buf =vmalloc (segment_size); -if (!file.buf) { + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) { ret = -ENOMEM ; goto out; } - file.file =NULL ; - file.size = segment_size; - file.read_pos =0 ; - file.count =sizeof (khdr);/* reserved space */ + ima_kexec_file.file =NULL ; + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (khdr);/* reserved space */ memset (&khdr,0 ,sizeof (khdr)); khdr.version =1 ;/* This is an append-only list, no need to hold the RCU read lock */ list_for_each_entry_rcu (qe, &ima_measurements, later, true) { -if (file.count < file.size) { +if (ima_kexec_file.count < ima_kexec_file.size) { khdr.count++; -ima_measurements_show (&file, qe); +ima_measurements_show (&ima_kexec_file, qe); }else { ret = -EINVAL ;break ;
@@ -55,23 +55,24 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,* fill in reserved space with some buffer details * (eg. version, buffer size, number of measurements) */ - khdr.buffer_size = file.count; + khdr.buffer_size = ima_kexec_file.count;if (ima_canonical_fmt) { khdr.version =cpu_to_le16 (khdr.version); khdr.count =cpu_to_le64 (khdr.count); khdr.buffer_size =cpu_to_le64 (khdr.buffer_size); } -memcpy (file.buf, &khdr,sizeof (khdr)); +memcpy (ima_kexec_file.buf, &khdr,sizeof (khdr));print_hex_dump_debug ("ima dump: " ,DUMP_PREFIX_NONE ,16 ,1 , - file.buf, file.count <100 ? file.count :100 , + ima_kexec_file.buf, ima_kexec_file.count <100 ? + ima_kexec_file.count :100 , true); - *buffer_size = file.count; - *buffer = file.buf; + *buffer_size = ima_kexec_file.count; + *buffer = ima_kexec_file.buf; out:if (ret == -EINVAL ) -vfree (file.buf); +vfree (ima_kexec_file.buf);return ret; }
Signature · 1 line
2.25.1
Re: [PATCH v11 1/9] ima: rename variable the set_file "file" to "ima_kexec_file"
Quoted 18 lines · steven chen
The current kernel behavior is IMA measurements snapshot is taken at kexec 'load' and not at kexec 'execute'. IMA log is then carried over to the new kernel after kexec 'execute'. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel.
To address the above, the following approach is proposed:
- Allocate the necessary buffer during the kexec load phase.
- Populate this buffer with the IMA measurements during the kexec execute phase.In the current implementation, a local variable "file" of type
seq_fileis used in the APIima_dump_measurement_list()to store the IMA measurements to be carried over across kexec system call. To make this buffer accessible at kexec 'execute' time, rename it to "ima_kexec_file" before making it a file variable to better reflect its purpose.
Quoted 3 lines
Renaming the local variable "file" of type
seq_filedefined in theima_dump_measurement_listfunction to "ima_kexec_file" will improve code readability and maintainability by making the variable's role more explicit.
Seems it's clearer with below paragraph to replace the whole log:
=====
Rename the local variable "file" of type seq_file defined in the ima_dump_measurement_list function to "ima_kexec_file" to improve code readability and maintainability by making the variable's role more explicit.
=====
The code change looks good to me.
Quoted 4 lines
Suggested-by Mimi Zohar <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>
If there's code change in patch content, the reviewing tag should be reset so that reviewing is taken again on the new change.
Quoted 82 lines
--- security/integrity/ima/ima_kexec.c | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)security/integrity/ima/ima_kexec.c +16
-15@@ -18,30 +18,30 @@static int ima_dump_measurement_list (unsigned long *buffer_size,void **buffer,unsigned long segment_size) { +struct seq_file ima_kexec_file;struct ima_queue_entry *qe; -struct seq_file file;struct ima_kexec_hdr khdr;int ret =0 ;/* segment size can't change between kexec load and execute */ - file.buf =vmalloc (segment_size); -if (!file.buf) { + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) { ret = -ENOMEM ; goto out; } - file.file =NULL ; - file.size = segment_size; - file.read_pos =0 ; - file.count =sizeof (khdr);/* reserved space */ + ima_kexec_file.file =NULL ; + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (khdr);/* reserved space */ memset (&khdr,0 ,sizeof (khdr)); khdr.version =1 ;/* This is an append-only list, no need to hold the RCU read lock */ list_for_each_entry_rcu (qe, &ima_measurements, later, true) { -if (file.count < file.size) { +if (ima_kexec_file.count < ima_kexec_file.size) { khdr.count++; -ima_measurements_show (&file, qe); +ima_measurements_show (&ima_kexec_file, qe); }else { ret = -EINVAL ;break ;@@ -55,23 +55,24 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,* fill in reserved space with some buffer details * (eg. version, buffer size, number of measurements) */ - khdr.buffer_size = file.count; + khdr.buffer_size = ima_kexec_file.count;if (ima_canonical_fmt) { khdr.version =cpu_to_le16 (khdr.version); khdr.count =cpu_to_le64 (khdr.count); khdr.buffer_size =cpu_to_le64 (khdr.buffer_size); } -memcpy (file.buf, &khdr,sizeof (khdr)); +memcpy (ima_kexec_file.buf, &khdr,sizeof (khdr));print_hex_dump_debug ("ima dump: " ,DUMP_PREFIX_NONE ,16 ,1 , - file.buf, file.count <100 ? file.count :100 , + ima_kexec_file.buf, ima_kexec_file.count <100 ? + ima_kexec_file.count :100 , true); - *buffer_size = file.count; - *buffer = file.buf; + *buffer_size = ima_kexec_file.count; + *buffer = ima_kexec_file.buf; out:if (ret == -EINVAL ) -vfree (file.buf); +vfree (ima_kexec_file.buf);return ret; }Signature · 1 line
2.25.1
Mimi Zohar
maintainerRe: [PATCH v11 1/9] ima: rename variable the set_file "file" to "ima_kexec_file"
In reply to steven chenPlease fix the Subject line: change set_file -> seq_file
Quoted 12 lines · steven chen
The current kernel behavior is IMA measurements snapshot is taken at kexec 'load' and not at kexec 'execute'. IMA log is then carried over to the new kernel after kexec 'execute'. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel.
To address the above, the following approach is proposed:
- Allocate the necessary buffer during the kexec load phase.
- Populate this buffer with the IMA measurements during the kexec execute phase.
Quoted 5 lines
In the current implementation, a local variable "file" of type
seq_fileis used in the APIima_dump_measurement_list()to store the IMA measurements to be carried over across kexec system call. To make this buffer accessible at kexec 'execute' time, rename it to "ima_kexec_file" before making it a file variable to better reflect its purpose.
Only the reason for the variable name change is needed. Please remove everything else.
Quoted 4 lines
Renaming the local variable "file" of type
seq_filedefined in theima_dump_measurement_listfunction to "ima_kexec_file" will improve code readability and maintainability by making the variable's role more explicit.
As previously mentioned, there is a difference when naming local and file static global variables. Variable naming is described
https://www.kernel.org/doc/html/v4.10/process/coding-style.html#naming
-> Before making the local ima_dump_measurement_list() seq_file "file" variable file static global, rename it to ima_kexec_file.
thanks,
Mimi
PATCH v11 2/9 ima: define and call ima_alloc_kexec_file_buf()
In reply to steven chenIn 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
To allow the buffer allocation and population to be separated into distinct steps, make the function local seq_file "ima_kexec_file" to a file variable.
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'.
--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)
security/integrity/ima/ima_kexec.c +35 -11
@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size) +{ +ima_free_kexec_file_buf (&ima_kexec_file); + +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +static int ima_dump_measurement_list (unsigned long *buffer_size,void **buffer,unsigned long segment_size) { -struct seq_file ima_kexec_file;struct ima_queue_entry *qe;struct ima_kexec_hdr khdr;int ret =0 ;/* segment size can't change between kexec load and execute */ - ima_kexec_file.buf =vmalloc (segment_size);if (!ima_kexec_file.buf) { - ret = -ENOMEM ; - goto out; +pr_err ("Kexec file buf not allocated\n" ); +return -EINVAL ; } - ima_kexec_file.file =NULL ; - ima_kexec_file.size = segment_size; - ima_kexec_file.read_pos =0 ; - ima_kexec_file.count =sizeof (khdr);/* reserved space */ -memset (&khdr,0 ,sizeof (khdr)); khdr.version =1 ;/* 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, *buffer_size = ima_kexec_file.count; *buffer = ima_kexec_file.buf; out: -if (ret == -EINVAL ) -vfree (ima_kexec_file.buf);return ret; }
@@ -111,6 +129,12 @@ void ima_add_kexec_buffer(struct kimage *image)return ; } + ret =ima_alloc_kexec_file_buf (kexec_segment_size); +if (ret <0 ) { +pr_err ("Not enough memory for the kexec measurement buffer.\n" ); +return ; + } +ima_dump_measurement_list (&kexec_buffer_size, &kexec_buffer, kexec_segment_size);if (!kexec_buffer) {
Signature · 1 line
2.25.1
Re: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 15 lines · steven chen
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 operationTo allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.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'.
Quoted 5 lines
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)
LGTM,
Quoted 86 lines
security/integrity/ima/ima_kexec.c +35
-11@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size) +{ +ima_free_kexec_file_buf (&ima_kexec_file); + +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +static int ima_dump_measurement_list (unsigned long *buffer_size,void **buffer,unsigned long segment_size) { -struct seq_file ima_kexec_file;struct ima_queue_entry *qe;struct ima_kexec_hdr khdr;int ret =0 ;/* segment size can't change between kexec load and execute */ - ima_kexec_file.buf =vmalloc (segment_size);if (!ima_kexec_file.buf) { - ret = -ENOMEM ; - goto out; +pr_err ("Kexec file buf not allocated\n" ); +return -EINVAL ; } - ima_kexec_file.file =NULL ; - ima_kexec_file.size = segment_size; - ima_kexec_file.read_pos =0 ; - ima_kexec_file.count =sizeof (khdr);/* reserved space */ -memset (&khdr,0 ,sizeof (khdr)); khdr.version =1 ;/* 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, *buffer_size = ima_kexec_file.count; *buffer = ima_kexec_file.buf; out: -if (ret == -EINVAL ) -vfree (ima_kexec_file.buf);return ret; }@@ -111,6 +129,12 @@ void ima_add_kexec_buffer(struct kimage *image)return ; } + ret =ima_alloc_kexec_file_buf (kexec_segment_size); +if (ret <0 ) { +pr_err ("Not enough memory for the kexec measurement buffer.\n" ); +return ; + } +ima_dump_measurement_list (&kexec_buffer_size, &kexec_buffer, kexec_segment_size);if (!kexec_buffer) {Signature · 1 line
2.25.1
Mimi Zohar
maintainerRe: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
In reply to steven chenQuoted 5 lines · steven chen
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
Repeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.
This change was already made in [PATCH v11 1/9] ima: rename variable the set_file "file" to "ima_kexec_file". Please remove.
Quoted 25 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +4
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{
security/integrity/ima/ima_kexec.c line 31
Quoted 10 lines
security/integrity/ima/ima_kexec.c +10
-0+vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size) +{ +ima_free_kexec_file_buf (&ima_kexec_file);
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.
Quoted 13 lines
security/integrity/ima/ima_kexec.c +13
-0+ +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +
Re: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 48 lines · Mimi Zohar
Quoted 5 lines · steven chen
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 operationRepeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.This change was already made in [PATCH v11 1/9] ima: rename variable the
set_file"file" to "ima_kexec_file". Please remove.Quoted 33 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +12
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size)
Quoted 8 lines
security/integrity/ima/ima_kexec.c line 31
Quoted 2 lines
security/integrity/ima/ima_kexec.c +2
-0+{ +ima_free_kexec_file_buf (&ima_kexec_file);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 thevfree()here.
I also noticed this, patch 7 will remedy this. Put patch 7 just after this patch or squash it into this patch?
[PATCH v11 7/9] ima: verify if the segment size has changed
Quoted 15 lines
Quoted 14 lines
security/integrity/ima/ima_kexec.c +13
-0+ +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +
Mimi Zohar
maintainerRe: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 58 lines · Baoquan He
Quoted 48 lines · Mimi Zohar
Quoted 5 lines · steven chen
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 operationRepeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.This change was already made in [PATCH v11 1/9] ima: rename variable the
set_file"file" to "ima_kexec_file". Please remove.Quoted 33 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +12
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size)Quoted 8 lines
security/integrity/ima/ima_kexec.c line 31
Quoted 2 lines
security/integrity/ima/ima_kexec.c +2
-0+{ +ima_free_kexec_file_buf (&ima_kexec_file);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 thevfree()here.
Quoted 4 lines
I also noticed this, patch 7 will remedy this. Put patch 7 just after this patch or squash it into this patch?
[PATCH v11 7/9] ima: verify if the segment size has changed
I'm glad you noticed this too! I've been staring at it for a while, not knowing what to do.
"ima: verify if the segment size has changed" is new to v11. It was originally part of this patch. My comment on v10 was:
The call to ima_reset_kexec_file() in ima_add_kexec_buffer() resets ima_kexec_file.buf() hiding the fact that the above test always fails and falls through. As a result, 'buf' is always being re-allocated.
and
Instead of adding and then removing the ima_reset_kexec_file() call from ima_add_kexec_buffer(), defer adding the segment size test to when it is actually possible for the segment size to change. Please make the segment size test as a separate patch.
ima_reset_kexec_file() will then only be called by ima_free_kexec_file_buf(). Inline the ima_reset_kexec_file() code in ima_free_kexec_file_buf().
Quoted 18 lines
Quoted 16 lines
Quoted 15 lines
security/integrity/ima/ima_kexec.c +13
-0+ +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +
Re: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 76 lines · Mimi Zohar
Quoted 58 lines · Baoquan He
Quoted 48 lines · Mimi Zohar
Quoted 5 lines · steven chen
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 operationRepeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.This change was already made in [PATCH v11 1/9] ima: rename variable the
set_file"file" to "ima_kexec_file". Please remove.Quoted 33 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +12
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size)Quoted 8 lines
security/integrity/ima/ima_kexec.c line 31
Quoted 2 lines
security/integrity/ima/ima_kexec.c +2
-0+{ +ima_free_kexec_file_buf (&ima_kexec_file);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 thevfree()here.Quoted 4 lines
I also noticed this, patch 7 will remedy this. Put patch 7 just after this patch or squash it into this patch?
[PATCH v11 7/9] ima: verify if the segment size has changed
I'm glad you noticed this too! I've been staring at it for a while, not knowing what to do.
"ima: verify if the segment size has changed" is new to v11. It was originally part of this patch. My comment on v10 was:
The call to
ima_reset_kexec_file()inima_add_kexec_buffer()resetsima_kexec_file.buf()hiding the fact that the above test always fails and falls through. As a result, 'buf' is always being re-allocated.and
Quoted 7 lines
Instead of adding and then removing the
ima_reset_kexec_file()call fromima_add_kexec_buffer(), defer adding the segment size test to when it is actually possible for the segment size to change. Please make the segment size test as a separate patch.
ima_reset_kexec_file()will then only be called byima_free_kexec_file_buf(). Inline theima_reset_kexec_file()code inima_free_kexec_file_buf().
Thanks for deliberating on this and the details sharing, Mimi.
It could be fine if we add note in patch 2 log to mention the possible failure. With my understanding, commit/patch bisectable means it won't break compiling and block the testing. The failure you are concerned about is not a blocker, right? And people won't back port partial patches of this series.
Nore sure if there's another better way we can take or detour.
Thanks
Baoquan
Quoted 20 lines
Quoted 19 lines
Quoted 17 lines
Quoted 16 lines
security/integrity/ima/ima_kexec.c +13
-0+ +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +
Mimi Zohar
maintainerRe: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 87 lines · Baoquan He
Quoted 76 lines · Mimi Zohar
Quoted 58 lines · Baoquan He
Quoted 48 lines · Mimi Zohar
Quoted 5 lines · steven chen
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 operationRepeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.This change was already made in [PATCH v11 1/9] ima: rename variable the
set_file"file" to "ima_kexec_file". Please remove.Quoted 33 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +12
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size)Quoted 8 lines
security/integrity/ima/ima_kexec.c line 31
Quoted 2 lines
security/integrity/ima/ima_kexec.c +2
-0+{ +ima_free_kexec_file_buf (&ima_kexec_file);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 thevfree()here.Quoted 4 lines
I also noticed this, patch 7 will remedy this. Put patch 7 just after this patch or squash it into this patch?
[PATCH v11 7/9] ima: verify if the segment size has changed
I'm glad you noticed this too! I've been staring at it for a while, not knowing what to do.
"ima: verify if the segment size has changed" is new to v11. It was originally part of this patch. My comment on v10 was:
The call to
ima_reset_kexec_file()inima_add_kexec_buffer()resetsima_kexec_file.buf()hiding the fact that the above test always fails and falls through. As a result, 'buf' is always being re-allocated.and
Quoted 7 lines
Instead of adding and then removing the
ima_reset_kexec_file()call fromima_add_kexec_buffer(), defer adding the segment size test to when it is actually possible for the segment size to change. Please make the segment size test as a separate patch.
ima_reset_kexec_file()will then only be called byima_free_kexec_file_buf(). Inline theima_reset_kexec_file()code inima_free_kexec_file_buf().Thanks for deliberating on this and the details sharing, Mimi.
Quoted 7 lines
It could be fine if we add note in patch 2 log to mention the possible failure. With my understanding, commit/patch bisectable means it won't break compiling and block the testing. The failure you are concerned about is not a blocker, right? And people won't back port partial patches of this series.
Nore sure if there's another better way we can take or detour.
Right, doing two consecutive kexec loads in a row is not common and won't block testing. Patch readability is more important, in this case, at least to me. I'm fine with your suggestion.
Thanks, Boaquan.
Quoted 22 lines
Quoted 20 lines
Quoted 19 lines
Quoted 17 lines
Quoted 16 lines
security/integrity/ima/ima_kexec.c +13
-0+ +/* segment size can't change between kexec load and execute */ + ima_kexec_file.buf =vmalloc (segment_size); +if (!ima_kexec_file.buf) +return -ENOMEM ; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos =0 ; + ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ + +return 0 ; +} +
Re: [PATCH v11 2/9] ima: define and call ima_alloc_kexec_file_buf()
Quoted 94 lines · Mimi Zohar
Quoted 93 lines · Baoquan He
Quoted 76 lines · Mimi Zohar
Quoted 58 lines · Baoquan He
Quoted 48 lines · Mimi Zohar
Quoted 5 lines · steven chen
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 operationRepeating this here is unnecessary.
Quoted 3 lines
To allow the buffer allocation and population to be separated into distinct steps, make the function local
seq_file"ima_kexec_file" to a file variable.This change was already made in [PATCH v11 1/9] ima: rename variable the
set_file"file" to "ima_kexec_file". Please remove.Quoted 33 lines
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'.
Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-)security/integrity/ima/ima_kexec.c +12
-0@@ -15,26 +15,46 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf (struct seq_file *sf) +{ +vfree (sf->buf); + sf->buf =NULL ; + sf->size =0 ; + sf->read_pos =0 ; + sf->count =0 ; +} + +static int ima_alloc_kexec_file_buf (size_t segment_size)Quoted 8 lines
security/integrity/ima/ima_kexec.c line 31
Quoted 2 lines
security/integrity/ima/ima_kexec.c +2
-0+{ +ima_free_kexec_file_buf (&ima_kexec_file);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 thevfree()here.Quoted 4 lines
I also noticed this, patch 7 will remedy this. Put patch 7 just after this patch or squash it into this patch?
[PATCH v11 7/9] ima: verify if the segment size has changed
I'm glad you noticed this too! I've been staring at it for a while, not knowing what to do.
"ima: verify if the segment size has changed" is new to v11. It was originally part of this patch. My comment on v10 was:
The call to
ima_reset_kexec_file()inima_add_kexec_buffer()resetsima_kexec_file.buf()hiding the fact that the above test always fails and falls through. As a result, 'buf' is always being re-allocated.and
Quoted 7 lines
Instead of adding and then removing the
ima_reset_kexec_file()call fromima_add_kexec_buffer(), defer adding the segment size test to when it is actually possible for the segment size to change. Please make the segment size test as a separate patch.
ima_reset_kexec_file()will then only be called byima_free_kexec_file_buf(). Inline theima_reset_kexec_file()code inima_free_kexec_file_buf().Thanks for deliberating on this and the details sharing, Mimi.
It could be fine if we add note in patch 2 log to mention the possible failure. With my understanding, commit/patch bisectable means it won't break compiling and block the testing. The failure you are concerned about is not a blocker, right? And people won't back port partial patches of this series.
Quoted 5 lines
Quoted 1 line
Nore sure if there's another better way we can take or detour.
Right, doing two consecutive kexec loads in a row is not common and won't block testing. Patch readability is more important, in this case, at least to me. I'm fine with your suggestion.
That's great, thanks for confirming.
PATCH v11 3/9 kexec: define functions to map and unmap segments
In reply to steven chenCurrently, the kernel behavior during kexec load is to fetch the IMA measurements logs and store logs in kernel memory. When a kexec reboot is triggered, these stored logs in the kernel memory are carried over to the second kernel. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel. This results in a mismatch between TPM PCR quotes and the actual IMA measurements list after kexec reboot, leading to remote attestation failure.
To solve this problem, the new design defers reading the IMA measurements logs into the kexec buffer to the kexec reboot phase, while still allocating the necessary buffer at kexec load time because it is not appropriate to allocate memory at the kexec reboot moment.
The content of memory segments carried over to the new kernel during the kexec system call can be changed at the kexec 'execute' stage, but the size of the memory segments cannot be changed at the kexec 'execute' stage.
To copy IMA measurement logs during the kexec operation, IMA allocates memory at the kexec 'load' stage and map the segments to the kimage structure. The mapped address will then be used to copy IMA measurements during the kexec 'execute' stage.
Currently, the mechanism to map and unmap segments to the kimage structure is not available to subsystems outside of kexec.
Implement kimage_map_segment() to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function takes a kimage pointer, a memory address, and a size, then gathers the source pages within the specified address range, creates an array of page pointers, and maps these to a contiguous virtual address range. The function returns the start virtual address of this range if successful, or NULL on failure.
Implement kimage_unmap_segment() for unmapping segments using vunmap().
From: Tushar Sugandhi <[email protected]>
--- include/linux/kexec.h | 6 +++++ kernel/kexec_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+)
include/linux/kexec.h +6 -0
@@ -467,13 +467,19 @@ extern bool kexec_file_dbg_print; #define kexec_dprintk(fmt, arg...) \ do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) +extern void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size); +extern void kimage_unmap_segment (void *buffer);#else /* !CONFIG_KEXEC_CORE */ struct pt_regs ;struct task_struct ; +struct kimage ;static inline void __crash_kexec (struct pt_regs *regs) { }static inline void crash_kexec (struct pt_regs *regs) { }static inline int kexec_should_crash (struct task_struct *p) {return 0 ; }static inline int kexec_crash_loaded (void ) {return 0 ; } +static inline void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size) +{return NULL ; } +static inline void kimage_unmap_segment (void *buffer) { }#define kexec_in_progress false#endif /* CONFIG_KEXEC_CORE */
kernel/kexec_core.c +54 -0
60 lines not on this page · raw message
Signature · 1 line
2.25.1
Re: [PATCH v11 3/9] kexec: define functions to map and unmap segments
Quoted 18 lines · steven chen
Currently, the kernel behavior during kexec load is to fetch the IMA measurements logs and store logs in kernel memory. When a kexec reboot is triggered, these stored logs in the kernel memory are carried over to the second kernel. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel. This results in a mismatch between TPM PCR quotes and the actual IMA measurements list after kexec reboot, leading to remote attestation failure.
To solve this problem, the new design defers reading the IMA measurements logs into the kexec buffer to the kexec reboot phase, while still allocating the necessary buffer at kexec load time because it is not appropriate to allocate memory at the kexec reboot moment.
The content of memory segments carried over to the new kernel during the kexec system call can be changed at the kexec 'execute' stage, but the size of the memory segments cannot be changed at the kexec 'execute' stage.
Quoted 7 lines
To copy IMA measurement logs during the kexec operation, IMA allocates memory at the kexec 'load' stage and map the segments to the kimage structure. The mapped address will then be used to copy IMA measurements during the kexec 'execute' stage.
Currently, the mechanism to map and unmap segments to the kimage structure is not available to subsystems outside of kexec.
There's no need to describe the plan of the whole series. From my point of view, the first few patches are prepared for later change. We can just mention this, and briefly tell what it's doing if it's complicated. For log of this patch, I would go with:
====
Implement kimage_map_segment() to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function gathers the source pages within the specified address range, and maps them to a contiguous virtual address range.
This is a preparation for later usage.
====
Other than this, the code change looks good to me.
Quoted 116 lines
Implement
kimage_map_segment()to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function takes a kimage pointer, a memory address, and a size, then gathers the source pages within the specified address range, creates an array of page pointers, and maps these to a contiguous virtual address range. The function returns the start virtual address of this range if successful, or NULL on failure.Implement
kimage_unmap_segment()for unmapping segments usingvunmap().From: Tushar Sugandhi <[email protected]>
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Acked-by Baoquan He <[email protected]>--- include/linux/kexec.h | 6 +++++ kernel/kexec_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+)include/linux/kexec.h +6
-0@@ -467,13 +467,19 @@ extern bool kexec_file_dbg_print; #define kexec_dprintk(fmt, arg...) \ do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) +extern void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size); +extern void kimage_unmap_segment (void *buffer);#else /* !CONFIG_KEXEC_CORE */ struct pt_regs ;struct task_struct ; +struct kimage ;static inline void __crash_kexec (struct pt_regs *regs) { }static inline void crash_kexec (struct pt_regs *regs) { }static inline int kexec_should_crash (struct task_struct *p) {return 0 ; }static inline int kexec_crash_loaded (void ) {return 0 ; } +static inline void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size) +{return NULL ; } +static inline void kimage_unmap_segment (void *buffer) { }#define kexec_in_progress false#endif /* CONFIG_KEXEC_CORE */ kernel/kexec_core.c +54
-0@@ -867,6 +867,60 @@ int kimage_load_segment(struct kimage *image,return result; } +void *kimage_map_segment (struct kimage *image, +unsigned long addr,unsigned long size) +{ +unsigned long src_page_addr, dest_page_addr =0 ; +unsigned long eaddr = addr + size; +kimage_entry_t *ptr, entry; +struct page **src_pages; +unsigned int npages; +void *vaddr =NULL ; +int i; + +/* +* Collect the source pages and map them in a contiguous VA range. +*/ + npages =PFN_UP (eaddr) -PFN_DOWN (addr); + src_pages =kmalloc_array (npages,sizeof (*src_pages),GFP_KERNEL ); +if (!src_pages) { +pr_err ("Could not allocate ima pages array.\n" ); +return NULL ; + } + + i =0 ; +for_each_kimage_entry (image, ptr, entry) { +if (entry &IND_DESTINATION ) { + dest_page_addr = entry &PAGE_MASK ; + }else if (entry &IND_SOURCE ) { +if (dest_page_addr >= addr && dest_page_addr < eaddr) { + src_page_addr = entry &PAGE_MASK ; + src_pages[i++] = +virt_to_page (__va (src_page_addr)); +if (i == npages) +break ; + dest_page_addr +=PAGE_SIZE ; + } + } + } + +/* Sanity check. */ +WARN_ON (i < npages); + + vaddr =vmap (src_pages, npages,VM_MAP ,PAGE_KERNEL ); +kfree (src_pages); + +if (!vaddr) +pr_err ("Could not map ima buffer.\n" ); + +return vaddr; +} + +void kimage_unmap_segment (void *segment_buffer) +{ +vunmap (segment_buffer); +} +struct kexec_load_limit {/* Mutex protects the limit count. */ struct mutex mutex;Signature · 1 line
2.25.1
Re: [PATCH v11 3/9] kexec: define functions to map and unmap segments
Quoted 37 lines · Baoquan He
Quoted 18 lines · steven chen
Currently, the kernel behavior during kexec load is to fetch the IMA measurements logs and store logs in kernel memory. When a kexec reboot is triggered, these stored logs in the kernel memory are carried over to the second kernel. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel. This results in a mismatch between TPM PCR quotes and the actual IMA measurements list after kexec reboot, leading to remote attestation failure.
To solve this problem, the new design defers reading the IMA measurements logs into the kexec buffer to the kexec reboot phase, while still allocating the necessary buffer at kexec load time because it is not appropriate to allocate memory at the kexec reboot moment.
The content of memory segments carried over to the new kernel during the kexec system call can be changed at the kexec 'execute' stage, but the size of the memory segments cannot be changed at the kexec 'execute' stage.
Quoted 7 lines
To copy IMA measurement logs during the kexec operation, IMA allocates memory at the kexec 'load' stage and map the segments to the kimage structure. The mapped address will then be used to copy IMA measurements during the kexec 'execute' stage.
Currently, the mechanism to map and unmap segments to the kimage structure is not available to subsystems outside of kexec.
There's no need to describe the plan of the whole series. From my point of view, the first few patches are prepared for later change. We can just mention this, and briefly tell what it's doing if it's complicated. For log of this patch, I would go with:
====
Implementkimage_map_segment()to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function gathers the source pages within the specified address range, and maps them to a contiguous virtual address range.
Quoted 4 lines
This is a preparation for later usage.
====Other than this, the code change looks good to me.
Hi Baoquan,
Thanks for your comments. Will update in next version.
Steven
Quoted 115 lines
Quoted 115 lines
Implement
kimage_map_segment()to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function takes a kimage pointer, a memory address, and a size, then gathers the source pages within the specified address range, creates an array of page pointers, and maps these to a contiguous virtual address range. The function returns the start virtual address of this range if successful, or NULL on failure.Implement
kimage_unmap_segment()for unmapping segments usingvunmap().From: Tushar Sugandhi <[email protected]>
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Acked-by Baoquan He <[email protected]>--- include/linux/kexec.h | 6 +++++ kernel/kexec_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+)include/linux/kexec.h +6
-0@@ -467,13 +467,19 @@ extern bool kexec_file_dbg_print; #define kexec_dprintk(fmt, arg...) \ do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) +extern void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size); +extern void kimage_unmap_segment (void *buffer);#else /* !CONFIG_KEXEC_CORE */ struct pt_regs ;struct task_struct ; +struct kimage ;static inline void __crash_kexec (struct pt_regs *regs) { }static inline void crash_kexec (struct pt_regs *regs) { }static inline int kexec_should_crash (struct task_struct *p) {return 0 ; }static inline int kexec_crash_loaded (void ) {return 0 ; } +static inline void *kimage_map_segment (struct kimage *image,unsigned long addr,unsigned long size) +{return NULL ; } +static inline void kimage_unmap_segment (void *buffer) { }#define kexec_in_progress false#endif /* CONFIG_KEXEC_CORE */ kernel/kexec_core.c +54
-0@@ -867,6 +867,60 @@ int kimage_load_segment(struct kimage *image,return result; } +void *kimage_map_segment (struct kimage *image, +unsigned long addr,unsigned long size) +{ +unsigned long src_page_addr, dest_page_addr =0 ; +unsigned long eaddr = addr + size; +kimage_entry_t *ptr, entry; +struct page **src_pages; +unsigned int npages; +void *vaddr =NULL ; +int i; + +/* +* Collect the source pages and map them in a contiguous VA range. +*/ + npages =PFN_UP (eaddr) -PFN_DOWN (addr); + src_pages =kmalloc_array (npages,sizeof (*src_pages),GFP_KERNEL ); +if (!src_pages) { +pr_err ("Could not allocate ima pages array.\n" ); +return NULL ; + } + + i =0 ; +for_each_kimage_entry (image, ptr, entry) { +if (entry &IND_DESTINATION ) { + dest_page_addr = entry &PAGE_MASK ; + }else if (entry &IND_SOURCE ) { +if (dest_page_addr >= addr && dest_page_addr < eaddr) { + src_page_addr = entry &PAGE_MASK ; + src_pages[i++] = +virt_to_page (__va (src_page_addr)); +if (i == npages) +break ; + dest_page_addr +=PAGE_SIZE ; + } + } + } + +/* Sanity check. */ +WARN_ON (i < npages); + + vaddr =vmap (src_pages, npages,VM_MAP ,PAGE_KERNEL ); +kfree (src_pages); + +if (!vaddr) +pr_err ("Could not map ima buffer.\n" ); + +return vaddr; +} + +void kimage_unmap_segment (void *segment_buffer) +{ +vunmap (segment_buffer); +} +struct kexec_load_limit {/* Mutex protects the limit count. */ struct mutex mutex;Signature · 1 line
2.25.1
PATCH v11 4/9 ima: kexec: skip IMA segment validation after kexec soft reboot
In reply to steven chenThe kexec_calculate_store_digests() function calculates and stores the digest of the segment during the kexec_file_load syscall, where the IMA segment is also allocated.
With this series, the IMA segment will be updated with the measurement log at the kexec execute stage when a soft reboot is initiated. Therefore, the digests should be updated for the IMA segment in the normal case.
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.
However, during the kexec execute stage, if kexec_calculate_store_digests() API is called to update the digest, it does not reuse the same memory segment allocated during the kexec 'load' stage and the new memory segment required cannot be transferred/mapped to the new kernel.
As a result, digest verification will fail in verify_sha256_digest() after a kexec soft reboot into the new kernel. Therefore, the digest calculation/verification of the IMA segment needs to be skipped.
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.
Since verify_sha256_digest() only verifies 'purgatory_sha_regions', no change is needed in verify_sha256_digest() in this context.
With this change, the IMA segment is not included in the digest calculation, storage, and verification.
--- include/linux/kexec.h | 3 +++ kernel/kexec_file.c | 22 ++++++++++++++++++++++ security/integrity/ima/ima_kexec.c | 3 +++ 3 files changed, 28 insertions(+)
include/linux/kexec.h +3 -0
@@ -362,6 +362,9 @@ struct kimage {phys_addr_t ima_buffer_addr;size_t ima_buffer_size; + +unsigned long ima_segment_index; +bool is_ima_segment_index_set;#endif /* Core ELF header buffer */
kernel/kexec_file.c +22 -0
@@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void) }#endif +#ifdef CONFIG_IMA_KEXEC +static bool check_ima_segment_index (struct kimage *image,int i) +{ +if (image->is_ima_segment_index_set && i == image->ima_segment_index) +return true; +else +return false; +} +#else +static bool check_ima_segment_index (struct kimage *image,int i) +{ +return false; +} +#endif +static int kexec_calculate_store_digests (struct kimage *image);/* Maximum size in bytes for kernel/initrd files. */
@@ -764,6 +779,13 @@ static int kexec_calculate_store_digests(struct kimage *image)if (ksegment->kbuf == pi->purgatory_buf)continue ; +/* +* Skip the segment if ima_segment_index is set and matches +* the current index +*/ +if (check_ima_segment_index (image, i)) +continue ; + ret =crypto_shash_update (desc, ksegment->kbuf, ksegment->bufsz);if (ret)
security/integrity/ima/ima_kexec.c +3 -0
@@ -145,6 +145,7 @@ void ima_add_kexec_buffer(struct kimage *image) kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; + image->is_ima_segment_index_set = false; ret =kexec_add_buffer (&kbuf);if (ret) {pr_err ("Error passing over kexec measurement buffer.\n" );
@@ -155,6 +156,8 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_addr = kbuf.mem; image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + image->ima_segment_index = image->nr_segments -1 ; + image->is_ima_segment_index_set = true;kexec_dprintk ("kexec measurement buffer for the loaded kernel at 0x%lx.\n" , kbuf.mem);
Signature · 1 line
2.25.1
Re: [PATCH v11 4/9] ima: kexec: skip IMA segment validation after kexec soft reboot
Quoted 27 lines · steven chen
The
kexec_calculate_store_digests()function calculates and stores the digest of the segment during thekexec_file_loadsyscall, where the IMA segment is also allocated.With this series, the IMA segment will be updated with the measurement log at the kexec execute stage when a soft reboot is initiated. Therefore, the digests should be updated for the IMA segment in the normal case.
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.
However, during the kexec execute stage, if
kexec_calculate_store_digests()API is called to update the digest, it does not reuse the same memory segment allocated during the kexec 'load' stage and the new memory segment required cannot be transferred/mapped to the new kernel.As a result, digest verification will fail in
verify_sha256_digest()after a kexec soft reboot into the new kernel. Therefore, the digest calculation/verification of the IMA segment needs to be skipped.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 thepurgatory_sha_regions.
Quoted 5 lines
Since
verify_sha256_digest()only verifies 'purgatory_sha_regions', no change is needed inverify_sha256_digest()in this context.With this change, the IMA segment is not included in the digest calculation, storage, and verification.
I would write the patch log like:
======
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.
======
Quoted 94 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>Acked-by Baoquan He <[email protected]>--- include/linux/kexec.h | 3 +++ kernel/kexec_file.c | 22 ++++++++++++++++++++++ security/integrity/ima/ima_kexec.c | 3 +++ 3 files changed, 28 insertions(+)include/linux/kexec.h +3
-0@@ -362,6 +362,9 @@ struct kimage {phys_addr_t ima_buffer_addr;size_t ima_buffer_size; + +unsigned long ima_segment_index; +bool is_ima_segment_index_set;#endif /* Core ELF header buffer */ kernel/kexec_file.c +22
-0@@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void) }#endif +#ifdef CONFIG_IMA_KEXEC +static bool check_ima_segment_index (struct kimage *image,int i) +{ +if (image->is_ima_segment_index_set && i == image->ima_segment_index) +return true; +else +return false; +} +#else +static bool check_ima_segment_index (struct kimage *image,int i) +{ +return false; +} +#endif +static int kexec_calculate_store_digests (struct kimage *image);/* Maximum size in bytes for kernel/initrd files. */ @@ -764,6 +779,13 @@ static int kexec_calculate_store_digests(struct kimage *image)if (ksegment->kbuf == pi->purgatory_buf)continue ; +/* +* Skip the segment if ima_segment_index is set and matches +* the current index +*/ +if (check_ima_segment_index (image, i)) +continue ; + ret =crypto_shash_update (desc, ksegment->kbuf, ksegment->bufsz);if (ret)security/integrity/ima/ima_kexec.c +3
-0@@ -145,6 +145,7 @@ void ima_add_kexec_buffer(struct kimage *image) kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; + image->is_ima_segment_index_set = false; ret =kexec_add_buffer (&kbuf);if (ret) {pr_err ("Error passing over kexec measurement buffer.\n" );@@ -155,6 +156,8 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_addr = kbuf.mem; image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + image->ima_segment_index = image->nr_segments -1 ; + image->is_ima_segment_index_set = true;kexec_dprintk ("kexec measurement buffer for the loaded kernel at 0x%lx.\n" , kbuf.mem);Signature · 1 line
2.25.1
Re: [PATCH v11 4/9] ima: kexec: skip IMA segment validation after kexec soft reboot
Quoted 48 lines · Baoquan He
Quoted 27 lines · steven chen
The
kexec_calculate_store_digests()function calculates and stores the digest of the segment during thekexec_file_loadsyscall, where the IMA segment is also allocated.With this series, the IMA segment will be updated with the measurement log at the kexec execute stage when a soft reboot is initiated. Therefore, the digests should be updated for the IMA segment in the normal case.
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.
However, during the kexec execute stage, if
kexec_calculate_store_digests()API is called to update the digest, it does not reuse the same memory segment allocated during the kexec 'load' stage and the new memory segment required cannot be transferred/mapped to the new kernel.As a result, digest verification will fail in
verify_sha256_digest()after a kexec soft reboot into the new kernel. Therefore, the digest calculation/verification of the IMA segment needs to be skipped.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 thepurgatory_sha_regions.Quoted 5 lines
Since
verify_sha256_digest()only verifies 'purgatory_sha_regions', no change is needed inverify_sha256_digest()in this context.With this change, the IMA segment is not included in the digest calculation, storage, and verification.
I would write the patch log like:
======
Currently, the functionkexec_calculate_store_digests()calculates and stores the digest of the segment during thekexec_file_loadsyscall, 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.
Quoted 7 lines
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 thepurgatory_sha_regions.With this change, the IMA segment is not included in the digest calculation, storage, and verification.
======
Hi Baoquan,
I will update it in next version.
Thanks for your comments.
Steven
Quoted 93 lines
Quoted 93 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>Acked-by Baoquan He <[email protected]>--- include/linux/kexec.h | 3 +++ kernel/kexec_file.c | 22 ++++++++++++++++++++++ security/integrity/ima/ima_kexec.c | 3 +++ 3 files changed, 28 insertions(+)include/linux/kexec.h +3
-0@@ -362,6 +362,9 @@ struct kimage {phys_addr_t ima_buffer_addr;size_t ima_buffer_size; + +unsigned long ima_segment_index; +bool is_ima_segment_index_set;#endif /* Core ELF header buffer */ kernel/kexec_file.c +22
-0@@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void) }#endif +#ifdef CONFIG_IMA_KEXEC +static bool check_ima_segment_index (struct kimage *image,int i) +{ +if (image->is_ima_segment_index_set && i == image->ima_segment_index) +return true; +else +return false; +} +#else +static bool check_ima_segment_index (struct kimage *image,int i) +{ +return false; +} +#endif +static int kexec_calculate_store_digests (struct kimage *image);/* Maximum size in bytes for kernel/initrd files. */ @@ -764,6 +779,13 @@ static int kexec_calculate_store_digests(struct kimage *image)if (ksegment->kbuf == pi->purgatory_buf)continue ; +/* +* Skip the segment if ima_segment_index is set and matches +* the current index +*/ +if (check_ima_segment_index (image, i)) +continue ; + ret =crypto_shash_update (desc, ksegment->kbuf, ksegment->bufsz);if (ret)security/integrity/ima/ima_kexec.c +3
-0@@ -145,6 +145,7 @@ void ima_add_kexec_buffer(struct kimage *image) kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; + image->is_ima_segment_index_set = false; ret =kexec_add_buffer (&kbuf);if (ret) {pr_err ("Error passing over kexec measurement buffer.\n" );@@ -155,6 +156,8 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_addr = kbuf.mem; image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + image->ima_segment_index = image->nr_segments -1 ; + image->is_ima_segment_index_set = true;kexec_dprintk ("kexec measurement buffer for the loaded kernel at 0x%lx.\n" , kbuf.mem);Signature · 1 line
2.25.1
PATCH v11 5/9 ima: kexec: define functions to copy IMA log at soft boot
In reply to steven chenThe IMA log is currently copied to the new kernel during kexec 'load' using ima_dump_measurement_list(). However, the log copied at kexec 'load' may result in loss of IMA measurements that only occurred after kexec "load'. Therefore, the log needs to be copied during kexec 'execute'. Setup the needed infrastructure to move the IMA log copy from kexec 'load' to 'execute'.
Define a new IMA hook ima_update_kexec_buffer() as a stub function. It will be used to call ima_dump_measurement_list() during kexec 'execute'.
Implement ima_kexec_post_load() function to be invoked after the new Kernel image has been loaded for kexec. ima_kexec_post_load() maps the IMA buffer to a segment in the newly loaded Kernel. It also registers the reboot notifier_block to trigger ima_update_kexec_buffer() at kexec 'execute'.
Set the priority of register_reboot_notifier to INT_MIN to ensure that the IMA log copy operation will happen at the end of the operation chain, which is crucial for maintaining the integrity of the logs
--- include/linux/ima.h | 3 ++ security/integrity/ima/ima_kexec.c | 47 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+)
include/linux/ima.h +3 -0
@@ -32,6 +32,9 @@ static inline void ima_appraise_parse_cmdline(void) {}#ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer (struct kimage *image); +extern void ima_kexec_post_load (struct kimage *image); +#else +static inline void ima_kexec_post_load (struct kimage *image) {}#endif #else
security/integrity/ima/ima_kexec.c +47 -0
63 lines not on this page · raw message
Signature · 1 line
2.25.1
Re: [PATCH v11 5/9] ima: kexec: define functions to copy IMA log at soft boot
Quoted 4 lines · steven chen
The IMA log is currently copied to the new kernel during kexec 'load' using
ima_dump_measurement_list(). However, the log copied at kexec 'load' may result in loss of IMA measurements that only occurred after kexec "load'.
Ok
Quoted 2 lines
Therefore, the log needs to be copied during kexec 'execute'.
The above line is unnecessary.
Quoted 12 lines
Setup the needed infrastructure to move the IMA log copy from kexec 'load' to 'execute'.
Define a new IMA hook
ima_update_kexec_buffer()as a stub function. It will be used to callima_dump_measurement_list()during kexec 'execute'.Implement
ima_kexec_post_load()function to be invoked after the new Kernel image has been loaded for kexec.ima_kexec_post_load()maps the IMA buffer to a segment in the newly loaded Kernel. It also registers the rebootnotifier_blockto triggerima_update_kexec_buffer()at kexec 'execute'.
Quoted 3 lines
Set the priority of
register_reboot_notifiertoINT_MINto ensure that the IMA log copy operation will happen at the end of the operation chain, which is crucial for maintaining the integrity of the logs
Instead of ", which is crucial for maintaining the integrity of the logs" say something like ", so that all the IMA measurement records extended into the TPM are copied."
Quoted 8 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>
Thanks, Steven. With the change to use INT_MIN, the "kexec_execute" record is now added to the IMA measurement list, extended into the PCR, and included in the IMA measurement list records copied.
Re: [PATCH v11 5/9] ima: kexec: define functions to copy IMA log at soft boot
Quoted 23 lines · Mimi Zohar
Quoted 4 lines · steven chen
The IMA log is currently copied to the new kernel during kexec 'load' using
ima_dump_measurement_list(). However, the log copied at kexec 'load' may result in loss of IMA measurements that only occurred after kexec "load'.Ok
Quoted 2 lines
Therefore, the log needs to be copied during kexec 'execute'.
The above line is unnecessary.
Quoted 12 lines
Setup the needed infrastructure to move the IMA log copy from kexec 'load' to 'execute'.
Define a new IMA hook
ima_update_kexec_buffer()as a stub function. It will be used to callima_dump_measurement_list()during kexec 'execute'.Implement
ima_kexec_post_load()function to be invoked after the new Kernel image has been loaded for kexec.ima_kexec_post_load()maps the IMA buffer to a segment in the newly loaded Kernel. It also registers the rebootnotifier_blockto triggerima_update_kexec_buffer()at kexec 'execute'.
Quoted 6 lines
Quoted 3 lines
Set the priority of
register_reboot_notifiertoINT_MINto ensure that the IMA log copy operation will happen at the end of the operation chain, which is crucial for maintaining the integrity of the logsInstead of ", which is crucial for maintaining the integrity of the logs" say something like ", so that all the IMA measurement records extended into the TPM are copied."
Hi Mimi,
I will update in next version.
Thanks,
Steven
Quoted 12 lines
Quoted 7 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Thanks, Steven. With the change to use
INT_MIN, the "kexec_execute" record is now added to the IMA measurement list, extended into the PCR, and included in the IMA measurement list records copied.Reviewed-by Mimi Zohar <[email protected]>
PATCH v11 6/9 ima: kexec: move IMA log copy from kexec load to execute
In reply to steven chenima_dump_measurement_list() is called during kexec 'load', which may result in loss of IMA measurements during kexec soft reboot. Due to missed measurements that only occurred after kexec 'load', this function needs to be called during kexec 'execute'.
Make the kexec_segment_size variable a local static variable within the file, so it can be accessed during both kexec 'load' and 'execute'.
Implement the kexec_post_load() function to be invoked after the new kernel image has been loaded for kexec. Instead of calling machine_kexec_post_load() directly from the kexec_file_load() syscall, call kexec_post_load(), which in turn calls machine_kexec_post_load() to maintain the original image processing.
Invoke ima_kexec_post_load() within the kexec_post_load() API only for kexec soft reboot scenarios, excluding KEXEC_FILE_ON_CRASH.
Register a reboot notifier for the ima_update_kexec_buffer() API within ima_kexec_post_load() to ensure it is called upon receiving a reboot notification.
Move the ima_dump_measurement_list() call from ima_add_kexec_buffer() to ima_update_kexec_buffer() to copy the IMA log at the kexec 'execute' stage.
When there is insufficient memory to copy all the measurement logs, copy as much of the measurement list as possible.
--- kernel/kexec_file.c | 11 +++++++- security/integrity/ima/ima_kexec.c | 43 ++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 15 deletions(-)
kernel/kexec_file.c +10 -1
@@ -201,6 +201,15 @@ kimage_validate_signature(struct kimage *image) }#endif +static int kexec_post_load (struct kimage *image,unsigned long flags) +{ +#ifdef CONFIG_IMA_KEXEC +if (!(flags &KEXEC_FILE_ON_CRASH )) +ima_kexec_post_load (image); +#endif +return machine_kexec_post_load (image); +} +/* * In file mode list of segments is prepared by kernel. Copy relevant * data from user space, do error checking, prepare segment list
@@ -428,7 +437,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,kimage_terminate (image); - ret =machine_kexec_post_load (image); + ret =kexec_post_load (image, flags);if (ret) goto out;
security/integrity/ima/ima_kexec.c +29 -14
80 lines not on this page · raw message
Signature · 1 line
2.25.1
Mimi Zohar
maintainerRe: [PATCH v11 6/9] ima: kexec: move IMA log copy from kexec load to execute
Quoted 4 lines · steven chen
ima_dump_measurement_list()is called during kexec 'load', which may result in loss of IMA measurements during kexec soft reboot. Due to missed measurements that only occurred after kexec 'load', this function needs to be called during kexec 'execute'.
Re-use the motivation from 5/9 (with tweak):
The IMA log is currently copied to the new kernel during kexec 'load' using ima_dump_measurement_list(). However, the IMA measurement list copied at kexec 'load' may result in loss of IMA measurements records that only occurred after the kexec 'load'.
And finish the paragraph with:
Move the IMA measurement list log copy from kexec 'load' to 'execute'.
Quoted 9 lines
Make the
kexec_segment_sizevariable a local static variable within the file, so it can be accessed during both kexec 'load' and 'execute'.Implement the
kexec_post_load()function to be invoked after the new kernel image has been loaded for kexec. Instead of callingmachine_kexec_post_load()directly from thekexec_file_load()syscall, callkexec_post_load(), which in turn callsmachine_kexec_post_load()to maintain the original image processing.
Define kexec_post_load() as a wrapper for calling ima_kexec_post_load() and machine_kexec_post_load(). Replace the existing direct call to machine_kexec_post_load() with kexec_post_load().
Quoted 3 lines
Invoke
ima_kexec_post_load()within thekexec_post_load()API only for kexec soft reboot scenarios, excludingKEXEC_FILE_ON_CRASH.
"Don't call ima_kexec_post_load() on KEXEC_FILE_ON_CRASH" would be listed in the Changelog if it changed, not here in the patch description. Please remove.
Quoted 4 lines
Register a reboot notifier for the
ima_update_kexec_buffer()API withinima_kexec_post_load()to ensure it is called upon receiving a reboot notification.
Registering the reboot notifier was done in "[PATCH v11 5/9] ima: kexec: define functions to copy IMA log at soft boot", not here. Please remove.
Quoted 3 lines
Move the
ima_dump_measurement_list()call fromima_add_kexec_buffer()toima_update_kexec_buffer()to copy the IMA log at the kexec 'execute' stage.
This information was already stated in the first paragraph as part of the motivation for the patch. Please remove.
Quoted 3 lines
When there is insufficient memory to copy all the measurement logs, copy as much of the measurement list as possible.
Is this comment still applicable to this patch?
Please review your patch descriptions before posting, making sure that everything is still applicable.
thanks,
Mimi
Quoted 8 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>
Re: [PATCH v11 6/9] ima: kexec: move IMA log copy from kexec load to execute
Quoted 48 lines · Mimi Zohar
Quoted 4 lines · steven chen
ima_dump_measurement_list()is called during kexec 'load', which may result in loss of IMA measurements during kexec soft reboot. Due to missed measurements that only occurred after kexec 'load', this function needs to be called during kexec 'execute'.Re-use the motivation from 5/9 (with tweak):
The IMA log is currently copied to the new kernel during kexec 'load' using
ima_dump_measurement_list(). However, the IMA measurement list copied at kexec 'load' may result in loss of IMA measurements records that only occurred after the kexec 'load'.And finish the paragraph with:
Move the IMA measurement list log copy from kexec 'load' to 'execute'.Quoted 7 lines
Make the
kexec_segment_sizevariable a local static variable within the file, so it can be accessed during both kexec 'load' and 'execute'.Implement the
kexec_post_load()function to be invoked after the new kernel image has been loaded for kexec. Instead of callingmachine_kexec_post_load()directly from thekexec_file_load()syscall, callkexec_post_load(), which in turn callsmachine_kexec_post_load()to maintain the original image processing.Define
kexec_post_load()as a wrapper for callingima_kexec_post_load()andmachine_kexec_post_load(). Replace the existing direct call tomachine_kexec_post_load()withkexec_post_load().Quoted 3 lines
Invoke
ima_kexec_post_load()within thekexec_post_load()API only for kexec soft reboot scenarios, excludingKEXEC_FILE_ON_CRASH."Don't call
ima_kexec_post_load()onKEXEC_FILE_ON_CRASH" would be listed in the Changelog if it changed, not here in the patch description. Please remove.Quoted 4 lines
Register a reboot notifier for the
ima_update_kexec_buffer()API withinima_kexec_post_load()to ensure it is called upon receiving a reboot notification.Registering the reboot notifier was done in "[PATCH v11 5/9] ima: kexec: define functions to copy IMA log at soft boot", not here. Please remove.
Quoted 3 lines
Move the
ima_dump_measurement_list()call fromima_add_kexec_buffer()toima_update_kexec_buffer()to copy the IMA log at the kexec 'execute' stage.This information was already stated in the first paragraph as part of the motivation for the patch. Please remove.
Quoted 3 lines
When there is insufficient memory to copy all the measurement logs, copy as much of the measurement list as possible.
Quoted 8 lines
Is this comment still applicable to this patch?
Please review your patch descriptions before posting, making sure that everything is still applicable.
thanks,
Mimi
Hi Mimi,
Thanks for your comments. I will update in next version.
Steven
Quoted 7 lines
Quoted 7 lines
Signed-off-by Tushar Sugandhi <[email protected]>Cc Eric Biederman <[email protected]>Cc Baoquan He <[email protected]>Cc Vivek Goyal <[email protected]>Cc Dave Young <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>
PATCH v11 7/9 ima: verify if the segment size has changed
In reply to steven chenkexec 'load' may be called multiple times. Free and realloc the buffer only if the segment_size is changed from the previous kexec 'load' call.
--- security/integrity/ima/ima_kexec.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
security/integrity/ima/ima_kexec.c +10 -0
@@ -33,6 +33,14 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)static int ima_alloc_kexec_file_buf (size_t segment_size) { +/* +* kexec 'load' may be called multiple times. +* Free and realloc the buffer only if the segment_size is +* changed from the previous kexec 'load' call. +*/ +if (ima_kexec_file.buf && ima_kexec_file.size == segment_size) + goto out; +ima_free_kexec_file_buf (&ima_kexec_file);/* segment size can't change between kexec load and execute */
@@ -41,6 +49,8 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)return -ENOMEM ; ima_kexec_file.size = segment_size; + +out: ima_kexec_file.read_pos =0 ; ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */
Signature · 1 line
2.25.1
Re: [PATCH v11 7/9] ima: verify if the segment size has changed
Quoted 2 lines · steven chen
kexec 'load' may be called multiple times. Free and realloc the buffer only if the
segment_sizeis changed from the previous kexec 'load' call.
This is a great example demonstrating how patch is nicely split. A reasonable unit including reasonable code change and log.
Quoted 37 lines
Signed-off-by steven chen <[email protected]>--- security/integrity/ima/ima_kexec.c | 10 ++++++++++ 1 file changed, 10 insertions(+)security/integrity/ima/ima_kexec.c +10
-0@@ -33,6 +33,14 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)static int ima_alloc_kexec_file_buf (size_t segment_size) { +/* +* kexec 'load' may be called multiple times. +* Free and realloc the buffer only if the segment_size is +* changed from the previous kexec 'load' call. +*/ +if (ima_kexec_file.buf && ima_kexec_file.size == segment_size) + goto out; +ima_free_kexec_file_buf (&ima_kexec_file);/* segment size can't change between kexec load and execute */ @@ -41,6 +49,8 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)return -ENOMEM ; ima_kexec_file.size = segment_size; + +out: ima_kexec_file.read_pos =0 ; ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ Signature · 1 line
2.25.1
Re: [PATCH v11 7/9] ima: verify if the segment size has changed
In reply to steven chenQuoted 4 lines · steven chen
kexec 'load' may be called multiple times. Free and realloc the buffer only if the
segment_sizeis changed from the previous kexec 'load' call.Signed-off-by steven chen <[email protected]>
Thanks, Steven.
PATCH v11 8/9 ima: make the kexec extra memory configurable
In reply to steven chenThe extra memory allocated for carrying the IMA measurement list across kexec is hard-coded 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 for the additional measurements.
Update ima_add_kexec_buffer() function to allocate memory based on the Kconfig option value, rather than the currently hard-coded one.
--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)
security/integrity/ima/Kconfig +10 -0
@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records. +config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on 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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif
security/integrity/ima/ima_kexec.c +11 -5
@@ -118,6 +118,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_memory;/* use more understandable variable names than defined in kbuf */ size_t kexec_buffer_size =0 ;
@@ -125,15 +126,20 @@ 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_memory =PAGE_SIZE /2 ; +else + extra_memory =CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB *1024 ; + + binary_runtime_size =ima_get_binary_runtime_size () + extra_memory; +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" );
Signature · 1 line
2.25.1
Re: [PATCH v11 8/9] ima: make the kexec extra memory configurable
Quoted 27 lines · steven chen
The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable.
Define a
Kconfigoption,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 for the additional measurements.Update
ima_add_kexec_buffer()function to allocate memory based on theKconfigoption value, rather than the currently hard-coded one.Suggested-by Stefan Berger <[email protected]>Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)security/integrity/ima/Kconfig +0
-0
security/integrity/ima/Kconfig config IMA_DISABLE_HTABLE · line 327
Quoted 7 lines
security/integrity/ima/Kconfig +4
-0@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records. +config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0
Usually a new Kconfig item which accepts a range should define the range boundary, otherwise it's not clear to people how large or how small it can be set. For example, can I set it as value of 1<<40? We should at least estimate a possible upper limit for it for other people's reference. My personal opinion.
The rest looks good to me.
Quoted 7 lines
security/integrity/ima/Kconfig +6
-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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif
...snip...
Re: [PATCH v11 8/9] ima: make the kexec extra memory configurable
Quoted 31 lines · Baoquan He
Quoted 30 lines · steven chen
The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable.
Define a
Kconfigoption,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 for the additional measurements.Update
ima_add_kexec_buffer()function to allocate memory based on theKconfigoption value, rather than the currently hard-coded one.Suggested-by Stefan Berger <[email protected]>Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)security/integrity/ima/Kconfig +0
-0@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records.
Quoted 9 lines
security/integrity/ima/Kconfig config IMA_DISABLE_HTABLE · line 327
Quoted 4 lines
security/integrity/ima/Kconfig +4
-0+config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0Usually a new
Kconfigitem which accepts a range should define the range boundary, otherwise it's not clear to people how large or how small it can be set. For example, can I set it as value of 1<<40? We should at least estimate a possible upper limit for it for other people's reference. My personal opinion.
Hi Baoquan,
How about I set range 2-40? Default set as 2, same as the fixed setting.
Thanks,
Steven
Quoted 11 lines
The rest looks good to me.
Quoted 7 lines
security/integrity/ima/Kconfig +6
-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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif...snip...
Mimi Zohar
maintainerRe: [PATCH v11 8/9] ima: make the kexec extra memory configurable
Quoted 42 lines · steven chen
Quoted 31 lines · Baoquan He
Quoted 30 lines · steven chen
The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable.
Define a
Kconfigoption,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 for the additional measurements.Update
ima_add_kexec_buffer()function to allocate memory based on theKconfigoption value, rather than the currently hard-coded one.Suggested-by Stefan Berger <[email protected]>Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)security/integrity/ima/Kconfig +0
-0@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records.Quoted 9 lines
security/integrity/ima/Kconfig config IMA_DISABLE_HTABLE · line 327
Quoted 4 lines
security/integrity/ima/Kconfig +4
-0+config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0Usually a new
Kconfigitem which accepts a range should define the range boundary, otherwise it's not clear to people how large or how small it can be set. For example, can I set it as value of 1<<40? We should at least estimate a possible upper limit for it for other people's reference. My personal opinion.
Quoted 3 lines
Hi Baoquan,
How about I set range 2-40? Default set as 2, same as the fixed setting.
0, the current default, sets the "extra" memory to the existing "extra half a page of memory for the additional measurements". For backwards compatibility, please do not change this.
The requirement for a larger "extra" measurement is coming from Microsoft. If this isn't any longer a requirement, we could drop this patch. Lakshmi, do you have any thoughts on this?
thanks,
Mimi
Quoted 15 lines
Quoted 12 lines
The rest looks good to me.
Quoted 7 lines
security/integrity/ima/Kconfig +6
-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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif...snip...
Re: [PATCH v11 8/9] ima: make the kexec extra memory configurable
Quoted 49 lines · Mimi Zohar
Quoted 41 lines · steven chen
Quoted 31 lines · Baoquan He
Quoted 30 lines · steven chen
The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable.
Define a
Kconfigoption,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 for the additional measurements.Update
ima_add_kexec_buffer()function to allocate memory based on theKconfigoption value, rather than the currently hard-coded one.Suggested-by Stefan Berger <[email protected]>Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)security/integrity/ima/Kconfig +0
-0@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records.Quoted 9 lines
security/integrity/ima/Kconfig config IMA_DISABLE_HTABLE · line 327
Quoted 4 lines
security/integrity/ima/Kconfig +4
-0+config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0Usually a new
Kconfigitem which accepts a range should define the range boundary, otherwise it's not clear to people how large or how small it can be set. For example, can I set it as value of 1<<40? We should at least estimate a possible upper limit for it for other people's reference. My personal opinion.Quoted 3 lines
Hi Baoquan,
How about I set range 2-40? Default set as 2, same as the fixed setting.
0, the current default, sets the "extra" memory to the existing "extra half a page of memory for the additional measurements". For backwards compatibility, please do not change this.
Quoted 7 lines
The requirement for a larger "extra" measurement is coming from Microsoft. If this isn't any longer a requirement, we could drop this patch. Lakshmi, do you have any thoughts on this?
thanks,
Mimi
How about the range set as 0-40 and the default as 0?
We (Microsoft) are ok with 0 as the default.
Thanks
Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
The rest looks good to me.
Quoted 7 lines
security/integrity/ima/Kconfig +6
-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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif...snip...
Mimi Zohar
maintainerRe: [PATCH v11 8/9] ima: make the kexec extra memory configurable
Quoted 50 lines · steven chen
Quoted 49 lines · Mimi Zohar
Quoted 41 lines · steven chen
Quoted 31 lines · Baoquan He
Quoted 30 lines · steven chen
The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable.
Define a
Kconfigoption,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 for the additional measurements.Update
ima_add_kexec_buffer()function to allocate memory based on theKconfigoption value, rather than the currently hard-coded one.Suggested-by Stefan Berger <[email protected]>Signed-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>Reviewed-by Mimi Zohar <[email protected]>--- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)security/integrity/ima/Kconfig +0
-0@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records.Quoted 9 lines
security/integrity/ima/Kconfig config IMA_DISABLE_HTABLE · line 327
Quoted 4 lines
security/integrity/ima/Kconfig +4
-0+config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0Usually a new
Kconfigitem which accepts a range should define the range boundary, otherwise it's not clear to people how large or how small it can be set. For example, can I set it as value of 1<<40? We should at least estimate a possible upper limit for it for other people's reference. My personal opinion.Quoted 3 lines
Hi Baoquan,
How about I set range 2-40? Default set as 2, same as the fixed setting.
0, the current default, sets the "extra" memory to the existing "extra half a page of memory for the additional measurements". For backwards compatibility, please do not change this.
Quoted 7 lines
Quoted 3 lines
The requirement for a larger "extra" measurement is coming from Microsoft. If this isn't any longer a requirement, we could drop this patch. Lakshmi, do you have any thoughts on this?
How about the range set as 0-40 and the default as 0?
We (Microsoft) are ok with 0 as the default.
Thanks, fine.
Quoted 18 lines
Thanks
Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
The rest looks good to me.
Quoted 7 lines
security/integrity/ima/Kconfig +6
-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 of 0, an extra half page of memory for those + additional measurements will be allocated. + endif...snip...
PATCH v11 9/9 ima: measure kexec load and exec events as critical data
In reply to steven chenThe amount of memory allocated at kexec load, even with the extra memory allocated, might not be large enough for the entire measurement list. The indeterminate interval between kexec 'load' and 'execute' could exacerbate this problem.
Define two new IMA events, 'kexec_load' and 'kexec_execute', to be measured as critical data at kexec 'load' and 'execute' respectively. Report the allocated kexec segment size, IMA binary log size and the runtime measurements count as part of those events.
These events, and the values reported through them, serve as markers in the IMA log to verify the IMA events are captured during kexec soft reboot. The presence of a 'kexec_load' event in between the last two 'boot_aggregate' events in the IMA log implies this is a kexec soft reboot, and not a cold-boot. And the absence of 'kexec_execute' event after kexec soft reboot implies missing events in that window which results in inconsistency with TPM PCR quotes, necessitating a cold boot for a successful remote attestation.
These critical data events are displayed as hex encoded ascii in the ascii_runtime_measurement_list. Verifying the critical data hash requires calculating the hash of the decoded ascii string.
For example, to verify the 'kexec_load' data hash:
sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_load | cut -d' ' -f 6 | xxd -r -p | sha256sum
To verify the 'kexec_execute' data hash:
sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_execute | cut -d' ' -f 6 | xxd -r -p | sha256sum
--- security/integrity/ima/ima.h | 6 ++++++ security/integrity/ima/ima_kexec.c | 21 +++++++++++++++++++++ security/integrity/ima/ima_queue.c | 5 +++++ 3 files changed, 32 insertions(+)
security/integrity/ima/ima.h +6 -0
@@ -240,6 +240,12 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key, unsigned long flags, bool create);#endif +#ifdef CONFIG_IMA_KEXEC +void ima_measure_kexec_event (const char *event_name); +#else +static inline void ima_measure_kexec_event (const char *event_name) {} +#endif +/* * The default binary_runtime_measurements list format is defined as the * platform native format. The canonical format is defined as little-endian.
security/integrity/ima/ima_kexec.c +21 -0
@@ -17,6 +17,8 @@#include "ima.h" #ifdef CONFIG_IMA_KEXEC +#define IMA_KEXEC_EVENT_LEN 256 +static bool ima_kexec_update_registered;static struct seq_file ima_kexec_file;static size_t kexec_segment_size;
@@ -31,6 +33,24 @@ static void ima_free_kexec_file_buf(struct seq_file *sf) sf->count =0 ; } +void ima_measure_kexec_event (const char *event_name) +{ +char ima_kexec_event[IMA_KEXEC_EVENT_LEN ]; +size_t buf_size =0 ; +long len; +int n; + + buf_size =ima_get_binary_runtime_size (); + len =atomic_long_read (&ima_htable.len); + + n =scnprintf (ima_kexec_event,IMA_KEXEC_EVENT_LEN , +"kexec_segment_size=%lu;ima_binary_runtime_size=%lu;" +"ima_runtime_measurements_count=%ld;" , + kexec_segment_size, buf_size, len); + +ima_measure_critical_data ("ima_kexec" , event_name, ima_kexec_event, n, false,NULL ,0 ); +} +static int ima_alloc_kexec_file_buf (size_t segment_size) {/*
@@ -53,6 +73,7 @@ static int ima_alloc_kexec_file_buf(size_t segment_size) out: ima_kexec_file.read_pos =0 ; ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */ +ima_measure_kexec_event ("kexec_load" );return 0 ; }
security/integrity/ima/ima_queue.c +5 -0
@@ -241,6 +241,11 @@ static int ima_reboot_notifier(struct notifier_block *nb, unsigned long action, void *data) { +#ifdef CONFIG_IMA_KEXEC + if (action == SYS_RESTART && data && !strcmp(data, "kexec reboot")) + ima_measure_kexec_event("kexec_execute"); +#endif + ima_measurements_suspend(); return NOTIFY_DONE;
Signature · 1 line
2.25.1
Re: [PATCH v11 9/9] ima: measure kexec load and exec events as critical data
Quoted 29 lines · steven chen
The amount of memory allocated at kexec load, even with the extra memory allocated, might not be large enough for the entire measurement list. The indeterminate interval between kexec 'load' and 'execute' could exacerbate this problem.
Define two new IMA events, '
kexec_load' and 'kexec_execute', to be measured as critical data at kexec 'load' and 'execute' respectively. Report the allocated kexec segment size, IMA binary log size and the runtime measurements count as part of those events.These events, and the values reported through them, serve as markers in the IMA log to verify the IMA events are captured during kexec soft reboot. The presence of a '
kexec_load' event in between the last two 'boot_aggregate' events in the IMA log implies this is a kexec soft reboot, and not a cold-boot. And the absence of 'kexec_execute' event after kexec soft reboot implies missing events in that window which results in inconsistency with TPM PCR quotes, necessitating a cold boot for a successful remote attestation.These critical data events are displayed as hex encoded ascii in the
ascii_runtime_measurement_list. Verifying the critical data hash requires calculating the hash of the decoded ascii string.For example, to verify the '
kexec_load' data hash:sudo cat
/sys/kernel/security/integrity/ima/ascii_runtime_measurementsQuoted 1 line
grep
kexec_load| cut -d' ' -f 6 | xxd -r -p | sha256sum
Quoted 8 lines
To verify the '
kexec_execute' data hash:sudo cat
/sys/kernel/security/integrity/ima/ascii_runtime_measurementsQuoted 1 line
grep
kexec_execute| cut -d' ' -f 6 | xxd -r -p | sha256sumSigned-off-by Tushar Sugandhi <[email protected]>Signed-off-by steven chen <[email protected]>Reviewed-by Stefan Berger <[email protected]>
Thanks, Steven.