mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] locking/lockdep: Validate class index in lock_chain_get_class()
@ 2026-06-16 16:40 Naveen Kumar Chaudhary
  2026-06-17 17:26 ` Waiman Long
  0 siblings, 1 reply; 3+ messages in thread
From: Naveen Kumar Chaudhary @ 2026-06-16 16:40 UTC (permalink / raw)
  To: peterz, mingo, will, boqun, longman; +Cc: linux-kernel

lock_chain_get_class() extracts a class index from chain_hlocks[] and
uses it to index directly into lock_classes[] without any validation.
If the chain data references a class that has been zapped (e.g., after
module unload), the class_idx bit will be cleared in lock_classes_in_use
and the function returns a pointer to a stale entry.

Add a DEBUG_LOCKS_WARN_ON() check using test_bit() on lock_classes_in_use.
Return NULL on failure so callers can handle it gracefully.

Update the sole caller in lockdep_proc.c to handle the NULL return.

Signed-off-by: Naveen Kumar Chaudhary <naveen.osdev@gmail.com>
---
 kernel/locking/lockdep.c      | 3 +++
 kernel/locking/lockdep_proc.c | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 2d4c5bab5af8..ca255269b714 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -3561,6 +3561,9 @@ struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i)
 	u16 chain_hlock = chain_hlocks[chain->base + i];
 	unsigned int class_idx = chain_hlock_class_idx(chain_hlock);
 
+	if (DEBUG_LOCKS_WARN_ON(!test_bit(class_idx, lock_classes_in_use)))
+		return NULL;
+
 	return lock_classes + class_idx;
 }
 
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c
index 1916db9aa46b..2d1f6b43edd5 100644
--- a/kernel/locking/lockdep_proc.c
+++ b/kernel/locking/lockdep_proc.c
@@ -170,7 +170,7 @@ static int lc_show(struct seq_file *m, void *v)
 
 	for (i = 0; i < chain->depth; i++) {
 		class = lock_chain_get_class(chain, i);
-		if (!class->key)
+		if (!class || !class->key)
 			continue;
 
 		seq_printf(m, "[%p] ", class->key);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] locking/lockdep: Validate class index in lock_chain_get_class()
  2026-06-16 16:40 [PATCH] locking/lockdep: Validate class index in lock_chain_get_class() Naveen Kumar Chaudhary
@ 2026-06-17 17:26 ` Waiman Long
  2026-06-20  3:43   ` Naveen Kumar Chaudhary
  0 siblings, 1 reply; 3+ messages in thread
From: Waiman Long @ 2026-06-17 17:26 UTC (permalink / raw)
  To: Naveen Kumar Chaudhary, peterz, mingo, will, boqun; +Cc: linux-kernel

On 6/16/26 12:40 PM, Naveen Kumar Chaudhary wrote:
> lock_chain_get_class() extracts a class index from chain_hlocks[] and
> uses it to index directly into lock_classes[] without any validation.
> If the chain data references a class that has been zapped (e.g., after
> module unload), the class_idx bit will be cleared in lock_classes_in_use
> and the function returns a pointer to a stale entry.
>
> Add a DEBUG_LOCKS_WARN_ON() check using test_bit() on lock_classes_in_use.
> Return NULL on failure so callers can handle it gracefully.
>
> Update the sole caller in lockdep_proc.c to handle the NULL return.
>
> Signed-off-by: Naveen Kumar Chaudhary <naveen.osdev@gmail.com>
> ---
>   kernel/locking/lockdep.c      | 3 +++
>   kernel/locking/lockdep_proc.c | 2 +-
>   2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 2d4c5bab5af8..ca255269b714 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -3561,6 +3561,9 @@ struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i)
>   	u16 chain_hlock = chain_hlocks[chain->base + i];
>   	unsigned int class_idx = chain_hlock_class_idx(chain_hlock);
>   
> +	if (DEBUG_LOCKS_WARN_ON(!test_bit(class_idx, lock_classes_in_use)))
> +		return NULL;
> +
>   	return lock_classes + class_idx;
>   }
>   
> diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c
> index 1916db9aa46b..2d1f6b43edd5 100644
> --- a/kernel/locking/lockdep_proc.c
> +++ b/kernel/locking/lockdep_proc.c
> @@ -170,7 +170,7 @@ static int lc_show(struct seq_file *m, void *v)
>   
>   	for (i = 0; i < chain->depth; i++) {
>   		class = lock_chain_get_class(chain, i);
> -		if (!class->key)
> +		if (!class || !class->key)
>   			continue;
>   
>   		seq_printf(m, "[%p] ", class->key);

When a class is zapped, that particular class should have been removed 
from the lock chains. Have you hit any cases where this warning can be 
triggered? Or is this just for making sure that this condition won't be 
triggered silently if it ever happens?

Regards,
Longman


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] locking/lockdep: Validate class index in lock_chain_get_class()
  2026-06-17 17:26 ` Waiman Long
@ 2026-06-20  3:43   ` Naveen Kumar Chaudhary
  0 siblings, 0 replies; 3+ messages in thread
From: Naveen Kumar Chaudhary @ 2026-06-20  3:43 UTC (permalink / raw)
  To: Waiman Long; +Cc: peterz, mingo, will, boqun, linux-kernel

I did not hit any condition yet. This is just for hardening to make sure
that this condition won't be triggered silently if it ever happens.

Regards,
Naveen

On Wed 17 Jun 01:26 PM, Waiman Long wrote:
> On 6/16/26 12:40 PM, Naveen Kumar Chaudhary wrote:
> > lock_chain_get_class() extracts a class index from chain_hlocks[] and
> > uses it to index directly into lock_classes[] without any validation.
> > If the chain data references a class that has been zapped (e.g., after
> > module unload), the class_idx bit will be cleared in lock_classes_in_use
> > and the function returns a pointer to a stale entry.
> > 
> > Add a DEBUG_LOCKS_WARN_ON() check using test_bit() on lock_classes_in_use.
> > Return NULL on failure so callers can handle it gracefully.
> > 
> > Update the sole caller in lockdep_proc.c to handle the NULL return.
> > 
> > Signed-off-by: Naveen Kumar Chaudhary <naveen.osdev@gmail.com>
> > ---
> >   kernel/locking/lockdep.c      | 3 +++
> >   kernel/locking/lockdep_proc.c | 2 +-
> >   2 files changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> > index 2d4c5bab5af8..ca255269b714 100644
> > --- a/kernel/locking/lockdep.c
> > +++ b/kernel/locking/lockdep.c
> > @@ -3561,6 +3561,9 @@ struct lock_class *lock_chain_get_class(struct lock_chain *chain, int i)
> >   	u16 chain_hlock = chain_hlocks[chain->base + i];
> >   	unsigned int class_idx = chain_hlock_class_idx(chain_hlock);
> > +	if (DEBUG_LOCKS_WARN_ON(!test_bit(class_idx, lock_classes_in_use)))
> > +		return NULL;
> > +
> >   	return lock_classes + class_idx;
> >   }
> > diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c
> > index 1916db9aa46b..2d1f6b43edd5 100644
> > --- a/kernel/locking/lockdep_proc.c
> > +++ b/kernel/locking/lockdep_proc.c
> > @@ -170,7 +170,7 @@ static int lc_show(struct seq_file *m, void *v)
> >   	for (i = 0; i < chain->depth; i++) {
> >   		class = lock_chain_get_class(chain, i);
> > -		if (!class->key)
> > +		if (!class || !class->key)
> >   			continue;
> >   		seq_printf(m, "[%p] ", class->key);
> 
> When a class is zapped, that particular class should have been removed from
> the lock chains. Have you hit any cases where this warning can be triggered?
> Or is this just for making sure that this condition won't be triggered
> silently if it ever happens?
> 
> Regards,
> Longman
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-20  3:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-16 16:40 [PATCH] locking/lockdep: Validate class index in lock_chain_get_class() Naveen Kumar Chaudhary
2026-06-17 17:26 ` Waiman Long
2026-06-20  3:43   ` Naveen Kumar Chaudhary

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®