bcachefs: Zero out mem_ptr field in btree ptr keys from journal replay
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 30 Jul 2021 18:33:06 +0000 (14:33 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:10 +0000 (17:09 -0400)
This fixes a bad ptr deref on recovery from unclean shutdown in
bch2_btree_node_get_noiter().

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/recovery.c

index 84e224fb0d019c2e2eb02ded749279b4c53860cc..afb72648fe5416a0cba73f59548f1933ad78fc86 100644 (file)
@@ -39,6 +39,20 @@ static void drop_alloc_keys(struct journal_keys *keys)
        keys->nr = dst;
 }
 
+/*
+ * Btree node pointers have a field to stack a pointer to the in memory btree
+ * node; we need to zero out this field when reading in btree nodes, or when
+ * reading in keys from the journal:
+ */
+static void zero_out_btree_mem_ptr(struct journal_keys *keys)
+{
+       struct journal_key *i;
+
+       for (i = keys->d; i < keys->d + keys->nr; i++)
+               if (i->k->k.type == KEY_TYPE_btree_ptr_v2)
+                       bkey_i_to_btree_ptr_v2(i->k)->v.mem_ptr = 0;
+}
+
 /* iterate over keys read from the journal: */
 
 static int __journal_key_cmp(enum btree_id     l_btree_id,
@@ -1072,6 +1086,8 @@ use_clean:
                drop_alloc_keys(&c->journal_keys);
        }
 
+       zero_out_btree_mem_ptr(&c->journal_keys);
+
        ret = journal_replay_early(c, clean, &c->journal_entries);
        if (ret)
                goto err;