Skip to content

Commit 6259301

Browse files
rohiths-msftSteve French
authored and
Steve French
committed
SMB3: Resolve data corruption of TCP server info fields
TCP server info field server->total_read is modified in parallel by demultiplex thread and decrypt offload worker thread. server->total_read is used in calculation to discard the remaining data of PDU which is not read into memory. Because of parallel modification, server->total_read can get corrupted and can result in discarding the valid data of next PDU. Signed-off-by: Rohith Surabattula <[email protected]> Reviewed-by: Aurelien Aptel <[email protected]> Reviewed-by: Pavel Shilovsky <[email protected]> CC: Stable <[email protected]> #5.4+ Signed-off-by: Steve French <[email protected]>
1 parent 3ece60e commit 6259301

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

fs/cifs/smb2ops.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4131,7 +4131,8 @@ smb3_is_transform_hdr(void *buf)
41314131
static int
41324132
decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
41334133
unsigned int buf_data_size, struct page **pages,
4134-
unsigned int npages, unsigned int page_data_size)
4134+
unsigned int npages, unsigned int page_data_size,
4135+
bool is_offloaded)
41354136
{
41364137
struct kvec iov[2];
41374138
struct smb_rqst rqst = {NULL};
@@ -4157,7 +4158,8 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
41574158

41584159
memmove(buf, iov[1].iov_base, buf_data_size);
41594160

4160-
server->total_read = buf_data_size + page_data_size;
4161+
if (!is_offloaded)
4162+
server->total_read = buf_data_size + page_data_size;
41614163

41624164
return rc;
41634165
}
@@ -4370,7 +4372,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
43704372
struct mid_q_entry *mid;
43714373

43724374
rc = decrypt_raw_data(dw->server, dw->buf, dw->server->vals->read_rsp_size,
4373-
dw->ppages, dw->npages, dw->len);
4375+
dw->ppages, dw->npages, dw->len, true);
43744376
if (rc) {
43754377
cifs_dbg(VFS, "error decrypting rc=%d\n", rc);
43764378
goto free_pages;
@@ -4476,7 +4478,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
44764478

44774479
non_offloaded_decrypt:
44784480
rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size,
4479-
pages, npages, len);
4481+
pages, npages, len, false);
44804482
if (rc)
44814483
goto free_pages;
44824484

@@ -4532,7 +4534,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
45324534
server->total_read += length;
45334535

45344536
buf_size = pdu_length - sizeof(struct smb2_transform_hdr);
4535-
length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0);
4537+
length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0, false);
45364538
if (length)
45374539
return length;
45384540

0 commit comments

Comments
 (0)