Bug 218219 - OOB Access in smb2_dump_detail
Summary: OOB Access in smb2_dump_detail
Status: RESOLVED CODE_FIX
Alias: None
Product: File System
Classification: Unclassified
Component: CIFS (show other bugs)
Hardware: All Linux
: P3 normal
Assignee: fs_cifs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-12-04 10:54 UTC by j51569436
Modified: 2024-10-03 17:11 UTC (History)
4 users (show)

See Also:
Kernel Version: 6.7.0
Subsystem:
Regression: No
Bisected commit-id:


Attachments
crash callstack (3.79 KB, text/plain)
2023-12-04 10:54 UTC, j51569436
Details
patch 1 (1.22 KB, patch)
2023-12-16 13:49 UTC, Paulo Alcantara
Details | Diff
patch v2 (2.95 KB, patch)
2023-12-19 16:19 UTC, Paulo Alcantara
Details | Diff

Description j51569436 2023-12-04 10:54:26 UTC
[1] If CONFIG_CIFS_DEBUG2 is set, then cifs_demultiplex_thread calls dump_detail.


```
static int
cifs_demultiplex_thread(void *p)
{
...
for (i = 0; i < num_mids; i++) {
			if (mids[i] != NULL) {
				mids[i]->resp_buf_size = server->pdu_size;

				if (bufs[i] != NULL) {
					if (server->ops->is_network_name_deleted &&
					    server->ops->is_network_name_deleted(bufs[i],
										 server)) {
						cifs_server_dbg(FYI,
								"Share deleted. Reconnect needed");
					}
				}

				if (!mids[i]->multiRsp || mids[i]->multiEnd)
					mids[i]->callback(mids[i]);

				release_mid(mids[i]);
			} else if (server->ops->is_oplock_break &&
				   server->ops->is_oplock_break(bufs[i],
								server)) {
				smb2_add_credits_from_hdr(bufs[i], server);
				cifs_dbg(FYI, "Received oplock break\n");
			} else {
				cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
						atomic_read(&mid_count));
				cifs_dump_mem("Received Data is: ", bufs[i],
					      HEADER_SIZE(server));
				smb2_add_credits_from_hdr(bufs[i], server);
#ifdef CONFIG_CIFS_DEBUG2 
				if (server->ops->dump_detail)
					server->ops->dump_detail(bufs[i],
								 server);//[1]
				cifs_dump_mids(server);
#endif /* CIFS_DEBUG2 */
			}
		}
```
//[2]In smb2_dump_detail, calc_smb_size is called, which refers to smb2_calc_size.



```
static void
smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
{
#ifdef CONFIG_CIFS_DEBUG2
	struct smb2_hdr *shdr = (struct smb2_hdr *)buf;

	cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
		 shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
		 shdr->Id.SyncId.ProcessId);
	cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
		 server->ops->calc_smb_size(buf));//[2]
#endif
}
```
In has_smb2_data_area, it attempts to retrieve an element at the index le16_to_cpu(shdr->Command). If a value larger than the length of has_smb2_data_area is input, an OOB (Out-Of-Bounds) Read occurs."




```
unsigned int
smb2_calc_size(void *buf)
{
	struct smb2_pdu *pdu = buf;
	struct smb2_hdr *shdr = &pdu->hdr;
	int offset; /* the offset from the beginning of SMB to data area */
	int data_length; /* the length of the variable length data area */
	/* Structure Size has already been checked to make sure it is 64 */
	int len = le16_to_cpu(shdr->StructureSize);

	/*
	 * StructureSize2, ie length of fixed parameter area has already
	 * been checked to make sure it is the correct length.
	 */
	len += le16_to_cpu(pdu->StructureSize2);

	if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)//[3]
		goto calc_size_exit;
```
Comment 1 j51569436 2023-12-04 10:54:49 UTC
Created attachment 305537 [details]
crash callstack
Comment 2 Paulo Alcantara 2023-12-16 13:49:30 UTC
Created attachment 305618 [details]
patch 1
Comment 3 Paulo Alcantara 2023-12-16 13:49:51 UTC
Thanks for the report.

Does the attached patch fix your problem?
Comment 4 Paulo Alcantara 2023-12-19 16:19:56 UTC
Created attachment 305633 [details]
patch v2

Follow v2 of this patch.  Please verify.
Comment 6 Steve French 2024-10-03 17:11:17 UTC
This was fixed upstream by:
commit 567320c46a60 ("smb: client: fix potential OOB in
smb2_dump_detail()").

Note You need to log in before you can comment on or make changes to this bug.