Skip to content

Commit

Permalink
ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop
Browse files Browse the repository at this point in the history
commit 368ba06 upstream.

The length field of netbios header must be greater than the SMB header
sizes(smb1 or smb2 header), otherwise the packet is an invalid SMB packet.

If `pdu_size` is 0, ksmbd allocates a 4 bytes chunk to `conn->request_buf`.
In the function `get_smb2_cmd_val` ksmbd will read cmd from
`rcv_hdr->Command`, which is `conn->request_buf + 12`, causing the KASAN
detector to print the following error message:

[    7.205018] BUG: KASAN: slab-out-of-bounds in get_smb2_cmd_val+0x45/0x60
[    7.205423] Read of size 2 at addr ffff8880062d8b50 by task ksmbd:42632/248
...
[    7.207125]  <TASK>
[    7.209191]  get_smb2_cmd_val+0x45/0x60
[    7.209426]  ksmbd_conn_enqueue_request+0x3a/0x100
[    7.209712]  ksmbd_server_process_request+0x72/0x160
[    7.210295]  ksmbd_conn_handler_loop+0x30c/0x550
[    7.212280]  kthread+0x160/0x190
[    7.212762]  ret_from_fork+0x1f/0x30
[    7.212981]  </TASK>

Cc: stable@vger.kernel.org
Reported-by: Chih-Yen Chang <cc85nod@gmail.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>
  • Loading branch information
namjaejeon authored and gregkh committed Jun 14, 2023
1 parent 8f29842 commit 543c12c
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions fs/ksmbd/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
return true;
}

#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr))
#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)

/**
* ksmbd_conn_handler_loop() - session thread to listen on new smb requests
* @p: connection instance
Expand Down Expand Up @@ -352,6 +355,9 @@ int ksmbd_conn_handler_loop(void *p)
if (pdu_size > MAX_STREAM_PROT_LEN)
break;

if (pdu_size < SMB1_MIN_SUPPORTED_HEADER_SIZE)
break;

/* 4 for rfc1002 length field */
/* 1 for implied bcc[0] */
size = pdu_size + 4 + 1;
Expand Down Expand Up @@ -379,6 +385,12 @@ int ksmbd_conn_handler_loop(void *p)
continue;
}

if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
SMB2_PROTO_NUMBER) {
if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
break;
}

if (!default_conn_ops.process_fn) {
pr_err("No connection request callback\n");
break;
Expand Down

0 comments on commit 543c12c

Please sign in to comment.