Commit 4328a67e authored by Seth Howell's avatar Seth Howell Committed by Tomasz Zawadzki
Browse files

lib/reduce: add array bounds checking for iovs.



We also need to make sure that the deconm_iov is large enough to handle
all of the iovs we claim to support plus 2, one for offset into the
chunk when doing writes and one for the remainder.
Plus a unittest to demonstrate the possible out of bounds error in the
library.

Change-Id: I7747ad39f76e50f25ecf5168b01e046f71fa0ea8
Signed-off-by: default avatarSeth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478125


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent c3fe5e4a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ struct spdk_reduce_vol_request {
	 *  the decomp engine, they point to a mix of the scratch buffer
	 *  and user buffer
	 */
	struct iovec				decomp_iov[REDUCE_MAX_IOVECS];
	struct iovec				decomp_iov[REDUCE_MAX_IOVECS + 2];
	int					decomp_iovcnt;

	/**
@@ -1376,6 +1376,10 @@ _iov_array_is_valid(struct spdk_reduce_vol *vol, struct iovec *iov, int iovcnt,
	uint64_t size = 0;
	int i;

	if (iovcnt > REDUCE_MAX_IOVECS) {
		return false;
	}

	for (i = 0; i < iovcnt; i++) {
		size += iov[i].iov_len;
	}
+40 −0
Original line number Diff line number Diff line
@@ -985,6 +985,45 @@ read_write(void)
	_read_write(4096);
}

static void
_readv_writev(uint32_t backing_blocklen)
{
	struct spdk_reduce_vol_params params = {};
	struct spdk_reduce_backing_dev backing_dev = {};
	struct iovec iov[REDUCE_MAX_IOVECS + 1];

	params.chunk_size = 16 * 1024;
	params.backing_io_unit_size = 4096;
	params.logical_block_size = 512;
	spdk_uuid_generate(&params.uuid);

	backing_dev_init(&backing_dev, &params, backing_blocklen);

	g_vol = NULL;
	g_reduce_errno = -1;
	spdk_reduce_vol_init(&params, &backing_dev, TEST_MD_PATH, init_cb, NULL);
	CU_ASSERT(g_reduce_errno == 0);
	SPDK_CU_ASSERT_FATAL(g_vol != NULL);

	g_reduce_errno = -1;
	spdk_reduce_vol_writev(g_vol, iov, REDUCE_MAX_IOVECS + 1, 2, REDUCE_MAX_IOVECS + 1, write_cb, NULL);
	CU_ASSERT(g_reduce_errno == -EINVAL);

	g_reduce_errno = -1;
	spdk_reduce_vol_unload(g_vol, unload_cb, NULL);
	CU_ASSERT(g_reduce_errno == 0);

	persistent_pm_buf_destroy();
	backing_dev_destroy(&backing_dev);
}

static void
readv_writev(void)
{
	_readv_writev(512);
	_readv_writev(4096);
}

static void
destroy_cb(void *ctx, int reduce_errno)
{
@@ -1257,6 +1296,7 @@ main(int argc, char **argv)
		CU_add_test(suite, "load", load) == NULL ||
		CU_add_test(suite, "write_maps", write_maps) == NULL ||
		CU_add_test(suite, "read_write", read_write) == NULL ||
		CU_add_test(suite, "readv_writev", readv_writev) == NULL ||
		CU_add_test(suite, "destroy", destroy) == NULL ||
		CU_add_test(suite, "defer_bdev_io", defer_bdev_io) == NULL ||
		CU_add_test(suite, "overlapped", overlapped) == NULL ||