[PATCH OLK-5.10 0/6] ksmbd: fix cve issues

This patch set fix three ksmbd cve issue. Dawei Li (1): ksmbd: Remove duplicated codes Namjae Jeon (3): ksmbd: validate mech token in session setup ksmbd: validate session id and tree id in compound request ksmbd: fix UAF issue in ksmbd_tcp_new_connection() Yang Yingliang (1): ksmbd: switch to use kmemdup_nul() helper luosili (1): ksmbd: fix uaf in smb20_oplock_break_ack fs/ksmbd/asn1.c | 32 +++++++++++++++++--------------- fs/ksmbd/connection.c | 6 ------ fs/ksmbd/connection.h | 2 +- fs/ksmbd/smb2pdu.c | 38 +++++++++++++++++++++++++------------- fs/ksmbd/transport_rdma.c | 11 ++++++----- fs/ksmbd/transport_tcp.c | 13 +++++++------ 6 files changed, 56 insertions(+), 46 deletions(-) -- 2.31.1

From: Dawei Li <set_pte_at@outlook.com> stable inclusion from stable-v5.15.81 commit a35ebf65899344cf1d4cbc8c8c773b4185bf8388 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I93E71 CVE: CVE-2024-26594 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- [ Upstream commit 7010357004096e54c884813e702d71147dc081f8 ] ksmbd_neg_token_init_mech_token() and ksmbd_neg_token_targ_resp_token() share same implementation, unify them. Signed-off-by: Dawei Li <set_pte_at@outlook.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Conflict: fs/ksmbd/asn1.c Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/asn1.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fs/ksmbd/asn1.c b/fs/ksmbd/asn1.c index b014f4638610..2276624e47ef 100644 --- a/fs/ksmbd/asn1.c +++ b/fs/ksmbd/asn1.c @@ -312,9 +312,9 @@ int ksmbd_neg_token_init_mech_type(void *context, size_t hdrlen, return -EBADMSG; } -int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, - unsigned char tag, const void *value, - size_t vlen) +static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, + unsigned char tag, const void *value, + size_t vlen) { struct ksmbd_conn *conn = context; @@ -327,17 +327,16 @@ int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, return 0; } -int ksmbd_neg_token_targ_resp_token(void *context, size_t hdrlen, +int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, unsigned char tag, const void *value, size_t vlen) { - struct ksmbd_conn *conn = context; - - conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL); - if (!conn->mechToken) - return -ENOMEM; + return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen); +} - memcpy(conn->mechToken, value, vlen); - conn->mechToken[vlen] = '\0'; - return 0; +int ksmbd_neg_token_targ_resp_token(void *context, size_t hdrlen, + unsigned char tag, const void *value, + size_t vlen) +{ + return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen); } -- 2.31.1

From: Yang Yingliang <yangyingliang@huawei.com> stable inclusion from stable-v5.15.81 commit d7ad0ac5a8f66c3527da2e85392e75095481768a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I93E71 CVE: CVE-2024-26594 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- [ Upstream commit 084ba46fc41c21ba827fd92e61f78def7a6e52ea ] Use kmemdup_nul() helper instead of open-coding to simplify the code. Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/asn1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/ksmbd/asn1.c b/fs/ksmbd/asn1.c index 2276624e47ef..a82739dc92b3 100644 --- a/fs/ksmbd/asn1.c +++ b/fs/ksmbd/asn1.c @@ -318,12 +318,10 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, { struct ksmbd_conn *conn = context; - conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL); + conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); if (!conn->mechToken) return -ENOMEM; - memcpy(conn->mechToken, value, vlen); - conn->mechToken[vlen] = '\0'; return 0; } -- 2.31.1

