aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorMark Johnston <[email protected]>2021-07-16 10:05:28 -0400
committerTony Hutter <[email protected]>2021-09-14 12:42:21 -0700
commit99df200ffce8a100146861295d9b1a41a5ff9104 (patch)
treeaadfa3a4b888c8cbd03da97d87d42cc1726df271 /module/zfs
parentbd910fdeb0ae36ad6d0f6d638bdd49106753ebfc (diff)
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 <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Mark Johnston <[email protected]> Closes #12383
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/zil.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/module/zfs/zil.c b/module/zfs/zil.c
index a60b0e04a..2eeb4fa4f 100644
--- a/module/zfs/zil.c
+++ b/module/zfs/zil.c
@@ -1619,7 +1619,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);
@@ -1653,8 +1653,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);
@@ -1748,6 +1749,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);