* [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal
@ 2024-11-04 10:47 Breno Leitao
2024-11-19 18:10 ` Mimi Zohar
0 siblings, 1 reply; 4+ messages in thread
From: Breno Leitao @ 2024-11-04 10:47 UTC (permalink / raw)
To: Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, Eric W. Biederman,
Andrew Morton, Thiago Jung Bauermann
Cc: Mimi Zohar, linux-integrity, linux-security-module, linux-kernel,
noodles, Breno Leitao
Fix a potential RCU issue where ima_measurements list is traversed using
list_for_each_entry_rcu() without proper RCU read lock protection. This
caused warnings when CONFIG_PROVE_RCU was enabled:
security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
Add rcu_read_lock() before iterating over ima_measurements list to ensure
proper RCU synchronization, consistent with other RCU list traversals in
the codebase.
Signed-off-by: Breno Leitao <leitao@debian.org>
Fixes: 7b8589cc29e7 ("ima: on soft reboot, save the measurement list")
---
security/integrity/ima/ima_kexec.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 52e00332defed39774c9e23e045f1377cfa30d0c..3b17ddb91d35ac806aedd2ee970ff365675dac0b 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -37,6 +37,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
memset(&khdr, 0, sizeof(khdr));
khdr.version = 1;
+ rcu_read_lock();
list_for_each_entry_rcu(qe, &ima_measurements, later) {
if (file.count < file.size) {
khdr.count++;
@@ -46,6 +47,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
break;
}
}
+ rcu_read_unlock();
if (ret < 0)
goto out;
---
base-commit: f488649e40f8900d23b86afeab7d4b78c063d5d1
change-id: 20241104-ima_rcu-ee83da87d050
Best regards,
--
Breno Leitao <leitao@debian.org>
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal
2024-11-04 10:47 [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal Breno Leitao
@ 2024-11-19 18:10 ` Mimi Zohar
2024-11-20 19:44 ` Breno Leitao
0 siblings, 1 reply; 4+ messages in thread
From: Mimi Zohar @ 2024-11-19 18:10 UTC (permalink / raw)
To: Breno Leitao, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, Eric W. Biederman,
Andrew Morton, Thiago Jung Bauermann
Cc: Mimi Zohar, linux-integrity, linux-security-module, linux-kernel,
noodles
Hi Breno,
On Mon, 2024-11-04 at 02:47 -0800, Breno Leitao wrote:
> Fix a potential RCU issue where ima_measurements list is traversed using
> list_for_each_entry_rcu() without proper RCU read lock protection. This
> caused warnings when CONFIG_PROVE_RCU was enabled:
>
> security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
>
> Add rcu_read_lock() before iterating over ima_measurements list to ensure
> proper RCU synchronization, consistent with other RCU list traversals in
> the codebase.
The synchronization is to prevent freeing of data while walking the RCU list. In
this case, new measurements are only appended to the IMA measurement list. So
there shouldn't be an issue.
The IMA measurement list is being copied during kexec "load", while other
processes are still running. Depending on the IMA policy, the kexec "load",
itself, and these other processes may result in additional measurements, which
should be copied across kexec. Adding the rcu_read_{lock, unlock} would
unnecessarily prevent them from being copied.
There have been discussions about deferring copying the IMA measurement list
from kexec "load" to later at "exec" and about trimming the IMA measurement
list. At least for now, neither of these changes have been upstreamed.
Perhaps add a comment as a reminder as to why it is currently safe.
Mimi
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Fixes: 7b8589cc29e7 ("ima: on soft reboot, save the measurement list")
> ---
> security/integrity/ima/ima_kexec.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 52e00332defed39774c9e23e045f1377cfa30d0c..3b17ddb91d35ac806aedd2ee970ff365675dac0b 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -37,6 +37,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
>
> memset(&khdr, 0, sizeof(khdr));
> khdr.version = 1;
> + rcu_read_lock();
> list_for_each_entry_rcu(qe, &ima_measurements, later) {
> if (file.count < file.size) {
> khdr.count++;
> @@ -46,6 +47,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
> break;
> }
> }
> + rcu_read_unlock();
>
> if (ret < 0)
> goto out;
>
> ---
> base-commit: f488649e40f8900d23b86afeab7d4b78c063d5d1
> change-id: 20241104-ima_rcu-ee83da87d050
>
> Best regards,
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal
2024-11-19 18:10 ` Mimi Zohar
@ 2024-11-20 19:44 ` Breno Leitao
2024-11-20 20:38 ` Mimi Zohar
0 siblings, 1 reply; 4+ messages in thread
From: Breno Leitao @ 2024-11-20 19:44 UTC (permalink / raw)
To: Mimi Zohar
Cc: Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Eric W. Biederman, Andrew Morton,
Thiago Jung Bauermann, Mimi Zohar, linux-integrity,
linux-security-module, linux-kernel, noodles
Hello Mimi,
On Tue, Nov 19, 2024 at 01:10:10PM -0500, Mimi Zohar wrote:
> Hi Breno,
>
> On Mon, 2024-11-04 at 02:47 -0800, Breno Leitao wrote:
> > Fix a potential RCU issue where ima_measurements list is traversed using
> > list_for_each_entry_rcu() without proper RCU read lock protection. This
> > caused warnings when CONFIG_PROVE_RCU was enabled:
> >
> > security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
> >
> > Add rcu_read_lock() before iterating over ima_measurements list to ensure
> > proper RCU synchronization, consistent with other RCU list traversals in
> > the codebase.
>
> The synchronization is to prevent freeing of data while walking the RCU list. In
> this case, new measurements are only appended to the IMA measurement list. So
> there shouldn't be an issue.
>
> The IMA measurement list is being copied during kexec "load", while other
> processes are still running. Depending on the IMA policy, the kexec "load",
> itself, and these other processes may result in additional measurements, which
> should be copied across kexec. Adding the rcu_read_{lock, unlock} would
> unnecessarily prevent them from being copied.
Thank you for the detailed explanation. Since rcu_read_lock() operations are
lightweight, I believe keeping them wouldn't impact performance significantly.
However, if you prefer the lockless approach, I would suggest adding an
argument to list_for_each_entry_rcu() to keep the warning out. What are
your thoughts on this?
Author: Breno Leitao <leitao@debian.org>
Date: Mon Nov 4 02:26:45 2024 -0800
ima: kexec: silence RCU list traversal warning
The ima_measurements list is append-only and doesn't require rcu_read_lock()
protection. However, lockdep issues a warning when traversing RCU lists
without the read lock:
security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
Fix this by using the lockless variant of list_for_each_entry_rcu() with
the last argument set to true. This tells the RCU subsystem that
traversing this append-only list without the read lock is intentional
and safe.
This change silences the lockdep warning while maintaining the correct
semantics for the append-only list traversal.
Signed-off-by: Breno Leitao <leitao@debian.org>
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 52e00332defed..9d45f4d26f731 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -37,7 +37,8 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
memset(&khdr, 0, sizeof(khdr));
khdr.version = 1;
- list_for_each_entry_rcu(qe, &ima_measurements, later) {
+ /* 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) {
khdr.count++;
ima_measurements_show(&file, qe);
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal
2024-11-20 19:44 ` Breno Leitao
@ 2024-11-20 20:38 ` Mimi Zohar
0 siblings, 0 replies; 4+ messages in thread
From: Mimi Zohar @ 2024-11-20 20:38 UTC (permalink / raw)
To: Breno Leitao
Cc: Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Eric W. Biederman, Andrew Morton,
Thiago Jung Bauermann, Mimi Zohar, linux-integrity,
linux-security-module, linux-kernel, noodles
On Wed, 2024-11-20 at 19:44 +0000, Breno Leitao wrote:
> Hello Mimi,
>
> On Tue, Nov 19, 2024 at 01:10:10PM -0500, Mimi Zohar wrote:
> > Hi Breno,
> >
> > On Mon, 2024-11-04 at 02:47 -0800, Breno Leitao wrote:
> > > Fix a potential RCU issue where ima_measurements list is traversed using
> > > list_for_each_entry_rcu() without proper RCU read lock protection. This
> > > caused warnings when CONFIG_PROVE_RCU was enabled:
> > >
> > > security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
> > >
> > > Add rcu_read_lock() before iterating over ima_measurements list to ensure
> > > proper RCU synchronization, consistent with other RCU list traversals in
> > > the codebase.
> >
> > The synchronization is to prevent freeing of data while walking the RCU list. In
> > this case, new measurements are only appended to the IMA measurement list. So
> > there shouldn't be an issue.
> >
> > The IMA measurement list is being copied during kexec "load", while other
> > processes are still running. Depending on the IMA policy, the kexec "load",
> > itself, and these other processes may result in additional measurements, which
> > should be copied across kexec. Adding the rcu_read_{lock, unlock} would
> > unnecessarily prevent them from being copied.
>
> Thank you for the detailed explanation. Since rcu_read_lock() operations are
> lightweight, I believe keeping them wouldn't impact performance significantly.
It's not a question of performance, but of missing measurements in the IMA
measurement list.
>
> However, if you prefer the lockless approach, I would suggest adding an
> argument to list_for_each_entry_rcu() to keep the warning out. What are
> your thoughts on this?
Yes, this is better.
thanks,
Mimi
>
> Author: Breno Leitao <leitao@debian.org>
> Date: Mon Nov 4 02:26:45 2024 -0800
>
> ima: kexec: silence RCU list traversal warning
>
> The ima_measurements list is append-only and doesn't require rcu_read_lock()
> protection. However, lockdep issues a warning when traversing RCU lists
> without the read lock:
>
> security/integrity/ima/ima_kexec.c:40 RCU-list traversed in non-reader section!!
>
> Fix this by using the lockless variant of list_for_each_entry_rcu() with
> the last argument set to true. This tells the RCU subsystem that
> traversing this append-only list without the read lock is intentional
> and safe.
>
> This change silences the lockdep warning while maintaining the correct
> semantics for the append-only list traversal.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
>
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 52e00332defed..9d45f4d26f731 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -37,7 +37,8 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
>
> memset(&khdr, 0, sizeof(khdr));
> khdr.version = 1;
> - list_for_each_entry_rcu(qe, &ima_measurements, later) {
> + /* 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) {
> khdr.count++;
> ima_measurements_show(&file, qe);
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-11-20 20:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-04 10:47 [PATCH] ima: kexec: Add RCU read lock protection for ima_measurements list traversal Breno Leitao
2024-11-19 18:10 ` Mimi Zohar
2024-11-20 19:44 ` Breno Leitao
2024-11-20 20:38 ` Mimi Zohar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox