bcachefs: Don't overflow stack in bch2_extent_merge_inline()
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 30 May 2019 00:06:06 +0000 (20:06 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:23 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bkey.h
fs/bcachefs/extents.c

index 45de61d492a4bf426f2bbd19abe49fe89c20af25..ba08d95aae6f9603d7e7f42aa699851825377b6f 100644 (file)
@@ -41,10 +41,7 @@ struct bkey_s {
 
 #define bkey_next(_k)          vstruct_next(_k)
 
-static inline unsigned bkey_val_u64s(const struct bkey *k)
-{
-       return k->u64s - BKEY_U64s;
-}
+#define bkey_val_u64s(_k)      ((_k)->u64s - BKEY_U64s)
 
 static inline size_t bkey_val_bytes(const struct bkey *k)
 {
index c5a0d6c8e63ae445a99a6ec4b3b7db15e0e875d8..a5582a6f6ef670af61772a04353b45afa951f67f 100644 (file)
@@ -1651,6 +1651,10 @@ static bool bch2_extent_merge_inline(struct bch_fs *c,
 
        EBUG_ON(bkey_written(b, m));
 
+       if (bkey_val_u64s(l) > BKEY_EXTENT_VAL_U64s_MAX ||
+           bkey_val_u64s(r) > BKEY_EXTENT_VAL_U64s_MAX)
+               return BCH_MERGE_NOMERGE;
+
        /*
         * We need to save copies of both l and r, because we might get a
         * partial merge (which modifies both) and then fails to repack