Merge tag 'for-6.2-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Feb 2023 22:05:16 +0000 (14:05 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 Feb 2023 22:05:16 +0000 (14:05 -0800)
Pull btrfs fixes from David Sterba:

 - explicitly initialize zlib work memory to fix a KCSAN warning

 - limit number of send clones by maximum memory allocated

 - limit device size extent in case it device shrink races with chunk
   allocation

 - raid56 fixes:
     - fix copy&paste error in RAID6 stripe recovery
     - make error bitmap update atomic

* tag 'for-6.2-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: raid56: make error_bitmap update atomic
  btrfs: send: limit number of clones and allocated memory size
  btrfs: zlib: zero-initialize zlib workspace
  btrfs: limit device extents to the device size
  btrfs: raid56: fix stripes if vertical errors are found

fs/btrfs/raid56.c
fs/btrfs/send.c
fs/btrfs/volumes.c
fs/btrfs/zlib.c

index 6a2cf754912df27a9573aeb5f11e8bc85d217aa0..ff4b1d583788c81b224cc3eb108d8d3c94a5d4ad 100644 (file)
@@ -1426,12 +1426,20 @@ static void rbio_update_error_bitmap(struct btrfs_raid_bio *rbio, struct bio *bi
        u32 bio_size = 0;
        struct bio_vec *bvec;
        struct bvec_iter_all iter_all;
+       int i;
 
        bio_for_each_segment_all(bvec, bio, iter_all)
                bio_size += bvec->bv_len;
 
-       bitmap_set(rbio->error_bitmap, total_sector_nr,
-                  bio_size >> rbio->bioc->fs_info->sectorsize_bits);
+       /*
+        * Since we can have multiple bios touching the error_bitmap, we cannot
+        * call bitmap_set() without protection.
+        *
+        * Instead use set_bit() for each bit, as set_bit() itself is atomic.
+        */
+       for (i = total_sector_nr; i < total_sector_nr +
+            (bio_size >> rbio->bioc->fs_info->sectorsize_bits); i++)
+               set_bit(i, rbio->error_bitmap);
 }
 
 /* Verify the data sectors at read time. */
@@ -1886,7 +1894,7 @@ pstripe:
                sector->uptodate = 1;
        }
        if (failb >= 0) {
-               ret = verify_one_sector(rbio, faila, sector_nr);
+               ret = verify_one_sector(rbio, failb, sector_nr);
                if (ret < 0)
                        goto cleanup;
 
index e65e6b6600a744b240405ca4c973ccb55e9e85e1..d50182b6deec8fec035f9735b1a5e6ecefb8e27e 100644 (file)
@@ -8073,10 +8073,10 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
        /*
         * Check that we don't overflow at later allocations, we request
         * clone_sources_count + 1 items, and compare to unsigned long inside
-        * access_ok.
+        * access_ok. Also set an upper limit for allocation size so this can't
+        * easily exhaust memory. Max number of clone sources is about 200K.
         */
-       if (arg->clone_sources_count >
-           ULONG_MAX / sizeof(struct clone_root) - 1) {
+       if (arg->clone_sources_count > SZ_8M / sizeof(struct clone_root)) {
                ret = -EINVAL;
                goto out;
        }
index bcfef75b97da0de6315e0ab76da7c03e272a5a79..4cdadf30163d5edf1b411be65dbca6dd4e179377 100644 (file)
@@ -1600,7 +1600,7 @@ again:
        if (ret < 0)
                goto out;
 
-       while (1) {
+       while (search_start < search_end) {
                l = path->nodes[0];
                slot = path->slots[0];
                if (slot >= btrfs_header_nritems(l)) {
@@ -1623,6 +1623,9 @@ again:
                if (key.type != BTRFS_DEV_EXTENT_KEY)
                        goto next;
 
+               if (key.offset > search_end)
+                       break;
+
                if (key.offset > search_start) {
                        hole_size = key.offset - search_start;
                        dev_extent_hole_check(device, &search_start, &hole_size,
@@ -1683,6 +1686,7 @@ next:
        else
                ret = 0;
 
+       ASSERT(max_hole_start + max_hole_size <= search_end);
 out:
        btrfs_free_path(path);
        *start = max_hole_start;
index 01a13de11832097f01d745f4357276d6463bef52..da7bb9187b68a3e2d17bbbbfb0774d45aa94936e 100644 (file)
@@ -63,7 +63,7 @@ struct list_head *zlib_alloc_workspace(unsigned int level)
 
        workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
                        zlib_inflate_workspacesize());
-       workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL);
+       workspace->strm.workspace = kvzalloc(workspacesize, GFP_KERNEL);
        workspace->level = level;
        workspace->buf = NULL;
        /*