]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Preserve itx alloc size for zio_data_buf_free()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 4 Dec 2017 19:44:39 +0000 (11:44 -0800)
committerTony Hutter <hutter2@llnl.gov>
Tue, 5 Dec 2017 01:21:39 +0000 (17:21 -0800)
Using zio_data_buf_alloc() to allocate the itx's may be unsafe
because the itx->itx_lr.lrc_reclen field is not constant from
allocation to free.  Using a different itx->itx_lr.lrc_reclen
size in zio_data_buf_free() can result in the allocation being
returned to the wrong kmem cache.

This issue can be avoided entirely by storing the allocation size
in itx->itx_size and using that for zio_data_buf_free().

Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #6912

include/sys/zil.h
module/zfs/zil.c

index 95fd324b4abfdcb15746dc85957f0318843e5b8e..020a0b10f1dd1e79f2996f6df9c5653295ffe942 100644 (file)
@@ -394,6 +394,7 @@ typedef struct itx {
        uint8_t         itx_sync;       /* synchronous transaction */
        zil_callback_t  itx_callback;   /* Called when the itx is persistent */
        void            *itx_callback_data; /* User data for the callback */
+       size_t          itx_size;       /* allocated itx structure size */
        uint64_t        itx_oid;        /* object id */
        lr_t            itx_lr;         /* common part of log record */
        /* followed by type-specific part of lr_xx_t and its immediate data */
index 6a1f190f5e6c20ae61a87f935162d61a86adccd5..4d714cefc758ed75b31c579756f593a37e5907c1 100644 (file)
@@ -1214,17 +1214,20 @@ cont:
 itx_t *
 zil_itx_create(uint64_t txtype, size_t lrsize)
 {
+       size_t itxsize;
        itx_t *itx;
 
        lrsize = P2ROUNDUP_TYPED(lrsize, sizeof (uint64_t), size_t);
+       itxsize = offsetof(itx_t, itx_lr) + lrsize;
 
-       itx = zio_data_buf_alloc(offsetof(itx_t, itx_lr) + lrsize);
+       itx = zio_data_buf_alloc(itxsize);
        itx->itx_lr.lrc_txtype = txtype;
        itx->itx_lr.lrc_reclen = lrsize;
        itx->itx_lr.lrc_seq = 0;        /* defensive */
        itx->itx_sync = B_TRUE;         /* default is synchronous */
        itx->itx_callback = NULL;
        itx->itx_callback_data = NULL;
+       itx->itx_size = itxsize;
 
        return (itx);
 }
@@ -1232,7 +1235,7 @@ zil_itx_create(uint64_t txtype, size_t lrsize)
 void
 zil_itx_destroy(itx_t *itx)
 {
-       zio_data_buf_free(itx, offsetof(itx_t, itx_lr)+itx->itx_lr.lrc_reclen);
+       zio_data_buf_free(itx, itx->itx_size);
 }
 
 /*