| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
ipmi: Fix use-after-free of cmd_rcvr in _ipmi_destroy_user()
Commit 9e91f8a6c868 ("ipmi:msghandler: Remove srcu for the
ipmi_interfaces list") dropped the synchronize_rcu() between unlinking
the command receivers from intf->cmd_rcvrs and freeing them, updating
only the comment that explains why the barrier is needed.
The cmd_rcvrs list is still traversed under plain RCU: find_cmd_rcvr()
walks it inside rcu_read_lock(), and handle_ipmb_get_msg_cmd() borrows
rcvr->user from that lookup within the same read-side section. Without
the grace period, _ipmi_destroy_user() can kfree() a cmd_rcvr while a
reader still holds a pointer to it, causing a use-after-free.
The rework only made srcu unnecessary for the interfaces list; the
cmd_rcvrs list still relies on plain RCU. Restore the synchronize_rcu()
before freeing the receivers. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: charger-manager: register regulators before exposing sysfs
charger_manager_remove() and the err_reg_extcon probe error path free each
charger regulator with regulator_put() before tearing down the power_supply
sysfs entries (power_supply_unregister()). charger_manager_remove() also
calls try_charger_enable(cm, false) after the regulator_put() loop. A
concurrent write to a charger's externally_control sysfs attribute that
lands between regulator_put() and power_supply_unregister() can run
charger_externally_control_store() and call try_charger_enable(), which,
when charging is enabled, dereferences the already-freed consumer handle.
When charging is enabled, try_charger_enable(cm, false) in .remove() also
dereferences the freed handles directly. Both leave use-after-free windows.
Symmetrically, probe registers the sysfs entries (power_supply_register)
before acquiring the regulators (regulator_get, inside
charger_manager_register_extcon), so userspace can reach externally_control
before the regulators are available.
Split charger_manager_register_extcon() on the sync/async boundary:
charger_manager_get_regulators() (regulator_get only, no async producer)
now runs before power_supply_register() so sysfs is not live before
regulators are available, and charger_manager_register_extcon() keeps only
the extcon notifier/work setup, still after power_supply_register() so a
power_supply_register() failure cannot reach extcon setup. This keeps the
sysfs setup/teardown ordering symmetric without introducing an asynchronous
producer on the earlier probe-error path.
Move power_supply_unregister() and try_charger_enable(cm, false) ahead of
the regulator_put() loop on both teardown paths, and adjust err_reg_extcon
(power_supply_unregister() then fall through err_regulator for
regulator_put(); get_regulators self-rolls back on its own failure).
This does not address the separate extcon-notifier-driven deref of the same
handles, which needs its own synchronization design.
Found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/percpu: Fix MVIY_PERCPU() with older binutils
Commit a737737cdb9c ("s390/percpu: Infrastructure for more efficient
this_cpu operations") introduced MVIY_PERCPU(), which stringifies
arguments that are already C string literals. This generates an
assembler macro invocation with whitespace-separated quoted arguments:
GEN_MVIY "459712" "%r3"
GNU as versions prior to binutils 2.39 drop the separating whitespace
between quoted macro arguments during input scrubbing. They
consequently parse the invocation as a single argument and emit
repeated warnings:
Warning: missing closing `"'
The .ifc in GEN_MVIY never matches and GNU as exits successfully
without emitting the mviy instruction. As a result, the interrupted
per-CPU sequence is not marked in lowcore and the exception return
path cannot repair the per-CPU address register after migration.
All MVIY_PERCPU() callers pass C string literals. Use them directly
and separate the assembler macro arguments with an explicit comma. The
resulting invocation is:
GEN_MVIY 459712, %r3
This form is unambiguous for GNU as and LLVM's integrated assembler.
This behavior was fixed in GNU as from binutils 2.39, but Linux
supports binutils 2.30. |
| In the Linux kernel, the following vulnerability has been resolved:
iommu/msm: Unwind probe state on registration failure
msm_iommu_probe() adds its devm-managed IOMMU object to
qcom_iommu_devices before adding the IOMMU sysfs device and registering
it with the IOMMU core.
If iommu_device_sysfs_add() fails, probe returns with the object still on
qcom_iommu_devices. The driver core then releases the devm allocation,
leaving a dangling list entry that later list walks may dereference.
If iommu_device_register() fails, the same dangling list entry remains
and the sysfs device is left registered as well.
Unwind the sysfs device and global list entry in reverse setup order on
the corresponding failure paths. |
| In the Linux kernel, the following vulnerability has been resolved:
iommu/tegra241-cmdqv: Reject a vSID wider than the SID_MATCH field
tegra241_vintf_init_vsid() programs the guest-provided vSID into SID_MATCH,
whose VIRT_SID field spans bits [20:1] with bit 0 as the match-enable flag.
The HW therefore matches only a 20-bit Stream ID.
The bound check rejects only virt_sid > UINT_MAX, which admits a value far
wider than the field. The write "virt_sid << 1 | 0x1" then drops every bit
above 20: a virt_sid of 0x80000000 lands as SID_MATCH = 0x1, a valid match
on vSID 0, so the entry aliases the wrong Stream ID. Because vdev->virt_id
is guest-controlled, a VMM can trigger it.
Validate virt_sid against the field width with FIELD_MAX(), and program the
register with FIELD_PREP() so the value and the field stay consistent. |
| In the Linux kernel, the following vulnerability has been resolved:
iommufd: Fix UAF in selftest IOPF reporting
IOMMUFD selftest TRIGGER_IOPF borrows an attach handle from
group->pasid_array without synchronizing against PASID detach,
then a concurrent iommu_report_device_fault() can dereference
that borrowed handle's domain pointer after the detach erases
the handle and frees the backing struct iommufd_attach_handle.
TRIGGER_IOPF then dereferences the freed handle, causing a UAF.
Fix by adding a iopf_rwsem in mock_dev to follow the expected design
of a real driver. Hold its read side across the whole
iommu_report_device_fault() call, and its write side around every
path that attaches, detaches, or replaces a device domain.
This can block new reports and drains in-flight reports before an old
attach handle or the IOPF fault parameter can be removed.
Also take the write side while registering a mock device, since
it can invoke the mock driver's default-domain attach callback. |
| In the Linux kernel, the following vulnerability has been resolved:
mmc: via-sdmmc: cancel card-detect work on remove
Disabling the device interrupt and freeing the IRQ prevents new card-detect
work from being queued, but carddet_work already queued by the handler can
still run after via_sd_remove() returns. via_sdc_card_detect() recovers the
host through container_of() and dereferences its MMIO base; once remove()
returns the host can be freed, so that work would touch freed memory.
Cancel carddet_work after freeing the IRQ and before cancelling
finish_bh_work, which the card-detect handler can also queue. carddet_work
can re-enable the interrupt through via_reset_pcictrl(); mask it again
afterwards.
This issue was found by an in-house static analysis tool and confirmed by
manual code review. |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86/amd/pmc: Propagate SMU errors and validate S2D address
amd_stb_s2d_init() discards the return value of several S2D SMU commands.
When the SMU refuses a command (e.g. "SMU cmd failed. err: 0xff") the
failure is only noticed indirectly - if at all - and reported as -EIO,
masking the real error.
More seriously, the S2D_PHYS_ADDR_LOW/HIGH return values are ignored, so
on failure phys_addr_low/hi are left uninitialised and the assembled
address is passed straight to devm_ioremap(). When the SMU leaves them at
zero this maps physical address 0 and trips the ioremap-on-RAM warning:
amd_pmc AMDI000B:00: SMU cmd failed. err: 0xff
ioremap on RAM at 0x0000000000000000 - 0x0000000000ffffff
WARNING: CPU: 13 PID: 4592 at arch/x86/mm/ioremap.c:...
Check the return value of each SMU command and propagate it, and reject a
zero physical address before calling devm_ioremap(). |
| In the Linux kernel, the following vulnerability has been resolved:
platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails
amd_pmc_probe() registers the LPS0 s2idle handler with
acpi_register_lps0_dev() and creates the driver's debugfs directory before
calling amd_stb_s2d_init(), which is the last step in probe that can fail.
When amd_stb_s2d_init() fails (for example the S2D telemetry region cannot
be ioremapped on a long-running system, or the SMU rejects the S2D setup)
the error path only calls pci_dev_put() and returns. This leaves
amd_pmc_s2idle_dev_ops on the global lps0_s2idle_devops_head list and leaks
the debugfs directory, while the devm-managed resources backing the handler
are torn down.
Reloading the module then walks the corrupted list in
acpi_register_lps0_dev() and hits:
list_add corruption. next->prev should be prev, but was NULL.
kernel BUG at lib/list_debug.c:29!
acpi_register_lps0_dev+0x44/0x80
amd_pmc_probe+0x224/0x380 [amd_pmc]
platform_probe+0x67/0x90
Even without a reload, the stale registration means the next s2idle
transition calls into torn-down driver state.
Unwind the debugfs directory and the LPS0 registration on the
amd_stb_s2d_init() error path. acpi_unregister_lps0_dev() is safe to call
unconditionally here: it is guarded on the same conditions as
acpi_register_lps0_dev(), which is exactly what amd_pmc_remove() already
relies on. |
| In the Linux kernel, the following vulnerability has been resolved:
ipmi: Remove all sysfs files on registration failure
ipmi_add_smi() creates the nr_users and nr_msgs files before trying to
create the maintenance_mode file. If that last creation fails, the error
path removes only nr_users before dropping the final reference to the
interface.
Remove nr_msgs as well so no sysfs attribute embedded in the freed
interface remains registered. |
| In the Linux kernel, the following vulnerability has been resolved:
ipmi:msghandler: Cancel work cleanly on an error
If an error occurs during startup of an IPMI interface, it may have
scheduled work to run. The work needs to be canceled before the
interface can be freed. |
| In the Linux kernel, the following vulnerability has been resolved:
net: bnxt: ring the doorbell when SW USO exits early
When a burst of packets is handed down to the driver, the driver defers
the doorbell to the end by setting txr->kick_pending = 1. The normal TX
path handles this, but the SW USO path can miss it if it returns
early.
If bnxt_sw_udp_gso_xmit runs but returns early with NETDEV_TX_BUSY and
txr->kick_pending was previously set to 1, then the TX queue can
stall because the driver wrote some BDs but never wrote the doorbell.
The device won't know to do the TX which would generate the completion
that would wake the queue back up.
Simplify bnxt_sw_udp_gso_xmit to set txr->kick_pending in its success
case and check the flag on return. The added check after
bnxt_sw_udp_gso_xmit returns ensures that any pending doorbells are
written handling both successful USO and any early returns, which
prevents the TX queue stall mentioned above.
This TX queue stall was observed on a production system with a netdev TX
watchdog informing about the queue stall. |
| In the Linux kernel, the following vulnerability has been resolved:
net: ipa: fix stalled modem TX queue after runtime resume
ipa_start_xmit() unconditionally stops the TX queue before calling
pm_runtime_get(), relying on the wake scheduled by runtime resume
(ipa_modem_wake_queue_work()) to restart it once power is ACTIVE.
But that work is queued from within the runtime resume callback,
before the device's power state reaches RPM_ACTIVE, so it can run
while the device is still RPM_RESUMING. The wake is then consumed
too early: the transmit it restarts stops the queue again,
pm_runtime_get() returns -EINPROGRESS without arranging any future
wake (deferred_resume exists only for RPM_SUSPENDING), and after the
resume completes nothing is left to wake the queue. Transmit stalls
permanently: packets pile up in the qdisc behind the stopped queue,
the device runtime-suspends, and since the netdev registers no
ndo_tx_timeout the watchdog never fires. Observed on SM7635
(Fairphone 6) as the cellular data path going permanently deaf
within hours, RX included, since nothing resumes the suspended
endpoints.
Close the window by making the wake work wait for the resume to
complete (pm_runtime_get_sync()) before waking the queue. Every
queue stop is then guaranteed a later wake that happens while power
is ACTIVE; a transmit racing a new suspend/resume cycle re-schedules
the work. If the device could not be resumed, wake the queue anyway
so pending packets are dropped by the transmit path rather than
stranded.
The STARTED power flag used to narrow this window: a wake running
before the transmit path's stop suppressed that stop, but only once,
as the flag was cleared by the first stop it absorbed. Removing the
flag made a single transmit during an in-flight resume sufficient to
strand the queue, which is the form observed.
With an accelerated reproducer (autosuspend delay shortened to 5 ms,
~20 packets/s of TX), an unpatched kernel stalled three times in
230 s / 4380 packets; with this patch the same test ran 3601 s /
70298 packets without a stall. |
| In the Linux kernel, the following vulnerability has been resolved:
net: mctp: hold a reference to the route device in mctp_route_lookup()
mctp_route_lookup() uses rt->dev without holding a reference on it.
mctp_route_lookup_single() returns the route under RCU only, so the
route's device can be torn down concurrently: mctp_dev_put() drops the
last reference and synchronously kfree()s mdev->addrs. mctp_dev_saddr()
then reads rt->dev->addrs[0], giving a use-after-free reachable by an
unprivileged local AF_MCTP user on the receive/forwarding path (no
CAP_NET_RAW required):
BUG: KASAN: slab-use-after-free in mctp_route_lookup
Read of size 1 at addr ... by task mctp_uaf/...
mctp_route_lookup
mctp_pkttype_receive
Freed by task ...:
kfree
mctp_dev_put
mctp_dev_notify
In the same window mctp_dst_from_route() -> mctp_dev_hold() also
increments a refcount that has already reached zero
("refcount_t: addition on 0 ... mctp_dev_hold").
This reintroduces the use-after-free class of CVE-2023-3439: the source
address lookup was moved ahead of the point where the destination takes
its device reference.
Take a reference with refcount_inc_not_zero() before touching rt->dev,
skip a device that is already dead, and drop the reference once the
destination has taken its own. |
| In the Linux kernel, the following vulnerability has been resolved:
net: ravb: serialize PTP clock teardown
ravb_ptp_interrupt() can race with ravb_ptp_stop() and pass the clock to
ptp_clock_event() while ptp_clock_unregister() is freeing it. This can
lead to a use-after-free.
Use READ_ONCE() and WRITE_ONCE() for lockless access to the clock pointer.
Atomically detach it with xchg() before disabling PTP interrupts, then
synchronize all IRQs which can invoke ravb_ptp_interrupt() before
unregistering the detached clock.
A handler which read the old pointer completes before the clock is
unregistered, while later handlers read NULL and skip the event. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: bound the peer rkey counts in SMC-Rv2 LLC messages
On a link whose device has max_recv_sge == 1 there is no shared v2 receive
buffer, and smc_llc_save_add_link_rkeys() takes the v2 extension from 44
bytes past the start of the queue entry's inline message:
ext = (struct smc_llc_msg_add_link_v2_ext *)(llc_msg + SMC_WR_TX_SIZE);
The entry is a 72-byte allocation and the extension starts at offset 68, so
ext->num_rkeys at offset 94 is already past it. This happens on every
SMC-Rv2 link addition, whatever the peer sends:
[ 2.490065] BUG: KASAN: slab-out-of-bounds in smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490431] Read of size 2 at addr ffff8880056406de by task smctest/106
[ 2.490709]
[ 2.490792] CPU: 0 UID: 0 PID: 106 Comm: smctest Not tainted 7.2.0-rc5-p1-g77a5d9d9c99f #32 PREEMPT(lazy)
[ 2.490795] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2.490798] Call Trace:
[ 2.490803] <TASK>
[ 2.490805] dump_stack_lvl+0x53/0x70
[ 2.490810] print_report+0xd0/0x630
[ 2.490828] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 2.490832] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490834] kasan_report+0xce/0x100
[ 2.490836] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490837] smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.490839] ? smcr_buf_map_lgr+0x1bf/0x2b0
[ 2.490844] smc_llc_cli_add_link+0xca7/0x1e80
[ 2.490848] ? smc_llc_wait+0x355/0x810
[ 2.490850] ? __pfx_smc_llc_wait+0x10/0x10
[ 2.490851] ? __pfx_smc_llc_cli_add_link+0x10/0x10
[ 2.490853] ? __pfx_autoremove_wake_function+0x10/0x10
[ 2.490863] __smc_connect+0x3f5c/0x4980
[ 2.490873] ? __pfx_kernel_connect+0x10/0x10
[ 2.490888] ? __pfx___smc_connect+0x10/0x10
[ 2.490891] ? release_sock+0x148/0x1d0
[ 2.490894] smc_connect+0x42c/0x580
[ 2.490896] __sys_connect+0xfc/0x130
[ 2.490898] ? __pfx___sys_connect+0x10/0x10
[ 2.490900] ? handle_mm_fault+0x1a1/0x430
[ 2.490908] __x64_sys_connect+0x6d/0xb0
[ 2.490909] ? fpregs_assert_state_consistent+0x56/0xe0
[ 2.490917] do_syscall_64+0xf9/0x540
[ 2.490921] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2.490924] RIP: 0033:0x421bb4
[ 2.490927] Code: ff f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 80 3d ad 34 09 00 00 74 13 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 4c c3 0f 1f 00 55 48 89 e5 48 83 ec 10 89 55
[ 2.490929] RSP: 002b:00007ffd473b01a8 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
[ 2.490935] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000421bb4
[ 2.490936] RDX: 0000000000000010 RSI: 00007ffd473b01d0 RDI: 0000000000000003
[ 2.490937] RBP: 0000000000003930 R08: 0000000000000004 R09: 0000000000000000
[ 2.490938] R10: 00007ffd473b0f98 R11: 0000000000000202 R12: 0000000000000006
[ 2.490939] R13: 00007ffd473b0f87 R14: 0000000000000003 R15: 00007ffd473b0f90
[ 2.490940] </TASK>
[ 2.490941]
[ 2.499545] Allocated by task 44:
[ 2.499693] kasan_save_stack+0x33/0x60
[ 2.499860] kasan_save_track+0x14/0x30
[ 2.500026] __kasan_kmalloc+0x8f/0xa0
[ 2.500190] __kmalloc_cache_noprof+0x158/0x370
[ 2.500393] smc_llc_enqueue+0x72/0x560
[ 2.500559] smc_wr_rx_tasklet_fn+0x474/0xa80
[ 2.500747] tasklet_action_common+0x20f/0x8a0
[ 2.500945] handle_softirqs+0x18e/0x590
[ 2.501115] do_softirq+0x3b/0x60
[ 2.501266] __local_bh_enable_ip+0x61/0x70
[ 2.501446] __alloc_skb+0x732/0x890
[ 2.501604] rxe_init_packet+0x16b/0x4f0
[ 2.501783] prepare_ack_packet+0xb8/0x830
[ 2.501962] rxe_receiver+0x495/0x96e0
[ 2.502125] do_work+0x144/0x470
[ 2.502269] process_one_work+0x633/0x1030
[ 2.502450] worker_thread+0x45b/0xd10
[ 2.50261
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: carry oversized SMC-Rv2 LLC messages in the queue entry
smc_llc_rmt_delete_rkey() and smc_llc_save_add_link_rkeys() read the part
of a v2 message that does not fit into the 44-byte union smc_llc_msg, and
both bound themselves by the size of the buffer it landed in, not by what
arrived. On a link with a shared v2 receive buffer a 44-byte
DELETE_RKEY_V2 declaring 255 rkeys reaches rkey[9..254] in whatever an
earlier message left in lgr->wr_rx_buf_v2, and passes each of them to
smc_rtoken_delete(). One of those 255 matched a registered rtoken and
deleted it. An ADD_LINK on such a link installs up to 255 rtokens from
the same bytes.
Copy the tail into the queue entry, so its length is the length of the
message that arrived, and declare the rkeys that fit inline as a member of
the union instead of reaching them through a cast. The same
DELETE_RKEY_V2 now processes the 9 rkeys it carries. The copy is limited
to the longest tail the two functions can read, so the peer does not pick
the size of the entry.
The bound the previous patch placed on links without a shared v2 receive
buffer is no longer needed. |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: fix use-after-free of the LLC qentry in smc_llc_srv_add_link()
smc_llc_srv_add_link() keeps add_llc pointing into the queue entry:
add_llc = &qentry->msg.add_link; smc_llc.c:1482
...
smc_llc_save_add_link_info(link_new, add_llc); smc_llc.c:1494
smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); smc_llc.c:1495
...
u8 *llc_msg = smc_link_shared_v2_rxbuf(link) ?
(u8 *)lgr->wr_rx_buf_v2 : (u8 *)add_llc; smc_llc.c:1504
smc_llc_save_add_link_rkeys(link, link_new, llc_msg); smc_llc.c:1506
smc_llc_flow_qentry_del() kfree()s the entry, so on a link without a shared
v2 receive buffer the pointer handed to smc_llc_save_add_link_rkeys() is
already freed. Before the Fixes: commit that branch always used
lgr->wr_rx_buf_v2 and add_llc was not used after the free.
Reproduced on an unpatched tree over rxe, with KASAN, kasan_multi_shot
and a link forced to max_recv_sge == 1: the entry is freed and read by
the same call, and the freeing frame is smc_llc_srv_add_link() itself.
[ 2.523161] BUG: KASAN: slab-use-after-free in smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523499] Read of size 2 at addr ffff8880052194de by task kworker/0:1/11
[ 2.523789]
[ 2.523862] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0-rc5-p0-g2c9dd296545d #35 PREEMPT(lazy)
[ 2.523865] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2.523866] Workqueue: smc_hs_wq smc_listen_work
[ 2.523869] Call Trace:
[ 2.523870] <TASK>
[ 2.523871] dump_stack_lvl+0x53/0x70
[ 2.523872] print_report+0xd0/0x630
[ 2.523874] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 2.523876] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523878] kasan_report+0xce/0x100
[ 2.523879] ? smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523881] smc_llc_save_add_link_rkeys+0x333/0x350
[ 2.523883] ? smcr_buf_reg_lgr+0x2a4/0x660
[ 2.523885] smc_llc_srv_add_link+0xaa2/0x1e50
[ 2.523888] ? _printk+0xba/0xf0
[ 2.523897] ? __pfx_smc_llc_srv_add_link+0x10/0x10
[ 2.523899] ? down_write+0xb0/0x130
[ 2.523903] ? __pfx_down_write+0x10/0x10
[ 2.523905] smc_listen_work+0x489e/0x4d00
[ 2.523907] ? kmem_cache_free+0x1c6/0x3a0
[ 2.523911] ? __pfx_smc_listen_work+0x10/0x10
[ 2.523913] ? release_sock+0x148/0x1d0
[ 2.523915] ? smc_tcp_listen_work+0xb4f/0xfc0
[ 2.523917] ? _raw_spin_lock_irq+0x80/0xe0
[ 2.523918] ? __pfx__raw_spin_lock_irq+0x10/0x10
[ 2.523920] process_one_work+0x633/0x1030
[ 2.523922] ? assign_work+0x11d/0x370
[ 2.523924] worker_thread+0x45b/0xd10
[ 2.523926] ? __pfx_worker_thread+0x10/0x10
[ 2.523928] ? __pfx_worker_thread+0x10/0x10
[ 2.523929] kthread+0x2c6/0x3b0
[ 2.523931] ? recalc_sigpending+0x15c/0x1e0
[ 2.523934] ? __pfx_kthread+0x10/0x10
[ 2.523935] ret_from_fork+0x36e/0x5a0
[ 2.523937] ? __pfx_ret_from_fork+0x10/0x10
[ 2.523938] ? __switch_to+0x572/0xdd0
[ 2.523943] ? __pfx_kthread+0x10/0x10
[ 2.523944] ret_from_fork_asm+0x1a/0x30
[ 2.523947] </TASK>
[ 2.523948]
[ 2.531253] Allocated by task 48:
[ 2.531399] kasan_save_stack+0x33/0x60
[ 2.531570] kasan_save_track+0x14/0x30
[ 2.531737] __kasan_kmalloc+0x8f/0xa0
[ 2.531905] __kmalloc_cache_noprof+0x158/0x370
[ 2.532100] smc_llc_enqueue+0x72/0x560
[ 2.532268] smc_wr_rx_tasklet_fn+0x474/0xa80
[ 2.532491] tasklet_action_common+0x20f/0x8a0
[ 2.532714] handle_softirqs+0x18e/0x590
[ 2.532886] do_softirq+0x3b/0x60
[ 2.533036] __local_bh_enable_ip+0x61/0x70
[ 2.533221] __alloc_skb+0x732/0x890
[ 2.533384] rxe_init_packet+0x16b/0x4f0
[ 2.533567] prepare_ack_packet+0xb8/0x830
[ 2.533760] rxe_receiver+0x495/0x96e0
[ 2.533933] do_work+0x144/0x470
[ 2
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
net/smc: stop killed, freed and out_of_sync sharing a byte
The three connection state flags are single-bit bitfields, so they occupy
one byte of struct smc_connection and every store to one is a
read-modify-write of the other two:
u8 killed : 1;
u8 freed : 1;
u8 out_of_sync : 1;
They are not written under a common lock. smc_cdc_msg_validate() sets
out_of_sync from the receive tasklet, while smc_conn_kill() sets killed
from process context under lock_sock(), and the receive path does not defer
to the backlog when the socket is owned -- smc_cdc_msg_recv() takes only
bh_lock_sock().
Give each flag its own byte so a store no longer touches its neighbours.
All readers test them as booleans and are unchanged. struct smc_connection
grows by two bytes. |
| In the Linux kernel, the following vulnerability has been resolved:
mfd: qnap-mcu: keep the reply buffer alive past a command timeout
qnap_mcu_exec() publishes an on-stack buffer to the receive path:
unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE];
...
reply->data = rx;
reply->length = length;
and qnap_mcu_receive_buf() writes into it from the serdev receive path,
which runs out of flush_to_ldisc() and is not serialized against
qnap_mcu_exec() at all. bus_lock cannot cover it, because qnap_mcu_exec()
holds that mutex across wait_for_completion_timeout().
On a timeout qnap_mcu_exec() returns with reply->data still pointing at
its own frame. A reply that arrives late, or an unsolicited message from
the MCU, is then written into a stack frame that has been left, corrupting
whatever runs next on that stack. The same applies when qnap_mcu_write()
fails, since that path returns without touching the reply state either.
Move the receive buffer into struct qnap_mcu. It is 37 bytes and the
structure is devm_kzalloc()ed, so it lives as long as the driver, and a
late write lands in memory that is still valid and is reinitialized by the
next command. bus_lock keeps commands from sharing it.
This deliberately does not clear reply->data or reply->length on the
timeout path. Doing so races with qnap_mcu_receive_buf(), which reads both
after its
if (!reply->length)
return size;
check: clearing reply->data gives a NULL dereference, and clearing
reply->length alone removes the reply->received == reply->length exit
condition, so the copy loop runs until the uart chunk is consumed and
overruns the buffer. Leaving both set keeps the write bounded by
reply->length, which qnap_mcu_exec() has already checked against
sizeof(mcu->rx). |