diff options
author | Alexander Motin <[email protected]> | 2023-09-29 11:22:46 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2023-10-03 09:06:07 -0700 |
commit | 3079bf2e6c0733b9bccac573324871f49dd6d503 (patch) | |
tree | f0532a2838e0eb176e9d069ce1d8ab03e3399763 /module | |
parent | b34bf2d5f6158c8ebeb47687a3fb7a2d3cc3aea7 (diff) |
Restrict short block cloning requests
If we are copying only one block and it is smaller than recordsize
property, do not allow destination to grow beyond one block if it
is not there yet. Otherwise the destination will get stuck with
that block size forever, that can be as small as 512 bytes, no
matter how big the destination grow later.
Reviewed-by: Kay Pedersen <[email protected]>
Reviewed-by: Rob Norris <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Alexander Motin <[email protected]>
Sponsored by: iXsystems, Inc.
Closes #15321
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/zfs_vnops.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index a64e1e2dc..40d6c87a7 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -1206,6 +1206,19 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp, goto unlock; } + /* + * If we are copying only one block and it is smaller than recordsize + * property, do not allow destination to grow beyond one block if it + * is not there yet. Otherwise the destination will get stuck with + * that block size forever, that can be as small as 512 bytes, no + * matter how big the destination grow later. + */ + if (len <= inblksz && inblksz < outzfsvfs->z_max_blksz && + outzp->z_size <= inblksz && outoff + len > inblksz) { + error = SET_ERROR(EINVAL); + goto unlock; + } + error = zn_rlimit_fsize(outoff + len); if (error != 0) { goto unlock; |