From 88be308b2ff98f032a6773d4530276687f5e38dc Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 16 Jul 2021 10:05:28 -0400 Subject: [PATCH] Zero pad bytes following TX_WRITE log data When logging a TX_WRITE record in the case where file data has to be copied from the DMU, we pad the log record size to a multiple of 8 bytes. In this case, any padding bytes should be zeroed, otherwise the contents of uninitialized memory are written to the ZIL. This was found using KMSAN. Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: Mark Johnston Closes #12383 --- module/zfs/zil.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/module/zfs/zil.c b/module/zfs/zil.c index e89e10f680..8c6f0d8255 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -1617,7 +1617,7 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) lr_t *lrcb, *lrc; lr_write_t *lrwb, *lrw; char *lr_buf; - uint64_t dlen, dnow, lwb_sp, reclen, txg, max_log_data; + uint64_t dlen, dnow, dpad, lwb_sp, reclen, txg, max_log_data; ASSERT(MUTEX_HELD(&zilog->zl_issuer_lock)); ASSERT3P(lwb, !=, NULL); @@ -1651,8 +1651,9 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb) if (lrc->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY) { dlen = P2ROUNDUP_TYPED( lrw->lr_length, sizeof (uint64_t), uint64_t); + dpad = dlen - lrw->lr_length; } else { - dlen = 0; + dlen = dpad = 0; } reclen = lrc->lrc_reclen; zilog->zl_cur_used += (reclen + dlen); @@ -1746,6 +1747,9 @@ cont: error = zilog->zl_get_data(itx->itx_private, itx->itx_gen, lrwb, dbuf, lwb, lwb->lwb_write_zio); + if (dbuf != NULL && error == 0 && dnow == dlen) + /* Zero any padding bytes in the last block. */ + bzero((char *)dbuf + lrwb->lr_length, dpad); if (error == EIO) { txg_wait_synced(zilog->zl_dmu_pool, txg);