* [PATCH 0/2] Fix memory-corruption for passthrough metadata [not found] <CGME20230811160449epcas5p3beee9d2c65c71e95d8e92f25fb1f98c4@epcas5p3.samsung.com> @ 2023-08-11 15:59 ` Kanchan Joshi 2023-08-11 15:59 ` [PATCH 1/2] nvme: fix memory corruption " Kanchan Joshi 2023-08-11 15:59 ` [PATCH 2/2] nvme: avoid memory corruption for sync passthrough Kanchan Joshi 0 siblings, 2 replies; 5+ messages in thread From: Kanchan Joshi @ 2023-08-11 15:59 UTC (permalink / raw) To: hch, kbusch, axboe, sagi Cc: linux-nvme, vincentfu, ankit.kumar, joshiiitr, gost.dev, Kanchan Joshi Malformed user-space application can specify smaller meta-buffer and larger data-buffer. For DIX namespace, nvme-driver allocates a meta-buffer (of same small size that user specified) and that is passed to the device for DMA. Device can do DMA writes (of larger length) into unrelated kernel memory, leading to random crashes [1]. Patch 1: avoids the above for uring passthrough Patch 2: avoid the same for sync passthrough [1] [ 6815.014478] general protection fault, probably for non-canonical address 0x70e3cdbe9133b7a6: 0000 [#1] PREEMPT SMP PTI [ 6815.014505] CPU: 1 PID: 434 Comm: systemd-timesyn Tainted: G OE 6.4.0-rc3+ #5 [ 6815.014516] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [ 6815.014522] RIP: 0010:__kmem_cache_alloc_node+0x100/0x440 [ 6815.014551] Code: 48 85 c0 0f 84 fb 02 00 00 41 83 ff ff 74 10 48 8b 00 48 c1 e8 36 41 39 c7 0f 85 e5 02 00 00 41 8b 45 28 49 8b 7d 00 4c 01 e0 <48> 8b 18 48 89 c1 49 33 9d b8 00 00 00 4c 89 e0 48 0f c9 48 31 cb [ 6815.014559] RSP: 0018:ffffb510c0577d18 EFLAGS: 00010216 [ 6815.014569] RAX: 70e3cdbe9133b7a6 RBX: ffff8a9ec1042300 RCX: 0000000000000010 [ 6815.014575] RDX: 00000000048b0001 RSI: 0000000000000dc0 RDI: 0000000000037060 [ 6815.014581] RBP: ffffb510c0577d58 R08: ffffffffb9ffa280 R09: 0000000000000000 [ 6815.014586] R10: ffff8a9ecbcab1f0 R11: 0000000000000000 R12: 70e3cdbe9133b79e [ 6815.014591] R13: ffff8a9ec1042300 R14: 0000000000000dc0 R15: 00000000ffffffff [ 6815.014597] FS: 00007fce590d6940(0000) GS:ffff8a9f3dd00000(0000) knlGS:0000000000000000 [ 6815.014604] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 6815.014609] CR2: 00005579abbb6498 CR3: 000000000d9b0000 CR4: 00000000000006e0 [ 6815.014622] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 6815.014627] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 6815.014632] Call Trace: [ 6815.014650] <TASK> [ 6815.014655] ? apparmor_sk_alloc_security+0x40/0x80 [ 6815.014673] kmalloc_trace+0x2a/0xa0 [ 6815.014684] apparmor_sk_alloc_security+0x40/0x80 [ 6815.014694] security_sk_alloc+0x3f/0x60 [ 6815.014703] sk_prot_alloc+0x75/0x110 [ 6815.014712] sk_alloc+0x31/0x200 [ 6815.014721] inet_create+0xd8/0x3a0 [ 6815.014734] __sock_create+0x11b/0x220 [ 6815.014749] __sys_socket_create.part.0+0x49/0x70 [ 6815.014756] ? __secure_computing+0x94/0xf0 [ 6815.014768] __sys_socket+0x3c/0xc0 [ 6815.014776] __x64_sys_socket+0x1a/0x30 [ 6815.014783] do_syscall_64+0x3b/0x90 [ 6815.014794] entry_SYSCALL_64_after_hwframe+0x72/0xdc [ 6815.014804] RIP: 0033:0x7fce59aa795b Kanchan Joshi (2): nvme: fix memory corruption for passthrough metadata nvme: avoid memory corruption for sync passthrough drivers/nvme/host/ioctl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) -- 2.25.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] nvme: fix memory corruption for passthrough metadata 2023-08-11 15:59 ` [PATCH 0/2] Fix memory-corruption for passthrough metadata Kanchan Joshi @ 2023-08-11 15:59 ` Kanchan Joshi 2023-08-11 16:57 ` Keith Busch 2023-08-11 15:59 ` [PATCH 2/2] nvme: avoid memory corruption for sync passthrough Kanchan Joshi 1 sibling, 1 reply; 5+ messages in thread From: Kanchan Joshi @ 2023-08-11 15:59 UTC (permalink / raw) To: hch, kbusch, axboe, sagi Cc: linux-nvme, vincentfu, ankit.kumar, joshiiitr, gost.dev, Kanchan Joshi, stable, Vincent Fu User can specify a smaller meta buffer than what the device is wired to update/access. This may lead to Device doing a larger DMA operation, overwriting unrelated kernel memory. Detect this situation for uring passthrough, and bail out. Fixes: 456cba386e94 ("nvme: wire-up uring-cmd support for io-passthru on char-device") Cc: stable@vger.kernel.org Reported-by: Vincent Fu <vincent.fu@samsung.com> Signed-off-by: Kanchan Joshi <joshi.k@samsung.com> --- drivers/nvme/host/ioctl.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 19a5177bc360..fb73fa95f090 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -320,6 +320,30 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) meta_len, lower_32_bits(io.slba), NULL, 0, 0); } +static bool nvme_validate_passthru_meta(struct nvme_ctrl *ctrl, + struct nvme_ns *ns, + struct nvme_command *c, + __u64 meta, __u32 meta_len) +{ + /* + * User may specify smaller meta-buffer with a larger data-buffer. + * Driver allocated meta buffer will also be small. + * Device can do larger dma into that, overwriting unrelated kernel + * memory. + */ + if (ns && (meta_len || meta)) { + u16 nlb = lower_16_bits(le32_to_cpu(c->common.cdw12)); + + if (meta_len != (nlb + 1) * ns->ms) { + dev_err(ctrl->device, + "%s: metadata length does not match!\n", current->comm); + return false; + } + } + + return true; +} + static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, struct nvme_ns *ns, __u32 nsid) { @@ -593,6 +617,10 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, d.metadata_len = READ_ONCE(cmd->metadata_len); d.timeout_ms = READ_ONCE(cmd->timeout_ms); + if (!nvme_validate_passthru_meta(ctrl, ns, &c, d.metadata, + d.metadata_len)) + return -EINVAL; + if (issue_flags & IO_URING_F_NONBLOCK) { rq_flags |= REQ_NOWAIT; blk_flags = BLK_MQ_REQ_NOWAIT; -- 2.25.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] nvme: fix memory corruption for passthrough metadata 2023-08-11 15:59 ` [PATCH 1/2] nvme: fix memory corruption " Kanchan Joshi @ 2023-08-11 16:57 ` Keith Busch 2023-08-14 6:41 ` Kanchan Joshi 0 siblings, 1 reply; 5+ messages in thread From: Keith Busch @ 2023-08-11 16:57 UTC (permalink / raw) To: Kanchan Joshi Cc: hch, axboe, sagi, linux-nvme, vincentfu, ankit.kumar, joshiiitr, gost.dev, stable, Vincent Fu On Fri, Aug 11, 2023 at 09:29:05PM +0530, Kanchan Joshi wrote: > +static bool nvme_validate_passthru_meta(struct nvme_ctrl *ctrl, > + struct nvme_ns *ns, > + struct nvme_command *c, > + __u64 meta, __u32 meta_len) > +{ > + /* > + * User may specify smaller meta-buffer with a larger data-buffer. > + * Driver allocated meta buffer will also be small. > + * Device can do larger dma into that, overwriting unrelated kernel > + * memory. > + */ > + if (ns && (meta_len || meta)) { > + u16 nlb = lower_16_bits(le32_to_cpu(c->common.cdw12)); > + > + if (meta_len != (nlb + 1) * ns->ms) { > + dev_err(ctrl->device, > + "%s: metadata length does not match!\n", current->comm); > + return false; > + } Don't you need to check the command PRINFO PRACT bit to know if metadata length is striped/generated on the controller side? ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] nvme: fix memory corruption for passthrough metadata 2023-08-11 16:57 ` Keith Busch @ 2023-08-14 6:41 ` Kanchan Joshi 0 siblings, 0 replies; 5+ messages in thread From: Kanchan Joshi @ 2023-08-14 6:41 UTC (permalink / raw) To: Keith Busch Cc: hch, axboe, sagi, linux-nvme, vincentfu, ankit.kumar, joshiiitr, gost.dev, stable, Vincent Fu [-- Attachment #1: Type: text/plain, Size: 971 bytes --] On Fri, Aug 11, 2023 at 10:57:36AM -0600, Keith Busch wrote: >On Fri, Aug 11, 2023 at 09:29:05PM +0530, Kanchan Joshi wrote: >> +static bool nvme_validate_passthru_meta(struct nvme_ctrl *ctrl, >> + struct nvme_ns *ns, >> + struct nvme_command *c, >> + __u64 meta, __u32 meta_len) >> +{ >> + /* >> + * User may specify smaller meta-buffer with a larger data-buffer. >> + * Driver allocated meta buffer will also be small. >> + * Device can do larger dma into that, overwriting unrelated kernel >> + * memory. >> + */ >> + if (ns && (meta_len || meta)) { >> + u16 nlb = lower_16_bits(le32_to_cpu(c->common.cdw12)); >> + >> + if (meta_len != (nlb + 1) * ns->ms) { >> + dev_err(ctrl->device, >> + "%s: metadata length does not match!\n", current->comm); >> + return false; >> + } > >Don't you need to check the command PRINFO PRACT bit to know if metadata >length is striped/generated on the controller side? Good point. Will add that check in v2. [-- Attachment #2: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] nvme: avoid memory corruption for sync passthrough 2023-08-11 15:59 ` [PATCH 0/2] Fix memory-corruption for passthrough metadata Kanchan Joshi 2023-08-11 15:59 ` [PATCH 1/2] nvme: fix memory corruption " Kanchan Joshi @ 2023-08-11 15:59 ` Kanchan Joshi 1 sibling, 0 replies; 5+ messages in thread From: Kanchan Joshi @ 2023-08-11 15:59 UTC (permalink / raw) To: hch, kbusch, axboe, sagi Cc: linux-nvme, vincentfu, ankit.kumar, joshiiitr, gost.dev, Kanchan Joshi Sync passthrough metadata handling also needs to avoid the situation of device writing into unrelated kernel memory. Signed-off-by: Kanchan Joshi <joshi.k@samsung.com> --- drivers/nvme/host/ioctl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index fb73fa95f090..f7adabbc9e9f 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -388,6 +388,10 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns, c.common.cdw14 = cpu_to_le32(cmd.cdw14); c.common.cdw15 = cpu_to_le32(cmd.cdw15); + if (!nvme_validate_passthru_meta(ctrl, ns, &c, cmd.metadata, + cmd.metadata_len)) + return -EINVAL; + if (!nvme_cmd_allowed(ns, &c, 0, open_for_write)) return -EACCES; @@ -435,6 +439,10 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns, c.common.cdw14 = cpu_to_le32(cmd.cdw14); c.common.cdw15 = cpu_to_le32(cmd.cdw15); + if (!nvme_validate_passthru_meta(ctrl, ns, &c, cmd.metadata, + cmd.metadata_len)) + return -EINVAL; + if (!nvme_cmd_allowed(ns, &c, flags, open_for_write)) return -EACCES; -- 2.25.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-08-14 6:45 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20230811160449epcas5p3beee9d2c65c71e95d8e92f25fb1f98c4@epcas5p3.samsung.com>
2023-08-11 15:59 ` [PATCH 0/2] Fix memory-corruption for passthrough metadata Kanchan Joshi
2023-08-11 15:59 ` [PATCH 1/2] nvme: fix memory corruption " Kanchan Joshi
2023-08-11 16:57 ` Keith Busch
2023-08-14 6:41 ` Kanchan Joshi
2023-08-11 15:59 ` [PATCH 2/2] nvme: avoid memory corruption for sync passthrough Kanchan Joshi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox