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:
parent
f98bc8f6d3
commit
72f9918bf9
@ -99,6 +99,23 @@ cuse_io_ctx_free(struct cuse_io_ctx *ctx)
|
|||||||
return; \
|
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
|
static void
|
||||||
cuse_nvme_passthru_cmd_cb(void *arg, const struct spdk_nvme_cpl *cpl)
|
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 */
|
/* 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_base = &((struct nvme_passthru_cmd *)arg)->result;
|
||||||
out_iov[out_iovcnt].iov_len = sizeof(uint32_t);
|
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) {
|
if (out_bufsz == 0) {
|
||||||
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
|
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
|
||||||
return;
|
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_iov[out_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
|
||||||
out_iovcnt += 1;
|
out_iovcnt += 1;
|
||||||
}
|
}
|
||||||
|
if (!fuse_check_req_size(req, out_iov, out_iovcnt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (out_bufsz == 0) {
|
if (out_bufsz == 0) {
|
||||||
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
|
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
|
||||||
return;
|
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_iov[in_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
|
||||||
in_iovcnt += 1;
|
in_iovcnt += 1;
|
||||||
}
|
}
|
||||||
|
if (!fuse_check_req_size(req, in_iov, in_iovcnt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (in_bufsz == sizeof(*user_io)) {
|
if (in_bufsz == sizeof(*user_io)) {
|
||||||
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, out_iovcnt);
|
fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, out_iovcnt);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user