bcachefs: Fix integer overflow in bch2_disk_reservation_get()
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 17 Jan 2021 18:19:16 +0000 (13:19 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:51 +0000 (17:08 -0400)
The sectors argument shouldn't have been a u32 - it can be up to U32_MAX
(i.e. fallocate creating persistent reservations), and if replication is
enabled we'll overflow when we calculate the real number of sectors to
reserve. Oops.

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

index 1bbd1ee080ecb9bc802f2038804ea410415fa308..11907abd9b4c8b41362a77d3a1400d3a217a8e5f 100644 (file)
@@ -2109,7 +2109,7 @@ int bch2_trans_mark_update(struct btree_trans *trans,
 #define SECTORS_CACHE  1024
 
 int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
-                             unsigned sectors, int flags)
+                             u64 sectors, int flags)
 {
        struct bch_fs_pcpu *pcpu;
        u64 old, v, get;
index 2e9c4e46c61c07a25183850fe1d8ca5a0a057a17..a0ef9c041d5c6cd4d0f951374d254778a362d33d 100644 (file)
@@ -282,8 +282,8 @@ static inline void bch2_disk_reservation_put(struct bch_fs *c,
 #define BCH_DISK_RESERVATION_NOFAIL            (1 << 0)
 
 int bch2_disk_reservation_add(struct bch_fs *,
-                            struct disk_reservation *,
-                            unsigned, int);
+                             struct disk_reservation *,
+                             u64, int);
 
 static inline struct disk_reservation
 bch2_disk_reservation_init(struct bch_fs *c, unsigned nr_replicas)
@@ -300,8 +300,7 @@ bch2_disk_reservation_init(struct bch_fs *c, unsigned nr_replicas)
 
 static inline int bch2_disk_reservation_get(struct bch_fs *c,
                                            struct disk_reservation *res,
-                                           unsigned sectors,
-                                           unsigned nr_replicas,
+                                           u64 sectors, unsigned nr_replicas,
                                            int flags)
 {
        *res = bch2_disk_reservation_init(c, nr_replicas);