From 56a2a0981ed770ed316769d078c892b1e8fa67a9 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 18 Nov 2023 20:01:03 -0500 Subject: [PATCH] ZIL: Do not encrypt block pointers in lr_clone_range_t In case of crash cloned blocks need to be claimed on pool import. It is only possible if they (lr_bps) and their count (lr_nbps) are not encrypted but only authenticated, similar to block pointer in lr_write_t. Few other fields can be and are still encrypted. This should fix panic on ZIL claim after crash when block cloning is actively used. Reviewed-by: Richard Yao Reviewed-by: Tom Caputi Reviewed-by: Sean Eric Fagan Reviewed-by: Brian Behlendorf Reviewed-by: Edmund Nadolski Signed-off-by: Alexander Motin Sponsored by: iXsystems, Inc. Closes #15543 Closes #15513 --- module/os/freebsd/zfs/zio_crypt.c | 13 +++++++++++++ module/os/linux/zfs/zio_crypt.c | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/module/os/freebsd/zfs/zio_crypt.c b/module/os/freebsd/zfs/zio_crypt.c index fdbe13dbb5..024a931d78 100644 --- a/module/os/freebsd/zfs/zio_crypt.c +++ b/module/os/freebsd/zfs/zio_crypt.c @@ -1364,6 +1364,19 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf, vec++; total_len += crypt_len; } + } else if (txtype == TX_CLONE_RANGE) { + const size_t o = offsetof(lr_clone_range_t, lr_nbps); + crypt_len = o - sizeof (lr_t); + dst_iovecs[vec].iov_base = (char *)dlrp + sizeof (lr_t); + dst_iovecs[vec].iov_len = crypt_len; + + /* copy the bps now since they will not be encrypted */ + memcpy(dlrp + o, slrp + o, lr_len - o); + memcpy(aadp, slrp + o, lr_len - o); + aadp += lr_len - o; + aad_len += lr_len - o; + vec++; + total_len += crypt_len; } else { crypt_len = lr_len - sizeof (lr_t); dst_iovecs[vec].iov_base = (char *)dlrp + diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c index 55554d09ee..775ab8efbc 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -1543,6 +1543,21 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf, nr_iovecs++; total_len += crypt_len; } + } else if (txtype == TX_CLONE_RANGE) { + const size_t o = offsetof(lr_clone_range_t, lr_nbps); + crypt_len = o - sizeof (lr_t); + src_iovecs[nr_iovecs].iov_base = slrp + sizeof (lr_t); + src_iovecs[nr_iovecs].iov_len = crypt_len; + dst_iovecs[nr_iovecs].iov_base = dlrp + sizeof (lr_t); + dst_iovecs[nr_iovecs].iov_len = crypt_len; + + /* copy the bps now since they will not be encrypted */ + memcpy(dlrp + o, slrp + o, lr_len - o); + memcpy(aadp, slrp + o, lr_len - o); + aadp += lr_len - o; + aad_len += lr_len - o; + nr_iovecs++; + total_len += crypt_len; } else { crypt_len = lr_len - sizeof (lr_t); src_iovecs[nr_iovecs].iov_base = slrp + sizeof (lr_t);