Skip to content

Commit eec04ea

Browse files
Paulo AlcantaraSteve French
authored andcommitted
smb: client: fix OOB in receive_encrypted_standard()
Fix potential OOB in receive_encrypted_standard() if server returned a large shdr->NextCommand that would end up writing off the end of @next_buffer. Fixes: b24df3e ("cifs: update receive_encrypted_standard to handle compounded responses") Cc: [email protected] Reported-by: Robert Morris <[email protected]> Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent a39b6ac commit eec04ea

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

fs/smb/client/smb2ops.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4943,6 +4943,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
49434943
struct smb2_hdr *shdr;
49444944
unsigned int pdu_length = server->pdu_size;
49454945
unsigned int buf_size;
4946+
unsigned int next_cmd;
49464947
struct mid_q_entry *mid_entry;
49474948
int next_is_large;
49484949
char *next_buffer = NULL;
@@ -4971,14 +4972,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
49714972
next_is_large = server->large_buf;
49724973
one_more:
49734974
shdr = (struct smb2_hdr *)buf;
4974-
if (shdr->NextCommand) {
4975+
next_cmd = le32_to_cpu(shdr->NextCommand);
4976+
if (next_cmd) {
4977+
if (WARN_ON_ONCE(next_cmd > pdu_length))
4978+
return -1;
49754979
if (next_is_large)
49764980
next_buffer = (char *)cifs_buf_get();
49774981
else
49784982
next_buffer = (char *)cifs_small_buf_get();
4979-
memcpy(next_buffer,
4980-
buf + le32_to_cpu(shdr->NextCommand),
4981-
pdu_length - le32_to_cpu(shdr->NextCommand));
4983+
memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd);
49824984
}
49834985

49844986
mid_entry = smb2_find_mid(server, buf);
@@ -5002,8 +5004,8 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
50025004
else
50035005
ret = cifs_handle_standard(server, mid_entry);
50045006

5005-
if (ret == 0 && shdr->NextCommand) {
5006-
pdu_length -= le32_to_cpu(shdr->NextCommand);
5007+
if (ret == 0 && next_cmd) {
5008+
pdu_length -= next_cmd;
50075009
server->large_buf = next_is_large;
50085010
if (next_is_large)
50095011
server->bigbuf = buf = next_buffer;

0 commit comments

Comments
 (0)