Skip to content

Commit 307f77e

Browse files
dhowellssmfrench
authored andcommitted
cifs: Fix reversion of the iter in cifs_readv_receive().
cifs_read_iter_from_socket() copies the iterator that's passed in for the socket to modify as and if it will, and then advances the original iterator by the amount sent. However, both callers revert the advancement (although receive_encrypted_read() zeros beyond the iterator first). The problem is, though, that cifs_readv_receive() reverts by the original length, not the amount transmitted which can cause an oops in iov_iter_revert(). Fix this by: (1) Remove the iov_iter_advance() from cifs_read_iter_from_socket(). (2) Remove the iov_iter_revert() from both callers. This fixes the bug in cifs_readv_receive(). (3) In receive_encrypted_read(), if we didn't get back as much data as the buffer will hold, copy the iterator, advance the copy and use the copy to drive iov_iter_zero(). As a bonus, this gets rid of some unnecessary work. This was triggered by generic/074 with the "-o sign" mount option. Fixes: 3ee1a1f ("cifs: Cut over to using netfslib") Signed-off-by: David Howells <[email protected]> cc: Steve French <[email protected]> cc: Paulo Alcantara <[email protected]> cc: Shyam Prasad N <[email protected]> cc: Rohith Surabattula <[email protected]> cc: Jeff Layton <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected] Signed-off-by: Steve French <[email protected]>
1 parent 2f3017e commit 307f77e

File tree

3 files changed

+7
-11
lines changed

3 files changed

+7
-11
lines changed

fs/smb/client/connect.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -811,13 +811,9 @@ cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter
811811
unsigned int to_read)
812812
{
813813
struct msghdr smb_msg = { .msg_iter = *iter };
814-
int ret;
815814

816815
iov_iter_truncate(&smb_msg.msg_iter, to_read);
817-
ret = cifs_readv_from_socket(server, &smb_msg);
818-
if (ret > 0)
819-
iov_iter_advance(iter, ret);
820-
return ret;
816+
return cifs_readv_from_socket(server, &smb_msg);
821817
}
822818

823819
static bool

fs/smb/client/smb2ops.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4869,9 +4869,12 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
48694869
goto discard_data;
48704870

48714871
server->total_read += rc;
4872-
if (rc < len)
4873-
iov_iter_zero(len - rc, &iter);
4874-
iov_iter_revert(&iter, len);
4872+
if (rc < len) {
4873+
struct iov_iter tmp = iter;
4874+
4875+
iov_iter_advance(&tmp, rc);
4876+
iov_iter_zero(len - rc, &tmp);
4877+
}
48754878
iov_iter_truncate(&iter, dw->len);
48764879

48774880
rc = cifs_discard_remaining_data(server);

fs/smb/client/transport.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,11 +1817,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
18171817
length = data_len; /* An RDMA read is already done. */
18181818
else
18191819
#endif
1820-
{
18211820
length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter,
18221821
data_len);
1823-
iov_iter_revert(&rdata->subreq.io_iter, data_len);
1824-
}
18251822
if (length > 0)
18261823
rdata->got_bytes += length;
18271824
server->total_read += length;

0 commit comments

Comments
 (0)