]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Feb 2026 14:37:14 +0000 (15:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Feb 2026 14:37:14 +0000 (15:37 +0100)
added patches:
nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch
series

queue-6.12/nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch [new file with mode: 0644]
queue-6.12/series [new file with mode: 0644]

diff --git a/queue-6.12/nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch b/queue-6.12/nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch
new file mode 100644 (file)
index 0000000..b306705
--- /dev/null
@@ -0,0 +1,72 @@
+From 52a0a98549344ca20ad81a4176d68d28e3c05a5c Mon Sep 17 00:00:00 2001
+From: YunJe Shin <yjshin0438@gmail.com>
+Date: Wed, 28 Jan 2026 09:41:07 +0900
+Subject: nvmet-tcp: add bounds checks in nvmet_tcp_build_pdu_iovec
+
+From: YunJe Shin <yjshin0438@gmail.com>
+
+commit 52a0a98549344ca20ad81a4176d68d28e3c05a5c upstream.
+
+nvmet_tcp_build_pdu_iovec() could walk past cmd->req.sg when a PDU
+length or offset exceeds sg_cnt and then use bogus sg->length/offset
+values, leading to _copy_to_iter() GPF/KASAN. Guard sg_idx, remaining
+entries, and sg->length/offset before building the bvec.
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Signed-off-by: YunJe Shin <ioerts@kookmin.ac.kr>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Joonkyo Jung <joonkyoj@yonsei.ac.kr>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/target/tcp.c |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -357,11 +357,14 @@ static void nvmet_tcp_free_cmd_buffers(s
+       cmd->req.sg = NULL;
+ }
++static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue);
++
+ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
+ {
+       struct bio_vec *iov = cmd->iov;
+       struct scatterlist *sg;
+       u32 length, offset, sg_offset;
++      unsigned int sg_remaining;
+       int nr_pages;
+       length = cmd->pdu_len;
+@@ -369,9 +372,22 @@ static void nvmet_tcp_build_pdu_iovec(st
+       offset = cmd->rbytes_done;
+       cmd->sg_idx = offset / PAGE_SIZE;
+       sg_offset = offset % PAGE_SIZE;
++      if (!cmd->req.sg_cnt || cmd->sg_idx >= cmd->req.sg_cnt) {
++              nvmet_tcp_fatal_error(cmd->queue);
++              return;
++      }
+       sg = &cmd->req.sg[cmd->sg_idx];
++      sg_remaining = cmd->req.sg_cnt - cmd->sg_idx;
+       while (length) {
++              if (!sg_remaining) {
++                      nvmet_tcp_fatal_error(cmd->queue);
++                      return;
++              }
++              if (!sg->length || sg->length <= sg_offset) {
++                      nvmet_tcp_fatal_error(cmd->queue);
++                      return;
++              }
+               u32 iov_len = min_t(u32, length, sg->length - sg_offset);
+               bvec_set_page(iov, sg_page(sg), iov_len,
+@@ -379,6 +395,7 @@ static void nvmet_tcp_build_pdu_iovec(st
+               length -= iov_len;
+               sg = sg_next(sg);
++              sg_remaining--;
+               iov++;
+               sg_offset = 0;
+       }
diff --git a/queue-6.12/series b/queue-6.12/series
new file mode 100644 (file)
index 0000000..6bd96d5
--- /dev/null
@@ -0,0 +1 @@
+nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch