bcachefs: Fix a use after free
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 27 Feb 2022 16:34:21 +0000 (11:34 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:26 +0000 (17:09 -0400)
This fixes a regression from "bcachefs: Stash a copy of key being
overwritten in btree_insert_entry". In btree_key_can_insert_cached(), we
may reallocate the key cache key, invalidating pointers previously
returned by peek() - fix it by issuing a transaction restart.

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

index dc4dfcd..42ee54c 100644 (file)
@@ -382,7 +382,18 @@ btree_key_can_insert_cached(struct btree_trans *trans,
 
        ck->u64s        = new_u64s;
        ck->k           = new_k;
-       return BTREE_INSERT_OK;
+       /*
+        * Keys returned by peek() are no longer valid pointers, so we need a
+        * transaction restart:
+        */
+       trace_trans_restart_key_cache_key_realloced(trans->fn, _RET_IP_,
+                                            path->btree_id, &path->pos);
+       /*
+        * Not using btree_trans_restart() because we can't unlock here, we have
+        * write locks held:
+        */
+       trans->restarted = true;
+       return -EINTR;
 }
 
 static inline void do_btree_insert_one(struct btree_trans *trans,
index b35022d..af37852 100644 (file)
@@ -918,6 +918,14 @@ TRACE_EVENT(trans_restart_mem_realloced,
                  __entry->bytes)
 );
 
+DEFINE_EVENT(transaction_restart_iter, trans_restart_key_cache_key_realloced,
+       TP_PROTO(const char *trans_fn,
+                unsigned long caller_ip,
+                enum btree_id btree_id,
+                struct bpos *pos),
+       TP_ARGS(trans_fn, caller_ip, btree_id, pos)
+);
+
 #endif /* _TRACE_BCACHEFS_H */
 
 /* This part must be outside protection */