59 lines
1.9 KiB
Diff
59 lines
1.9 KiB
Diff
From 33213a5be19ee403b58d57f4f311bd65ee261e3a Mon Sep 17 00:00:00 2001
|
|
From: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Date: Tue, 26 Nov 2024 22:59:27 -0500
|
|
Subject: [PATCH 129/233] bcachefs: Fix null ptr deref in
|
|
btree_path_lock_root()
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Historically, we required that all btree node roots point to a valid
|
|
(possibly fake) node, but we're improving our ability to continue in the
|
|
presence of errors.
|
|
|
|
Reported-by: syzbot+e22007d6acb9c87c2362@syzkaller.appspotmail.com
|
|
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
|
---
|
|
fs/bcachefs/btree_iter.c | 11 ++++++++---
|
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
|
index 89f9665ce70d..80c3b55ce763 100644
|
|
--- a/fs/bcachefs/btree_iter.c
|
|
+++ b/fs/bcachefs/btree_iter.c
|
|
@@ -722,7 +722,7 @@ static inline int btree_path_lock_root(struct btree_trans *trans,
|
|
unsigned long trace_ip)
|
|
{
|
|
struct bch_fs *c = trans->c;
|
|
- struct btree *b, **rootp = &bch2_btree_id_root(c, path->btree_id)->b;
|
|
+ struct btree_root *r = bch2_btree_id_root(c, path->btree_id);
|
|
enum six_lock_type lock_type;
|
|
unsigned i;
|
|
int ret;
|
|
@@ -730,7 +730,12 @@ static inline int btree_path_lock_root(struct btree_trans *trans,
|
|
EBUG_ON(path->nodes_locked);
|
|
|
|
while (1) {
|
|
- b = READ_ONCE(*rootp);
|
|
+ struct btree *b = READ_ONCE(r->b);
|
|
+ if (unlikely(!b)) {
|
|
+ BUG_ON(!r->error);
|
|
+ return r->error;
|
|
+ }
|
|
+
|
|
path->level = READ_ONCE(b->c.level);
|
|
|
|
if (unlikely(path->level < depth_want)) {
|
|
@@ -755,7 +760,7 @@ static inline int btree_path_lock_root(struct btree_trans *trans,
|
|
BUG();
|
|
}
|
|
|
|
- if (likely(b == READ_ONCE(*rootp) &&
|
|
+ if (likely(b == READ_ONCE(r->b) &&
|
|
b->c.level == path->level &&
|
|
!race_fault())) {
|
|
for (i = 0; i < path->level; i++)
|
|
--
|
|
2.45.2
|
|
|