From 38dd7f7403f905e3991ce64fc967234defc513d1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 12 Jun 2023 08:33:14 +0200 Subject: [PATCH] 6.3-stable patches 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 --- ...-pdu_size-in-ksmbd_conn_handler_loop.patch | 73 ++++++++++ ...ound-read-in-deassemble_neg_contexts.patch | 83 ++++++++++++ ...t-of-bound-read-in-parse_lease_state.patch | 125 ++++++++++++++++++ ...-acls-dereferencing-possible-err_ptr.patch | 72 ++++++++++ queue-6.3/series | 4 + 5 files changed, 357 insertions(+) create mode 100644 queue-6.3/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch create mode 100644 queue-6.3/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch create mode 100644 queue-6.3/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch create mode 100644 queue-6.3/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch 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 index 00000000000..77df6a449e4 --- /dev/null +++ b/queue-6.3/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch @@ -0,0 +1,73 @@ +From 368ba06881c395f1c9a7ba22203cf8d78b4addc0 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +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 + +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] +[ 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] + +Cc: stable@vger.kernel.org +Reported-by: Chih-Yen Chang +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..a2bc85727a4 --- /dev/null +++ b/queue-6.3/ksmbd-fix-out-of-bound-read-in-deassemble_neg_contexts.patch @@ -0,0 +1,83 @@ +From f1a411873c85b642f13b01f21b534c2bab81fc1b Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Sun, 28 May 2023 00:23:09 +0900 +Subject: ksmbd: fix out-of-bound read in deassemble_neg_contexts() + +From: Namjae Jeon + +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] +[ 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 +Tested-by: Chih-Yen Chang +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ead9c9d15ba --- /dev/null +++ b/queue-6.3/ksmbd-fix-out-of-bound-read-in-parse_lease_state.patch @@ -0,0 +1,125 @@ +From fc6c6a3c324c1b3e93a03d0cfa3749c781f23de0 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Sun, 28 May 2023 00:23:41 +0900 +Subject: ksmbd: fix out-of-bound read in parse_lease_state() + +From: Namjae Jeon + +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] +[ 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 +Tested-by: Chih-Yen Chang +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e6e48aa2838 --- /dev/null +++ b/queue-6.3/ksmbd-fix-posix_acls-and-acls-dereferencing-possible-err_ptr.patch @@ -0,0 +1,72 @@ +From 25933573ef48f3586f559c2cac6c436c62dcf63f Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Tue, 30 May 2023 21:42:34 +0900 +Subject: ksmbd: fix posix_acls and acls dereferencing possible ERR_PTR() + +From: Namjae Jeon + +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 +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + 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; + diff --git a/queue-6.3/series b/queue-6.3/series index 91142120da3..2f503f933db 100644 --- a/queue-6.3/series +++ b/queue-6.3/series @@ -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 -- 2.47.2