]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blobdiff - queue-6.6/ksmbd-fix-slab-out-of-bounds-in-smb2_allocate_rsp_buf.patch
6.6-stable patches
[thirdparty/kernel/stable-queue.git] / queue-6.6 / ksmbd-fix-slab-out-of-bounds-in-smb2_allocate_rsp_buf.patch
diff --git a/queue-6.6/ksmbd-fix-slab-out-of-bounds-in-smb2_allocate_rsp_buf.patch b/queue-6.6/ksmbd-fix-slab-out-of-bounds-in-smb2_allocate_rsp_buf.patch
new file mode 100644 (file)
index 0000000..45c4eec
--- /dev/null
@@ -0,0 +1,53 @@
+From c119f4ede3fa90a9463f50831761c28f989bfb20 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Thu, 11 Apr 2024 23:02:15 +0900
+Subject: ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit c119f4ede3fa90a9463f50831761c28f989bfb20 upstream.
+
+If ->ProtocolId is SMB2_TRANSFORM_PROTO_NUM, smb2 request size
+validation could be skipped. if request size is smaller than
+sizeof(struct smb2_query_info_req), slab-out-of-bounds read can happen in
+smb2_allocate_rsp_buf(). This patch allocate response buffer after
+decrypting transform request. smb3_decrypt_req() will validate transform
+request size and avoid slab-out-of-bound in smb2_allocate_rsp_buf().
+
+Reported-by: Norbert Szetei <norbert@doyensec.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/server.c |   13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/server/server.c
++++ b/fs/smb/server/server.c
+@@ -167,20 +167,17 @@ static void __handle_ksmbd_work(struct k
+       int rc;
+       bool is_chained = false;
+-      if (conn->ops->allocate_rsp_buf(work))
+-              return;
+-
+       if (conn->ops->is_transform_hdr &&
+           conn->ops->is_transform_hdr(work->request_buf)) {
+               rc = conn->ops->decrypt_req(work);
+-              if (rc < 0) {
+-                      conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+-                      goto send;
+-              }
+-
++              if (rc < 0)
++                      return;
+               work->encrypted = true;
+       }
++      if (conn->ops->allocate_rsp_buf(work))
++              return;
++
+       rc = conn->ops->init_rsp_hdr(work);
+       if (rc) {
+               /* either uid or tid is not correct */