From 960347d3a684a0063614eb293950f8f8c7dce7e1 Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Fri, 18 Jan 2019 14:06:48 -0500 Subject: [PATCH] Fix 0 byte memory leak in zfs receive Currently, when a DRR_OBJECT record is read into memory in receive_read_record(), memory is allocated for the bonus buffer. However, if the object doesn't have a bonus buffer the code will still "allocate" the zero bytes, but the memory will not be passed to the processing thread for cleanup later. This causes the spl kmem tracking code to report a leak. This patch simply changes the code so that it only allocates this memory if it has a non-zero length. Reviewed by: Matt Ahrens Reviewed-by: Brian Behlendorf Signed-off-by: Tom Caputi Closes #8266 --- module/zfs/dmu_recv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c index 257f157fd9..4ac6f2f17f 100644 --- a/module/zfs/dmu_recv.c +++ b/module/zfs/dmu_recv.c @@ -1785,6 +1785,8 @@ receive_read_payload_and_next_header(struct receive_arg *ra, int len, void *buf) ra->rrd->payload_size = len; ra->rrd->bytes_read = ra->bytes_read; } + } else { + ASSERT3P(buf, ==, NULL); } ra->prev_cksum = ra->cksum; @@ -1936,9 +1938,12 @@ receive_read_record(struct receive_arg *ra) { struct drr_object *drro = &ra->rrd->header.drr_u.drr_object; uint32_t size = DRR_OBJECT_PAYLOAD_SIZE(drro); - void *buf = kmem_zalloc(size, KM_SLEEP); + void *buf = NULL; dmu_object_info_t doi; + if (size != 0) + buf = kmem_zalloc(size, KM_SLEEP); + err = receive_read_payload_and_next_header(ra, size, buf); if (err != 0) { kmem_free(buf, size);