ZIL: Assert record sizes in different places

This should make sure we have log written without overflows.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #15517
This commit is contained in:
Alexander Motin 2023-11-28 16:35:14 -05:00 committed by Brian Behlendorf
parent 2e259c6f00
commit ad47eca195
6 changed files with 115 additions and 37 deletions

View File

@ -1251,7 +1251,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
iovec_t *dst_iovecs; iovec_t *dst_iovecs;
zil_chain_t *zilc; zil_chain_t *zilc;
lr_t *lr; lr_t *lr;
uint64_t txtype, lr_len; uint64_t txtype, lr_len, nused;
uint_t crypt_len, nr_iovecs, vec; uint_t crypt_len, nr_iovecs, vec;
uint_t aad_len = 0, total_len = 0; uint_t aad_len = 0, total_len = 0;
@ -1268,7 +1268,10 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
zilc = (zil_chain_t *)src; zilc = (zil_chain_t *)src;
slrp = src + sizeof (zil_chain_t); slrp = src + sizeof (zil_chain_t);
aadp = aadbuf; aadp = aadbuf;
blkend = src + ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused); nused = ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused);
ASSERT3U(nused, >=, sizeof (zil_chain_t));
ASSERT3U(nused, <=, datalen);
blkend = src + nused;
/* /*
* Calculate the number of encrypted iovecs we will need. * Calculate the number of encrypted iovecs we will need.
@ -1287,6 +1290,8 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
txtype = lr->lrc_txtype; txtype = lr->lrc_txtype;
lr_len = lr->lrc_reclen; lr_len = lr->lrc_reclen;
} }
ASSERT3U(lr_len, >=, sizeof (lr_t));
ASSERT3U(lr_len, <=, blkend - slrp);
nr_iovecs++; nr_iovecs++;
if (txtype == TX_WRITE && lr_len != sizeof (lr_write_t)) if (txtype == TX_WRITE && lr_len != sizeof (lr_write_t))

View File

@ -1405,7 +1405,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
boolean_t *no_crypt) boolean_t *no_crypt)
{ {
int ret; int ret;
uint64_t txtype, lr_len; uint64_t txtype, lr_len, nused;
uint_t nr_src, nr_dst, crypt_len; uint_t nr_src, nr_dst, crypt_len;
uint_t aad_len = 0, nr_iovecs = 0, total_len = 0; uint_t aad_len = 0, nr_iovecs = 0, total_len = 0;
iovec_t *src_iovecs = NULL, *dst_iovecs = NULL; iovec_t *src_iovecs = NULL, *dst_iovecs = NULL;
@ -1432,7 +1432,10 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
zilc = (zil_chain_t *)src; zilc = (zil_chain_t *)src;
slrp = src + sizeof (zil_chain_t); slrp = src + sizeof (zil_chain_t);
aadp = aadbuf; aadp = aadbuf;
blkend = src + ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused); nused = ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused);
ASSERT3U(nused, >=, sizeof (zil_chain_t));
ASSERT3U(nused, <=, datalen);
blkend = src + nused;
/* calculate the number of encrypted iovecs we will need */ /* calculate the number of encrypted iovecs we will need */
for (; slrp < blkend; slrp += lr_len) { for (; slrp < blkend; slrp += lr_len) {
@ -1445,6 +1448,8 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
txtype = BSWAP_64(lr->lrc_txtype); txtype = BSWAP_64(lr->lrc_txtype);
lr_len = BSWAP_64(lr->lrc_reclen); lr_len = BSWAP_64(lr->lrc_reclen);
} }
ASSERT3U(lr_len, >=, sizeof (lr_t));
ASSERT3U(lr_len, <=, blkend - slrp);
nr_iovecs++; nr_iovecs++;
if (txtype == TX_WRITE && lr_len != sizeof (lr_write_t)) if (txtype == TX_WRITE && lr_len != sizeof (lr_write_t))

View File

