Skip to content

Commit

Permalink
ksmbd: fix out of bounds in init_smb2_rsp_hdr()
Browse files Browse the repository at this point in the history
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: [email protected] # ZDI-CAN-21541
Signed-off-by: Namjae Jeon <[email protected]>
  • Loading branch information
namjaejeon committed Jul 23, 2023
1 parent 03bef3d commit d149845
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
7 changes: 6 additions & 1 deletion server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
19 changes: 11 additions & 8 deletions smb_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,27 +425,30 @@ 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;
}
#endif

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,
Expand Down
2 changes: 1 addition & 1 deletion smb_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,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);

bool ksmbd_pdu_size_has_room(unsigned int pdu);

Expand Down

0 comments on commit d149845

Please sign in to comment.