ksmbd: fix out of bounds in init_smb2_rsp_hdr()
If client send smb2 negotiate request and then send smb1 negotiate request, init_smb2_rsp_hdr is called for smb1 negotiate request since need_neg is set to false. This patch ignore smb1 packets after ->need_neg is set to false. Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21541 Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
e202a1e863
commit
536bb492d3
|
@ -286,6 +286,7 @@ static void handle_ksmbd_work(struct work_struct *wk)
|
|||
static int queue_ksmbd_work(struct ksmbd_conn *conn)
|
||||
{
|
||||
struct ksmbd_work *work;
|
||||
int err;
|
||||
|
||||
work = ksmbd_alloc_work_struct();
|
||||
if (!work) {
|
||||
|
@ -297,7 +298,11 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
|
|||
work->request_buf = conn->request_buf;
|
||||
conn->request_buf = NULL;
|
||||
|
||||
ksmbd_init_smb_server(work);
|
||||
err = ksmbd_init_smb_server(work);
|
||||
if (err) {
|
||||
ksmbd_free_work_struct(work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ksmbd_conn_enqueue_request(work);
|
||||
atomic_inc(&conn->r_count);
|
||||
|
|
|
@ -388,26 +388,29 @@ static struct smb_version_cmds smb1_server_cmds[1] = {
|
|||
[SMB_COM_NEGOTIATE_EX] = { .proc = smb1_negotiate, },
|
||||
};
|
||||
|
||||
static void init_smb1_server(struct ksmbd_conn *conn)
|
||||
static int init_smb1_server(struct ksmbd_conn *conn)
|
||||
{
|
||||
conn->ops = &smb1_server_ops;
|
||||
conn->cmds = smb1_server_cmds;
|
||||
conn->max_cmds = ARRAY_SIZE(smb1_server_cmds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ksmbd_init_smb_server(struct ksmbd_work *work)
|
||||
int ksmbd_init_smb_server(struct ksmbd_work *work)
|
||||
{
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
__le32 proto;
|
||||
|
||||
if (conn->need_neg == false)
|
||||
return;
|
||||
|
||||
proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol;
|
||||
if (conn->need_neg == false) {
|
||||
if (proto == SMB1_PROTO_NUMBER)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proto == SMB1_PROTO_NUMBER)
|
||||
init_smb1_server(conn);
|
||||
else
|
||||
init_smb3_11_server(conn);
|
||||
return init_smb1_server(conn);
|
||||
return init_smb3_11_server(conn);
|
||||
}
|
||||
|
||||
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
|
||||
|
|
|
@ -427,7 +427,7 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn);
|
|||
|
||||
int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count);
|
||||
|
||||
void ksmbd_init_smb_server(struct ksmbd_work *work);
|
||||
int ksmbd_init_smb_server(struct ksmbd_work *work);
|
||||
|
||||
struct ksmbd_kstat;
|
||||
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
|
||||
|
|
Loading…
Reference in New Issue