Skip to content

Commit

Permalink
ZIL: Assert record sizes on claim and replay
Browse files Browse the repository at this point in the history
This should make sure we have enough data for specific log record
types.  I.e. the log is written properly without overflows.

Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
  • Loading branch information
amotin committed Nov 12, 2023
1 parent 3a8d9b8 commit 98498c5
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
50 changes: 43 additions & 7 deletions module/zfs/zfs_replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
uint64_t dnodesize;
int error;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lracl));

txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
if (byteswap) {
byteswap_uint64_array(lracl, sizeof (*lracl));
Expand Down Expand Up @@ -470,6 +472,8 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
uint64_t dnodesize;
int error;

ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));

txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr));
Expand Down Expand Up @@ -613,6 +617,8 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
int error;
int vflg = 0;

ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -648,6 +654,8 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
int error;
int vflg = 0;

ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -715,12 +723,14 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
{
zfsvfs_t *zfsvfs = arg1;
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)
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));
}

Expand All @@ -730,12 +740,14 @@ zfs_replay_rename_exchange(void *arg1, void *arg2, boolean_t byteswap)
#ifdef __linux__
zfsvfs_t *zfsvfs = arg1;
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)
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,
NULL));
#else
Expand All @@ -750,14 +762,13 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
zfsvfs_t *zfsvfs = arg1;
lr_rename_whiteout_t *lr = arg2;
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. */
xvattr_t xva;
uint64_t objid;
uint64_t dnodesize;

ASSERT3U(lr->lr_rename.lr_common.lrc_reclen, >, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand All @@ -783,6 +794,9 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
if (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,
RENAME_WHITEOUT, &xva.xva_vattr));
#else
Expand All @@ -800,6 +814,8 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
int error;
uint64_t eod, offset, length;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -863,6 +879,8 @@ zfs_replay_write2(void *arg1, void *arg2, boolean_t byteswap)
int error;
uint64_t end;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -910,6 +928,8 @@ zfs_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
flock64_t fl = {0};
int error;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -940,6 +960,8 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
int error;
void *start;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

xva_init(&xva);
if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr));
Expand Down Expand Up @@ -1002,6 +1024,9 @@ zfs_replay_setsaxattr(void *arg1, void *arg2, boolean_t byteswap)
size_t size;
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,
SPA_FEATURE_ZILSAXATTR));
if (byteswap)
Expand Down Expand Up @@ -1079,6 +1104,10 @@ zfs_replay_acl_v0(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp;
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) {
byteswap_uint64_array(lr, sizeof (*lr));
zfs_oldace_byteswap(ace, lr->lr_aclcnt);
Expand Down Expand Up @@ -1124,6 +1153,9 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp;
int error;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));
ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr) + lr->lr_acl_bytes);

if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr));
zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE);
Expand Down Expand Up @@ -1171,6 +1203,10 @@ zfs_replay_clone_range(void *arg1, void *arg2, boolean_t byteswap)
znode_t *zp;
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)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down
7 changes: 5 additions & 2 deletions module/zfs/zil.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
lr_t *lr = (lr_t *)lrp;
reclen = lr->lrc_reclen;
ASSERT3U(reclen, >=, sizeof (lr_t));
ASSERT3U(reclen, <=, end - lrp);
if (lr->lrc_seq > claim_lr_seq) {
arc_buf_destroy(abuf, &abuf);
goto done;
Expand Down Expand Up @@ -596,7 +597,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;
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
Expand All @@ -623,7 +624,9 @@ zil_claim_clone_range(zilog_t *zilog, const lr_t *lrc, void *tx)
spa_t *spa;
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) {
return (0);
Expand Down
8 changes: 8 additions & 0 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ zvol_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
lr_truncate_t *lr = arg2;
uint64_t offset, length;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -487,6 +489,8 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap)
dmu_tx_t *tx;
int error;

ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr));

if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr));

Expand Down Expand Up @@ -540,6 +544,10 @@ zvol_replay_clone_range(void *arg1, void *arg2, boolean_t byteswap)
uint_t ii;
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);
cmn_err(CE_WARN, "ZFS dropping block cloning transaction for %s.",
name);
Expand Down

0 comments on commit 98498c5

Please sign in to comment.