Skip to content

Commit 426a35d

Browse files
TREXNEGROsmfrench
authored andcommitted
smb: client: detect short folioq copy in cifs_copy_folioq_to_iter()
cifs_copy_folioq_to_iter() copies a requested number of bytes from a folio queue into the destination iterator. Since the encrypted SMB2 READ path was changed to pass the server-declared payload length (data_len) instead of the larger folioq buffer length, the caller can ask for fewer bytes than the folio queue holds. In that case the helper continues walking the remaining folios after data_size has reached zero and calls copy_folio_to_iter() with len = 0, which is unnecessary work. The helper also returns 0 (success) when the folio queue is exhausted before data_size bytes have been copied. The caller has no way to distinguish that from a full copy and the reported transfer count ends up larger than the amount of data placed in the iterator. Add an early exit when data_size reaches zero, and return an error when the folio queue is exhausted before all requested bytes have been copied. Signed-off-by: Jeremy Erazo <mendozayt13@gmail.com> Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent e7ae89a commit 426a35d

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

fs/smb/client/smb2ops.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4706,9 +4706,15 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
47064706
{
47074707
for (; folioq; folioq = folioq->next) {
47084708
for (int s = 0; s < folioq_count(folioq); s++) {
4709-
struct folio *folio = folioq_folio(folioq, s);
4710-
size_t fsize = folio_size(folio);
4711-
size_t n, len = umin(fsize - skip, data_size);
4709+
struct folio *folio;
4710+
size_t fsize, n, len;
4711+
4712+
if (data_size == 0)
4713+
return 0;
4714+
4715+
folio = folioq_folio(folioq, s);
4716+
fsize = folio_size(folio);
4717+
len = umin(fsize - skip, data_size);
47124718

47134719
n = copy_folio_to_iter(folio, skip, len, iter);
47144720
if (n != len) {
@@ -4721,6 +4727,12 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
47214727
}
47224728
}
47234729

4730+
if (data_size != 0) {
4731+
cifs_dbg(VFS, "%s: short copy, %zu bytes missing\n",
4732+
__func__, data_size);
4733+
return smb_EIO2(smb_eio_trace_rx_copy_to_iter, 0, data_size);
4734+
}
4735+
47244736
return 0;
47254737
}
47264738

0 commit comments

Comments
 (0)