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: Ahriben Gonzalez <ahribeng@gmail.com>
Change-Id: I9ce5fdc413b047a1ec074468be5abf433da26d7f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10855
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Ahriben Gonzalez 2021-12-27 10:14:36 -08:00 committed by Keith Lucas
parent f98bc8f6d3
commit 72f9918bf9

View File

@ -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;