From: Namjae Jeon <linkinjeon@kernel.org> stable inclusion from stable-v5.15.81 commit dd1de9268745f0eac83a430db7afc32cbd62e84b category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I93E71 CVE: CVE-2024-26594 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- [ Upstream commit 92e470163d96df8db6c4fa0f484e4a229edb903d ] If client send invalid mech token in session setup request, ksmbd validate and make the error if it is invalid. Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-22890 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/asn1.c | 5 +++++ fs/ksmbd/connection.h | 1 + fs/ksmbd/smb2pdu.c | 22 +++++++++++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/fs/ksmbd/asn1.c b/fs/ksmbd/asn1.c index a82739dc92b3..8391963ff2a8 100644 --- a/fs/ksmbd/asn1.c +++ b/fs/ksmbd/asn1.c @@ -318,10 +318,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, { struct ksmbd_conn *conn = context; + if (!vlen) + return -EINVAL; + conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); if (!conn->mechToken) return -ENOMEM; + conn->mechTokenLen = (unsigned int)vlen; + return 0; } diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h index 2e3d96e63953..75a1849ba828 100644 --- a/fs/ksmbd/connection.h +++ b/fs/ksmbd/connection.h @@ -85,6 +85,7 @@ struct ksmbd_conn { __u16 dialect; char *mechToken; + unsigned int mechTokenLen; struct ksmbd_conn_ops *conn_ops; diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index b21ac851345f..7234ff23af80 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -1421,7 +1421,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn, char *name; unsigned int name_off, name_len, secbuf_len; - secbuf_len = le16_to_cpu(req->SecurityBufferLength); + if (conn->use_spnego && conn->mechToken) + secbuf_len = conn->mechTokenLen; + else + secbuf_len = le16_to_cpu(req->SecurityBufferLength); if (secbuf_len < sizeof(struct authenticate_message)) { ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len); return NULL; @@ -1513,7 +1516,10 @@ static int ntlm_authenticate(struct ksmbd_work *work, struct authenticate_message *authblob; authblob = user_authblob(conn, req); - sz = le16_to_cpu(req->SecurityBufferLength); + if (conn->use_spnego && conn->mechToken) + sz = conn->mechTokenLen; + else + sz = le16_to_cpu(req->SecurityBufferLength); rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess); if (rc) { set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD); @@ -1786,8 +1792,7 @@ int smb2_sess_setup(struct ksmbd_work *work) negblob_off = le16_to_cpu(req->SecurityBufferOffset); negblob_len = le16_to_cpu(req->SecurityBufferLength); - if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) || - negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { + if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) { rc = -EINVAL; goto out_err; } @@ -1796,8 +1801,15 @@ int smb2_sess_setup(struct ksmbd_work *work) negblob_off); if (decode_negotiation_token(conn, negblob, negblob_len) == 0) { - if (conn->mechToken) + if (conn->mechToken) { negblob = (struct negotiate_message *)conn->mechToken; + negblob_len = conn->mechTokenLen; + } + } + + if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { + rc = -EINVAL; + goto out_err; } if (server_conf.auth_mechs & conn->auth_mechs) { -- 2.31.1

From: Namjae Jeon <linkinjeon@kernel.org> stable inclusion from stable-v5.15.81 commit 017d85c94f02090a87f4a473dbe0d6ee0da72693 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I92OR4 CVE: CVE-2023-52442 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- [ Upstream commit 3df0411e132ee74a87aa13142dfd2b190275332e ] `smb2_get_msg()` in smb2_get_ksmbd_tcon() and smb2_check_user_session() will always return the first request smb2 header in a compound request. if `SMB2_TREE_CONNECT_HE` is the first command in compound request, will return 0, i.e. The tree id check is skipped. This patch use ksmbd_req_buf_next() to get current command in compound. Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21506 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> Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/smb2pdu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 7234ff23af80..7d4283e3d4b1 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -86,9 +86,9 @@ struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn */ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) { - struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); unsigned int cmd = le16_to_cpu(req_hdr->Command); - int tree_id; + unsigned int tree_id; if (cmd == SMB2_TREE_CONNECT_HE || cmd == SMB2_CANCEL_HE || @@ -113,7 +113,7 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) pr_err("The first operation in the compound does not have tcon\n"); return -EINVAL; } - if (work->tcon->id != tree_id) { + if (tree_id != UINT_MAX && 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; @@ -570,9 +570,9 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) */ int smb2_check_user_session(struct ksmbd_work *work) { - struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); struct ksmbd_conn *conn = work->conn; - unsigned int cmd = conn->ops->get_cmd_val(work); + unsigned int cmd = le16_to_cpu(req_hdr->Command); unsigned long long sess_id; /* @@ -598,7 +598,7 @@ int smb2_check_user_session(struct ksmbd_work *work) pr_err("The first operation in the compound does not have sess\n"); return -EINVAL; } - if (work->sess->id != sess_id) { + if (sess_id != ULLONG_MAX && 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; -- 2.31.1

From: luosili <rootlab@huawei.com> stable inclusion from stable-v5.15.81 commit 694e13732e830cbbfedb562e57f28644927c33fd category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I94P2I CVE: CVE-2023-52479 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- commit c69813471a1ec081a0b9bf0c6bd7e8afd818afce upstream. drop reference after use opinfo. Signed-off-by: luosili <rootlab@huawei.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> Conflict: fs/ksmbd/transport_tcp.c Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 7d4283e3d4b1..2f025205c843 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -8046,10 +8046,10 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) goto err_out; } - opinfo_put(opinfo); - ksmbd_fd_put(work, fp); opinfo->op_state = OPLOCK_STATE_NONE; wake_up_interruptible_all(&opinfo->oplock_q); + opinfo_put(opinfo); + ksmbd_fd_put(work, fp); rsp->StructureSize = cpu_to_le16(24); rsp->OplockLevel = rsp_oplevel; -- 2.31.1

From: Namjae Jeon <linkinjeon@kernel.org> stable inclusion from stable-v5.15.81 commit 999daf367b924fdf14e9d83e034ee0f86bc17ec6 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I932W8 CVE: CVE-2024-26592 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=l... -------------------------------- [ Upstream commit 38d20c62903d669693a1869aa68c4dd5674e2544 ] The race is between the handling of a new TCP connection and its disconnection. It leads to UAF on `struct tcp_transport` in ksmbd_tcp_new_connection() function. Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-22991 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Conflict: fs/ksmbd/transport_tcp.c Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/ksmbd/connection.c | 6 ------ fs/ksmbd/connection.h | 1 - fs/ksmbd/transport_rdma.c | 11 ++++++----- fs/ksmbd/transport_tcp.c | 13 +++++++------ 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c index f0818e764230..d48d177cba6b 100644 --- a/fs/ksmbd/connection.c +++ b/fs/ksmbd/connection.c @@ -434,13 +434,7 @@ static void stop_sessions(void) again: down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { - struct task_struct *task; - t = conn->transport; - task = t->handler; - if (task) - ksmbd_debug(CONN, "Stop session handler %s/%d\n", - task->comm, task_pid_nr(task)); ksmbd_conn_set_exiting(conn); if (t->ops->shutdown) { up_read(&conn_list_lock); diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h index 75a1849ba828..9708ba99d8a5 100644 --- a/fs/ksmbd/connection.h +++ b/fs/ksmbd/connection.h @@ -128,7 +128,6 @@ struct ksmbd_transport_ops { struct ksmbd_transport { struct ksmbd_conn *conn; struct ksmbd_transport_ops *ops; - struct task_struct *handler; }; #define KSMBD_TCP_RECV_TIMEOUT (7 * HZ) diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c index d3b60b833a81..2a8640ce1107 100644 --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -1976,6 +1976,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs) static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) { struct smb_direct_transport *t; + struct task_struct *handler; int ret; if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { @@ -1993,11 +1994,11 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) if (ret) goto out_err; - KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, - KSMBD_TRANS(t)->conn, "ksmbd:r%u", - smb_direct_port); - if (IS_ERR(KSMBD_TRANS(t)->handler)) { - ret = PTR_ERR(KSMBD_TRANS(t)->handler); + handler = kthread_run(ksmbd_conn_handler_loop, + KSMBD_TRANS(t)->conn, "ksmbd:r%u", + smb_direct_port); + if (IS_ERR(handler)) { + ret = PTR_ERR(handler); pr_err("Can't start thread\n"); goto out_err; } diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c index d34812d140eb..79b40f26587c 100644 --- a/fs/ksmbd/transport_tcp.c +++ b/fs/ksmbd/transport_tcp.c @@ -183,6 +183,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) struct sockaddr *csin; int rc = 0; struct tcp_transport *t; + struct task_struct *handler; t = alloc_transport(client_sk); if (!t) @@ -195,13 +196,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) goto out_error; } - KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, - KSMBD_TRANS(t)->conn, - "ksmbd:%u", - ksmbd_tcp_get_port(csin)); - if (IS_ERR(KSMBD_TRANS(t)->handler)) { + handler = kthread_run(ksmbd_conn_handler_loop, + KSMBD_TRANS(t)->conn, + "ksmbd:%u", + ksmbd_tcp_get_port(csin)); + if (IS_ERR(handler)) { pr_err("cannot start conn thread\n"); - rc = PTR_ERR(KSMBD_TRANS(t)->handler); + rc = PTR_ERR(handler); free_transport(t); } return rc; -- 2.31.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/5378 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/W... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/5378 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/W...
participants (2)
-
Long Li
-
patchwork bot