mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
smb: client: reject short READ responses in CIFSSMBRead()
CIFSSMBRead() reads DataLengthHigh, DataLength and DataOffset out of
the READ_RSP returned by the server without first checking that a
whole READ_RSP was actually received. The length of the response is
recorded in rsp_iov.iov_len, but nothing constrains it to be at least
read_rsp_size before those fields are dereferenced.
A malicious or compromised SMB1 server can return a response shorter
than the READ_RSP header, so that parsing the header itself reads past
the end of the receive buffer. SMB1 is not negotiated by default;
reaching this code requires an explicit vers=1.0 mount.
Reject the response unless it is at least read_rsp_size bytes long.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Suggested-by: Paulo Alcantara <pc@manguebit.org>
Cc: stable@vger.kernel.org # 6.19.x
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
This commit is contained in:
parent
89a312991d
commit
e6142a8bfc
|
|
@ -1719,6 +1719,14 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
pSMBr = (READ_RSP *)rsp_iov.iov_base;
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "Send error in read = %d\n", rc);
|
||||
} else if (rsp_iov.iov_len < tcon->ses->server->vals->read_rsp_size) {
|
||||
/* check that the received response can hold a whole READ_RSP */
|
||||
cifs_dbg(FYI, "%s: server returned short header. got=%zu expected=%zu\n",
|
||||
__func__, rsp_iov.iov_len,
|
||||
tcon->ses->server->vals->read_rsp_size);
|
||||
rc = smb_EIO2(smb_eio_trace_read_rsp_short,
|
||||
rsp_iov.iov_len, tcon->ses->server->vals->read_rsp_size);
|
||||
*nbytes = 0;
|
||||
} else {
|
||||
int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
|
||||
data_length = data_length << 16;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user