Commit c622e096 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by ZhaoLong Wang
Browse files

smb: client: fix OOB in receive_encrypted_standard()

stable inclusion
from stable-v6.6.8
commit 534733397da26de0303057ce0b93a22bda150365
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8WEOK
CVE: CVE-2024-0565

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=534733397da26de0303057ce0b93a22bda150365



--------------------------------

commit eec04ea119691e65227a97ce53c0da6b9b74b0b7 upstream.

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: b24df3e3 ("cifs: update receive_encrypted_standard to handle compounded responses")
Cc: stable@vger.kernel.org
Reported-by: default avatarRobert Morris <rtm@csail.mit.edu>
Signed-off-by: default avatarPaulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZhaoLong Wang <wangzhaolong1@huawei.com>
parent 806899e4
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -4937,6 +4937,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
	struct smb2_hdr *shdr;
	unsigned int pdu_length = server->pdu_size;
	unsigned int buf_size;
	unsigned int next_cmd;
	struct mid_q_entry *mid_entry;
	int next_is_large;
	char *next_buffer = NULL;
@@ -4965,14 +4966,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
	next_is_large = server->large_buf;
one_more:
	shdr = (struct smb2_hdr *)buf;
	if (shdr->NextCommand) {
	next_cmd = le32_to_cpu(shdr->NextCommand);
	if (next_cmd) {
		if (WARN_ON_ONCE(next_cmd > pdu_length))
			return -1;
		if (next_is_large)
			next_buffer = (char *)cifs_buf_get();
		else
			next_buffer = (char *)cifs_small_buf_get();
		memcpy(next_buffer,
		       buf + le32_to_cpu(shdr->NextCommand),
		       pdu_length - le32_to_cpu(shdr->NextCommand));
		memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd);
	}

	mid_entry = smb2_find_mid(server, buf);
@@ -4996,8 +4998,8 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
	else
		ret = cifs_handle_standard(server, mid_entry);

	if (ret == 0 && shdr->NextCommand) {
		pdu_length -= le32_to_cpu(shdr->NextCommand);
	if (ret == 0 && next_cmd) {
		pdu_length -= next_cmd;
		server->large_buf = next_is_large;
		if (next_is_large)
			server->bigbuf = buf = next_buffer;