| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: only rebind the reopened file's own oplock on durable reconnect
ksmbd_reopen_durable_fd() walks the inode's m_op_list and rebinds every
detached oplock to the reconnecting session:
list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
lockdep_is_held(&ci->m_lock)) {
if (op->conn)
continue;
op->conn = ksmbd_conn_get(fp->conn);
op->sess = work->sess;
}
The only key is op->conn == NULL, which every detached durable handle on
that inode matches, not just the one owned by fp. When two sessions hold
durable handles on the same file and both disconnect, reconnecting one of
them adopts the other session's oplock: op->sess is overwritten with the
reconnecting session without taking a reference on it, while op->conn
pins the connection.
The sibling teardown path, session_fd_check(), keys on the identity of
the connection being torn down (op->conn == conn) rather than on shared
state, and so does not have this problem.
Once the adopting session is destroyed, ksmbd_session_destroy() frees it
while the foreign oplock still points at it. The reader in
ksmbd_close_fd_app_instance_id() validates only opinfo->conn, which is
still live thanks to the reference taken above, and then dereferences the
stale session:
if (!opinfo->conn) {
up_read(&fp->f_ci->m_lock);
goto out;
}
ft = &opinfo->sess->file_table;
write_lock(&ft->lock);
BUG: KASAN: slab-use-after-free in _raw_write_lock+0x74/0xd0
Write of size 4 at addr ffff88810a970528 by task kworker/0:0/9
Workqueue: ksmbd-io handle_ksmbd_work
Call Trace:
_raw_write_lock+0x74/0xd0
ksmbd_close_fd_app_instance_id+0x183/0x410
smb2_open+0x1346/0x4430
handle_ksmbd_work+0x2bb/0x7b0
Reached from an authenticated session against a share with the default
durable-handle and oplock configuration: two sessions open the same file
with a durable-v2 handle and an RH lease under distinct AppInstanceIds,
both log off, one reconnects with DH2C, and a later durable-v2 create
carrying the other AppInstanceId walks into the freed session.
Constrain the loop to the oplock owned by the file being reopened. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix OOB read/write from unvalidated DataOffset in coalesce_t2()
coalesce_t2() computes data pointers directly from server-supplied
DataOffset fields with no validation against buffer bounds:
data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
data_area_of_src = (char *)&pSMBs->hdr.Protocol +
get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
data_area_of_tgt += total_in_tgt;
...
memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
A small DataOffset can push a pointer below the actual byte area,
overwriting header fields; a large one can push it past the buffer
end, causing out-of-bounds heap reads (source) or writes (target).
The BCC overflow guard does not prevent this: BCC reflects how much
data is present, while DataOffset controls where in the buffer it
starts.
The "validate target area" comment present since the function was
first written in 2005 was a placeholder that was never implemented.
Add lower- and upper-bound checks for both data pointers before the
memcpy, and before any target header fields are modified. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix use-before-check of ReparseDataLength in reparse_buf_ptr()
reparse_buf_ptr() reads buf->ReparseDataLength before checking that
count covers the full fixed header:
buf = (struct reparse_data_buffer *)((u8 *)io + off);
len = sizeof(*buf); /* 8 bytes */
rdlen = le16_to_cpu(buf->ReparseDataLength); /* offset 4, 2 bytes */
if (count < len || count < rdlen + len) /* check comes after */
struct reparse_data_buffer has ReparseDataLength at offset 4. If a
server returns OutputCount < 6, the read at offset 4-5 reaches past
the end of the received data. The off+count bounds against iov_len
were already validated, but that does not protect against count being
smaller than sizeof(*buf).
Split the check: verify count >= sizeof(*buf) before reading
ReparseDataLength, then verify count covers the data region. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: reject a tree connect response whose byte count is too small
CIFSTCon() bounds its strnlen() over the byte area with the server's
ByteCount minus two, which for ByteCount 0 or 1 goes negative as an int
and converts to a huge size_t. The later subtraction wraps the __u16
bytes_left, and that is what bounds cifs_strndup_from_utf16(): a bound of
up to 65535 against a ~16 KB cifs_req_poolp object runs off the end of the
slab object, and the bytes reach userspace through tcon->nativeFileSystem
in /proc/fs/cifs/DebugData.
Reject a byte area too small for what the parser consumes. Two bytes is
the least it can consume, and no conformant response carries fewer. The
new trace point is the 129th smb_eio_trace entry, which __mode(byte)
cannot represent, so the attribute goes with it. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: restore the data_offset bound in is_valid_oplock_break()
Commit 83bfbd0bb902 ("cifs: Remove the RFC1002 header from smb_hdr")
changed the quantity this bound is measured against. It used to be
srv->total_read minus the 4-byte RFC1002 preamble that total_read then
included, so it was the SMB message length. The same commit stopped
counting the preamble, and the mechanical substitution to
srv->total_read - srv->pdu_size left an expression that is identically
zero: standard_receive3() reads MID_HEADER_SIZE() bytes and then exactly
pdu_length - MID_HEADER_SIZE() more, adding both to total_read.
len is therefore 0, the subtraction below it wraps, and no __u32
DataOffset can exceed the result, so the check from commit 097f5863b1a0
("cifs: read overflow in is_valid_oplock_break()") no longer rejects
anything. Use total_read, which is now the message length on its own. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: universal-pidff: stop the device when force-feedback init fails
universal_pidff_probe() starts the device with hid_hw_start() and then, if
force-feedback initialisation fails, returns the error through a label that
only does "return error". The device is left started.
The HID core does not unwind on the driver's behalf. __hid_device_probe()
releases the devres group, closes the report and clears hdev->driver:
if (ret) {
devres_release_group(&hdev->dev, hdev->devres_group_id);
hid_close_report(hdev);
hdev->driver = NULL;
}
The hidraw character device that hid_hw_start() registered through
hid_connect() is allocated with kzalloc() and added with cdev_device_add(),
so it is not devres-managed and survives that. With hdev->driver NULL,
hid_device_remove() skips hid_hw_stop() as well, because it only unwinds
while a driver is still attached. The registration therefore outlives the
device on both paths.
Opening the surviving /dev/hidrawX writes into freed memory. KASAN reports
a use-after-free write from hidraw_open() -> hid_hw_open() -> the
transport's open callback, which takes a spinlock inside the freed object.
A descriptor that carries a PID usage page and no input reports is enough:
hidraw claims the device so hid_hw_start() succeeds, while hid->inputs
stays empty so force-feedback init fails. The other failure returns in
hid_pidff_init_with_quirks() - no output reports, an allocation failure,
pidff_init_fields(), pidff_check_autocenter(), an unusable effect count,
input_ff_create() - all reach the same label.
Stop the device on that path. hid-dr.c and hid-emsff.c, which start the
device with the same HID_CONNECT_DEFAULT & ~HID_CONNECT_FF mask, already do
this. The two earlier gotos must keep returning without hid_hw_stop(),
since neither has a started device, so give the path that fails after the
start its own label.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com> |
| In the Linux kernel, the following vulnerability has been resolved:
HID: mcp2221: clear rxbuf after I2C/SMBus transfer completes
mcp_i2c_smbus_read() stores the caller-supplied buffer pointer in
mcp->rxbuf for the duration of a transfer but never clears it when the
transfer finishes or times out. Once the caller frees or reuses the
buffer, mcp->rxbuf becomes a dangling pointer. A delayed or spurious
MCP2221_I2C_GET_DATA report can then drive mcp2221_raw_event() to
memcpy device data into the freed memory, causing a write
use-after-free.
Route all return paths through a single exit point that clears
mcp->rxbuf and mcp->rxbuf_size, so that the existing !mcp->rxbuf guard
in the raw_event handler can reject any report arriving after the
transfer has ended. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: intel-thc-hid: intel-quickspi: validate report size before copy
write_cmd_to_txdma() builds an output report in qsdev->report_buf, a heap
buffer allocated in quickspi_alloc_report_buf() to the device-descriptor
derived max_report_len (a few hundred bytes for a touch controller). It
copies the caller-supplied report into that buffer:
memcpy(write_buf->content, report_buf, report_buf_len);
The HID core caps a report at HID_MAX_BUFFER_SIZE (16384) by default, and
quickspi_hid_ll_driver does not set max_buffer_size, so the length reaches
the driver unbounded. A hidraw SET_REPORT/SET_FEATURE ioctl carrying a
report larger than max_report_len therefore overflows report_buf with
attacker-controlled length and content.
Record the report_buf allocation size and reject reports that do not fit
before copying, matching the equivalent guard in the intel-quicki2c
sibling (quicki2c_init_write_buf()) and the hid-goodix-spi fix.
write_cmd_to_txdma() writes the output report header ahead of the content
in the same buffer, so size the allocation to cover the header as well.
That keeps the added bound from rejecting a maximum-sized report. |
| In the Linux kernel, the following vulnerability has been resolved:
HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer
quickspi_hid_raw_request() receives the caller's buffer length in len, but
quickspi_get_report() never sees it and copies the whole device-supplied
response into buf regardless:
memcpy(buf, qsdev->report_buf, qsdev->report_len);
qsdev->report_len comes from the input report the touch controller returns,
while buf is sized to whatever the caller asked hidraw for through
HIDIOCGFEATURE or HIDIOCGINPUT. A response larger than that overflows buf
with device-controlled content.
The intel-quicki2c sibling already passes the caller length down to
quicki2c_get_report() and validates the response against it before the
copy. Do the same here. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: bound the free-cluster bitmap scan to the volume
vol->lcn_empty_bits_per_page is sized from vol->nr_clusters at mount, but
ntfs_cluster_alloc() bounds its scan of that array by the size of $Bitmap.
Those are independent on-disk quantities and the mount-time check only
rejects a $Bitmap that is too small, so an image whose $Bitmap covers more
clusters than the volume has lets the scan index past the array. A run
whose LCN lies in that gap takes the allocator straight there, since the
caller passes the file's own last LCN as its locality hint. KASAN reports
a slab out-of-bounds read when a file on such a volume is extended.
Clamp the scan to what that array covers, mirroring the max_index
calculation the mount-time scan already uses, and reject a decoded LCN
at or beyond nr_clusters in the mapping pairs decoder. Conforming
volumes are unaffected. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: reject invalid empty mapping pairs
Reject an attribute with empty mapping pairs if it has inconsistent
highest VCN and size. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: reject invalid MFT LCNs from boot sector
The NTFS boot sector stores the MFT and MFTMirr locations as unsigned
64-bit LCNs, but parse_ntfs_boot_sector() decoded them into an s64.
A crafted high-bit value could therefore become negative and pass
the existing upper-bound check. The invalid value then propagated into
the MFT zone allocator and could result in an out-of-bounds access to
lcn_empty_bits_per_page. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: validate non-resident attribute offsets
ntfs_attr_update_meta() shifts the attribute name when converting between
non-sparse and sparse attributes. Converting to sparse also adds the
compressed_size field before the name and mapping pairs, requiring eight
additional bytes in the attribute record.
However, the validator does not check that name_offset is within safe
boundaries for these operations or that the additional space is available.
A malicious MFT record could set name_offset such that:
1. The name is positioned at the very end of a non-sparse attribute.
Converting to sparse would shift the name forward by 8 bytes,
writing beyond the attribute boundary.
2. The name overlaps with the mapping pairs, causing corruption during
conversion.
Add validation to ensure:
- For named attributes, name_offset is within valid bounds
- Name does not extend beyond the attribute or overlap with mapping pairs
- For non-sparse, non-compressed attributes, eight bytes are available
after mapping_pairs_offset for the compressed_size field
The space check also covers unnamed attributes, for which name_offset = 0
is valid and no name range needs to be checked. |
| In the Linux kernel, the following vulnerability has been resolved:
ntfs: verify run length exceeding volume boundary
The mapping pairs decoder validates that the starting LCN is within the
volume but does not check if the run extends beyond the volume boundary.
A malformed NTFS image with a crafted mapping pairs array could cause
the kernel to access memory beyond the volume boundary, potentially leading
to memory corruption and privilege escalation.
Add validation to ensure lcn + length stays within nr_clusters. |
| In the Linux kernel, the following vulnerability has been resolved:
erofs: skip sufficiently large global buffers when resizing
z_erofs_gbuf_nrpages is advanced only after every global buffer has been
grown. If a resize fails after some buffers were enlarged, a retry
revisits those enlarged buffers.
Retrying the same size then returns -ENOMEM because alloc_pages_bulk()
has no pages to add and the unchanged return value is treated as a
failure. Retrying an intermediate size allocates a temporary pointer
array smaller than gbuf->nrpages and copies more existing pointers than
the array can hold.
Skip buffers that already satisfy the request. Once all remaining
buffers have caught up, advancing z_erofs_gbuf_nrpages again describes
the guaranteed minimum size across the pool. |
| In the Linux kernel, the following vulnerability has been resolved:
ext2: Fix lost inode updates for IS_SYNC inodes
ext2_setsize() and ext2_xattr_set2() had a construct like:
if (IS_SYNC(inode)) {
sync_inode_metadata(inode, 1);
} else {
mark_inode_dirty(inode);
}
which leads to lost inode updates for IS_SYNC inodes because
sync_inode_metadata() does anything only if the inode is already dirty
and hence inode updates may be simply lost. Fix the problem by
unconditionally marking the inode dirty and *then* call
sync_inode_metadata(). |
| In the Linux kernel, the following vulnerability has been resolved:
fanotify: fix use-after-free of file range info
fsnotify_pre_content() builds its file_range on the triggering task's
stack. fanotify_alloc_perm_event() saves a pointer to range.pos in the
heap-allocated permission event so copy_range_info_to_user() can report
the offset later.
The event reader can set the event state to FAN_EVENT_REPORTED and then
sleep while preparing the file descriptor. If a signal interrupts the
triggering task at that point, fanotify_get_response() changes the state
to FAN_EVENT_CANCELED and returns. This unwinds the file_range stack
frame while the reader still owns the event. The reader then dereferences
pevent->ppos and copies the stale stack value to userspace.
KASAN reported:
BUG: KASAN: use-after-free in fanotify_read+0x293e/0x2970
Read of size 8 at addr ffff88811434fc50 by task fanotify_inotif/95
Call Trace:
fanotify_read+0x293e/0x2970
vfs_read+0x177/0xa20
ksys_read+0xf7/0x1c0
do_syscall_64+0xf9/0x540
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Store the range position directly in the permission event and use
FANOTIFY_NO_RANGE when range information is unavailable. The event remains
alive until the reader finishes, so the reported offset no longer depends
on the triggering task's stack. |
| In the Linux kernel, the following vulnerability has been resolved:
ACPI: APEI: GHES: fix ARM section length accounting after header
In ghes_handle_arm_hw_error(), after skipping the cper_sec_proc_arm
header with (err + 1), the remaining length was reduced by sizeof(err)
(pointer size) instead of sizeof(*err) (structure size).
That overestimates the bytes left for cper_arm_err_info records and can
let the parser read past the CPER section when err_info_num is large
enough relative to error_data_length.
Use sizeof(*err) so the length accounting matches the pointer advance
and the earlier sizeof(*err) size check. |
| In the Linux kernel, the following vulnerability has been resolved:
block: validate user space vectors during extraction
The bio-based drivers don't necessarily check the alignment split, and
stacking block drivers don't always handle a misalignment detected after
submitting the bio. Validate user vectors against the device's
dma_alignment as the bio is built from the iov_iter, rejecting
misaligned early with -EINVAL. |
| In the Linux kernel, the following vulnerability has been resolved:
bpf, x86: Fix per-CPU address resolution into an extended register
The destination of the per-CPU address MOV is encoded in ModRM.reg,
which is extended by REX.R, but the REX prefix is built with
add_1mod(), which sets REX.B. REX.B extends ModRM.rm and SIB.base, and
this instruction addresses memory as disp32 with no base, so the bit
has no effect at all and the high register bit is simply lost.
Every is_ereg() destination therefore resolves to the wrong register,
picking whichever one shares the low three bits:
R5 -> RAX R7 -> RBP R8 -> RSI R9 -> RDI
With BPF_REG_5, whose reg2hex is 0, the emitted
65 49 03 04 25 <off> add %gs:<off>,%rax
adds the per-CPU offset to RAX rather than R8. The destination keeps
the unadjusted address and RAX is clobbered, so the program goes on to
dereference a pointer that was never made per-CPU:
BUG: unable to handle page fault for address: 0000607e386a8894
RIP: bpf_prog_707837aafd2aa9ae_update_percpu_data+0x93/0xc9
Call Trace:
__bpf_prog_test_run_raw_tp+0x2dc/0x7d0
__flush_smp_call_function_queue+0x1e9/0xc80
Kernel panic - not syncing: Fatal exception in interrupt
R5 is the mildest of the four, aliasing a scratch register and faulting
at the store. R7 aliases RBP and would corrupt the frame pointer, R8
and R9 alias the argument registers.
Use add_2mod() so the register goes through REX.R, matching how
add_2reg() places it in ModRM.reg and how emit_priv_frame_ptr()
hardcodes 0x4c for the same instruction with R9. Encodings for the
non-extended registers are unchanged.
Problem showed up when trying to resurrect BPF_GCC CI (selftests built
with BPF_GCC).
This has gone unnoticed because clang reloads the address into R1
before each per-CPU access, so the destination is never an extended
register. GCC keeps several per-CPU addresses live at once, and
test_progs-bpf_gcc panics the kernel in global_percpu_data/init, where
the address of a .percpu variable ends up in R5. |