[PATCH OLK-5.10 0/2] Fix CVE-2024-53179
This patch set fix CVE-2024-53179 Paulo Alcantara (1): smb: client: fix use-after-free of signing key Shyam Prasad N (1): cifs: missed ref-counting smb session in find fs/cifs/smb2proto.h | 2 -- fs/cifs/smb2transport.c | 59 ++++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 17 deletions(-) -- 2.39.2
From: Shyam Prasad N <sprasad@microsoft.com> stable inclusion from stable-v5.10.220 commit 78ebec450ef4f0720c592638d92bad679d75d7ce category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAEZ CVE: CVE-2024-53179 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=t... -------------------------------- [ Upstream commit e695a9ad0305af6e8b0cbc24a54976ac2120cbb3 ] When we lookup an smb session based on session id, we did not up the ref-count for the session. This can potentially cause issues if the session is freed from under us. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: 02c418774f76 ("smb: client: fix deadlock in smb2_find_smb_tcon()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/cifs/smb2transport.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index d659eb70df76..f40b8de2aeeb 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -154,6 +154,7 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { if (ses->Suid != ses_id) continue; + ++ses->ses_count; return ses; } @@ -205,7 +206,14 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) return NULL; } tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); + if (!tcon) { + cifs_put_smb_ses(ses); + spin_unlock(&cifs_tcp_ses_lock); + return NULL; + } spin_unlock(&cifs_tcp_ses_lock); + /* tcon already has a ref to ses, so we don't need ses anymore */ + cifs_put_smb_ses(ses); return tcon; } @@ -239,7 +247,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, if (rc) { cifs_server_dbg(VFS, "%s: sha256 alloc failed\n", __func__); - return rc; + goto out; } shash = &sdesc->shash; } else { @@ -290,6 +298,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, out: if (allocate_crypto) cifs_free_hash(&hash, &sdesc); + if (ses) + cifs_put_smb_ses(ses); return rc; } -- 2.39.2
From: Paulo Alcantara <pc@manguebit.com> mainline inclusion from mainline-v6.10-rc2 commit 343d7fe6df9e247671440a932b6a73af4fa86d95 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAEZ CVE: CVE-2024-53179 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Customers have reported use-after-free in @ses->auth_key.response with SMB2.1 + sign mounts which occurs due to following race: task A task B cifs_mount() dfs_mount_share() get_session() cifs_mount_get_session() cifs_send_recv() cifs_get_smb_ses() compound_send_recv() cifs_setup_session() smb2_setup_request() kfree_sensitive() smb2_calc_signature() crypto_shash_setkey() *UAF* Fix this by ensuring that we have a valid @ses->auth_key.response by checking whether @ses->ses_status is SES_GOOD or SES_EXITING with @ses->ses_lock held. After commit 24a9799aa8ef ("smb: client: fix UAF in smb2_reconnect_server()"), we made sure to call ->logoff() only when @ses was known to be good (e.g. valid ->auth_key.response), so it's safe to access signing key when @ses->ses_status == SES_EXITING. Cc: stable@vger.kernel.org Reported-by: Jay Shin <jaeshin@redhat.com> Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com> Conflicts: fs/cifs/smb2proto.h fs/cifs/smb2transport.c fs/smb/client/smb2proto.h fs/smb/client/smb2transport.c [Conflicts due to fs/cifs move to fs/smb/client] Signed-off-by: Long Li <leo.lilong@huawei.com> --- fs/cifs/smb2proto.h | 2 -- fs/cifs/smb2transport.c | 51 ++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 3184a5efcdba..b8c07877f938 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -50,8 +50,6 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst); extern struct mid_q_entry *smb2_setup_async_request( struct TCP_Server_Info *server, struct smb_rqst *rqst); -extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, - __u64 ses_id); extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid); extern int smb2_calc_signature(struct smb_rqst *rqst, diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index f40b8de2aeeb..430dce8cab90 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -92,7 +92,7 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server) static -int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) +int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) { struct cifs_chan *chan; struct cifs_ses *ses = NULL; @@ -161,16 +161,36 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) return NULL; } -struct cifs_ses * -smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) +static int smb2_get_sign_key(struct TCP_Server_Info *server, + __u64 ses_id, u8 *key) { struct cifs_ses *ses; + int rc = -ENOENT; spin_lock(&cifs_tcp_ses_lock); - ses = smb2_find_smb_ses_unlocked(server, ses_id); - spin_unlock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + if (ses->Suid != ses_id) + continue; - return ses; + rc = 0; + switch (ses->status) { + case CifsExiting: /* SMB2_LOGOFF */ + case CifsGood: + if (likely(ses->auth_key.response)) { + memcpy(key, ses->auth_key.response, + SMB2_NTLMV2_SESSKEY_SIZE); + } else { + rc = -EIO; + } + break; + default: + rc = -EAGAIN; + break; + } + break; + } + spin_unlock(&cifs_tcp_ses_lock); + return rc; } static struct cifs_tcon * @@ -227,16 +247,18 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, unsigned char *sigptr = smb2_signature; struct kvec *iov = rqst->rq_iov; struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base; - struct cifs_ses *ses; struct shash_desc *shash; struct crypto_shash *hash; struct sdesc *sdesc = NULL; struct smb_rqst drqst; + __u64 sid = le64_to_cpu(shdr->SessionId); + u8 key[SMB2_NTLMV2_SESSKEY_SIZE]; - ses = smb2_find_smb_ses(server, shdr->SessionId); - if (!ses) { - cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); - return 0; + rc = smb2_get_sign_key(server, sid, key); + if (unlikely(rc)) { + cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n", + __func__, sid, rc); + return rc; } memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); @@ -255,8 +277,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, shash = &server->secmech.sdeschmacsha256->shash; } - rc = crypto_shash_setkey(hash, ses->auth_key.response, - SMB2_NTLMV2_SESSKEY_SIZE); + rc = crypto_shash_setkey(hash, key, sizeof(key)); if (rc) { cifs_server_dbg(VFS, "%s: Could not update with response\n", @@ -298,8 +319,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, out: if (allocate_crypto) cifs_free_hash(&hash, &sdesc); - if (ses) - cifs_put_smb_ses(ses); return rc; } @@ -553,7 +572,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct smb_rqst drqst; u8 key[SMB3_SIGN_KEY_SIZE]; - rc = smb2_get_sign_key(shdr->SessionId, server, key); + rc = smb3_get_sign_key(shdr->SessionId, server, key); if (rc) return 0; -- 2.39.2
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/19275 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/AAS... 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/19275 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/AAS...
participants (2)
-
Long Li -
patchwork bot