@ -309,6 +309,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
uint64_t dnodesize; uint64_t dnodesize;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lracl));
txtype = (lr->lr_common.lrc_txtype & ~TX_CI); txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lracl, sizeof (*lracl)); byteswap_uint64_array(lracl, sizeof (*lracl));
@ -470,6 +472,8 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
uint64_t dnodesize; uint64_t dnodesize;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
txtype = (lr->lr_common.lrc_txtype & ~TX_CI); txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -613,6 +617,8 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
int error; int error;
int vflg = 0; int vflg = 0;
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -648,6 +654,8 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
int error; int error;
int vflg = 0; int vflg = 0;
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -715,12 +723,14 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_t *lr = arg2; lr_rename_t *lr = arg2;
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1; ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1;
return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, 0, NULL)); return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, 0, NULL));
} }
@ -730,12 +740,14 @@ zfs_replay_rename_exchange(void *arg1, void *arg2, boolean_t byteswap)
#ifdef __linux__ #ifdef __linux__
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_t *lr = arg2; lr_rename_t *lr = arg2;
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1; ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1;
return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, RENAME_EXCHANGE, return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, RENAME_EXCHANGE,
NULL)); NULL));
#else #else
@ -750,14 +762,13 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_whiteout_t *lr = arg2; lr_rename_whiteout_t *lr = arg2;
int error; int error;
/* sname and tname follow lr_rename_whiteout_t */
char *sname = (char *)(lr + 1);
char *tname = sname + strlen(sname) + 1;
/* For the whiteout file. */ /* For the whiteout file. */
xvattr_t xva; xvattr_t xva;
uint64_t objid; uint64_t objid;
uint64_t dnodesize; uint64_t dnodesize;
ASSERT3U(lr->lr_rename.lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -783,6 +794,9 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
if (error) if (error)
return (error); return (error);
/* sname and tname follow lr_rename_whiteout_t */
char *sname = (char *)(lr + 1);
char *tname = sname + strlen(sname) + 1;
return (do_zfs_replay_rename(zfsvfs, &lr->lr_rename, sname, tname, return (do_zfs_replay_rename(zfsvfs, &lr->lr_rename, sname, tname,
RENAME_WHITEOUT, &xva.xva_vattr)); RENAME_WHITEOUT, &xva.xva_vattr));
#else #else
@ -800,6 +814,8 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
int error; int error;
uint64_t eod, offset, length; uint64_t eod, offset, length;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -863,6 +879,8 @@ zfs_replay_write2(void *arg1, void *arg2, boolean_t byteswap)
int error; int error;
uint64_t end; uint64_t end;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -910,6 +928,8 @@ zfs_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
flock64_t fl = {0}; flock64_t fl = {0};
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -940,6 +960,8 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
int error; int error;
void *start; void *start;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
xva_init(&xva); xva_init(&xva);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -1002,6 +1024,9 @@ zfs_replay_setsaxattr(void *arg1, void *arg2, boolean_t byteswap)
size_t size; size_t size;
int error = 0; int error = 0;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr) + lr->lr_size);
ASSERT(spa_feature_is_active(zfsvfs->z_os->os_spa, ASSERT(spa_feature_is_active(zfsvfs->z_os->os_spa,
SPA_FEATURE_ZILSAXATTR)); SPA_FEATURE_ZILSAXATTR));
if (byteswap) if (byteswap)
@ -1079,6 +1104,10 @@ zfs_replay_acl_v0(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp; znode_t *zp;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr) +
sizeof (ace_t) * lr->lr_aclcnt);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
zfs_oldace_byteswap(ace, lr->lr_aclcnt); zfs_oldace_byteswap(ace, lr->lr_aclcnt);
@ -1124,6 +1153,9 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp; znode_t *zp;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr) + lr->lr_acl_bytes);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE); zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE);
@ -1171,6 +1203,10 @@ zfs_replay_clone_range(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp; znode_t *zp;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >=, offsetof(lr_clone_range_t,
lr_bps[lr->lr_nbps]));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));

View File

@ -522,6 +522,7 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
lr_t *lr = (lr_t *)lrp; lr_t *lr = (lr_t *)lrp;
reclen = lr->lrc_reclen; reclen = lr->lrc_reclen;
ASSERT3U(reclen, >=, sizeof (lr_t)); ASSERT3U(reclen, >=, sizeof (lr_t));
ASSERT3U(reclen, <=, end - lrp);
if (lr->lrc_seq > claim_lr_seq) { if (lr->lrc_seq > claim_lr_seq) {
arc_buf_destroy(abuf, &abuf); arc_buf_destroy(abuf, &abuf);
goto done; goto done;
@ -604,7 +605,7 @@ zil_claim_write(zilog_t *zilog, const lr_t *lrc, void *tx, uint64_t first_txg)
lr_write_t *lr = (lr_write_t *)lrc; lr_write_t *lr = (lr_write_t *)lrc;
int error; int error;
ASSERT(lrc->lrc_txtype == TX_WRITE); ASSERT3U(lrc->lrc_reclen, >=, sizeof (*lr));
/* /*
* If the block is not readable, don't claim it. This can happen * If the block is not readable, don't claim it. This can happen
@ -631,7 +632,9 @@ zil_claim_clone_range(zilog_t *zilog, const lr_t *lrc, void *tx)
spa_t *spa; spa_t *spa;
uint_t ii; uint_t ii;
ASSERT(lrc->lrc_txtype == TX_CLONE_RANGE); ASSERT3U(lrc->lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lrc->lrc_reclen, >=, offsetof(lr_clone_range_t,
lr_bps[lr->lr_nbps]));
if (tx == NULL) { if (tx == NULL) {
return (0); return (0);
@ -691,7 +694,7 @@ zil_free_write(zilog_t *zilog, const lr_t *lrc, void *tx, uint64_t claim_txg)
lr_write_t *lr = (lr_write_t *)lrc; lr_write_t *lr = (lr_write_t *)lrc;
blkptr_t *bp = &lr->lr_blkptr; blkptr_t *bp = &lr->lr_blkptr;
ASSERT(lrc->lrc_txtype == TX_WRITE); ASSERT3U(lrc->lrc_reclen, >=, sizeof (*lr));
/* /*
* If we previously claimed it, we need to free it. * If we previously claimed it, we need to free it.
@ -712,7 +715,9 @@ zil_free_clone_range(zilog_t *zilog, const lr_t *lrc, void *tx)
spa_t *spa; spa_t *spa;
uint_t ii; uint_t ii;
ASSERT(lrc->lrc_txtype == TX_CLONE_RANGE); ASSERT3U(lrc->lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lrc->lrc_reclen, >=, offsetof(lr_clone_range_t,
lr_bps[lr->lr_nbps]));
if (tx == NULL) { if (tx == NULL) {
return (0); return (0);
@ -1794,6 +1799,7 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
itx = list_next(&lwb->lwb_itxs, itx)) itx = list_next(&lwb->lwb_itxs, itx))
zil_lwb_commit(zilog, lwb, itx); zil_lwb_commit(zilog, lwb, itx);
lwb->lwb_nused = lwb->lwb_nfilled; lwb->lwb_nused = lwb->lwb_nfilled;
ASSERT3U(lwb->lwb_nused, <=, lwb->lwb_nmax);
lwb->lwb_root_zio = zio_root(spa, zil_lwb_flush_vdevs_done, lwb, lwb->lwb_root_zio = zio_root(spa, zil_lwb_flush_vdevs_done, lwb,
ZIO_FLAG_CANFAIL); ZIO_FLAG_CANFAIL);
@ -2023,13 +2029,16 @@ zil_lwb_assign(zilog_t *zilog, lwb_t *lwb, itx_t *itx, list_t *ilwbs)
return (lwb); return (lwb);
} }
reclen = lr->lrc_reclen;
if (lr->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY) { if (lr->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY) {
ASSERT3U(reclen, ==, sizeof (lr_write_t));
dlen = P2ROUNDUP_TYPED( dlen = P2ROUNDUP_TYPED(
lrw->lr_length, sizeof (uint64_t), uint64_t); lrw->lr_length, sizeof (uint64_t), uint64_t);
} else { } else {
ASSERT3U(reclen, >=, sizeof (lr_t));
dlen = 0; dlen = 0;
} }
reclen = lr->lrc_reclen; ASSERT3U(reclen, <=, zil_max_log_data(zilog, 0));
zilog->zl_cur_used += (reclen + dlen); zilog->zl_cur_used += (reclen + dlen);
cont: cont:
@ -2048,19 +2057,19 @@ cont:
if (lwb == NULL) if (lwb == NULL)
return (NULL); return (NULL);
lwb_sp = lwb->lwb_nmax - lwb->lwb_nused; lwb_sp = lwb->lwb_nmax - lwb->lwb_nused;
/*
* There must be enough space in the new, empty log block to
* hold reclen. For WR_COPIED, we need to fit the whole
* record in one block, and reclen is the header size + the
* data size. For WR_NEED_COPY, we can create multiple
* records, splitting the data into multiple blocks, so we
* only need to fit one word of data per block; in this case
* reclen is just the header size (no data).
*/
ASSERT3U(reclen + MIN(dlen, sizeof (uint64_t)), <=, lwb_sp);
} }
/*
* There must be enough space in the log block to hold reclen.
* For WR_COPIED, we need to fit the whole record in one block,
* and reclen is the write record header size + the data size.
* For WR_NEED_COPY, we can create multiple records, splitting
* the data into multiple blocks, so we only need to fit one
* word of data per block; in this case reclen is just the header
* size (no data).
*/
ASSERT3U(reclen + MIN(dlen, sizeof (uint64_t)), <=, lwb_sp);
dnow = MIN(dlen, lwb_sp - reclen); dnow = MIN(dlen, lwb_sp - reclen);
if (dlen > dnow) { if (dlen > dnow) {
ASSERT3U(lr->lrc_txtype, ==, TX_WRITE); ASSERT3U(lr->lrc_txtype, ==, TX_WRITE);
@ -2236,7 +2245,9 @@ zil_itx_create(uint64_t txtype, size_t olrsize)
size_t itxsize, lrsize; size_t itxsize, lrsize;
itx_t *itx; itx_t *itx;
ASSERT3U(olrsize, >=, sizeof (lr_t));
lrsize = P2ROUNDUP_TYPED(olrsize, sizeof (uint64_t), size_t); lrsize = P2ROUNDUP_TYPED(olrsize, sizeof (uint64_t), size_t);
ASSERT3U(lrsize, >=, olrsize);
itxsize = offsetof(itx_t, itx_lr) + lrsize; itxsize = offsetof(itx_t, itx_lr) + lrsize;
itx = zio_data_buf_alloc(itxsize); itx = zio_data_buf_alloc(itxsize);
@ -2255,6 +2266,10 @@ zil_itx_create(uint64_t txtype, size_t olrsize)
static itx_t * static itx_t *
zil_itx_clone(itx_t *oitx) zil_itx_clone(itx_t *oitx)
{ {
ASSERT3U(oitx->itx_size, >=, sizeof (itx_t));
ASSERT3U(oitx->itx_size, ==,
offsetof(itx_t, itx_lr) + oitx->itx_lr.lrc_reclen);
itx_t *itx = zio_data_buf_alloc(oitx->itx_size); itx_t *itx = zio_data_buf_alloc(oitx->itx_size);
memcpy(itx, oitx, oitx->itx_size); memcpy(itx, oitx, oitx->itx_size);
itx->itx_callback = NULL; itx->itx_callback = NULL;
@ -2265,6 +2280,9 @@ zil_itx_clone(itx_t *oitx)
void void
zil_itx_destroy(itx_t *itx) zil_itx_destroy(itx_t *itx)
{ {
ASSERT3U(itx->itx_size, >=, sizeof (itx_t));
ASSERT3U(itx->itx_lr.lrc_reclen, ==,
itx->itx_size - offsetof(itx_t, itx_lr));
IMPLY(itx->itx_lr.lrc_txtype == TX_COMMIT, itx->itx_callback == NULL); IMPLY(itx->itx_lr.lrc_txtype == TX_COMMIT, itx->itx_callback == NULL);
IMPLY(itx->itx_callback != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT); IMPLY(itx->itx_callback != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT);
@ -2348,7 +2366,7 @@ void
zil_remove_async(zilog_t *zilog, uint64_t oid) zil_remove_async(zilog_t *zilog, uint64_t oid)
{ {
uint64_t otxg, txg; uint64_t otxg, txg;
itx_async_node_t *ian; itx_async_node_t *ian, ian_search;
avl_tree_t *t; avl_tree_t *t;
avl_index_t where; avl_index_t where;
list_t clean_list; list_t clean_list;
@ -2375,7 +2393,8 @@ zil_remove_async(zilog_t *zilog, uint64_t oid)
* Locate the object node and append its list. * Locate the object node and append its list.
*/ */
t = &itxg->itxg_itxs->i_async_tree; t = &itxg->itxg_itxs->i_async_tree;
ian = avl_find(t, &oid, &where); ian_search.ia_foid = oid;
ian = avl_find(t, &ian_search, &where);
if (ian != NULL) if (ian != NULL)
list_move_tail(&clean_list, &ian->ia_list); list_move_tail(&clean_list, &ian->ia_list);
mutex_exit(&itxg->itxg_lock); mutex_exit(&itxg->itxg_lock);
@ -2573,7 +2592,7 @@ void
zil_async_to_sync(zilog_t *zilog, uint64_t foid) zil_async_to_sync(zilog_t *zilog, uint64_t foid)
{ {
uint64_t otxg, txg; uint64_t otxg, txg;
itx_async_node_t *ian; itx_async_node_t *ian, ian_search;
avl_tree_t *t; avl_tree_t *t;
avl_index_t where; avl_index_t where;
@ -2603,7 +2622,8 @@ zil_async_to_sync(zilog_t *zilog, uint64_t foid)
*/ */
t = &itxg->itxg_itxs->i_async_tree; t = &itxg->itxg_itxs->i_async_tree;
if (foid != 0) { if (foid != 0) {
ian = avl_find(t, &foid, &where); ian_search.ia_foid = foid;
ian = avl_find(t, &ian_search, &where);
if (ian != NULL) { if (ian != NULL) {
list_move_tail(&itxg->itxg_itxs->i_sync_list, list_move_tail(&itxg->itxg_itxs->i_sync_list,
&ian->ia_list); &ian->ia_list);

View File

@ -363,11 +363,14 @@ zio_checksum_compute(zio_t *zio, enum zio_checksum checksum,
zil_chain_t zilc; zil_chain_t zilc;
abd_copy_to_buf(&zilc, abd, sizeof (zil_chain_t)); abd_copy_to_buf(&zilc, abd, sizeof (zil_chain_t));
size = P2ROUNDUP_TYPED(zilc.zc_nused, ZIL_MIN_BLKSZ, uint64_t nused = P2ROUNDUP_TYPED(zilc.zc_nused,
uint64_t); ZIL_MIN_BLKSZ, uint64_t);
ASSERT3U(size, >=, nused);
size = nused;
eck = zilc.zc_eck; eck = zilc.zc_eck;
eck_offset = offsetof(zil_chain_t, zc_eck); eck_offset = offsetof(zil_chain_t, zc_eck);
} else { } else {
ASSERT3U(size, >=, sizeof (zio_eck_t));
eck_offset = size - sizeof (zio_eck_t); eck_offset = size - sizeof (zio_eck_t);
abd_copy_to_buf_off(&eck, abd, eck_offset, abd_copy_to_buf_off(&eck, abd, eck_offset,
sizeof (zio_eck_t)); sizeof (zio_eck_t));
@ -448,12 +451,13 @@ zio_checksum_error_impl(spa_t *spa, const blkptr_t *bp,
return (SET_ERROR(ECKSUM)); return (SET_ERROR(ECKSUM));
} }
if (nused > size) { nused = P2ROUNDUP_TYPED(nused, ZIL_MIN_BLKSZ, uint64_t);
if (size < nused)
return (SET_ERROR(ECKSUM)); return (SET_ERROR(ECKSUM));
} size = nused;
size = P2ROUNDUP_TYPED(nused, ZIL_MIN_BLKSZ, uint64_t);
} else { } else {
if (size < sizeof (zio_eck_t))
return (SET_ERROR(ECKSUM));
eck_offset = size - sizeof (zio_eck_t); eck_offset = size - sizeof (zio_eck_t);
abd_copy_to_buf_off(&eck, abd, eck_offset, abd_copy_to_buf_off(&eck, abd, eck_offset,
sizeof (zio_eck_t)); sizeof (zio_eck_t));

View File

@ -417,6 +417,8 @@ zvol_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
lr_truncate_t *lr = arg2; lr_truncate_t *lr = arg2;
uint64_t offset, length; uint64_t offset, length;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -453,6 +455,8 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap)
dmu_tx_t *tx; dmu_tx_t *tx;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
@ -506,6 +510,10 @@ zvol_replay_clone_range(void *arg1, void *arg2, boolean_t byteswap)
uint_t ii; uint_t ii;
int error; int error;
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >=, offsetof(lr_clone_range_t,
lr_bps[lr->lr_nbps]));
dmu_objset_name(os, name); dmu_objset_name(os, name);
cmn_err(CE_WARN, "ZFS dropping block cloning transaction for %s.", cmn_err(CE_WARN, "ZFS dropping block cloning transaction for %s.",
name); name);