Hello. When specifying an smb2 header for communication with ksmbd, a user can send `SMB2_TRANSFORM_PROTO_NUM` that is not handled properly, triggering an out-of-bounds memory read.
), initially, the size check is for all headers. On x86-64, this minimum is 37B.
Later in the same function, this check for the smb2 header could be bypassed, since we are sending `SMB2_TRANSFORM_PROTO_NUM` (
https://elixir.bootlin.com/linux/latest/source/fs/smb/server/connection.c#L354):
if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
SMB2_PROTO_NUMBER) {
if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
break;
}
The minimum size is at least 68B this time.
Finally in `smb2_allocate_rsp_buf` (
https://elixir.bootlin.com/linux/v6.8.4/source/fs/smb/server/smb2pdu.c#L535) if the code is `SMB2_QUERY_INFO_HE` we skip the header (assuming SMB2, but SMB1 size was only checked). In case we send a request that is less than `&req->InfoType - req` (66), we trigger OOB data access.
if (cmd == SMB2_QUERY_INFO_HE) {
struct smb2_query_info_req *req;
req = smb2_get_msg(work->request_buf);
if ((req->InfoType == SMB2_O_INFO_FILE &&
(req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
req->FileInfoClass == FILE_ALL_INFORMATION)) ||
req->InfoType == SMB2_O_INFO_SECURITY)
sz = large_sz;
}
In the PoC, we are sending a `pdu_size` of size 0x32 (50).
It seems the issue is similar to this one
https://github.com/torvalds/linux/commit/368ba06881c395f1c9a7ba22203cf8d78b4addc0 here, where the size check is done only for `SMB2_PROTO_NUMBER` and not `SMB2_TRANSFORM_PROTO_NUM`. The issue might also appear in other interesting ways, but I have not fully analyzed the root cause. I am not sure in what version was the bug introduced, but I reproduced the issue on Linux kernel 6.3 until the latest version, 6.8.4. Let me please know if you have additional questions.
N.