linux/security/integrity/ima/ima_queue.c

577 lines
15 KiB

ima: Suspend PCR extends and log appends when rebooting To avoid the following types of error messages due to a failure by the TPM driver to use the TPM, suspend TPM PCR extensions and the appending of entries to the IMA log once IMA's reboot notifier has been called. This avoids trying to use the TPM after the TPM subsystem has been shut down. [111707.685315][ T1] ima: Error Communicating to TPM chip, result: -19 [111707.685960][ T1] ima: Error Communicating to TPM chip, result: -19 Synchronization with the ima_extend_list_mutex to set ima_measurements_suspended ensures that the TPM subsystem is not shut down when IMA holds the mutex while appending to the log and extending the PCR. The alternative of reading the system_state variable would not provide this guarantee. This error could be observed on a ppc64 machine running SuSE Linux where processes are still accessing files after devices have been shut down. Suspending the IMA log and PCR extensions shortly before reboot does not seem to open a significant measurement gap since neither TPM quoting would work for attestation nor that new log entries could be written to anywhere after devices have been shut down. However, there's a time window between the invocation of the reboot notifier and the shutdown of devices. This includes all subsequently invoked reboot notifiers as well as kernel_restart_prepare() where __usermodehelper_disable() waits for all running_helpers to exit. During this time window IMA could now miss log entries even though attestation would still work. The reboot of the system shortly after may make this small gap insignificant. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2024-11-18 09:57:31 -05:00
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 17:04:11 +09:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Suspend PCR extends and log appends when rebooting To avoid the following types of error messages due to a failure by the TPM driver to use the TPM, suspend TPM PCR extensions and the appending of entries to the IMA log once IMA's reboot notifier has been called. This avoids trying to use the TPM after the TPM subsystem has been shut down. [111707.685315][ T1] ima: Error Communicating to TPM chip, result: -19 [111707.685960][ T1] ima: Error Communicating to TPM chip, result: -19 Synchronization with the ima_extend_list_mutex to set ima_measurements_suspended ensures that the TPM subsystem is not shut down when IMA holds the mutex while appending to the log and extending the PCR. The alternative of reading the system_state variable would not provide this guarantee. This error could be observed on a ppc64 machine running SuSE Linux where processes are still accessing files after devices have been shut down. Suspending the IMA log and PCR extensions shortly before reboot does not seem to open a significant measurement gap since neither TPM quoting would work for attestation nor that new log entries could be written to anywhere after devices have been shut down. However, there's a time window between the invocation of the reboot notifier and the shutdown of devices. This includes all subsequently invoked reboot notifiers as well as kernel_restart_prepare() where __usermodehelper_disable() waits for all running_helpers to exit. During this time window IMA could now miss log entries even though attestation would still work. The reboot of the system shortly after may make this small gap insignificant. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2024-11-18 09:57:31 -05:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Replace static htable queue with dynamically allocated array The IMA hash table is a fixed-size array of hlist_head buckets: struct hlist_head ima_htable[IMA_MEASURE_HTABLE_SIZE]; IMA_MEASURE_HTABLE_SIZE is (1 << IMA_HASH_BITS) = 1024 buckets, each a struct hlist_head (one pointer, 8 bytes on 64-bit). That is 8 KiB allocated in BSS for every kernel, regardless of whether IMA is ever used, and regardless of how many measurements are actually made. Replace the fixed-size array with a RCU-protected pointer to a dynamically allocated array that is initialized in ima_init_htable(), which is called from ima_init() during early boot. ima_init_htable() calls the static function ima_alloc_replace_htable() which, other than initializing the hash table the first time, can also hot-swap the existing hash table with a blank one. The allocation in ima_alloc_replace_htable() uses kcalloc() so the buckets are zero-initialised (equivalent to HLIST_HEAD_INIT { .first = NULL }). Callers of ima_alloc_replace_htable() must call synchronize_rcu() and free the returned hash table. Finally, access the hash table with rcu_dereference() in ima_lookup_digest_entry() (reader side) and with rcu_dereference_protected() in ima_add_digest_entry() (writer side). No functional change: bucket count, hash function, and all locking remain identical. Link: https://github.com/linux-integrity/linux/issues/1 Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:26 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Suspend PCR extends and log appends when rebooting To avoid the following types of error messages due to a failure by the TPM driver to use the TPM, suspend TPM PCR extensions and the appending of entries to the IMA log once IMA's reboot notifier has been called. This avoids trying to use the TPM after the TPM subsystem has been shut down. [111707.685315][ T1] ima: Error Communicating to TPM chip, result: -19 [111707.685960][ T1] ima: Error Communicating to TPM chip, result: -19 Synchronization with the ima_extend_list_mutex to set ima_measurements_suspended ensures that the TPM subsystem is not shut down when IMA holds the mutex while appending to the log and extending the PCR. The alternative of reading the system_state variable would not provide this guarantee. This error could be observed on a ppc64 machine running SuSE Linux where processes are still accessing files after devices have been shut down. Suspending the IMA log and PCR extensions shortly before reboot does not seem to open a significant measurement gap since neither TPM quoting would work for attestation nor that new log entries could be written to anywhere after devices have been shut down. However, there's a time window between the invocation of the reboot notifier and the shutdown of devices. This includes all subsequently invoked reboot notifiers as well as kernel_restart_prepare() where __usermodehelper_disable() waits for all running_helpers to exit. During this time window IMA could now miss log entries even though attestation would still work. The reboot of the system shortly after may make this small gap insignificant. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2024-11-18 09:57:31 -05:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Add support for staging measurements with prompt Introduce the ability of staging the IMA measurement list and deleting them with a prompt. Staging means moving the current measurement list records to a separate location, and allowing users to read and delete it. This causes the current measurement list to be emptied (since records were moved) and new measurements to be added on the empty list. Staging can be done only once at a time. In the event of kexec(), staging is aborted and staged records will be carried over to the new kernel. Introduce ascii_runtime_measurements_<algo>_staged and binary_runtime_measurements_<algo>_staged interfaces to access and delete the measurements. Use 'echo A > <IMA _staged interface>' and 'echo D > <IMA _staged interface>' to respectively stage and delete the entire measurements list. Locking of these interfaces is also mediated with a call to _ima_measurements_open() and with ima_measurements_release(). Implement the staging functionality by introducing the new global measurements list ima_measurements_staged, and ima_queue_stage() and ima_queue_staged_delete_all() to respectively move measurements from the current measurements list to the staged one, and to move staged measurements to the ima_measurements_trim list for deletion. Introduce ima_queue_delete() to delete the measurements. Staging is forbidden after measurement is suspended, and between staging and deleting, so that walking the staged and current measurements list can be done locklessly in ima_dump_measurement_list(). Strict ordering of suspending and dumping is enforced by two reboot notifiers with different priority. Refusing to delete staged measurements also signals to user space that those measurements are already carried over to the secondary kernel, so that it does not save them twice. Finally, introduce the BINARY_STAGED and BINARY_FULL binary measurements list types, to maintain the counters and the binary size of staged measurements and the full measurements list (including records that were staged). BINARY still represents the current binary measurements list. Use the binary size for the BINARY + BINARY_STAGED types in ima_add_kexec_buffer(), since both measurements list types are copied to the secondary kernel during kexec. Use BINARY_FULL in ima_measure_kexec_event(), to generate a critical data record. It should be noted that the BINARY_FULL counter is not passed through kexec. Thus, the number of records included in the kexec critical data records refers to the records since the critical data records generated from the previous kexec event. Note: This code derives from the Alt-IMA Huawei project, whose license is GPL-2.0 OR MIT. Link: https://github.com/linux-integrity/linux/issues/1 Suggested-by: Gregory Lumen <gregorylumen@linux.microsoft.com> (staging revert) Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-06-05 19:22:33 +02:00
ima: Suspend PCR extends and log appends when rebooting To avoid the following types of error messages due to a failure by the TPM driver to use the TPM, suspend TPM PCR extensions and the appending of entries to the IMA log once IMA's reboot notifier has been called. This avoids trying to use the TPM after the TPM subsystem has been shut down. [111707.685315][ T1] ima: Error Communicating to TPM chip, result: -19 [111707.685960][ T1] ima: Error Communicating to TPM chip, result: -19 Synchronization with the ima_extend_list_mutex to set ima_measurements_suspended ensures that the TPM subsystem is not shut down when IMA holds the mutex while appending to the log and extending the PCR. The alternative of reading the system_state variable would not provide this guarantee. This error could be observed on a ppc64 machine running SuSE Linux where processes are still accessing files after devices have been shut down. Suspending the IMA log and PCR extensions shortly before reboot does not seem to open a significant measurement gap since neither TPM quoting would work for attestation nor that new log entries could be written to anywhere after devices have been shut down. However, there's a time window between the invocation of the reboot notifier and the shutdown of devices. This includes all subsequently invoked reboot notifiers as well as kernel_restart_prepare() where __usermodehelper_disable() waits for all running_helpers to exit. During this time window IMA could now miss log entries even though attestation would still work. The reboot of the system shortly after may make this small gap insignificant. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2024-11-18 09:57:31 -05:00
ima: measure kexec load and exec events as critical data 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_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 Co-developed-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Steven Chen <chenste@linux.microsoft.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Acked-by: Baoquan He <bhe@redhat.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com> # ppc64/kvm Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2025-04-21 15:25:15 -07:00
ima: Suspend PCR extends and log appends when rebooting To avoid the following types of error messages due to a failure by the TPM driver to use the TPM, suspend TPM PCR extensions and the appending of entries to the IMA log once IMA's reboot notifier has been called. This avoids trying to use the TPM after the TPM subsystem has been shut down. [111707.685315][ T1] ima: Error Communicating to TPM chip, result: -19 [111707.685960][ T1] ima: Error Communicating to TPM chip, result: -19 Synchronization with the ima_extend_list_mutex to set ima_measurements_suspended ensures that the TPM subsystem is not shut down when IMA holds the mutex while appending to the log and extending the PCR. The alternative of reading the system_state variable would not provide this guarantee. This error could be observed on a ppc64 machine running SuSE Linux where processes are still accessing files after devices have been shut down. Suspending the IMA log and PCR extensions shortly before reboot does not seem to open a significant measurement gap since neither TPM quoting would work for attestation nor that new log entries could be written to anywhere after devices have been shut down. However, there's a time window between the invocation of the reboot notifier and the shutdown of devices. This includes all subsequently invoked reboot notifiers as well as kernel_restart_prepare() where __usermodehelper_disable() waits for all running_helpers to exit. During this time window IMA could now miss log entries even though attestation would still work. The reboot of the system shortly after may make this small gap insignificant. Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2024-11-18 09:57:31 -05:00