]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix l2arc_apply_transforms ztest crash
authorPaul Dagnelie <pcd@delphix.com>
Tue, 19 Sep 2023 15:58:14 +0000 (08:58 -0700)
committerGitHub <noreply@github.com>
Tue, 19 Sep 2023 15:58:14 +0000 (08:58 -0700)
In #13375 we modified the allocation size of the buffer that we use
to apply l2arc transforms to be the size of the arc hdr we're using,
rather than the allocation size that will be in place on the disk,
because sometimes the hdr size is larger. Unfortunately, sometimes
the allocation size is larger, which means that we overflow the buffer
in that case. This change modifies the allocation to be the max of
the two values

Reviewed-by: Mark Maybee <mark.maybee@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <pcd@delphix.com>
Closes #15177
Closes #15248

module/zfs/arc.c

index 7023f448182a1523a741999581b49ca717e4aeef..22dc0ed5e3b6adfde7f5fef1435f42ee409ecf6a 100644 (file)
@@ -9092,15 +9092,16 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize,
                 * write things before deciding to fail compression in nearly
                 * every case.)
                 */
-               cabd = abd_alloc_for_io(size, ismd);
-               tmp = abd_borrow_buf(cabd, size);
+               uint64_t bufsize = MAX(size, asize);
+               cabd = abd_alloc_for_io(bufsize, ismd);
+               tmp = abd_borrow_buf(cabd, bufsize);
 
                psize = zio_compress_data(compress, to_write, &tmp, size,
                    hdr->b_complevel);
 
                if (psize >= asize) {
                        psize = HDR_GET_PSIZE(hdr);
-                       abd_return_buf_copy(cabd, tmp, size);
+                       abd_return_buf_copy(cabd, tmp, bufsize);
                        HDR_SET_COMPRESS(hdr, ZIO_COMPRESS_OFF);
                        to_write = cabd;
                        abd_copy(to_write, hdr->b_l1hdr.b_pabd, psize);
@@ -9110,9 +9111,9 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize,
                }
                ASSERT3U(psize, <=, HDR_GET_PSIZE(hdr));
                if (psize < asize)
-                       memset((char *)tmp + psize, 0, asize - psize);
+                       memset((char *)tmp + psize, 0, bufsize - psize);
                psize = HDR_GET_PSIZE(hdr);
-               abd_return_buf_copy(cabd, tmp, size);
+               abd_return_buf_copy(cabd, tmp, bufsize);
                to_write = cabd;
        }