bcachefs: Guard against journal seq overflow
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 28 Nov 2024 02:58:43 +0000 (21:58 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:20 +0000 (01:36 -0500)
Wraparound is impractical to handle since in various places we use 0 as
a sentinal value - but 64 bits (or 56, because the btree write buffer
steals a few bits) is enough for all practical purposes.

Reported-by: syzbot+73ed43fbe826227bd4e0@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/journal.c
fs/bcachefs/journal_types.h

index 95cccda3b22cd86bd19388c261dfab2022d39a91..dc66521964b7523ced697c4b8fd727c35316ee5b 100644 (file)
@@ -382,6 +382,10 @@ static int journal_entry_open(struct journal *j)
        if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf))
                return JOURNAL_ERR_max_in_flight;
 
+       if (bch2_fs_fatal_err_on(journal_cur_seq(j) >= JOURNAL_SEQ_MAX,
+                                c, "cannot start: journal seq overflow"))
+               return JOURNAL_ERR_insufficient_devices; /* -EROFS */
+
        BUG_ON(!j->cur_entry_sectors);
 
        buf->expires            =
@@ -1270,6 +1274,11 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
        bool had_entries = false;
        u64 last_seq = cur_seq, nr, seq;
 
+       if (cur_seq >= JOURNAL_SEQ_MAX) {
+               bch_err(c, "cannot start: journal seq overflow");
+               return -EINVAL;
+       }
+
        genradix_for_each_reverse(&c->journal_entries, iter, _i) {
                i = *_i;
 
index 425d1abb257ee227b52b489fce697080cd541571..e9bd716fbb71083bea09a9c2105817c2bed95708 100644 (file)
@@ -9,6 +9,9 @@
 #include "super_types.h"
 #include "fifo.h"
 
+/* btree write buffer steals 8 bits for its own purposes: */
+#define JOURNAL_SEQ_MAX                ((1ULL << 56) - 1)
+
 #define JOURNAL_BUF_BITS       2
 #define JOURNAL_BUF_NR         (1U << JOURNAL_BUF_BITS)
 #define JOURNAL_BUF_MASK       (JOURNAL_BUF_NR - 1)