]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jun 2023 06:33:14 +0000 (08:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jun 2023 06:33:14 +0000 (08:33 +0200)
added patches:
ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch
ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch
ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch
ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch

queue-6.3/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch [new file with mode: 0644]
queue-6.3/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch [new file with mode: 0644]
queue-6.3/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch [new file with mode: 0644]
queue-6.3/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch [new file with mode: 0644]
queue-6.3/series

diff --git a/queue-6.3/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch b/queue-6.3/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch
new file mode 100644 (file)
index 0000000..77df6a4
--- /dev/null
@@ -0,0 +1,73 @@
+From 368ba06881c395f1c9a7ba22203cf8d78b4addc0 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Tue, 30 May 2023 23:10:31 +0900
+Subject: ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit 368ba06881c395f1c9a7ba22203cf8d78b4addc0 upstream.
+
+The length field of netbios header must be greater than the SMB header
+sizes(smb1 or smb2 header), otherwise the packet is an invalid SMB packet.
+
+If `pdu_size` is 0, ksmbd allocates a 4 bytes chunk to `conn->request_buf`.
+In the function `get_smb2_cmd_val` ksmbd will read cmd from
+`rcv_hdr->Command`, which is `conn->request_buf + 12`, causing the KASAN
+detector to print the following error message:
+
+[    7.205018] BUG: KASAN: slab-out-of-bounds in get_smb2_cmd_val+0x45/0x60
+[    7.205423] Read of size 2 at addr ffff8880062d8b50 by task ksmbd:42632/248
+...
+[    7.207125]  <TASK>
+[    7.209191]  get_smb2_cmd_val+0x45/0x60
+[    7.209426]  ksmbd_conn_enqueue_request+0x3a/0x100
+[    7.209712]  ksmbd_server_process_request+0x72/0x160
+[    7.210295]  ksmbd_conn_handler_loop+0x30c/0x550
+[    7.212280]  kthread+0x160/0x190
+[    7.212762]  ret_from_fork+0x1f/0x30
+[    7.212981]  </TASK>
+
+Cc: stable@vger.kernel.org
+Reported-by: Chih-Yen Chang <cc85nod@gmail.com>
+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/ksmbd/connection.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -294,6 +294,9 @@ bool ksmbd_conn_alive(struct ksmbd_conn
+       return true;
+ }
++#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr))
++#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)
++
+ /**
+  * ksmbd_conn_handler_loop() - session thread to listen on new smb requests
+  * @p:                connection instance
+@@ -350,6 +353,9 @@ int ksmbd_conn_handler_loop(void *p)
+               if (pdu_size > MAX_STREAM_PROT_LEN)
+                       break;
++              if (pdu_size < SMB1_MIN_SUPPORTED_HEADER_SIZE)
++                      break;
++
+               /* 4 for rfc1002 length field */
+               /* 1 for implied bcc[0] */
+               size = pdu_size + 4 + 1;
+@@ -377,6 +383,12 @@ int ksmbd_conn_handler_loop(void *p)
+                       continue;
+               }
++              if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
++                  SMB2_PROTO_NUMBER) {
++                      if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
++                              break;
++              }
++
+               if (!default_conn_ops.process_fn) {
+                       pr_err("No connection request callback\n");
+                       break;
diff --git a/queue-6.3/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch b/queue-6.3/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch
new file mode 100644 (file)
index 0000000..a2bc857
--- /dev/null
@@ -0,0 +1,83 @@
+From f1a411873c85b642f13b01f21b534c2bab81fc1b Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sun, 28 May 2023 00:23:09 +0900
+Subject: ksmbd: fix out-of-bound read in deassemble_neg_contexts()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit f1a411873c85b642f13b01f21b534c2bab81fc1b upstream.
+
+The check in the beginning is
+`clen + sizeof(struct smb2_neg_context) <= len_of_ctxts`,
+but in the end of loop, `len_of_ctxts` will subtract
+`((clen + 7) & ~0x7) + sizeof(struct smb2_neg_context)`, which causes
+integer underflow when clen does the 8 alignment. We should use
+`(clen + 7) & ~0x7` in the check to avoid underflow from happening.
+
+Then there are some variables that need to be declared unsigned
+instead of signed.
+
+[   11.671070] BUG: KASAN: slab-out-of-bounds in smb2_handle_negotiate+0x799/0x1610
+[   11.671533] Read of size 2 at addr ffff888005e86cf2 by task kworker/0:0/7
+...
+[   11.673383] Call Trace:
+[   11.673541]  <TASK>
+[   11.673679]  dump_stack_lvl+0x33/0x50
+[   11.673913]  print_report+0xcc/0x620
+[   11.674671]  kasan_report+0xae/0xe0
+[   11.675171]  kasan_check_range+0x35/0x1b0
+[   11.675412]  smb2_handle_negotiate+0x799/0x1610
+[   11.676217]  ksmbd_smb_negotiate_common+0x526/0x770
+[   11.676795]  handle_ksmbd_work+0x274/0x810
+...
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Chih-Yen Chang <cc85nod@gmail.com>
+Tested-by: Chih-Yen Chang <cc85nod@gmail.com>
+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/ksmbd/smb2pdu.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -991,13 +991,13 @@ static void decode_sign_cap_ctxt(struct
+ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
+                                     struct smb2_negotiate_req *req,
+-                                    int len_of_smb)
++                                    unsigned int len_of_smb)
+ {
+       /* +4 is to account for the RFC1001 len field */
+       struct smb2_neg_context *pctx = (struct smb2_neg_context *)req;
+       int i = 0, len_of_ctxts;
+-      int offset = le32_to_cpu(req->NegotiateContextOffset);
+-      int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
++      unsigned int offset = le32_to_cpu(req->NegotiateContextOffset);
++      unsigned int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
+       __le32 status = STATUS_INVALID_PARAMETER;
+       ksmbd_debug(SMB, "decoding %d negotiate contexts\n", neg_ctxt_cnt);
+@@ -1011,7 +1011,7 @@ static __le32 deassemble_neg_contexts(st
+       while (i++ < neg_ctxt_cnt) {
+               int clen, ctxt_len;
+-              if (len_of_ctxts < sizeof(struct smb2_neg_context))
++              if (len_of_ctxts < (int)sizeof(struct smb2_neg_context))
+                       break;
+               pctx = (struct smb2_neg_context *)((char *)pctx + offset);
+@@ -1066,9 +1066,8 @@ static __le32 deassemble_neg_contexts(st
+               }
+               /* offsets must be 8 byte aligned */
+-              clen = (clen + 7) & ~0x7;
+-              offset = clen + sizeof(struct smb2_neg_context);
+-              len_of_ctxts -= clen + sizeof(struct smb2_neg_context);
++              offset = (ctxt_len + 7) & ~0x7;
++              len_of_ctxts -= offset;
+       }
+       return status;
+ }
diff --git a/queue-6.3/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch b/queue-6.3/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch
new file mode 100644 (file)
index 0000000..ead9c9d
--- /dev/null
@@ -0,0 +1,125 @@
+From fc6c6a3c324c1b3e93a03d0cfa3749c781f23de0 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sun, 28 May 2023 00:23:41 +0900
+Subject: ksmbd: fix out-of-bound read in parse_lease_state()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit fc6c6a3c324c1b3e93a03d0cfa3749c781f23de0 upstream.
+
+This bug is in parse_lease_state, and it is caused by the missing check
+of `struct create_context`. When the ksmbd traverses the create_contexts,
+it doesn't check if the field of `NameOffset` and `Next` is valid,
+The KASAN message is following:
+
+[    6.664323] BUG: KASAN: slab-out-of-bounds in parse_lease_state+0x7d/0x280
+[    6.664738] Read of size 2 at addr ffff888005c08988 by task kworker/0:3/103
+...
+[    6.666644] Call Trace:
+[    6.666796]  <TASK>
+[    6.666933]  dump_stack_lvl+0x33/0x50
+[    6.667167]  print_report+0xcc/0x620
+[    6.667903]  kasan_report+0xae/0xe0
+[    6.668374]  kasan_check_range+0x35/0x1b0
+[    6.668621]  parse_lease_state+0x7d/0x280
+[    6.668868]  smb2_open+0xbe8/0x4420
+[    6.675137]  handle_ksmbd_work+0x282/0x820
+
+Use smb2_find_context_vals() to find smb2 create request lease context.
+smb2_find_context_vals validate create context fields.
+
+Cc: stable@vger.kernel.org
+Reported-by: Chih-Yen Chang <cc85nod@gmail.com>
+Tested-by: Chih-Yen Chang <cc85nod@gmail.com>
+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/ksmbd/oplock.c |   70 ++++++++++++++++++++----------------------------------
+ 1 file changed, 26 insertions(+), 44 deletions(-)
+
+--- a/fs/ksmbd/oplock.c
++++ b/fs/ksmbd/oplock.c
+@@ -1415,56 +1415,38 @@ void create_lease_buf(u8 *rbuf, struct l
+  */
+ struct lease_ctx_info *parse_lease_state(void *open_req)
+ {
+-      char *data_offset;
+       struct create_context *cc;
+-      unsigned int next = 0;
+-      char *name;
+-      bool found = false;
+       struct smb2_create_req *req = (struct smb2_create_req *)open_req;
+-      struct lease_ctx_info *lreq = kzalloc(sizeof(struct lease_ctx_info),
+-              GFP_KERNEL);
++      struct lease_ctx_info *lreq;
++
++      cc = smb2_find_context_vals(req, SMB2_CREATE_REQUEST_LEASE, 4);
++      if (IS_ERR_OR_NULL(cc))
++              return NULL;
++
++      lreq = kzalloc(sizeof(struct lease_ctx_info), GFP_KERNEL);
+       if (!lreq)
+               return NULL;
+-      data_offset = (char *)req + le32_to_cpu(req->CreateContextsOffset);
+-      cc = (struct create_context *)data_offset;
+-      do {
+-              cc = (struct create_context *)((char *)cc + next);
+-              name = le16_to_cpu(cc->NameOffset) + (char *)cc;
+-              if (le16_to_cpu(cc->NameLength) != 4 ||
+-                  strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
+-                      next = le32_to_cpu(cc->Next);
+-                      continue;
+-              }
+-              found = true;
+-              break;
+-      } while (next != 0);
+-
+-      if (found) {
+-              if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
+-                      struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
+-
+-                      memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
+-                      lreq->req_state = lc->lcontext.LeaseState;
+-                      lreq->flags = lc->lcontext.LeaseFlags;
+-                      lreq->duration = lc->lcontext.LeaseDuration;
+-                      memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
+-                             SMB2_LEASE_KEY_SIZE);
+-                      lreq->version = 2;
+-              } else {
+-                      struct create_lease *lc = (struct create_lease *)cc;
+-
+-                      memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
+-                      lreq->req_state = lc->lcontext.LeaseState;
+-                      lreq->flags = lc->lcontext.LeaseFlags;
+-                      lreq->duration = lc->lcontext.LeaseDuration;
+-                      lreq->version = 1;
+-              }
+-              return lreq;
+-      }
++      if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
++              struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
+-      kfree(lreq);
+-      return NULL;
++              memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
++              lreq->req_state = lc->lcontext.LeaseState;
++              lreq->flags = lc->lcontext.LeaseFlags;
++              lreq->duration = lc->lcontext.LeaseDuration;
++              memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
++                              SMB2_LEASE_KEY_SIZE);
++              lreq->version = 2;
++      } else {
++              struct create_lease *lc = (struct create_lease *)cc;
++
++              memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
++              lreq->req_state = lc->lcontext.LeaseState;
++              lreq->flags = lc->lcontext.LeaseFlags;
++              lreq->duration = lc->lcontext.LeaseDuration;
++              lreq->version = 1;
++      }
++      return lreq;
+ }
+ /**
diff --git a/queue-6.3/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch b/queue-6.3/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch
new file mode 100644 (file)
index 0000000..e6e48aa
--- /dev/null
@@ -0,0 +1,72 @@
+From 25933573ef48f3586f559c2cac6c436c62dcf63f Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Tue, 30 May 2023 21:42:34 +0900
+Subject: ksmbd: fix posix_acls and acls dereferencing possible ERR_PTR()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit 25933573ef48f3586f559c2cac6c436c62dcf63f upstream.
+
+Dan reported the following error message:
+
+fs/smb/server/smbacl.c:1296 smb_check_perm_dacl()
+    error: 'posix_acls' dereferencing possible ERR_PTR()
+fs/smb/server/vfs.c:1323 ksmbd_vfs_make_xattr_posix_acl()
+    error: 'posix_acls' dereferencing possible ERR_PTR()
+fs/smb/server/vfs.c:1830 ksmbd_vfs_inherit_posix_acl()
+    error: 'acls' dereferencing possible ERR_PTR()
+
+__get_acl() returns a mix of error pointers and NULL. This change it
+with IS_ERR_OR_NULL().
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Cc: stable@vger.kernel.org
+Reported-by: Dan Carpenter <dan.carpenter@linaro.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/ksmbd/smbacl.c |    4 ++--
+ fs/ksmbd/vfs.c    |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ksmbd/smbacl.c
++++ b/fs/ksmbd/smbacl.c
+@@ -1290,7 +1290,7 @@ int smb_check_perm_dacl(struct ksmbd_con
+       if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
+               posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
+-              if (posix_acls && !found) {
++              if (!IS_ERR_OR_NULL(posix_acls) && !found) {
+                       unsigned int id = -1;
+                       pa_entry = posix_acls->a_entries;
+@@ -1314,7 +1314,7 @@ int smb_check_perm_dacl(struct ksmbd_con
+                               }
+                       }
+               }
+-              if (posix_acls)
++              if (!IS_ERR_OR_NULL(posix_acls))
+                       posix_acl_release(posix_acls);
+       }
+--- a/fs/ksmbd/vfs.c
++++ b/fs/ksmbd/vfs.c
+@@ -1377,7 +1377,7 @@ static struct xattr_smb_acl *ksmbd_vfs_m
+               return NULL;
+       posix_acls = get_inode_acl(inode, acl_type);
+-      if (!posix_acls)
++      if (IS_ERR_OR_NULL(posix_acls))
+               return NULL;
+       smb_acl = kzalloc(sizeof(struct xattr_smb_acl) +
+@@ -1886,7 +1886,7 @@ int ksmbd_vfs_inherit_posix_acl(struct m
+               return -EOPNOTSUPP;
+       acls = get_inode_acl(parent_inode, ACL_TYPE_DEFAULT);
+-      if (!acls)
++      if (IS_ERR_OR_NULL(acls))
+               return -ENOENT;
+       pace = acls->a_entries;
index 91142120da32523712e4ceab807c56f3ad47650f..2f503f933db0180376b971f8e4256b5c12c909d5 100644 (file)
@@ -146,3 +146,7 @@ vduse-avoid-empty-string-for-dev-name.patch
 vdpa-mlx5-fix-hang-when-cvq-commands-are-triggered-d.patch
 vhost-support-packed-when-setting-getting-vring_base.patch
 vhost_vdpa-support-packed-when-setting-getting-vring.patch
+ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch
+ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch
+ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch
+ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch