From: Carlos Llamas <cmllamas@google.com>
To: stable@vger.kernel.org
Cc: sashal@kernel.org, boqun.feng@gmail.com, bvanassche@acm.org,
cmllamas@google.com, gregkh@linuxfoundation.org,
longman@redhat.com, paulmck@kernel.org, xuewen.yan@unisoc.com,
zhiguo.niu@unisoc.com, kernel-team@android.com,
penguin-kernel@i-love.sakura.ne.jp, peterz@infradead.org
Subject: [PATCH 5.4.y 3/4] locking/lockdep: Avoid potential access of invalid memory in lock_class
Date: Sat, 12 Oct 2024 23:22:43 +0000 [thread overview]
Message-ID: <20241012232244.2768048-4-cmllamas@google.com> (raw)
In-Reply-To: <20241012232244.2768048-1-cmllamas@google.com>
From: Waiman Long <longman@redhat.com>
commit 61cc4534b6550997c97a03759ab46b29d44c0017 upstream.
It was found that reading /proc/lockdep after a lockdep splat may
potentially cause an access to freed memory if lockdep_unregister_key()
is called after the splat but before access to /proc/lockdep [1]. This
is due to the fact that graph_lock() call in lockdep_unregister_key()
fails after the clearing of debug_locks by the splat process.
After lockdep_unregister_key() is called, the lock_name may be freed
but the corresponding lock_class structure still have a reference to
it. That invalid memory pointer will then be accessed when /proc/lockdep
is read by a user and a use-after-free (UAF) error will be reported if
KASAN is enabled.
To fix this problem, lockdep_unregister_key() is now modified to always
search for a matching key irrespective of the debug_locks state and
zap the corresponding lock class if a matching one is found.
[1] https://lore.kernel.org/lkml/77f05c15-81b6-bddd-9650-80d5f23fe330@i-love.sakura.ne.jp/
Fixes: 8b39adbee805 ("locking/lockdep: Make lockdep_unregister_key() honor 'debug_locks' again")
Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lkml.kernel.org/r/20220103023558.1377055-1-longman@redhat.com
Signed-off-by: Carlos Llamas <cmllamas@google.com>
---
kernel/locking/lockdep.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index b9fabbab3918..8e0351970a1d 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -5302,7 +5302,13 @@ void lockdep_reset_lock(struct lockdep_map *lock)
lockdep_reset_lock_reg(lock);
}
-/* Unregister a dynamically allocated key. */
+/*
+ * Unregister a dynamically allocated key.
+ *
+ * Unlike lockdep_register_key(), a search is always done to find a matching
+ * key irrespective of debug_locks to avoid potential invalid access to freed
+ * memory in lock_class entry.
+ */
void lockdep_unregister_key(struct lock_class_key *key)
{
struct hlist_head *hash_head = keyhashentry(key);
@@ -5317,10 +5323,8 @@ void lockdep_unregister_key(struct lock_class_key *key)
return;
raw_local_irq_save(flags);
- if (!graph_lock())
- goto out_irq;
+ lockdep_lock();
- pf = get_pending_free();
hlist_for_each_entry_rcu(k, hash_head, hash_entry) {
if (k == key) {
hlist_del_rcu(&k->hash_entry);
@@ -5328,11 +5332,13 @@ void lockdep_unregister_key(struct lock_class_key *key)
break;
}
}
- WARN_ON_ONCE(!found);
- __lockdep_free_key_range(pf, key, 1);
- call_rcu_zapped(pf);
- graph_unlock();
-out_irq:
+ WARN_ON_ONCE(!found && debug_locks);
+ if (found) {
+ pf = get_pending_free();
+ __lockdep_free_key_range(pf, key, 1);
+ call_rcu_zapped(pf);
+ }
+ lockdep_unlock();
raw_local_irq_restore(flags);
/* Wait until is_dynamic_key() has finished accessing k->hash_entry. */
--
2.47.0.rc1.288.g06298d1525-goog
next prev parent reply other threads:[~2024-10-12 23:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-12 23:22 [PATCH 5.4.y 0/4] lockdep: deadlock fix and dependencies Carlos Llamas
2024-10-12 23:22 ` [PATCH 5.4.y 1/4] locking/lockdep: Fix bad recursion pattern Carlos Llamas
2024-10-12 23:22 ` [PATCH 5.4.y 2/4] locking/lockdep: Rework lockdep_lock Carlos Llamas
2024-10-12 23:22 ` Carlos Llamas [this message]
2024-10-12 23:22 ` [PATCH 5.4.y 4/4] lockdep: fix deadlock issue between lockdep and rcu Carlos Llamas
2024-10-13 14:23 ` [PATCH 5.4.y 0/4] lockdep: deadlock fix and dependencies Sasha Levin
2024-10-13 15:29 ` Carlos Llamas
2024-10-14 4:12 ` Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241012232244.2768048-4-cmllamas@google.com \
--to=cmllamas@google.com \
--cc=boqun.feng@gmail.com \
--cc=bvanassche@acm.org \
--cc=gregkh@linuxfoundation.org \
--cc=kernel-team@android.com \
--cc=longman@redhat.com \
--cc=paulmck@kernel.org \
--cc=penguin-kernel@i-love.sakura.ne.jp \
--cc=peterz@infradead.org \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
--cc=xuewen.yan@unisoc.com \
--cc=zhiguo.niu@unisoc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox