mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Preserve itx alloc size for zio_data_buf_free()
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
This commit is contained in:
		
							parent
							
								
									6db8f1a0d1
								
							
						
					
					
						commit
						4a98780933
					
				@ -394,6 +394,7 @@ typedef struct itx {
 | 
				
			|||||||
	uint8_t		itx_sync;	/* synchronous transaction */
 | 
						uint8_t		itx_sync;	/* synchronous transaction */
 | 
				
			||||||
	zil_callback_t	itx_callback;   /* Called when the itx is persistent */
 | 
						zil_callback_t	itx_callback;   /* Called when the itx is persistent */
 | 
				
			||||||
	void		*itx_callback_data; /* User data for the callback */
 | 
						void		*itx_callback_data; /* User data for the callback */
 | 
				
			||||||
 | 
						size_t		itx_size;	/* allocated itx structure size */
 | 
				
			||||||
	uint64_t	itx_oid;	/* object id */
 | 
						uint64_t	itx_oid;	/* object id */
 | 
				
			||||||
	lr_t		itx_lr;		/* common part of log record */
 | 
						lr_t		itx_lr;		/* common part of log record */
 | 
				
			||||||
	/* followed by type-specific part of lr_xx_t and its immediate data */
 | 
						/* followed by type-specific part of lr_xx_t and its immediate data */
 | 
				
			||||||
 | 
				
			|||||||
@ -1214,17 +1214,20 @@ cont:
 | 
				
			|||||||
itx_t *
 | 
					itx_t *
 | 
				
			||||||
zil_itx_create(uint64_t txtype, size_t lrsize)
 | 
					zil_itx_create(uint64_t txtype, size_t lrsize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						size_t itxsize;
 | 
				
			||||||
	itx_t *itx;
 | 
						itx_t *itx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lrsize = P2ROUNDUP_TYPED(lrsize, sizeof (uint64_t), size_t);
 | 
						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_txtype = txtype;
 | 
				
			||||||
	itx->itx_lr.lrc_reclen = lrsize;
 | 
						itx->itx_lr.lrc_reclen = lrsize;
 | 
				
			||||||
	itx->itx_lr.lrc_seq = 0;	/* defensive */
 | 
						itx->itx_lr.lrc_seq = 0;	/* defensive */
 | 
				
			||||||
	itx->itx_sync = B_TRUE;		/* default is synchronous */
 | 
						itx->itx_sync = B_TRUE;		/* default is synchronous */
 | 
				
			||||||
	itx->itx_callback = NULL;
 | 
						itx->itx_callback = NULL;
 | 
				
			||||||
	itx->itx_callback_data = NULL;
 | 
						itx->itx_callback_data = NULL;
 | 
				
			||||||
 | 
						itx->itx_size = itxsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (itx);
 | 
						return (itx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1232,7 +1235,7 @@ zil_itx_create(uint64_t txtype, size_t lrsize)
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
zil_itx_destroy(itx_t *itx)
 | 
					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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user