From 1ee95fdfb1af0611614020ee30decb449f868132 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Jul 2023 19:53:39 +0200 Subject: [PATCH] 5.15-stable patches added patches: ksmbd-fix-out-of-bound-read-in-smb2_write.patch ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch ksmbd-validate-command-payload-size.patch ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch --- ...-fix-out-of-bound-read-in-smb2_write.patch | 47 ++++++ ...buf_next-in-ksmbd_smb2_check_message.patch | 47 ++++++ .../ksmbd-validate-command-payload-size.patch | 89 ++++++++++ ...-and-tree-id-in-the-compound-request.patch | 159 ++++++++++++++++++ queue-5.15/series | 4 + 5 files changed, 346 insertions(+) create mode 100644 queue-5.15/ksmbd-fix-out-of-bound-read-in-smb2_write.patch create mode 100644 queue-5.15/ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch create mode 100644 queue-5.15/ksmbd-validate-command-payload-size.patch create mode 100644 queue-5.15/ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch diff --git a/queue-5.15/ksmbd-fix-out-of-bound-read-in-smb2_write.patch b/queue-5.15/ksmbd-fix-out-of-bound-read-in-smb2_write.patch new file mode 100644 index 00000000000..38c293077a5 --- /dev/null +++ b/queue-5.15/ksmbd-fix-out-of-bound-read-in-smb2_write.patch @@ -0,0 +1,47 @@ +From stable-owner@vger.kernel.org Thu Jul 20 15:25:37 2023 +From: Namjae Jeon +Date: Thu, 20 Jul 2023 22:23:30 +0900 +Subject: ksmbd: fix out-of-bound read in smb2_write +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, stfrench@microsoft.com, smfrench@gmail.com, Namjae Jeon , zdi-disclosures@trendmicro.com +Message-ID: <20230720132336.7614-4-linkinjeon@kernel.org> + +From: Namjae Jeon + +commit 5fe7f7b78290638806211046a99f031ff26164e1 upstream. + +ksmbd_smb2_check_message doesn't validate hdr->NextCommand. If +->NextCommand is bigger than Offset + Length of smb2 write, It will +allow oversized smb2 write length. It will cause OOB read in smb2_write. + +Cc: stable@vger.kernel.org +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21164 +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/smb2misc.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -352,10 +352,16 @@ int ksmbd_smb2_check_message(struct ksmb + int command; + __u32 clc_len; /* calculated length */ + __u32 len = get_rfc1002_len(work->request_buf); +- __u32 req_struct_size; ++ __u32 req_struct_size, next_cmd = le32_to_cpu(hdr->NextCommand); + +- if (le32_to_cpu(hdr->NextCommand) > 0) +- len = le32_to_cpu(hdr->NextCommand); ++ if ((u64)work->next_smb2_rcv_hdr_off + next_cmd > len) { ++ pr_err("next command(%u) offset exceeds smb msg size\n", ++ next_cmd); ++ return 1; ++ } ++ ++ if (next_cmd > 0) ++ len = next_cmd; + else if (work->next_smb2_rcv_hdr_off) + len -= work->next_smb2_rcv_hdr_off; + diff --git a/queue-5.15/ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch b/queue-5.15/ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch new file mode 100644 index 00000000000..a6f94bfe6f9 --- /dev/null +++ b/queue-5.15/ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch @@ -0,0 +1,47 @@ +From stable-owner@vger.kernel.org Thu Jul 20 15:25:31 2023 +From: Namjae Jeon +Date: Thu, 20 Jul 2023 22:23:28 +0900 +Subject: ksmbd: use ksmbd_req_buf_next() in ksmbd_smb2_check_message() +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, stfrench@microsoft.com, smfrench@gmail.com, Namjae Jeon , Ralph Boehme , Tom Talpey , Ronnie Sahlberg , Hyunchul Lee +Message-ID: <20230720132336.7614-2-linkinjeon@kernel.org> + +From: Ralph Boehme + +commit b83b27909e74d27796de19c802fbc3b65ab4ba9a upstream. + +Use ksmbd_req_buf_next() in ksmbd_smb2_check_message(). + +Cc: Tom Talpey +Cc: Ronnie Sahlberg +Cc: Steve French +Cc: Hyunchul Lee +Acked-by: Namjae Jeon +Signed-off-by: Ralph Boehme +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/smb2misc.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -347,16 +347,11 @@ static int smb2_validate_credit_charge(s + + int ksmbd_smb2_check_message(struct ksmbd_work *work) + { +- struct smb2_pdu *pdu = work->request_buf; ++ struct smb2_pdu *pdu = ksmbd_req_buf_next(work); + struct smb2_hdr *hdr = &pdu->hdr; + int command; + __u32 clc_len; /* calculated length */ +- __u32 len = get_rfc1002_len(pdu); +- +- if (work->next_smb2_rcv_hdr_off) { +- pdu = ksmbd_req_buf_next(work); +- hdr = &pdu->hdr; +- } ++ __u32 len = get_rfc1002_len(work->request_buf); + + if (le32_to_cpu(hdr->NextCommand) > 0) + len = le32_to_cpu(hdr->NextCommand); diff --git a/queue-5.15/ksmbd-validate-command-payload-size.patch b/queue-5.15/ksmbd-validate-command-payload-size.patch new file mode 100644 index 00000000000..4726d2b1249 --- /dev/null +++ b/queue-5.15/ksmbd-validate-command-payload-size.patch @@ -0,0 +1,89 @@ +From stable-owner@vger.kernel.org Thu Jul 20 15:25:32 2023 +From: Namjae Jeon +Date: Thu, 20 Jul 2023 22:23:29 +0900 +Subject: ksmbd: validate command payload size +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, stfrench@microsoft.com, smfrench@gmail.com, Namjae Jeon , Chih-Yen Chang +Message-ID: <20230720132336.7614-3-linkinjeon@kernel.org> + +From: Namjae Jeon + +commit 2b9b8f3b68edb3d67d79962f02e26dbb5ae3808d upstream. + +->StructureSize2 indicates command payload size. ksmbd should validate +this size with rfc1002 length before accessing it. +This patch remove unneeded check and add the validation for this. + +[ 8.912583] BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message+0x12a/0xc50 +[ 8.913051] Read of size 2 at addr ffff88800ac7d92c by task kworker/0:0/7 +... +[ 8.914967] Call Trace: +[ 8.915126] +[ 8.915267] dump_stack_lvl+0x33/0x50 +[ 8.915506] print_report+0xcc/0x620 +[ 8.916558] kasan_report+0xae/0xe0 +[ 8.917080] kasan_check_range+0x35/0x1b0 +[ 8.917334] ksmbd_smb2_check_message+0x12a/0xc50 +[ 8.917935] ksmbd_verify_smb_message+0xae/0xd0 +[ 8.918223] handle_ksmbd_work+0x192/0x820 +[ 8.918478] process_one_work+0x419/0x760 +[ 8.918727] worker_thread+0x2a2/0x6f0 +[ 8.919222] kthread+0x187/0x1d0 +[ 8.919723] ret_from_fork+0x1f/0x30 +[ 8.919954] + +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/smb2misc.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -352,6 +352,7 @@ int ksmbd_smb2_check_message(struct ksmb + int command; + __u32 clc_len; /* calculated length */ + __u32 len = get_rfc1002_len(work->request_buf); ++ __u32 req_struct_size; + + if (le32_to_cpu(hdr->NextCommand) > 0) + len = le32_to_cpu(hdr->NextCommand); +@@ -374,17 +375,9 @@ int ksmbd_smb2_check_message(struct ksmb + } + + if (smb2_req_struct_sizes[command] != pdu->StructureSize2) { +- if (command != SMB2_OPLOCK_BREAK_HE && +- (hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) { +- /* error packets have 9 byte structure size */ +- ksmbd_debug(SMB, +- "Illegal request size %u for command %d\n", +- le16_to_cpu(pdu->StructureSize2), command); +- return 1; +- } else if (command == SMB2_OPLOCK_BREAK_HE && +- hdr->Status == 0 && +- le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 && +- le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { ++ if (command == SMB2_OPLOCK_BREAK_HE && ++ le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 && ++ le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { + /* special case for SMB2.1 lease break message */ + ksmbd_debug(SMB, + "Illegal request size %d for oplock break\n", +@@ -393,6 +386,14 @@ int ksmbd_smb2_check_message(struct ksmb + } + } + ++ req_struct_size = le16_to_cpu(pdu->StructureSize2) + ++ __SMB2_HEADER_STRUCTURE_SIZE; ++ if (command == SMB2_LOCK_HE) ++ req_struct_size -= sizeof(struct smb2_lock_element); ++ ++ if (req_struct_size > len + 1) ++ return 1; ++ + if (smb2_calc_size(hdr, &clc_len)) + return 1; + diff --git a/queue-5.15/ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch b/queue-5.15/ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch new file mode 100644 index 00000000000..a692d04c07f --- /dev/null +++ b/queue-5.15/ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch @@ -0,0 +1,159 @@ +From stable-owner@vger.kernel.org Thu Jul 20 15:25:40 2023 +From: Namjae Jeon +Date: Thu, 20 Jul 2023 22:23:31 +0900 +Subject: ksmbd: validate session id and tree id in the compound request +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, stfrench@microsoft.com, smfrench@gmail.com, Namjae Jeon , zdi-disclosures@trendmicro.com +Message-ID: <20230720132336.7614-5-linkinjeon@kernel.org> + +From: Namjae Jeon + +commit 5005bcb4219156f1bf7587b185080ec1da08518e upstream. + +This patch validate session id and tree id in compound request. +If first operation in the compound is SMB2 ECHO request, ksmbd bypass +session and tree validation. So work->sess and work->tcon could be NULL. +If secound request in the compound access work->sess or tcon, It cause +NULL pointer dereferecing error. + +Cc: stable@vger.kernel.org +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21165 +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/server.c | 33 ++++++++++++++++++++------------- + fs/ksmbd/smb2pdu.c | 44 +++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 59 insertions(+), 18 deletions(-) + +--- a/fs/ksmbd/server.c ++++ b/fs/ksmbd/server.c +@@ -184,24 +184,31 @@ static void __handle_ksmbd_work(struct k + goto send; + } + +- if (conn->ops->check_user_session) { +- rc = conn->ops->check_user_session(work); +- if (rc < 0) { +- command = conn->ops->get_cmd_val(work); +- conn->ops->set_rsp_status(work, +- STATUS_USER_SESSION_DELETED); +- goto send; +- } else if (rc > 0) { +- rc = conn->ops->get_ksmbd_tcon(work); ++ do { ++ if (conn->ops->check_user_session) { ++ rc = conn->ops->check_user_session(work); + if (rc < 0) { +- conn->ops->set_rsp_status(work, +- STATUS_NETWORK_NAME_DELETED); ++ if (rc == -EINVAL) ++ conn->ops->set_rsp_status(work, ++ STATUS_INVALID_PARAMETER); ++ else ++ conn->ops->set_rsp_status(work, ++ STATUS_USER_SESSION_DELETED); + goto send; ++ } else if (rc > 0) { ++ rc = conn->ops->get_ksmbd_tcon(work); ++ if (rc < 0) { ++ if (rc == -EINVAL) ++ conn->ops->set_rsp_status(work, ++ STATUS_INVALID_PARAMETER); ++ else ++ conn->ops->set_rsp_status(work, ++ STATUS_NETWORK_NAME_DELETED); ++ goto send; ++ } + } + } +- } + +- do { + rc = __process_request(work, conn, &command); + if (rc == SERVER_HANDLER_ABORT) + break; +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -97,7 +97,6 @@ int smb2_get_ksmbd_tcon(struct ksmbd_wor + struct smb2_hdr *req_hdr = work->request_buf; + int tree_id; + +- work->tcon = NULL; + if (work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE || + work->conn->ops->get_cmd_val(work) == SMB2_CANCEL_HE || + work->conn->ops->get_cmd_val(work) == SMB2_LOGOFF_HE) { +@@ -111,10 +110,28 @@ int smb2_get_ksmbd_tcon(struct ksmbd_wor + } + + tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId); ++ ++ /* ++ * If request is not the first in Compound request, ++ * Just validate tree id in header with work->tcon->id. ++ */ ++ if (work->next_smb2_rcv_hdr_off) { ++ if (!work->tcon) { ++ pr_err("The first operation in the compound does not have tcon\n"); ++ return -EINVAL; ++ } ++ if (work->tcon->id != tree_id) { ++ pr_err("tree id(%u) is different with id(%u) in first operation\n", ++ tree_id, work->tcon->id); ++ return -EINVAL; ++ } ++ return 1; ++ } ++ + work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id); + if (!work->tcon) { + pr_err("Invalid tid %d\n", tree_id); +- return -EINVAL; ++ return -ENOENT; + } + + return 1; +@@ -569,7 +586,6 @@ int smb2_check_user_session(struct ksmbd + unsigned int cmd = conn->ops->get_cmd_val(work); + unsigned long long sess_id; + +- work->sess = NULL; + /* + * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not + * require a session id, so no need to validate user session's for +@@ -580,15 +596,33 @@ int smb2_check_user_session(struct ksmbd + return 0; + + if (!ksmbd_conn_good(work)) +- return -EINVAL; ++ return -EIO; + + sess_id = le64_to_cpu(req_hdr->SessionId); ++ ++ /* ++ * If request is not the first in Compound request, ++ * Just validate session id in header with work->sess->id. ++ */ ++ if (work->next_smb2_rcv_hdr_off) { ++ if (!work->sess) { ++ pr_err("The first operation in the compound does not have sess\n"); ++ return -EINVAL; ++ } ++ if (work->sess->id != sess_id) { ++ pr_err("session id(%llu) is different with the first operation(%lld)\n", ++ sess_id, work->sess->id); ++ return -EINVAL; ++ } ++ return 1; ++ } ++ + /* Check for validity of user session */ + work->sess = ksmbd_session_lookup_all(conn, sess_id); + if (work->sess) + return 1; + ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id); +- return -EINVAL; ++ return -ENOENT; + } + + static void destroy_previous_session(struct ksmbd_conn *conn, diff --git a/queue-5.15/series b/queue-5.15/series index ac0d9c24a17..e9d3b51ccd0 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -388,6 +388,10 @@ io_uring-use-io_schedule-in-cqring-wait.patch io_uring-add-reschedule-point-to-handle_tw_list.patch net-lan743x-don-t-sleep-in-atomic-context.patch workqueue-clean-up-work_-constant-types-clarify-masking.patch +ksmbd-use-ksmbd_req_buf_next-in-ksmbd_smb2_check_message.patch +ksmbd-validate-command-payload-size.patch +ksmbd-fix-out-of-bound-read-in-smb2_write.patch +ksmbd-validate-session-id-and-tree-id-in-the-compound-request.patch drm-panel-simple-add-connector_type-for-innolux_at04.patch drm-bridge-ti-sn65dsi86-fix-auxiliary-bus-lifetime.patch drm-panel-simple-add-powertip-ph800480t013-drm_displ.patch -- 2.47.3