Commit 93ef69ef authored by Ahriben Gonzalez's avatar Ahriben Gonzalez Committed by Tomasz Zawadzki
Browse files

nvme: Add Check for fuse request size



FUSE has a limitation of 128KiB. Adding a check that returns ENOMEM for
ioctl and logs the error. Applies to both in and out buffers

Signed-off-by: default avatarAhriben Gonzalez <ahribeng@gmail.com>
Change-Id: I9ce5fdc413b047a1ec074468be5abf433da26d7f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10855


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarMichael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent 0345729e
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -99,6 +99,23 @@ cuse_io_ctx_free(struct cuse_io_ctx *ctx)
		return;							\
	}

#define FUSE_MAX_SIZE 128*1024

static bool
fuse_check_req_size(fuse_req_t req, struct iovec iov[], int iovcnt)
{
	int total_iov_len = 0;
	for (int i = 0; i < iovcnt; i++) {
		total_iov_len += iov[i].iov_len;
		if (total_iov_len > FUSE_MAX_SIZE) {
			fuse_reply_err(req, ENOMEM);
			SPDK_ERRLOG("FUSE request cannot be larger that %d\n", FUSE_MAX_SIZE);
			return false;
		}
	}
	return true;
}

static void
cuse_nvme_passthru_cmd_cb(void *arg, const struct spdk_nvme_cpl *cpl)
{
@@ -259,6 +276,9 @@ cuse_nvme_passthru_cmd(fuse_req_t req, int cmd, void *arg,
		}
	}

	if (!fuse_check_req_size(req, in_iov, in_iovcnt)) {
		return;
	}
	/* Always make result field writeable regardless of data transfer bits */
	out_iov[out_iovcnt].iov_base = &((struct nvme_passthru_cmd *)arg)->result;
	out_iov[out_iovcnt].iov_len = sizeof(uint32_t);
@@ -279,6 +299,10 @@ cuse_nvme_passthru_cmd(fuse_req_t req, int cmd, void *arg,
		}
	}

	if (!fuse_check_req_size(req, out_iov, out_iovcnt)) {
		return;
	}

	if (out_bufsz == 0) {
		fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
		return;
@@ -619,6 +643,9 @@ cuse_nvme_submit_io(fuse_req_t req, int cmd, void *arg,
			out_iov[out_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
			out_iovcnt += 1;
		}
		if (!fuse_check_req_size(req, out_iov, out_iovcnt)) {
			return;
		}
		if (out_bufsz == 0) {
			fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
			return;
@@ -636,6 +663,9 @@ cuse_nvme_submit_io(fuse_req_t req, int cmd, void *arg,
			in_iov[in_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
			in_iovcnt += 1;
		}
		if (!fuse_check_req_size(req, in_iov, in_iovcnt)) {
			return;
		}
		if (in_bufsz == sizeof(*user_io)) {
			fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, out_iovcnt);
			return;