Commit 30210947 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French

ksmbd: fix racy issue under cocurrent smb2 tree disconnect

There is UAF issue under cocurrent smb2 tree disconnect.
This patch introduce TREE_CONN_EXPIRE flags for tcon to avoid cocurrent
access.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-20592
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent abcc506a
...@@ -109,7 +109,15 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, ...@@ -109,7 +109,15 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess, struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
unsigned int id) unsigned int id)
{ {
return xa_load(&sess->tree_conns, id); struct ksmbd_tree_connect *tcon;
tcon = xa_load(&sess->tree_conns, id);
if (tcon) {
if (test_bit(TREE_CONN_EXPIRE, &tcon->status))
tcon = NULL;
}
return tcon;
} }
struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess, struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
......
...@@ -14,6 +14,8 @@ struct ksmbd_share_config; ...@@ -14,6 +14,8 @@ struct ksmbd_share_config;
struct ksmbd_user; struct ksmbd_user;
struct ksmbd_conn; struct ksmbd_conn;
#define TREE_CONN_EXPIRE 1
struct ksmbd_tree_connect { struct ksmbd_tree_connect {
int id; int id;
...@@ -25,6 +27,7 @@ struct ksmbd_tree_connect { ...@@ -25,6 +27,7 @@ struct ksmbd_tree_connect {
int maximal_access; int maximal_access;
bool posix_extensions; bool posix_extensions;
unsigned long status;
}; };
struct ksmbd_tree_conn_status { struct ksmbd_tree_conn_status {
......
...@@ -2053,11 +2053,12 @@ int smb2_tree_disconnect(struct ksmbd_work *work) ...@@ -2053,11 +2053,12 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
ksmbd_debug(SMB, "request\n"); ksmbd_debug(SMB, "request\n");
if (!tcon) { if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) {
struct smb2_tree_disconnect_req *req = struct smb2_tree_disconnect_req *req =
smb2_get_msg(work->request_buf); smb2_get_msg(work->request_buf);
ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
smb2_set_err_rsp(work); smb2_set_err_rsp(work);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment