Bug 218218

Summary: Out-Of-Bounds Read vulnerability in smbCalcSize
Product: File System Reporter: j51569436
Component: CIFSAssignee: fs_cifs (fs_cifs)
Status: NEW ---    
Severity: normal CC: lsahlber, pc
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: 6.7.0 Subsystem:
Regression: No Bisected commit-id:
Attachments: POC of bug
patch 1
patch 2

Description j51569436 2023-12-04 10:37:45 UTC
[1] Retrieve WordCount and add offset*2 to the data part of smb
[2] Retrieve a 16-byte value from the calculated pointer

```c
unsigned int
smbCalcSize(void *buf)
{
	struct smb_hdr *ptr = buf;
	return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
		2 /* size of the bcc field */ + get_bcc(ptr));
}
...
static inline __u16
get_bcc(struct smb_hdr *hdr)
{
	__le16 *bc_ptr = (__le16 *)BCC(hdr);

	return get_unaligned_le16(bc_ptr);//[2]
}
...
static inline void *
BCC(struct smb_hdr *smb)
{
	return (void *)smb + sizeof(*smb) + 2 * smb->WordCount; //[1]
}
```


[2] cifs_demultiplex_thread → standard_receive3 → cifs_handle_standard → checkSMB → smbCalcSize

```c
int
checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
{
	struct smb_hdr *smb = (struct smb_hdr *)buf;
	__u32 rfclen = be32_to_cpu(smb->smb_buf_length);
	__u32 clc_len;  /* calculated length */
	cifs_dbg(FYI, "checkSMB Length: 0x%x, smb_buf_length: 0x%x\n",
		 total_read, rfclen);

	/* is this frame too small to even get to a BCC? */
	if (total_read < 2 + sizeof(struct smb_hdr)) {
...
	}

	/* otherwise, there is enough to get to the BCC */
	if (check_smb_hdr(smb))
		return -EIO;
	clc_len = smbCalcSize(smb);
```
Comment 1 j51569436 2023-12-04 10:38:17 UTC
Created attachment 305536 [details]
POC of bug
Comment 2 Paulo Alcantara 2023-12-16 13:46:39 UTC
Created attachment 305616 [details]
patch 1
Comment 3 Paulo Alcantara 2023-12-16 13:46:56 UTC
Created attachment 305617 [details]
patch 2
Comment 4 Paulo Alcantara 2023-12-16 13:47:52 UTC
Thanks for the report.

Does the attached patches fix your problem?