* [PATCH] smb: client: use data_len for SMB2 READ encrypted folioq copy
[not found] <CAH2r5mtBCP-sg6f3RH3RxO=-Fv9WznGmAwHHBQJBa=1+_DEnZA@mail.gmail.com>
@ 2026-05-15 19:31 ` Jeremy Erazo
0 siblings, 0 replies; only message in thread
From: Jeremy Erazo @ 2026-05-15 19:31 UTC (permalink / raw)
To: Steve French; +Cc: linux-cifs, linux-kernel
In handle_read_data() the encrypted/folioq branch
(buf_len <= data_offset, reached via receive_encrypted_read for
transform PDUs > CIFSMaxBufSize + MAX_HEADER_SIZE) copies the READ
payload using buffer_len rather than data_len:
rdata->result = cifs_copy_folioq_to_iter(buffer, buffer_len,
cur_off,
&rdata->subreq.io_iter);
...
rdata->got_bytes = buffer_len;
buffer_len comes from the SMB3 transform header OriginalMessageSize
field (OriginalMessageSize - read_rsp_size); it represents the size
of the decrypted message after the SMB2 header. data_len comes from
the SMB2 READ response DataLength field; it represents the actual
READ payload size and may be smaller than buffer_len when the
decrypted message contains padding or other trailing bytes after the
READ payload. The existing check `data_len > buffer_len - pad_len`
only enforces an upper bound, so a server that emits
OriginalMessageSize larger than read_rsp_size + pad_len + data_len
passes the check and the kernel copies buffer_len bytes per response,
ignoring the server-asserted DataLength.
Two observable failures with a crafted server (DataLength=4,
buffer_len=20000):
- the kernel returns 20000 bytes per sub-request to userspace and
sets got_bytes = buffer_len, even though the response claimed
only 4 bytes of payload;
- on a partial netfs sub-request whose iterator is sized to
data_len, the over-large copy_folio_to_iter() short-reads,
cifs_copy_folioq_to_iter() returns -EIO via the n != len path,
and the entire netfs read collapses to -EIO even though the
leading sub-requests succeeded.
Use data_len for the copy length and for got_bytes so the kernel
honours the server-asserted READ payload size. For well-formed
servers (where buffer_len == pad_len + data_len) the change is
behaviour-equivalent.
Signed-off-by: Jeremy Erazo <mendozayt13@gmail.com>
---
fs/smb/client/smb2ops.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4825,7 +4825,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
}
/* Copy the data to the output I/O iterator. */
- rdata->result = cifs_copy_folioq_to_iter(buffer, buffer_len,
+ rdata->result = cifs_copy_folioq_to_iter(buffer, data_len,
cur_off, &rdata->subreq.io_iter);
if (rdata->result != 0) {
if (is_offloaded)
@@ -4834,5 +4834,5 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
dequeue_mid(server, mid, rdata->result);
return 0;
}
- rdata->got_bytes = buffer_len;
+ rdata->got_bytes = data_len;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-15 19:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CAH2r5mtBCP-sg6f3RH3RxO=-Fv9WznGmAwHHBQJBa=1+_DEnZA@mail.gmail.com>
2026-05-15 19:31 ` [PATCH] smb: client: use data_len for SMB2 READ encrypted folioq copy Jeremy Erazo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox