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.

Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2023-11-18 20:01:03 -05:00 committed by Ameer Hamza
parent 20331b2aec
commit 33e7c6558c
2 changed files with 38 additions and 20 deletions

View File

@ -1338,19 +1338,14 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
* authenticate it.
*/
if (txtype == TX_WRITE) {
crypt_len = sizeof (lr_write_t) -
sizeof (lr_t) - sizeof (blkptr_t);
dst_iovecs[vec].iov_base = (char *)dlrp +
sizeof (lr_t);
const size_t o = offsetof(lr_write_t, lr_blkptr);
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 bp now since it will not be encrypted */
memcpy(dlrp + sizeof (lr_write_t) - sizeof (blkptr_t),
slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
sizeof (blkptr_t));
memcpy(aadp,
slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
sizeof (blkptr_t));
memcpy(dlrp + o, slrp + o, sizeof (blkptr_t));
memcpy(aadp, slrp + o, sizeof (blkptr_t));
aadp += sizeof (blkptr_t);
aad_len += sizeof (blkptr_t);
vec++;
@ -1364,10 +1359,22 @@ 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 +
sizeof (lr_t);
dst_iovecs[vec].iov_base = (char *)dlrp + sizeof (lr_t);
dst_iovecs[vec].iov_len = crypt_len;
vec++;
total_len += crypt_len;

View File

@ -1513,20 +1513,16 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
* authenticate it.
*/
if (txtype == TX_WRITE) {
crypt_len = sizeof (lr_write_t) -
sizeof (lr_t) - sizeof (blkptr_t);
const size_t o = offsetof(lr_write_t, lr_blkptr);
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 bp now since it will not be encrypted */
memcpy(dlrp + sizeof (lr_write_t) - sizeof (blkptr_t),
slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
sizeof (blkptr_t));
memcpy(aadp,
slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
sizeof (blkptr_t));
memcpy(dlrp + o, slrp + o, sizeof (blkptr_t));
memcpy(aadp, slrp + o, sizeof (blkptr_t));
aadp += sizeof (blkptr_t);
aad_len += sizeof (blkptr_t);
nr_iovecs++;
@ -1543,6 +1539,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);