Author: ZhaoJinming <zhaojinming@uniontech.com>
Date: Wed Jun 10 15:10:44 2026 +0800
accel/rocket: Fix error path handling in rocket_job_run()
commit 9b2dedadf6a91ac3fc9fae268bb556a041222711 upstream.
In rocket_job_run(), after taking an extra fence reference for
job->done_fence via dma_fence_get(), the error paths have three bugs:
- The dma_fence reference held by job->done_fence is never released,
causing a reference leak.
- pm_runtime_get_sync() increments the usage counter even on failure,
but the error path does not decrement it, leaking the runtime PM
reference and preventing the NPU from suspending.
- A valid but unsignaled fence is returned to the DRM scheduler,
which triggers WARN("Fence ... released with pending signals!")
when the scheduler drops its reference.
Fix by replacing pm_runtime_get_sync() with pm_runtime_resume_and_get()
which auto-balances the usage counter on failure, releasing both fence
references on error, and returning ERR_PTR(ret) instead of the
unsignaled fence.
Cc: stable@vger.kernel.org
Fixes: 0810d5ad88a1 ("accel/rocket: Add job submission IOCTL")
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Link: https://lore.kernel.org/r/20260610071045.3414828-1-zhaojinming@uniontech.com
[tomeu: Refactored error paths to use consolidated goto labels]
Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Sun May 24 15:57:16 2026 +0000
accel/rocket: fix NULL dereference and integer overflow in rocket_job_push()
commit a85402bff218f2b8f0d806e46c16c2f3d49cdda7 upstream.
rocket_job_push() allocates a temporary array to hold all input and
output GEM object pointers:
bos = kvmalloc_array(job->in_bo_count + job->out_bo_count,
sizeof(void *), GFP_KERNEL);
memcpy(bos, job->in_bos, job->in_bo_count * sizeof(void *));
memcpy(&bos[job->in_bo_count], job->out_bos, ...);
Two bugs exist:
1. Missing NULL check: if kvmalloc_array() fails, bos is NULL and
the subsequent memcpy() dereferences it, causing a kernel NULL
pointer dereference.
2. Integer overflow: in_bo_count and out_bo_count are both u32, set
directly from userspace-supplied in_bo_handle_count and
out_bo_handle_count with no prior validation. Their sum is computed
in u32 arithmetic and can wrap to a smaller value, causing the
allocation count passed to kvmalloc_array() to be smaller than
intended. Subsequent uses still operate on the original counts when
copying and locking objects, which may lead to out-of-bounds accesses
on the temporary array.
Fix by using check_add_overflow() to detect count overflow before the
allocation, and adding a NULL check on the allocation result.
Fixes: 0810d5ad88a1 ("accel/rocket: Add job submission IOCTL")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://lore.kernel.org/r/20260524155716.90955-1-meatuni001@gmail.com
Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuvam Pandey <shuvampandey1@gmail.com>
Date: Wed Jul 1 10:15:52 2026 -0700
accel/rocket: initialize job domain before cleanup paths
commit 70e6a33d68a9b03335c5426332666e52d07f45d6 upstream.
rocket_ioctl_submit_job() releases rjob through rocket_job_put() on
allocation error paths. rocket_job_cleanup() unconditionally calls
rocket_iommu_domain_put(job->domain), but job->domain is assigned only
after task copying and BO lookups. A failure before that assignment can
therefore clean up a job with a NULL domain pointer.
Take the per-file domain reference before the first error path can release
rjob. Also clear rjob->tasks after freeing it in rocket_copy_tasks(), so
the common cleanup path cannot free the task array again after a task-copy
error.
Fixes: 0810d5ad88a1 ("accel/rocket: Add job submission IOCTL")
Cc: stable@vger.kernel.org
Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
Link: https://lore.kernel.org/r/6a454b48.6a8fa39a.27019b.984b@mx.google.com
Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Terry Bowman <terry.bowman@amd.com>
Date: Mon Aug 3 17:17:59 2026 -0500
acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks
commit 6625ca499c3131ef63be3215f8f942d7a097ea3a upstream.
The CXL CPER work registration and unregistration helpers acquire
cxl_cper_work_lock and cxl_cper_prot_err_work_lock with a spinlock
guard(), which leaves local interrupts enabled. The corresponding post
paths (cxl_cper_post_event(), cxl_cper_post_prot_err()) execute in hard
IRQ context (they are called from the GHES error notification path) and
acquire the same locks with an irqsave guard().
If a CPU is holding one of these locks via a spinlock guard() when a GHES
interrupt arrives on the same CPU, the IRQ handler spins on the held lock
waiting for it to release, while the lock holder is preempted by the IRQ.
The result is a deadlock.
Convert both locks from spinlock_t to raw_spinlock_t and use guard() at
all call sites. On PREEMPT_RT kernels spinlock_t is backed by rt_mutex and
sleeping from hard IRQ context is not permitted; raw_spinlock_t is safe in
both contexts.
Add WARN_ONCE to both register functions to surface double-registration
bugs at runtime.
Restructure both unregister functions to clear the global work pointer
under the lock before calling cancel_work_sync(), closing the window
where a CPER interrupt could schedule work on a pointer about to be
freed. Add kfifo_reset() after cancel_work_sync() so stale entries
are not replayed on next module load.
Both kfifos are single-consumer: only one work_struct is registered at
a time, enforced by the WARN_ONCE guard in the register functions.
kfifo_reset() is safe outside the lock because cancel_work_sync() has
already quiesced the consumer, and no new consumer can register until
the current module exit completes and a fresh module init runs.
Remove the redundant cancel_work_sync() call from cxl_ras_exit() and
cxl_pci_driver_exit(). The CPER unregister functions now quiesce
the work internally.
Reported-by: Sashiko <sashiko@linuxfoundation.org>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Fixes: 5e4a264bf8b5 ("acpi/ghes: Process CXL Component Events")
Fixes: 36f257e3b0ba ("acpi/ghes, cxl/pci: Process CXL CPER Protocol Errors")
Cc: stable@vger.kernel.org
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260803221810.3685703-4-terry.bowman@amd.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nirmoy Das <nirmoyd@nvidia.com>
Date: Tue Jul 21 11:25:51 2026 -0700
ACPI: APEI: Fix ERST timeout unit conversion
commit a685d8eea4a6899dc887e393927c16fa18ff5e9a upstream.
The ACPI specification defines bits 63:32 returned by
GET_EXECUTE_OPERATION_TIMINGS as the maximum execution time in
microseconds. erst_get_timeout() instead multiplies the value by
NSEC_PER_MSEC.
Use NSEC_PER_USEC to express the firmware-provided microsecond timeout
in the nanosecond units expected by erst_timedout().
Fixes: fac475aab70b ("ACPI: APEI: Use ERST timeout for slow devices")
Cc: stable@vger.kernel.org
Signed-off-by: Nirmoy Das <nirmoyd@nvidia.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Link: https://patch.msgid.link/20260721182551.2434933-1-nirmoyd@nvidia.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: TanZheng <tanzheng@kylinos.cn>
Date: Thu Aug 6 09:09:44 2026 +0800
ACPI: APEI: GHES: fix ARM section length accounting after header
commit 903308ea40adf0577d82eab69882faf8836326ce upstream.
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.
Fixes: 87880af2d24e ("APEI/GHES: ARM processor Error: don't go past allocated memory")
Cc: stable@vger.kernel.org
Signed-off-by: TanZheng <tanzheng@kylinos.cn>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Link: https://patch.msgid.link/20260806010944.32384-1-kensanya@163.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Anirudh Prasad <icarus@a0rg.com>
Date: Sat Aug 15 01:36:23 2026 +0530
ACPI: pfr_update: fix stack buffer overflow in query_capability()
commit ced45be0073a8a31b30b4a7f68cd3a15734515de upstream.
query_capability() copies four ACPI buffer objects returned by the
firmware _DSM into fixed-size u8[16] fields in struct
pfru_update_cap_info using memcpy with the firmware-supplied length:
memcpy(&cap_hdr->code_type,
elements[CAP_CODE_TYPE_IDX].buffer.pointer,
elements[CAP_CODE_TYPE_IDX].buffer.length);
The same pattern repeats for drv_type, platform_id, and oem_id.
If the firmware returns buffer.length > 16 for any of these fields,
memcpy writes past the destination array.
struct pfru_update_cap_info is stack-allocated in pfru_ioctl().
Confirmed with KASAN on 7.2-rc6: three stack-out-of-bounds reports
are generated when a DSM returns 64-byte buffers, with writes reaching
44 bytes past the end of cap_hdr's [64, 156) frame window into
adjacent stack redzones.
Introduce a helper pointer to out_obj->package.elements and use it
to validate each buffer length against its destination field size
before copying, returning -EINVAL if the firmware supplies an
oversized buffer.
Fixes: 0db89fa243e5 ("ACPI: Introduce Platform Firmware Runtime Update device driver")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Anirudh Prasad <icarus@a0rg.com>
Link: https://patch.msgid.link/1a001e1fee9.637da6dc3533246.238498880682901704@a0rg.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Mon Jul 6 17:54:23 2026 +0000
alpha/PCI: Fix I/O port accessor argument order in pci_legacy_write()
commit 651fb94aaf245430590216d497fb8b02dd73d5f9 upstream.
pci_legacy_write() in arch/alpha/kernel/pci-sysfs.c passes its arguments to
outb(), outw() and outl() in the wrong order:
outb(port, val);
The Alpha I/O accessors in arch/alpha/include/asm/io.h take the value first
and the port second:
extern void outb(u8 b, unsigned long port);
So the port number is written as data to the I/O address taken from the
user-supplied value, and the intended write to the requested port never
happens.
The arguments have been reversed since the file was added, and the function
returns the access size regardless, so the caller sees success while the
requested port is left untouched.
Fixes: 10a0ef39fbd1 ("PCI/alpha: pci sysfs resources")
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Acked-by: Magnus Lindholm <linmag7@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260706175423.98305-1-kwilczynski@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Matt Turner <mattst88@gmail.com>
Date: Mon Aug 3 19:40:46 2026 -0400
alpha: don't leak hardware-fabricated FP exception bits to user space
commit bcfe3187412e342b4619efb92c945f073855ebc0 upstream.
On EV6 and later the hardware records exception status bits in the FPCR
before delivering a software completion trap, and those bits can be wrong
for the instruction that trapped. Converting a double that is exactly
representable as a subnormal float sets FPCR_UNF even though the result
is exact, and an underflow trap additionally sets FPCR_INE even when the
emulated operation turns out to be exact.
alpha_fp_emul() only wrote the FPCR when soft-fp raised an exception, so
whenever it determined that the instruction was exact the fabricated bits
stayed in the FPCR and were reported to user space by fetestexcept().
Pass the exception summary register down from do_entArith() so the
handler can tell which exceptions the hardware attributed to the trapping
instruction, and always write the FPCR. Clear the exceptions that the
trap reported but that soft-fp did not raise. EXC_SUM reports only the
underflow or overflow when the hardware also set INE, so treat INE as a
candidate in that case, and treat a trap with no reported exception as a
denormal operand trap, for which the hardware can fabricate INE and UNF
as well. Bits that software has already confirmed in ieee_state belong
to this or an earlier instruction and are never cleared.
The imprecise path passes no summary. There the trap was taken somewhere
in the trap shadow, so EXC_SUM is not attribution for the instruction
being re-executed -- and only EV6, which traps precisely and so never
takes that path, has fabricated bits to clear. For the same reason the
clearing is guarded by implver(), matching swcr_update_status().
On an UP1500 (EV68) this takes the glibc math testsuite from 831 failures
to 28, the remainder being unrelated to exception status.
This belongs with the preceding fix to ieee_swcr_to_fpcr(), and should
not be backported without it -- nor it without this. That fix stops
FPCR_DNOD being set unconditionally, so denormal operand traps start
firing again. Those traps very often find an exact result, which is
precisely the case where the old code left the FPCR unwritten and the
fabricated bits visible. Applied alone it would make spurious exception
flags more common, not less.
One case cannot be resolved here: an inexact instruction without the
software completion suffix never traps, so its INE reaches the FPCR
without being recorded anywhere else. Such a bit is indistinguishable
from an INE the hardware fabricated for a trapping instruction, and is
lost if an underflow or overflow trap with an exact result follows it.
The FPCR is the only record of those instructions and it carries no
attribution.
The bug predates the git history, so there is no commit to reference in a
Fixes tag.
Cc: stable@vger.kernel.org # 5.15+
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://lore.kernel.org/r/20260803-alpha-fp-exceptions-v1-2-c99d75608e60@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Matt Turner <mattst88@gmail.com>
Date: Mon Aug 3 19:40:45 2026 -0400
alpha: fix ieee_swcr_to_fpcr setting FPCR_DNOD unconditionally
commit 49672d026cc4773608e1222b69b29fd70f41336b upstream.
ieee_swcr_to_fpcr() converts the software IEEE trap-enable and status
bits kept in thread_info.ieee_state into the hardware FPCR format. It
contained:
fp |= (~sw & IEEE_TRAP_ENABLE_DNO) << 41;
FPCR_DNOD (bit 47) disables denormal operand traps: with it set the
hardware handles a denormal operand itself, treating it as zero, instead
of trapping for software completion. The intent was to set DNOD when the
user has not asked for SIGFPE on denormal operands, but
IEEE_TRAP_ENABLE_DNO is clear by default, so ieee_swcr_to_fpcr(0) always
set DNOD.
Instructions built with the software completion suffix therefore never
trapped on a denormal operand. The hardware silently substituted zero
and produced wrong results, affecting every program compiled with -mieee
and default FPU settings, glibc included.
Set FPCR_DNOD only when IEEE_MAP_DMZ is requested, which is exactly the
case where flushing denormal inputs to zero is what the user asked for.
DNOD then encodes MAP_DMZ, which ieee_fpcr_to_swcr() already recovers
from FPCR_DNZ, so drop its attempt to recover IEEE_TRAP_ENABLE_DNO from
DNOD; the DNO trap enable lives solely in ieee_state.
Both functions are in a uapi header, so the encoding change is visible to
userspace, but nothing outside the kernel is known to depend on DNOD
carrying the DNO trap enable, and the kernel is the only writer of the
FPCR.
This must not be backported on its own. Re-enabling denormal operand
traps exposes a second bug, fixed in the following patch: those traps
usually find an exact result, and for an exact result the emulator did
not write the FPCR back, leaving hardware-fabricated exception bits
visible to user space. Taken alone this change would make spurious
exception flags more common.
The bug predates the git history, so there is no commit to reference in a
Fixes tag.
Cc: stable@vger.kernel.org # 5.15+
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://lore.kernel.org/r/20260803-alpha-fp-exceptions-v1-1-c99d75608e60@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Matt Turner <mattst88@gmail.com>
Date: Thu May 28 19:05:15 2026 -0400
alpha: marvel: Fix irq_set_status_flags to use correct IRQ number
commit 3a3ac1f6c6a67b3803f2643584310f78301e58a8 upstream.
Pass base + i to irq_set_status_flags() to match the IRQ number
used in irq_set_chip_and_handler(). Previously, IRQ_LEVEL was set
on the wrong (low-numbered) IRQ descriptors rather than the IO7
IRQs at base + i.
Cc: stable@vger.kernel.org
Fixes: 08876fe8519c ("alpha: marvel: Convert irq_chip functions")
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://lore.kernel.org/r/20260528230516.1839694-1-mattst88@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Matt Turner <mattst88@gmail.com>
Date: Thu May 28 19:05:16 2026 -0400
alpha: marvel: Fix lock ordering in init_io7_irqs()
commit 24d68db713d63dfe3660c56b50e887784844baea upstream.
Move irq_set_chip_and_handler() and irq_set_status_flags() calls
outside the io7->irq_lock raw spinlock. These functions take
sparse_irq_lock, which is a mutex, and taking a sleeping lock while
holding a raw spinlock is invalid. The raw spinlock only needs to
protect the hardware CSR accesses.
This fixes the following lockdep splat during boot:
[ BUG: Invalid wait context ]
swapper/0/0 is trying to lock:
sparse_irq_lock{....}-{4:4}, at: irq_mark_irq
other info that might help us debug this:
context-{5:5}
1 lock held by swapper/0/0:
#0: &io7->irq_lock{....}-{2:2}, at: init_io7_irqs.constprop.0
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Magnus Lindholm <linmag7@gmail.com>
Link: https://lore.kernel.org/r/20260528230516.1839694-2-mattst88@gmail.com
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Baul Lee <baul.lee@xbow.com>
Date: Wed Aug 5 10:34:23 2026 +0900
ALSA: 6fire: bound the MIDI event length from the device
commit a478893b59e36cfe7d77a76b352f2db55502e879 upstream.
usb6fire_comm_receiver_handler() forwards a MIDI event using a length
byte the device supplies, with no bound and no check that the transfer
delivered that many bytes:
if (!urb->status) {
if (rt->receiver_buffer[0] == 0x10) /* midi in event */
if (midi_rt)
midi_rt->in_received(midi_rt,
rt->receiver_buffer + 2,
rt->receiver_buffer[1]);
}
receiver_buffer is a 64-byte kzalloc() buffer (COMM_RECEIVER_BUFSIZE), so
only 62 bytes follow the two-byte header. receiver_buffer[1] is a u8 the
device chooses, so a device that answers with 0x10 and a length of 0xFF
makes snd_rawmidi_receive() read 255 bytes starting two bytes into a
64-byte object. The bytes past the buffer are handed to userspace
through the rawmidi read path.
urb->actual_length is not consulted either, so a short transfer leaves
both the type byte and the length byte at their previous values and the
handler acts on stale data.
The receiver URB is submitted from usb6fire_comm_init() at probe, so the
read happens on plug with no user action; forwarding to userspace also
needs a MIDI input substream open, since usb6fire_midi_in_received()
only calls snd_rawmidi_receive() when rt->in is set.
KASAN on 7.2.0-rc5 (arm64), single packet from an emulated device:
BUG: KASAN: slab-out-of-bounds in snd_rawmidi_receive
Read of size 255 at addr ffff000009f64682 by task bash/183
__asan_memcpy
snd_rawmidi_receive
usb6fire_midi_in_received [snd_usb_6fire]
usb6fire_comm_receiver_handler [snd_usb_6fire]
Allocated by task 11:
usb6fire_comm_init [snd_usb_6fire]
usb6fire_chip_probe [snd_usb_6fire]
The buggy address is located 2 bytes inside of
allocated 64-byte region [ffff000009f64680, ffff000009f646c0)
Reject the event when the length exceeds the bytes that follow the
header, and require the transfer to have delivered the header plus that
many bytes. The receiver URB is submitted with a 64-byte
transfer_buffer_length, so a genuine device cannot deliver an event
longer than those 62 bytes and nothing valid is dropped.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Link: https://patch.msgid.link/20260805013423.38175-1-baul.lee@xbow.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:18 2026 +0200
ALSA: aloop: Check card index validity at probe
commit 819b106a9fd2ef3fd8abf898b9a8e4524eca8f48 upstream.
aloop driver blindly trusts that the given devptr->id value is within
the proper card index range at probe. It's OK for the devices the
driver itself creates at the module probe time, but if the device is
bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Baul Lee <baul.lee@xbow.com>
Date: Wed Aug 5 10:34:28 2026 +0900
ALSA: bcd2000: clear the URB pointers on disconnect
commit 459d3a64766f5ca2f1886daeaf24582831a5f5ab upstream.
bcd2000_free_usb_related_resources() frees both URBs and leaves the
pointers behind:
usb_kill_urb(bcd2k->midi_out_urb);
usb_kill_urb(bcd2k->midi_in_urb);
usb_free_urb(bcd2k->midi_out_urb);
usb_free_urb(bcd2k->midi_in_urb);
The rawmidi device outlives that call. A substream that is still open
when the device is unplugged reaches bcd2000_midi_send() from the
trigger path on close. That function writes to the freed URB and then
hands it to the USB core:
bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE;
...
ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC);
usb_kill_urb() does not stop a later submission either, so a submit that
races the disconnect can requeue the URB after it has been reaped.
midi_in_urb is exposed the same way: bcd2000_input_complete() resubmits
it from the completion handler.
KASAN on 7.2.0-rc5 (arm64):
BUG: KASAN: slab-use-after-free in bcd2000_midi_send [snd_bcd2000]
Write of size 4 at addr ffff00001827d388 by task bpoc/168
__asan_store4
bcd2000_midi_send [snd_bcd2000]
bcd2000_midi_output_trigger [snd_bcd2000]
snd_rawmidi_kernel_write1
close_substream.part.0
Freed by task 168:
usb_free_urb
bcd2000_disconnect [snd_bcd2000]
BUG: KASAN: slab-use-after-free in usb_submit_urb
Read of size 8 at addr ffff00001827d3b8 by task bpoc/168
Clear both pointers after freeing and test them on the paths that can
still run. Poison the URBs before freeing them: usb_poison_urb() waits
for a running completion handler and rejects any later submission, so
after it returns the input path is quiesced and only the rawmidi trigger
path can still reach bcd2000_midi_send(). No unpoison is needed; the
URBs are freed on the next line.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Link: https://patch.msgid.link/20260805013428.38204-1-baul.lee@xbow.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xu Rao <raoxu@uniontech.com>
Date: Thu Aug 13 14:55:24 2026 +0800
ALSA: hda/ext: preserve PPLCCTL bits when clearing reset
commit 36aa66de481d29edd63cbad9b5c4dc18c340fdf6 upstream.
snd_hdac_ext_stream_reset() polls PPLCCTL for STRST by masking the
register value with AZX_PPLCCTL_STRST:
val = readl(...) & AZX_PPLCCTL_STRST;
The same masked value is then used when clearing STRST. Since val
contains no bits other than STRST, clearing STRST from it always
produces zero. The subsequent writel() therefore writes zero to the
entire PPLCCTL register instead of clearing only the reset bit.
PPLCCTL contains other stream control fields, including the stream tag
in AZX_PPLCCTL_STRM_MASK. Those fields must not be modified as a side
effect of clearing stream reset.
Use snd_hdac_updatel() to clear STRST, matching the existing set-reset
path and preserving all unrelated PPLCCTL bits.
Fixes: df203a4e46f4 ("ALSA: hdac_ext: add extended stream capabilities")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/43BB7930B0F07C09+20260813065524.1955696-1-raoxu@uniontech.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Eckhart Mohr <e.mohr@tuxedocomputers.com>
Date: Fri Aug 21 16:44:34 2026 +0200
ALSA: hda/realtek: Add quirk for TongFang XxAF5xxx
commit e72d5659a2606056a0c34af212b46a3275a55bbf upstream.
Fix microphone detection on built in headphone jack for some devices
Signed-off-by: Eckhart Mohr <e.mohr@tuxedocomputers.com>
Cc: stable@vger.kernel.org
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Link: https://patch.msgid.link/20260821144437.27233-1-wse@tuxedocomputers.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Denis Batishchev <ii343hbka@gmail.com>
Date: Mon Aug 10 17:14:41 2026 +0200
ALSA: hda/realtek: Enable micmute LED on HP EliteBook 6 G1a p/n: AD3Q9ET#UUG
commit e7da28b820d12927de30abf554c727a319f80359 upstream.
The HP EliteBook 6 G1a (SSID 103c:8e0d) uses a Realtek ALC236 codec.
Without a quirk no fixup is selected and the mic-mute LED stays off.
It needs the same ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF quirk as the
already-supported 14" variant (SSID 103c:8dfb), so add it.
Signed-off-by: Denis Batishchev <ii343hbka@gmail.com>
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260810151440.2306217-2-ii343hbka@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhang Heng <zhangheng@kylinos.cn>
Date: Mon Aug 17 17:47:08 2026 +0800
ALSA: hda/realtek: Fix Lenovo Yoga Slim 7 14AKP10 quirk ordering
commit 75dc2eda659f6be4a370734f11baf25df8a9fd80 upstream.
The Yoga Slim 7 14AKP10 has a PCI SSID of 17aa:38b4 but a codec SSID of
17aa:391a. The current quirk table contains a PCI quirk for 17aa:38b4
(for the Legion Slim 7 16IRH8) which matches first, so the codec-specific
quirk for 17aa:391a is never applied.
This results in the wrong fixup being used (CS35L41_I2C_2 instead of the
correct bass speaker fixup), leaving the internal speakers misconfigured
or silent.
Remove the 17aa:391a entry from its PCI-SSID-sorted position and add it as
an HDA_CODEC_QUIRK directly before the 17aa:38b4 entry, because it must
match on the codec subsystem ID rather than the PCI SSID and it has to win
over the colliding PCI quirk for the Legion Slim 7 16IRH8. A comment is
added to explain the out-of-order placement, following the same style
already used for the 17aa:38bb and 17aa:38f9 codec-SSID overrides.
With this change, the correct ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN is
applied, restoring speaker output and auto-mute functionality.
The original quirk added in commit e6c888202297 ("ALSA: hda/realtek: Add
quirk for Lenovo Yoga Slim 7 14AKP10") matched on the PCI SSID 17aa:391a,
but this model actually exposes PCI SSID 17aa:38b4 (shared with the Legion
Slim 7 16IRH8), so that quirk never matched and the bass speaker remained
silent. Fix it by matching on the codec SSID and placing the entry before
the colliding 17aa:38b4 PCI quirk.
Fixes: e6c888202297 ("ALSA: hda/realtek: Add quirk for Lenovo Yoga Slim 7 14AKP10")
Cc: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221298
Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Link: https://patch.msgid.link/20260817094708.222154-1-zhangheng@kylinos.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:19 2026 +0200
ALSA: mpu401: Check card index validity at probe
commit f7dcecb92ed192ff5fcf842918fb1aaea84b5bdd upstream.
mpu401 driver blindly trusts that the given devptr->id value is within
the proper card index range at probe. It's OK for the devices the
driver itself creates at the module probe time, but if the device is
bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:22 2026 +0200
ALSA: mts64: Check card index validity at probe
commit d18a260720f86a5f8b5fcfefc4ba2e9dd01c10f8 upstream.
Although mts64 driver has a check of the given devptr->id value, it
doesn't check for a negative id, which is often given as "none" or
such value when bound via sysfs. This may lead to OOB access for
index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-6-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Tue Aug 18 22:47:17 2026 +0800
ALSA: pcxhr: initialize mutexes before requesting threaded IRQ
commit 6c97817e20598e5473094e0e38d1f51f1cf4dfff upstream.
pcxhr_probe() requests pcxhr_threaded_irq() before initializing
mgr->lock, even though the threaded handler takes that mutex.
Initialize the manager locks before request_threaded_irq() so an
early interrupt cannot run against uninitialized mutex state during
probe.
Fixes: 9bef72bdb26e ("ALSA: pcxhr: Use nonatomic PCM ops")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260818144717.2269918-1-runyu.xiao@seu.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:23 2026 +0200
ALSA: portman2x4: Check card index validity at probe
commit 3690ef20469d5959378260e2752f2314a2572913 upstream.
Although portman2x4 driver has a check of the given devptr->id value,
it doesn't check for a negative id, which is often given as "none" or
such value when bound via sysfs. This may lead to OOB access for
index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-7-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:20 2026 +0200
ALSA: serial-u16550: Check card index validity at probe
commit e0fb960b227fcdebe22e4f26c9486d60943c0424 upstream.
serial-u16550 driver blindly trusts that the given devptr->id value is
within the proper card index range at probe. It's OK for the devices
the driver itself creates at the module probe time, but if the device
is bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-4-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Sat Aug 8 10:45:54 2026 +0900
ALSA: ump: Fix corrupted data bytes at MIDI 1.0 SysEx to UMP conversion
commit 8a906c0b4f1ba123a95c166f644d2383bf30a420 upstream.
The cvt_legacy_sysex_to_ump() initialises only the first word of the
output packet and ORs the data bytes into it. The second word is left
alone, and the conversion context is kept across calls, so it still
carries the previous packet's bytes. Those stale bits corrupt the new
data. Any SysEx longer than six data bytes is affected.
A SysEx with the twelve data bytes 01..0c comes out as:
30160102 03040506
30260708 0b0e0f0e
The second packet declares six data bytes and four of them are wrong,
inside the declared length.
The sibling cvt_legacy_cmd_to_ump() already clears the second word. Do
the same here.
Fixes: 0b5288f5fe63 ("ALSA: ump: Add legacy raw MIDI support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260808014554.3550153-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Takashi Iwai <tiwai@suse.de>
Date: Thu Aug 6 17:32:21 2026 +0200
ALSA: virmidi: Check card index validity at probe
commit b65d5182ecd6b7a24a83d980a0d06e809ef876c5 upstream.
virmidi driver blindly trusts that the given devptr->id value is
within the proper card index range at probe. It's OK for the devices
the driver itself creates at the module probe time, but if the device
is bound manually via sysfs interface, this could be -1 as "none", and
this leads to OOB access for index[] and other parameters.
Add a sanity check for the card index and warn/correct it if it's a
value out of the range.
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260806153227.1460166-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jann Horn <jannh@google.com>
Date: Thu Aug 6 17:55:02 2026 +0200
apparmor: fix cred UAF caused by begin_current_label_crit_section()
commit 3f4ae5fab613dca01d6a2a8210dd832e009fcf47 upstream.
AppArmor's begin_current_label_crit_section() is a scary function called
from lots of LSM hooks (in particular VFS/socket-related ones) that checks
if the label referenced by the current creds is marked FLAG_STALE, and if
so, attempts to use aa_replace_current_label() to replace the creds with an
updated version that uses a new label.
The first problem with this is that it would directly lead to UAF of
`struct cred` if anything in the kernel takes a pointer to the current
creds and accesses these past a security hook invocation that replaces
creds, like so:
```
const struct cred *cred = current_cred();
alloc_file_pseudo(...);
uid_t uid = cred->euid;
```
I don't know if anything in the kernel actually does this, but I think it
is very surprising that this pattern could lead to UAF.
The second problem is that things go wrong when aa_replace_current_label()
runs with overridden credentials. aa_replace_current_label() bails out if
`current_cred() != current_real_cred()` (mirroring the check in
proc_pid_attr_write()), but this check can't actually reliably detect
overridden credentials because the overridden creds can be the same as the
objective creds.
So in approximately the following scenario, things go wrong:
1. task begins with <creds A> (as both objective and subjective creds),
with refcount=2
2. task grabs an extra reference on <creds A> for overriding
3. task calls override_creds(<creds A>), which returns a pointer to the old
subjective creds (<creds A>)
4. task enters AppArmor LSM hook
5. AppArmor checks that objective/subjective creds are equal
6. AppArmor replaces both cred pointers with <creds B> and drops 2 refs on
<creds A>
7. task leaves AppArmor LSM hook
8. task calls revert_creds(<creds A>)
9. now task->cred is <creds A> while task->real_cred is <creds B>, but the
task_struct logically holds two references to <creds B>
10. another task drops the extra reference on <creds A> that was used for
overriding, refcount drops to 0
11. now task->real_cred points to freed creds
At this point, any access to current_cred() will be UAF.
I have a test case where I run aa-disable on a profile while a process
using that profile is blocked on splice() from a FUSE passthrough file into
a full pipe; after the profile update, the pipe becomes empty, splice()
resumes, the credentials go out of sync, and a subsequent getuid() syscall
results in a KASAN UAF splat.
To fix this, instead of directly replacing creds, do it via task_work that
will run at the end of the current syscall. (The point in time at which the
cred replacement happens should have no correctness impact; it is just a
performance optimization to avoid unnecessarily touching the refcount of
the new label.)
Note that AppArmor still performs direct cred replacements in the
sb_pivotroot LSM hook after this change, and that direct cred replacements
can still happen in VFS ->write() callbacks via proc_pid_attr_write().
There are two options for what to do with aa_dup_task_ctx(): Either
explicitly reset new->label_replacement_pending after the entire
aa_task_ctx has been copied, or switch to manually copying members over.
I am switching to manually copying members over because that should make
bugs more obvious.
Cc: stable@vger.kernel.org
Fixes: c75afcd153f6 ("AppArmor: contexts used in attaching policy to system objects")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hyunwoo Kim <imv4bel@gmail.com>
Date: Mon Aug 10 18:51:33 2026 +0900
apparmor: fix out-of-bounds write when null terminating a label vec
commit 9f1e40193eef7f047e6b77cfb4b4cafdecd7a123 upstream.
aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE
is passed. If the components are all distinct no duplicates are dropped,
dups is 0 and the terminator goes to vec[n], so the caller has to provide
room for n + 1 entries.
aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len,
gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but
vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES
it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it
allocates exactly len pointers. The terminator therefore lands one entry
past the end of the local array when len is LOCAL_VEC_ENTRIES, and one
entry past the end of the allocation when len is larger.
len comes from the number of "//&" separated components in the label name
and label_count_strn_entries() does not bound it. An unprivileged task
reaches the parse by writing to /proc/self/attr/apparmor/current or through
lsm_set_self_attr(2), both of which go through do_setattr(), and the name
is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is
mode 0666, performs no permission check at all. Every component has to
resolve to a loaded profile, so a system with policy loaded is required.
The other two VEC_FLAG_TERMINATE users work on a label vec that
aa_label_alloc() has already sized with "+ 1 for null terminator entry on
vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing
len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of
the local array and into kzalloc().
Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nathan Chancellor <nathan@kernel.org>
Date: Thu Aug 13 20:12:55 2026 -0700
arch_numa: avoid false positive fortify warning in setup_node_to_cpumask_map()
commit f2b1cb39d5ccab090d8353788f186f7e7a1fffd4 upstream.
When building ARCH=riscv using clang with CONFIG_FORTIFY_SOURCE and
CONFIG_UBSAN_BOUNDS enabled, CONFIG_NR_CPUS > 64, and the default value of
2 for CONFIG_NODES_SHIFT, there is a compiletime warning from the fortify
routines.
In file included from mm/arch_numa.c:11:
In file included from include/linux/acpi.h:14:
In file included from include/linux/resource_ext.h:11:
In file included from include/linux/slab.h:17:
In file included from include/linux/gfp.h:7:
In file included from include/linux/mmzone.h:8:
In file included from include/linux/spinlock.h:60:
In file included from include/linux/interrupt_rc.h:17:
In file included from include/linux/smp.h:13:
In file included from include/linux/cpumask.h:11:
In file included from include/linux/bitmap.h:13:
In file included from include/linux/string.h:383:
include/linux/fortify-string.h:430:4: warning: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribue-warning]
430 | __write_overflow_field(p_size_field, size);
| ^
include/linux/fortify-string.h:430:4: note: called by function 'fortify_memset_chk(unsigned long, unsigned long, unsigned long)'
include/linux/bitmap.h:248:3: note: inlined by function 'setup_node_to_cpumask_map'
248 | memset(dst, 0, len);
| ^
include/linux/fortify-string.h:462:25: note: expanded from macro 'memset'
462 | #define memset(p, c, s) __fortify_memset_chk(p, c, s, \
| ^
include/linux/fortify-string.h:453:2: note: expanded from macro '__fortify_memset_chk'
453 | fortify_memset_chk(__fortify_size, p_size, p_size_field), \
| ^
include/linux/fortify-string.h:430:4: note: use '-gline-directives-only' (implied by '-g1') or higher for more accurate inlining chain locations
430 | __write_overflow_field(p_size_field, size);
| ^
1 warning generated.
In this configuration, MAX_NUMNODES is 4. clang unrolls the for loop in
setup_node_to_cpumask_map() past this, which triggers the fortify check
when accessing node_to_cpumask_map on the theoretical fifth loop iteration
because it would be an out of bounds write.
Make it clear to clang that nr_node_ids is bounded by MAX_NUMNODES due to
the logic in setup_nr_node_ids() by early returning in
setup_node_to_cpumask_map() should that condition be violated.
Link: https://lore.kernel.org/20260813-arch_numa-avoid-fortify-warning-v2-1-093ad97a78df@kernel.org
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2174
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Bill Wendling <morbo@google.com>
Cc: Justin Stitt <justinstitt@google.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Karl Mehltretter <kmehltretter@gmail.com>
Date: Thu Aug 20 00:27:12 2026 +0200
arm64: compat: Fix decrementing LDM/STM alignment emulation
commit f5b8b9037df387394a73aab47c5437bbac975077 upstream.
The compat alignment emulator inherited unsigned long data addresses from
the 32-bit ARM implementation.
In do_alignment_ldmstm(), nr_regs is an unsigned int holding the transfer
size. The function uses the same address addition for both transfer
directions, negating nr_regs first for a decrementing LDM or STM. The
32-bit negation wraps before the addition, so the handler adds nearly
4 GiB instead of subtracting the transfer size.
The resulting address lies outside the compat task's address space, so
decrementing LDM/STM emulation fails, while incrementing forms work.
For example, a backwards-moving copy routine using decrementing LDM/STM can
take an alignment fault when called with unaligned pointers. The compat
handler should emulate the transfer, but this bug instead causes SIGBUS.
The offset negated in do_alignment_finish_ldst() is offset_union.un, which
is already unsigned long and does not have this width mismatch.
Make nr_regs unsigned long so its negation and the address arithmetic
use the same width.
Fixes: 3fc24ef32d3b ("arm64: compat: Implement misalignment fixups for multiword loads")
Cc: stable@vger.kernel.org
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Date: Mon Apr 13 11:05:28 2026 +0200
arm64: dts: qcom: sm6115-pro1x: Correct touchscreen GPIO flags
commit 8e73ae5c34e4fbbd25a8324e3c0eb1e845d7f01e upstream.
IRQ_TYPE_xxx flags are not correct in the context of GPIO flags.
These are simple defines so they could be used in DTS but they will not
have the same meaning: IRQ_TYPE_LEVEL_LOW = 8 = GPIO_TRANSITORY.
Correct the touchscreen irq-gpios to use proper flags, assuming the
author of the code wanted similar logical behavior:
IRQ_TYPE_LEVEL_LOW => GPIO_ACTIVE_LOW
Fixes: e46b455e67f8 ("arm64: dts: qcom: sm6115-pro1x: Add Goodix Touchscreen")
Cc: stable@vger.kernel.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260413090527.53000-2-krzysztof.kozlowski@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Scott <mike.scott@oss.qualcomm.com>
Date: Wed May 20 18:09:34 2026 -0700
arm64: dts: qcom: x1-dell-thena: mark l12b and l15b always-on
commit 06c8fc3e132ce8659bc9f0877b5c6daaf41aadbd upstream.
The l12b and l15b supplies are used by components that are not (fully)
described (and some never will be) and must never be disabled.
Mark the regulators as always-on to prevent them from being disabled,
for example, when consumers probe defer or suspend.
Note that these supplies currently have no consumers described in
mainline for dell-thena beyond the audio codec (vdd-buck/vdd-rxtx/
vdd-io on wcd938x), which can release them when the codec goes idle.
The board-level gpio-fixed regulators that feed the Type-C retimer's
VDDIO and other rails are not described with a vin-supply link, so
the kernel cannot keep their parent LDOs alive on its own.
This mirrors the same change Johan Hovold applied to every other
X1E80100 board in a March 2025 series; commit 63169c07d740
("arm64: dts: qcom: x1e80100-dell-xps13-9345: mark l12b and l15b always-on")
is representative. The dell-thena board file was introduced four months
later and did not inherit that change; this patch closes the gap.
Fixes: e7733b42111c ("arm64: dts: qcom: Add support for Dell Inspiron 7441 / Latitude 7455")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Scott <mike.scott@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Acked-by: Val Packett <val@packett.cool>
Link: https://lore.kernel.org/r/20260521010935.1333494-4-mike.scott@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Quentin Schulz <quentin.schulz@cherry.de>
Date: Fri Jun 12 18:47:34 2026 +0200
arm64: dts: rockchip: fix eMMC reset polarity on PP-1516
commit 2a08921edcab6a462fa6ddb02c91b90b5ac92429 upstream.
According to the Jedec 5.1 specification, the device is held in reset
when RST_n is low, therefore the polarity of the line must be that, as
specified in the Device Tree binding (mmc/mmc-pwrseq-emmc.yaml).
Due to the wrong polarity, eMMC devices with RST_n_FUNCTION[162]
bitfield [1:0] set to 0x1 (the default is 0x0) will be held in reset
forever.
Cc: stable@vger.kernel.org
Fixes: 56198acdbf0d ("arm64: dts: rockchip: add px30-pp1516 base dtsi and board variants")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Link: https://patch.msgid.link/20260612-pp1516-emmc-polarity-v1-1-4816c1c909f7@cherry.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Quentin Schulz <quentin.schulz@cherry.de>
Date: Fri Jun 26 16:40:38 2026 +0200
arm64: dts: rockchip: fix eMMC reset polarity on PX30 Ringneck
commit dfe078755706ed50651ebbe0442843ecd4ae8389 upstream.
According to the Jedec 5.1 specification, the device is held in reset
when RST_n is low, therefore the polarity of the line must be that, as
specified in the Device Tree binding (mmc/mmc-pwrseq-emmc.yaml).
Due to the wrong polarity, eMMC devices with RST_n_FUNCTION[162]
bitfield [1:0] set to 0x1 (the default is 0x0) will be held in reset
forever.
Cc: stable@vger.kernel.org
Fixes: c484cf93f61b ("arm64: dts: rockchip: add PX30-µQ7 (Ringneck) SoM with Haikou baseboard")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Link: https://patch.msgid.link/20260626-ringneck-emmc-polarity-v1-1-90cefe57b316@cherry.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jakob Unterwurzacher <jakob.unterwurzacher@cherry.de>
Date: Tue Jun 9 10:17:25 2026 +0200
arm64: dts: rockchip: fix emmc reset polarity on px30-cobra
commit 85babf47515e2adf266dcc3be9804e31f752083e upstream.
Technically, the reset signal is active low - it's called RST_n after all.
But it is ignored completely unless RST_n_FUNCTION=1 (byte 162 in extcsd)
is set in the emmc. It is 0 per default.
For emmcs that have RST_n_FUNCTION=1 we failed like this:
[ 3.074480] mmc1: Failed to initialize a non-removable card
With this change they work normally.
Cc: stable@vger.kernel.org
Fixes: bb510ddc9d3e ("arm64: dts: rockchip: add px30-cobra base dtsi and board variants")
Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher@cherry.de>
Tested-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
Link: https://patch.msgid.link/20260609081728.30616-2-jakobunt@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fabio Estevam <festevam@nabladev.com>
Date: Thu Jul 16 22:07:34 2026 -0300
arm64: dts: rockchip: Fix rk3399-roc-pc-plus analog audio
commit 4f7259ebe1eba4778768a4f5a0bbbe439d10f3f3 upstream.
The ES8388 sound card on the rk3399-roc-pc-plus fails to probe because
i2s1 cannot claim its MCLK pin:
pinctrl: pin gpio4-0 already requested by ff880000.i2s; cannot claim for ff890000.i2s
pinctrl: error -EINVAL: pin-128 (ff890000.i2s)
pinctrl: error -EINVAL: could not request pin 128 (gpio4-0) from group i2s-8ch-mclk-pin
on device rockchip-pinctrl
GPIO4_A0 is routed as SCLK_I2S_8CH_OUT and is used by i2s1 as the
external MCLK for the ES8388 codec. The board dts already removes
GPIO4_A0 from the i2s0_8ch_bus pin group, but i2s0 still claims the
same pin through its bclk_off state.
Since the i2s driver requests both states, this blocks i2s1 pinctrl
setup and leaves the simple-audio-card deferred with a parse error.
Override i2s0_8ch_bus_bclk_off as well, matching the existing
i2s0_8ch_bus override, so GPIO4_A0 is left for i2s1/ES8388 audio.
Cc: stable@vger.kernel.org
Fixes: 6d9a7bd6a13c ("arm64: dts: rockchip: add support for Firefly ROC-RK3399-PC-PLUS")
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Link: https://patch.msgid.link/20260717010736.578419-1-festevam@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fabio Estevam <festevam@nabladev.com>
Date: Thu Jul 2 23:56:48 2026 -0300
arm64: dts: rockchip: Fix rk3588s-roc-pc audio description
commit b4db45b3ec97a9d0d23446084f45e095b2ba2020 upstream.
The rk3588s-roc-pc ES8388 codec is connected to the i2s0_8ch audio
interface. Use the matching I2S0 MCLK output for the codec clock
instead of I2S1.
Using the I2S1 MCLK can leave the ALSA PCM running while the codec has
no usable master clock for the active audio path, resulting in silent
headphone output.
Also make the CPU DAI provide bitclock and frame clock. This matches
the active Rockchip I2S controller side and avoids relying on the codec
to drive the bus clocks.
Route the headphone output to LOUT2 and ROUT2, matching the old 5.10
BSP device tree. LOUT1 and ROUT1 are used for the speaker route there,
so using them for the headphone widget can leave the headphone jack
silent even while the ALSA path is active.
The old BSP also used hp-con-gpio on GPIO1_A4. Model that GPIO as a
simple audio amplifier so DAPM enables the headphone connection when the
headphone path is active.
Cc: stable@vger.kernel.org
Fixes: 7f9509791507 ("arm64: dts: rockchip: add DTs for Firefly ROC-RK3588S-PC")
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Link: https://patch.msgid.link/20260703025648.180135-1-festevam@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Karl Mehltretter <kmehltretter@gmail.com>
Date: Sun Jul 26 20:22:53 2026 +0200
arm64: proton-pack: Restore the nospectre_bhb command-line option
commit 2f6fc0612607c95489c960aaefc8cb5578cdab8c upstream.
Commit 7f1635737823 ("arm64: proton-pack: Fix hard lockup due to print in
scheduler context") moved the "mitigation disabled" printks into
spectre_print_disabled_mitigations(). For spectre-v2 and spectre-v4 only
the pr_info_once() calls were removed, but for spectre-bhb the whole
branch went with the print:
- } else if (cpu_mitigations_off() || __nospectre_bhb) {
- pr_info_once("spectre-bhb mitigation disabled ...\n");
spectre_bhb_enable_mitigation() therefore no longer tests __nospectre_bhb
or cpu_mitigations_off() and the mitigation is enabled regardless of the
command line. The parameter is still parsed and its flag is still checked
by spectre_print_disabled_mitigations(), so the kernel prints "spectre-bhb
mitigation disabled by command-line option" while
/sys/devices/system/cpu/vulnerabilities/spectre_v2 reports "Mitigation:
CSV2, BHB" and the vectors are switched to EL1_VECTOR_BHB_LOOP.
The only remaining escape is the SPECTRE_VULNERABLE arm at the top of the
chain, which a CSV2 core never reaches, so from Cortex-A76 and Neoverse N1
onwards both nospectre_bhb and mitigations=off are ignored. Both are
documented in Documentation/admin-guide/kernel-parameters.txt.
The identical mistake was made on the neighbouring compile-time-option
branch immediately before this regression and fixed shortly afterwards;
this command-line branch was missed.
build_bhb_mitigation() in arch/arm64/net/bpf_jit_comp.c still tests both
flags, so nospectre_bhb currently keeps the exception-vector loop while
dropping the cBPF epilogue mitigation.
Restore the check, folded into a spectre_bhb_mitigations_off() helper
alongside its spectre_v2/v4 counterparts, and use it for the boot-time
print in spectre_print_disabled_mitigations() as well. The print itself
already lives there and does not need restoring.
Tested under QEMU with -cpu neoverse-n1 (CSV2, no ECBHB, no CLRBHB).
Before, spectre_v2 read "Mitigation: CSV2, BHB" with and without the
option; after, nospectre_bhb and mitigations=off both give "Mitigation:
CSV2, but not BHB" and a boot without either is unchanged.
Fixes: 7f1635737823 ("arm64: proton-pack: Fix hard lockup due to print in scheduler context")
Assisted-by: Claude:claude-opus-5
Cc: stable@vger.kernel.org
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Date: Sun Jun 14 02:45:38 2026 +0100
ARM: 9477/1: Disable broken eBPF JIT on the Risc PC
commit 7e8ee82e69fde9d589272ec5e6f702358903be1f upstream.
The eBPF JIT unconditionally generates ldrh/strh instructions, which do
not function correctly on the Risc PC because its bus is unable to
signal half-word accesses. Work around this issue by disabling the eBPF
JIT when building for ARMv3 (the Risc PC is the only currently
supported machine whose kernel is built for ARMv3).
Comments from Ethan Nelson-Moore:
From LKML: https://lore.kernel.org/all/CAD++jL=0qYGoygUwGEXQL7C_ROnC7kfpRv8RA+H5tNWwYu+pQA@mail.gmail.com/
The commit message has been updated slightly relative to the version on LKML to clarify that the Risc PC is not actually ARMv3.
Fixes: 39c13c204bb1 ("arm: eBPF JIT compiler")
Cc: stable@vger.kernel.org
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Christopher Tolang <christophertolang@gmail.com>
Date: Sun Aug 23 19:32:21 2026 +0800
ASoC: amd: yc: Add DMI entry for MSI Thin A15 B7UC
commit e2aa5ad3be41accfcdcccc62348f21af7baa3a38 upstream.
This model requires an additional detection quirk to enable the internal
microphone.
Fixes: fa991481b8b2 ("ASoC: amd: add YC machine driver using dmic")
Cc: stable@vger.kernel.org
Assisted-by: OpenAI Codex
Signed-off-by: Christopher Tolang <christophertolang@gmail.com>
Link: https://patch.msgid.link/20260823113221.19744-1-christophertolang@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Niklas Cassel <cassel@kernel.org>
Date: Thu Jul 2 12:59:58 2026 +0200
ata: libata-scsi: fix DSM TRIM for sector sizes larger than 2048 bytes
commit 79cce911e623c0baa0fde307ce3a434e084b881a upstream.
ata_scsi_write_same_xlat() translates a SCSI WRITE SAME command with the
UNMAP bit set into an ATA DATA SET MANAGEMENT TRIM command. The TRIM
descriptor is built by ata_format_dsm_trim_descr() into the 2048-byte
ata_scsi_rbuf staging buffer, and the number of bytes copied is compared
against the logical sector size by the caller:
size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
if (size != len) /* len == sdp->sector_size */
goto invalid_param_len;
ata_format_dsm_trim_descr() clamps the copy length to ATA_SCSI_RBUF_SIZE
(2048). On a device whose logical sector size exceeds that (e.g. a 4Kn
device, where sector_size == 4096) the function can never return more than
2048, while the caller expects it to return sector_size. The comparison
therefore always fails, so every TRIM is rejected with "Parameter list
length error" and WARN_ON() splats on each attempt. TRIM / discard is
thus completely broken on such devices.
The descriptor was incorrectly sized from the logical sector size. A DSM
TRIM payload is a list of 512-byte pages, each holding up to
ATA_MAX_TRIM_RNUM (64) LBA Range Entries, and is independent of the logical
sector size. The Block Limits VPD page already advertises a single such
page as the maximum WRITE SAME length (65535 * ATA_MAX_TRIM_RNUM logical
blocks), so the block layer never sends a request that needs more than one
page.
Emit exactly one 512-byte page, independent of the logical sector size,
and transfer only that page (COUNT == 1). For a 512-byte-sector device
this is unchanged; devices with larger logical sectors now work instead of
failing every TRIM.
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Fixes: ef2d7392c4ec ("libata: SCT Write Same / DSM Trim")
Cc: stable@vger.kernel.org
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Tue Aug 11 22:01:27 2026 +0000
audit: avoid dropping live tree ref on fsnotify rule autoremove
commit 783f0f0974c156aca630f4ffff248671082a098d upstream.
audit_del_rule() is used for both netlink deletion templates and internal
fsnotify autoremove. The former passes a parsed template which owns a
temporary tree reference; the latter passes the installed entry itself.
The unconditional audit_put_tree() at the end of audit_del_rule() assumes
the template case. For mixed AUDIT_DIR plus AUDIT_EXE rules, an fsnotify
autoremove event therefore drops the installed rule's live tree reference.
Repeating this across rules sharing the same tree can free the tree while
another rule still references it, and a later autoremove dereferences the
freed pathname while comparing rules.
Move the temporary-tree put to audit_rule_change(), the caller that owns
deletion templates. Keep it in the AUDIT_DEL_RULE cleanup so both
successful deletion and -ENOENT still release the parser-owned tree.
Cc: stable@kernel.org
Fixes: 34d99af52ad4 ("audit: implement audit by executable")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Ricardo Robaina <rrobaina@redhat.com>
Tested-by: Ricardo Robaina <rrobaina@redhat.com>
[PM: dropped unnecessary comment for line length reasons]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hongyan Xu <getshell@seu.edu.cn>
Date: Sat Aug 15 18:59:50 2026 +0800
auxdisplay: charlcd: cancel backlight work on registration failure
commit e3e3bf40916c1e810df03958cfa7ba6883cdce79 upstream.
With CONFIG_CHARLCD_BL_FLASH, charlcd_init() schedules bl_work before
charlcd_register() calls misc_register(). If registration fails, the
caller frees the charlcd object while delayed work still contains its
address.
Add charlcd_deinit() to cancel the delayed work and turn the backlight
off. Use it for both registration rollback and normal unregistration.
Fixes: 39f8ea46724e ("auxdisplay: charlcd: Extract character LCD core from misc/panel")
Cc: stable@vger.kernel.org
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: 胡连勤 <hulianqin@vivo.com>
Date: Wed Aug 12 11:59:04 2026 +0000
block: set QUEUE_FLAG_DYING unconditionally in blk_mark_disk_dead()
commit 7e9a46004b471eaf69b082c473d865316a4158e0 upstream.
Disks created via blk_mq_alloc_disk_for_queue() (e.g. SCSI SD disks)
do not have GD_OWNS_QUEUE set. Currently __blk_mark_disk_dead() only
sets QUEUE_FLAG_DYING when GD_OWNS_QUEUE is set, so for such disks
blk_queue_enter() and __bio_queue_enter() cannot detect the dying
state via blk_queue_dying() and remain blocked waiting for I/O that
will never complete after surprise removal.
blk_mark_disk_dead() is the explicit "surprise removal" API -- the
caller has already decided the disk is dead. Setting QUEUE_FLAG_DYING
unconditionally here is appropriate: any in-flight I/O from other
threads should get -ENODEV immediately from blk_queue_enter()
regardless of GD_OWNS_QUEUE ownership.
For disks that already have GD_OWNS_QUEUE set, __blk_mark_disk_dead()
will set the flag again which is harmless.
Fixes: 6f8191fdf41d ("block: simplify disk shutdown")
Cc: stable@vger.kernel.org
Signed-off-by: Lianqin Hu <hulianqin@vivo.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/PUZPR06MB62247E82E66A3ED46CC3E6C7D2DC2@PUZPR06MB6224.apcprd06.prod.outlook.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Christoph Zwerschke <cito@online.de>
Date: Sun Jul 5 11:28:56 2026 +0200
Bluetooth: btusb: Add ASUS USB-BT540 for Realtek 8761CU
commit 980084de4d9b25193398d89a1c0430ba3501b683 upstream.
Add the vendor/product ID (0x0b05, 0x1bef) to the usb_device_id table for
the Realtek RTL8761CU-based ASUS USB-BT540 adapter. It binds via the
generic Bluetooth class today, so BTUSB_REALTEK is never set and the
rtl8761cu firmware is not loaded, leaving the controller non-functional.
With the entry the driver loads rtl_bt/rtl8761cu_fw.bin (already shipped by
linux-firmware) and the adapter works (tested: A2DP and ASHA).
Similar to commit bc597f0cc44f
("Bluetooth: btusb: Add TP-Link UB600 for Realtek 8761BUV").
Device info from /sys/kernel/debug/usb/devices:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 22 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0b05 ProdID=1bef Rev= 2.00
S: Manufacturer=Realtek
S: Product=Bluetooth Controller
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
Cc: stable@vger.kernel.org
Signed-off-by: Christoph Zwerschke <cito@online.de>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Christoph Zwerschke <cito@online.de>
Date: Sun Jul 5 11:28:57 2026 +0200
Bluetooth: btusb: Add ASUS USB-BT600 for Realtek 8761CU
commit 6f0624b4427e38c3bb63a951c536cf8adaee1238 upstream.
Add the vendor/product ID (0x0b05, 0x1d70) to the usb_device_id table for
the Realtek RTL8761CU-based ASUS USB-BT600 adapter. It binds via the
generic Bluetooth class today, so BTUSB_REALTEK is never set and the
rtl8761cu firmware is not loaded, leaving the controller non-functional.
With the entry the driver loads rtl_bt/rtl8761cu_fw.bin (already shipped by
linux-firmware) and the adapter works (tested: A2DP and ASHA).
Similar to commit bc597f0cc44f
("Bluetooth: btusb: Add TP-Link UB600 for Realtek 8761BUV").
Device info from /sys/kernel/debug/usb/devices:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 23 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0b05 ProdID=1d70 Rev= 2.00
S: Manufacturer=Realtek
S: Product=Bluetooth Controller
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms
Cc: stable@vger.kernel.org
Signed-off-by: Christoph Zwerschke <cito@online.de>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Junjie Cao <junjie.cao@intel.com>
Date: Mon Aug 24 13:32:27 2026 +0800
Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728
commit ca0583c24661749508a0979189c254388a685559 upstream.
Commit 5ead2063611a ("Bluetooth: btrtl: fix RTL8761B/BU broken LE
extended scan") set HCI_QUIRK_BROKEN_EXT_SCAN for every CHIP_ID_8761B
device to cure repeated 0x2042 failures on an 0bda:a728 dongle. The
brokenness is per-dongle, not per-chip: on a TP-Link UB500 (2357:0604,
RTL8761BU, fw 0xdfc6d922) extended scan works, and the legacy scan
path the quirk forces is what is broken -- LE Set Scan Enable (0x200c)
times out with -110 about 30 s after firmware load, btusb resets the
device, and the adapter re-enumerates in an endless loop (382 firmware
reloads in one boot). 7.1.8, which predates the stable backport, runs
clean on this unit; 7.1.9 loops.
Move the quirk from btrtl's chip-wide switch to a btusb device-table
flag on the USB id the original fix was verified against. Other 8761B
dongles return to their earlier long-standing behaviour.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2521504
Fixes: 5ead2063611a ("Bluetooth: btrtl: fix RTL8761B/BU broken LE extended scan")
Cc: stable@vger.kernel.org
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Sat Aug 15 15:24:19 2026 +0900
Bluetooth: eir: Fix OOB read in eir_get_service_data()
commit 4beb198bc59b242404a47c21990bc84165052c8a upstream.
eir_get_service_data() walks the advertising data for a Service Data
field with a matching UUID. On a mismatch it advances:
eir += dlen;
eir_len -= dlen;
eir_get_data() reports dlen as the field's data length, but the field
spans dlen + 2 bytes once its length and type bytes count, and more
when non-Service-Data fields were skipped to reach it. The pointer
lands correctly on the next field. eir_len does not, and the shortfall
compounds across fields until eir_get_data() reads the length and type
bytes of a "field" past the end of the buffer.
For an ISO broadcast sink that buffer is hcon->le_per_adv_data[], filled
from the periodic advertising reports of a remote broadcaster. A PA
payload packed with mismatching Service Data fields walks off the array
into the rest of struct hci_conn. A drifted field that matches the BAA
UUID puts those bytes in iso_pi(sk)->base, where user space reads them
back with getsockopt(BT_ISO_BASE).
Recompute eir_len from the end of the buffer each iteration.
Fixes: 8f9ae5b3ae80 ("Bluetooth: eir: Add helpers for managing service data")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Date: Tue Aug 18 10:49:34 2026 +0100
Bluetooth: hci_bcm4377: Ignore reserved PHY in ext adv reports on BCM4378
commit aec6a8d80e3da0ab5c9303a0281fd06d077f8716 upstream.
Commit ed2a2ef16a6b ("Bluetooth: Add quirk to ignore reserved PHY bits in
LE Extended Adv Report") added a quirk to handle creative use of the
reserved bits in the PHY fields for 4388 controllers in Apple silicon.
I observed the same issue with the BCM4378 Bluetooth controller (14e4:5f69,
rev 05) on an Apple MacBook Pro (13-inch, M2, 2022):
> HCI Event: LE Meta Event (0x3e) plen 51
LE Extended Advertising Report (0x0d)
Num reports: 1
Entry 0
Event type: 0x2513
Props: 0x0013
Connectable
Scannable
Use legacy advertising PDUs
Data status: Complete
Reserved (0x2500)
Legacy PDU Type: Reserved (0x2513)
Address type: Random (0x01)
Address: EA:C1:82:F0:24:C6 (Static)
Primary PHY: Reserved
Secondary PHY: No packets
SID: no ADI field (0xff)
TX power: 127 dBm
RSSI: -57 dBm (0xc7)
Periodic advertising interval: 0.00 msec (0x0000)
Direct address type: Public (0x00)
Direct address: 00:00:00:00:00:00 (OUI 00-00-00)
Data length: 25
This results in the firmware rejecting connection attempts with
"Unsupported Feature or Parameter Value" (0x11).
Fix the issue by using the same quirk for BCM4378 devices too.
I tested this locally and confirmed that the issue is resolved.
This was observed when attempting to connect a Kinesis Advantage 360
keyboard to the MacBook.
Assisted-by: Claude:claude-fable-5
Fixes: 2e7ed5f5e69b ("Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync")
Cc: stable@vger.kernel.org
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Sven Peter <sven@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guangshuo Li <lgs201920130244@gmail.com>
Date: Sat Aug 8 13:15:32 2026 +0800
Bluetooth: hci_bcm: fix usage_count leak when autosuspend_delay is negative
commit dc6b7c771a963e20aedf4a21ffa22543b9837ba8 upstream.
bcm_request_irq() calls pm_runtime_use_autosuspend(), but bcm_close()
does not call the matching pm_runtime_dont_use_autosuspend() when
tearing down runtime PM.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during driver teardown, this reference is not dropped and usage_count
remains unbalanced.
Add the missing pm_runtime_dont_use_autosuspend() call before disabling
runtime PM.
This issue was found by manual code inspection.
Fixes: e88ab30d3669 ("Bluetooth: hci_bcm: Add suspend/resume runtime PM functions")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Date: Tue Aug 18 15:29:34 2026 +0200
Bluetooth: hci_conn: re-enable advertising only for peripheral role
commit ed5fb41d3b6b6e665e7f97fd54bd1f9531c7477f upstream.
hci_le_conn_failed() unconditionally calls hci_enable_advertising(),
although its own comment states advertising should be re-enabled only
when the failed attempt was made as a peripheral.
hci_le_conn_failed() is reached from hci_conn_failed() for every failed
LE connection, including outgoing central connections. For a central
attempt this enable is redundant: hci_le_create_conn_sync() already
restores advertising via hci_resume_advertising_sync() in its done:
block. Because hci_enable_advertising() only queues the work on
cmd_sync_work, it runs *after* that resume has already succeeded and
set HCI_LE_ADV.
The resulting HCI sequence, captured on a BCM43455 (no LE Extended
Advertising, so legacy advertising is used):
LE Create Connection Status Success
... 13.8 s, peer never answers ...
LE Set Advertising Parameters (0x2006) Success <- done: resume,
LE Set Advertising Enable (0x200a) Success HCI_LE_ADV set
LE Create Connection Cancel (0x200e) Success
LE Connection Complete Unknown Conn Id
LE Set Advertising Parameters (0x2006) Command Disallowed (0x0c)
The last command is the queued enable from hci_le_conn_failed() running
as a second hci_enable_advertising_sync() pass. It clears HCI_LE_ADV
(hci_sync.c, "Clear the HCI_LE_ADV bit temporarily"), then sends
LE Set Advertising Parameters while the controller is still advertising,
which the controller correctly rejects with Command Disallowed.
The disable-first call at the top of hci_enable_advertising_sync()
cannot prevent this: hci_disable_advertising_sync() returns early
without sending anything when HCI_LE_ADV is clear, so it is a no-op
exactly when the flag is wrong.
hci_enable_advertising_sync() then returns without sending LE Set
Advertising Enable, so HCI_LE_ADV is never set again. The legacy
software rotation loop re-arms hci_schedule_adv_instance_sync() every
HCI_DEFAULT_ADV_DURATION (2 s), and its "already advertising" shortcut
tests HCI_LE_ADV, which can no longer become true. The command is
therefore retried every 2 s indefinitely:
Bluetooth: hci0: Opcode 0x2006 failed: -16
Observed on a gateway as 5326 occurrences over 3 hours, ending only when
bluetoothd was restarted. Connection attempts that succeed do not call
hci_le_conn_failed() and never trigger this.
Add the role test the comment already describes. Both other
hci_enable_advertising() call sites reached from a failed/closed LE
connection (hci_cs_disconnect() and hci_disconn_complete_evt()) already
guard on conn->role == HCI_ROLE_SLAVE; this one was missed.
Reproducing needs legacy advertising (ext_adv_capable() false, so the
software rotation loop is used), simultaneous peripheral advertising and
outgoing central connects, and a central connect that times out rather
than failing fast.
The Fixes tag points at the commit that introduced the advertising
restart into this path for the directed-advertising (peripheral) case;
the role test that the later commit 0b1db38ca26b ("Bluetooth: Fix check
for direct advertising") added to the sibling paths was never applied
here.
Fixes: 3c857757ef6e ("Bluetooth: Add directed advertising support through connect()")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5 btmon
Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xin Chen <xin.chen2@oss.qualcomm.com>
Date: Wed Aug 19 21:53:21 2026 +0800
Bluetooth: hci_core: use skb_get() instead of skb_clone() for req_skb
commit f5afdff569a09d1cb8cf19826199d024725576cb upstream.
BT enable fails intermittently with -ETIMEDOUT (-110). The kernel log
shows the HCI Read Local Version command was sent and the firmware
replied with status 0x00 (logged by hci_req_cmd_complete() BT_DBG),
but the waiter in __hci_cmd_sync_sk() never woke up and timed out
after 10 s:
bluetooth hci0: Opcode 0xfc00 // __hci_cmd_sync_sk
bluetooth hci0: opcode 0xfc00 plen 1 // hci_cmd_sync_add
bluetooth hci0: skb len 4 // hci_cmd_sync_alloc
bluetooth hci0: length 1 // hci_req_sync_run
Bluetooth: hci0 cmd_cnt 1 cmd queued 1 // hci_cmd_work
Bluetooth: hci0 type 1 len 4 // hci_send_frame
Bluetooth: opcode 0xfc00 status 0x00 // hci_req_cmd_complete
<-- req_skb NULL: req_complete_skb not set,
hci_cmd_sync_complete() never called,
req_status stays HCI_REQ_PEND -->
<-- 10 s later: wait_event_interruptible_timeout expires -->
bluetooth hci0: end: err -110 // __hci_cmd_sync_sk
The root cause is that hci_send_cmd_sync() clones the sent command
into hdev->req_skb so that hci_req_cmd_complete() can locate the
registered completion callback. Under memory pressure this
skb_clone() fails, leaving hdev->req_skb NULL. The firmware reply
is received and processed, but hci_req_cmd_complete() finds NULL
req_skb, so hci_cmd_sync_complete() is never called, req_status
stays HCI_REQ_PEND, and the waiter times out with -ETIMEDOUT.
req_skb is only used to read bt_cb(skb)->hci callbacks and opcode --
it is never modified. Replace skb_clone() with skb_get(), which
simply increments the reference count of hdev->sent_cmd without
allocating new memory and therefore cannot fail.
This issue was first observed as a use-after-free in ttyport_close()
when ttyport_open() failed, which was investigated in an earlier
patch series [1]. That investigation led to the discovery of the
true root cause described above.
[1] https://lore.kernel.org/all/20250430111617.1151390-1-quic_cxin@quicinc.com/
Fixes: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
Cc: stable@vger.kernel.org
Signed-off-by: Xin Chen <xin.chen2@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Date: Tue Aug 18 15:29:35 2026 +0200
Bluetooth: hci_event: clear HCI_LE_ADV only on a created connection
commit 941929abe5feaed672b9a52e330e547d333240c6 upstream.
le_conn_complete_evt() clears HCI_LE_ADV before looking at the event
status, on the premise stated in its comment that all controllers stop
advertising when a connection is created.
That premise only holds when a connection was actually created. On a
non-zero status none was, and the controller is still advertising: after
the host issues LE Create Connection Cancel the event arrives with
Unknown Connection Identifier (0x02), and a connection timeout behaves
the same way. Clearing the flag there leaves the host believing
advertising is off while the controller has it on.
It is also wrong for extended advertising, where several sets can be
advertising at once. hci_cc_le_set_ext_adv_enable() is careful about
this - on disabling one set it walks hdev->adv_instances and only clears
HCI_LE_ADV once no instance is still enabled. The unconditional clear
here discards that bookkeeping, so one set connecting drops the flag
while the others keep advertising.
The direction of the error matters. A flag left set is self-correcting:
hci_disable_advertising_sync() sends LE Set Advertising Enable(0) and
the command complete puts the state back. A flag left clear is not,
because that same function returns early without sending anything while
the flag is clear:
- LE Set Advertising Parameters is then sent to a controller that is
still advertising, and is correctly rejected with Command Disallowed
(0x0c);
- hci_enable_advertising_sync() returns at that point, before the
LE Set Advertising Enable that would set HCI_LE_ADV again.
On a controller without LE Extended Advertising that is reachable from
here: hci_schedule_adv_instance_sync() re-arms adv_instance_expire every
HCI_DEFAULT_ADV_DURATION (2 s) and its "already advertising" shortcut
tests HCI_LE_ADV, which can no longer become true, so the parameter
write is retried for as long as advertising is configured:
Bluetooth: hci0: Opcode 0x2006 failed: -16
Only clear the flag when a connection was established.
Note this is not on its own sufficient to stop that retry loop - the
redundant enable queued by hci_le_conn_failed() clears HCI_LE_ADV itself
and recreates the same mismatch, which patch 1 addresses. This patch
fixes the event handler reporting a state the controller is not in.
Verified on the affected device (BCM43455, legacy advertising only) with
this patch and patch 1 applied. A 221 s btmon capture with an out-of-range
peer at -90 dBm contains two outgoing connection attempts that the host
cancelled, each producing exactly the event this patch changes:
< LE Set Advertising Parameters 0x2006 Success
< LE Set Advertising Enable 0x200a Success
< LE Create Connection Cancel 0x200e Success
> LE Connection Complete Unknown Connection Identifier (0x02), central
Nothing follows either one; the next command is an unrelated scan restart
70 ms later. Over the whole capture: 7 LE Set Advertising Parameters sent,
all Success; 10 LE Set Advertising Enable, all Success; no Command
Disallowed of any opcode, and no 2 s cadence anywhere. Two central
connections to other peers completed normally afterwards, with feature
exchange and a connection parameter update, so advertising was still live
across the cancelled attempts.
The extended advertising case above is a code argument, not a measurement:
this controller has no LE Extended Advertising, so that path is not
exercised by the capture.
Fixes: fbd96c151cdc ("Bluetooth: Fix clearing HCI_LE_ADV for LE connections")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5 btmon
Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guangshuo Li <lgs201920130244@gmail.com>
Date: Sat Aug 8 13:26:54 2026 +0800
Bluetooth: hci_h5: fix usage_count leak when autosuspend_delay is negative
commit 853a92b97ca547a7ddd9790ff90651b2fd943498 upstream.
h5_btrtl_open() calls pm_runtime_use_autosuspend(), but
h5_btrtl_close() does not call the matching
pm_runtime_dont_use_autosuspend() when tearing down runtime PM.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during driver teardown, this reference is not dropped and usage_count
remains unbalanced.
Add the missing pm_runtime_dont_use_autosuspend() call before disabling
runtime PM.
This issue was found by manual code inspection.
Fixes: d9dd833cf6d2 ("Bluetooth: hci_h5: Add runtime suspend")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guangshuo Li <lgs201920130244@gmail.com>
Date: Sat Aug 8 13:30:57 2026 +0800
Bluetooth: hci_intel: fix usage_count leak when autosuspend_delay is negative
commit c7e9a8cb6918656884a0757c92465075c7555ffa upstream.
intel_set_power() calls pm_runtime_use_autosuspend() when powering on
the device, but the power-off path does not call the matching
pm_runtime_dont_use_autosuspend() before disabling runtime PM.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped and usage_count remains
unbalanced.
Add the missing pm_runtime_dont_use_autosuspend() call before disabling
runtime PM.
This issue was found by manual code inspection.
Fixes: 74cdad37cd24 ("Bluetooth: hci_intel: Add runtime PM support")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ibrahim Abdelkader <iabdelka@qti.qualcomm.com>
Date: Tue Aug 11 10:37:29 2026 +0200
Bluetooth: hci_sync: Clear HCI_CMD_PENDING when dropping the last request
commit cb19774faa57c51efa189d8b8606aeabccebc53b upstream.
A synchronous HCI command that never receives a response leaves
HCI_CMD_PENDING set: hci_req_cmd_complete() is the only place that clears
it, and it only runs when a response matching the last command sent
arrives.
hci_send_cmd_sync() populates hdev->req_skb only when the flag transitions
from clear to set, while hci_dev_open_sync() and hci_dev_close_sync() drop
req_skb without clearing the flag. After a timeout followed by either, the
two disagree: the flag claims a request is outstanding while req_skb is
NULL. Subsequent synchronous commands are then sent with no req_skb, so
hci_event_packet() has nothing to match an arriving event against, and the
caller times out even though the controller answered.
Commands answered by Command Complete recover on their own, since
hci_req_cmd_complete() clears the flag as a side effect. Drivers using
__hci_cmd_sync_ev() with a custom event do not, because a vendor event
never reaches that path. On a WCN3988 (hci_qca over UART) this makes a
controller firmware hang unrecoverable: the driver injects a hardware
error and re-runs qca_setup(), qca_read_soc_version() waits for
HCI_EV_VENDOR, the reply arrives within 4 ms and is discarded, and every
retry fails the same way. The adapter is left down until the driver is
unbound and rebound, or power is removed.
Clear the flag wherever the last request is dropped, restoring the
invariant that req_skb is non-NULL exactly when HCI_CMD_PENDING is set.
Verified on hardware by forcing a command timeout: without this change
setup fails on every attempt, with it setup succeeds on the first.
Fixes: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Abdelkader <iabdelka@qti.qualcomm.com>
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Gongwei Li <ligongwei@kylinos.cn>
Date: Fri Aug 21 10:45:55 2026 +0800
Bluetooth: hci_uart: Fix false success return in hci_uart_setup()
commit a9355799343e10014f2acfd4b6844d2335ecafea upstream.
When reading the local version information for vendor detection
fails, the error is only printed and 0 is returned, which masks the
setup failure from the HCI core.
Return PTR_ERR(skb) instead.
Fixes: fb2ce8d11f039 ("Bluetooth: hci_uart: Add support for vendor detection flag")
Fixes: 82f5169bf3d3b ("Bluetooth: hci_uart: add serdev driver support library")
Cc: stable@vger.kernel.org
Signed-off-by: Gongwei Li <ligongwei@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hang Nan <2122295973@qq.com>
Date: Wed Aug 19 08:57:58 2026 +0800
Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
commit 560bef609fa5992745929e8d7d458b9d88dd2830 upstream.
iso_conn_ready() looks up the BIS listener socket with iso_get_sock(),
which takes a reference, and then, without re-checking its state,
creates a child socket from it:
parent = iso_get_sock(hdev, ...);
if (!parent)
return;
lock_sock(parent);
sk = iso_sock_alloc(sock_net(parent), NULL, BTPROTO_ISO, ...);
...
iso_chan_add(conn, sk, parent);
...
release_sock(parent);
sock_put(parent);
If the listener socket is closed concurrently, between iso_get_sock()
and lock_sock(), the reference taken by iso_get_sock() may be the last
one: the close path drops the link-list reference, and once
iso_conn_ready() drops its own reference at the end of the function the
socket is freed. The child socket, however, is already linked to the
freed parent, and a later disconnect of the child runs iso_chan_del()
-> bt_accept_unlink(), which dereferences the dangling parent pointer
into the freed accept queue (a use-after-free). The same dangling
pointer is also dereferenced through parent->***() in
iso_chan_del().
Fix it the same way the connected (non-BIS) path was fixed in commit
0d255e63fcf3 ("Bluetooth: ISO: hold sk properly in iso_conn_ready"):
after taking the socket lock, re-check that the parent is still a
listening, alive socket, and bail out otherwise.
Fixes: ccf74f2390d60 ("Bluetooth: Add BTPROTO_ISO socket type")
Cc: stable@vger.kernel.org
Signed-off-by: Hang Nan <2122295973@qq.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chengfeng Ye <nicoyip.dev@gmail.com>
Date: Sun Aug 23 00:43:41 2026 +0800
Bluetooth: RFCOMM: serialize security confirmation handling
commit 759c185d0bbdb131357408f50b8735e04ed3caff upstream.
rfcomm_security_cfm() looks up a session on session_list and then walks
its DLC list without holding rfcomm_mutex. Since RFCOMM session teardown
uses rfcomm_mutex, krfcommd can close and free the same session and DLCs
concurrently:
hci_rx_work krfcommd
----------- ---------
rfcomm_session_get()
rfcomm_lock()
rfcomm_session_close()
rfcomm_dlc_unlink()
rfcomm_session_del()
kfree(s)
rfcomm_unlock()
walk s->dlcs
The callback can then read a freed session list head and touch freed DLCs
while updating their flags or timers.
Serialize the session lookup and DLC traversal in rfcomm_security_cfm()
with rfcomm_mutex. This matches the existing RFCOMM session lifetime
rules and prevents concurrent rfcomm_session_del() / rfcomm_dlc_unlink()
from tearing the objects down while the callback is using them.
KASAN reported:
BUG: KASAN: slab-use-after-free in rfcomm_security_cfm+0x41c/0x440
Read of size 8 at addr ffff888111fb3960 by task kworker/u17:1/89
Workqueue: hci0 hci_rx_work
Call Trace:
rfcomm_security_cfm+0x41c/0x440
hci_encrypt_cfm+0x139/0x590
hci_encrypt_change_evt+0x37b/0xc40
hci_event_packet+0x71b/0xb20
hci_rx_work+0x293/0x730
Allocated by task 69:
rfcomm_session_add+0x9e/0x2f0
rfcomm_run+0x44b/0x41e0
Freed by task 69:
kfree+0x131/0x3c0
rfcomm_session_del+0x188/0x220
rfcomm_run+0x1985/0x41e0
Fixes: 08c30aca9e698faddebd34f81e1196295f9dc063 ("Bluetooth: Remove RFCOMM session refcnt")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jiangshan Yi <yijiangshan@kylinos.cn>
Date: Sat Aug 15 20:21:49 2026 +0800
bnx2x: fix double free in bnx2x_init_firmware() error path
commit d2796ffe38cb4155afe0eab23636295b096c27a5 upstream.
bnx2x_init_firmware() frees bp->init_ops, bp->init_data and
bp->init_ops_offsets in its error path without setting them to NULL.
The cleanup function bnx2x_release_firmware() frees the same three
pointers unconditionally, so if init_firmware fails and
release_firmware is later called (e.g. from __bnx2x_remove or through
the function state machine), all three are freed a second time.
Set each pointer to NULL after kfree() in the error path so that the
subsequent kfree(NULL) in bnx2x_release_firmware() is a safe no-op.
Fixes: 94a78b79cb5f ("bnx2x: Separated FW from the source.")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260815122149.951215-1-yijiangshan@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joe Damato <joe@dama.to>
Date: Tue Aug 25 17:02:33 2026 -0700
bnxt_en: Write doorbell when linearizing skb fails
commit 00eeab0c644a881a1dc86fbffb7e6047a6ce8ecd upstream.
When the driver is handed a burst of packets, the doorbell is deferred
until the end. If the last packet has a huge number of frags, but fails
to linearize, the doorbell will not be written adding latency on TX for
any packets in the ring and holding their DMA mappings until the next
TX. Note that the queue is not stopped, so this issue would delay
pending BDs until the next TX.
This issue was discovered by Sashiko and reading the code verifies that,
while unlikely, it is possible.
Fix this by jumping to tx_free, which replicates the same pre-existing
logic but also writes the doorbell.
Fixes: b91e82129400 ("bnxt_en: Linearize TX SKB if the fragments exceed the max")
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Link: https://patch.msgid.link/20260826000234.2031564-1-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vineet Gupta <vineet.gupta@linux.dev>
Date: Fri Aug 14 15:02:53 2026 -0700
bpf, x86: Fix per-CPU address resolution into an extended register
commit 5bbbce02e500d47d8e259a45be5a7be9741d0533 upstream.
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.
Fixes: 7bdbf7446305 ("bpf: add special internal-only MOV instruction to resolve per-CPU addrs")
Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260814220254.3797467-2-vineet.gupta@linux.dev
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Daniel Borkmann <borkmann@iogearbox.net>
Date: Mon Aug 3 23:01:47 2026 +0200
bpf: Disable preemption in __bpf_get_stack
commit b1a47b2708d4e95dbd23aee2ec83752190897b3f upstream.
get_perf_callchain() returns a per-CPU perf_callchain_entry buffer and
releases its recursion slot via put_callchain_entry() before returning,
so nothing keeps the entry reserved while __bpf_get_stack() consumes
it below.
A preemptible BPF program (e.g. a non-sleepable raw tracepoint program
on a PREEMPT kernel, which runs under migrate_disable() but not
preempt_disable()) can be scheduled out between obtaining the entry
and the copy. Another task scheduled on the same CPU then reuses the
same per-CPU buffer and overwrites trace->nr with a larger value.
copy_len is then computed from the inflated trace->nr and can exceed
the caller's buffer, causing an out-of-bounds write in the memcpy()
and in the build_id path.
The rcu_read_lock() taken here alone does not prevent this. It is
only taken on the may_fault path, and under CONFIG_PREEMPT_RCU it does
not disable preemption; it merely keeps perf's callchain buffer array
alive (freed via call_rcu()) and does nothing to stop another task
from reusing the entry.
Disable preemption around obtaining the callchain entry and copying
it into the caller's buffer, so the entry cannot be reused underneath
us and trace->nr stays bounded by max_depth. Build ID resolution may
fault and is therefore deferred until after preemption is re-enabled;
by then the instruction pointers have already been copied into buf,
so it operates only on that private copy. Note, preempt_disable() also
subsumes the buffer-lifetime guarantee the rcu_read_lock() provided,
since a preempt-disabled section is an RCU read-side critical section
for the callchain buffers' call_rcu() reclaim.
Fixes: c195651e565a ("bpf: add bpf_get_stack helper")
Reported-by: Tao Chen <chen.dylane@linux.dev>
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <borkmann@iogearbox.net>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/bpf/20260803210149.296496-11-jolsa@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Closes: https://lore.kernel.org/bpf/20260206090653.1336687-1-chen.dylane@linux.dev/
[ changed Fixes: commit ]
Author: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed Apr 1 00:20:19 2026 +0200
bpf: Fix incorrect pruning due to atomic fetch precision tracking
[ Upstream commit 179ee84a89114b854ac2dd1d293633a7f6c8dac1 ]
When backtrack_insn encounters a BPF_STX instruction with BPF_ATOMIC
and BPF_FETCH, the src register (or r0 for BPF_CMPXCHG) also acts as
a destination, thus receiving the old value from the memory location.
The current backtracking logic does not account for this. It treats
atomic fetch operations the same as regular stores where the src
register is only an input. This leads the backtrack_insn to fail to
propagate precision to the stack location, which is then not marked
as precise!
Later, the verifier's path pruning can incorrectly consider two states
equivalent when they differ in terms of stack state. Meaning, two
branches can be treated as equivalent and thus get pruned when they
should not be seen as such.
Fix it as follows: Extend the BPF_LDX handling in backtrack_insn to
also cover atomic fetch operations via is_atomic_fetch_insn() helper.
When the fetch dst register is being tracked for precision, clear it,
and propagate precision over to the stack slot. For non-stack memory,
the precision walk stops at the atomic instruction, same as regular
BPF_LDX. This covers all fetch variants.
Before:
0: (b7) r1 = 8 ; R1=8
1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8
2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs=r2 stack= before 2: (b7) r2 = 0
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
After:
0: (b7) r1 = 8 ; R1=8
1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8
2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs= stack=-8 before 2: (b7) r2 = 0
mark_precise: frame0: regs= stack=-8 before 1: (7b) *(u64 *)(r10 -8) = r1
mark_precise: frame0: regs=r1 stack= before 0: (b7) r1 = 8
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
Fixes: 5ffa25502b5a ("bpf: Add instructions for atomic_[cmp]xchg")
Fixes: 5ca419f2864a ("bpf: Add BPF_FETCH field / create atomic_fetch_add instruction")
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260331222020.401848-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Wed Aug 5 06:02:28 2026 +0000
bpf: Harden bloom filter sizing and indexing on 32-bit kernels
commit 11c1e836710dcba03e50454a4eedfdbaf8d3050e upstream.
bloom_map_alloc() has two 32-bit-specific problems when the computed
bitmap reaches the U32_MAX fallback case.
First, BITS_TO_BYTES(U32_MAX) is evaluated with 32-bit arithmetic. The
addition performed by DIV_ROUND_UP wraps, so the map allocates only the
fixed-size bloom filter object while keeping bitset_mask == U32_MAX.
Subsequent updates can then write past the allocated object.
Second, fixing only the allocation size is not sufficient. The bloom hash
is a u32, but set_bit() takes a signed long bit number and x86 test_bit()
eventually feeds the index to variable_test_bit(long, ...). On 32-bit
kernels, hashes in [0x80000000, U32_MAX] therefore become negative bit
offsets. x86 bt/bts with a memory operand interpret those offsets relative
to the supplied base, so a map with bitset_mask == U32_MAX can read or
write before bloom->bitset even after allocating the full 512 MiB bitmap.
Keep the U32_MAX fallback, but split each hash into a word pointer and an
in-word bit number before calling test_bit() or set_bit(). The bitops
argument is then always in [0, BITS_PER_LONG - 1], while BIT_WORD(h) still
selects the intended word in the full bitmap.
Compute the bitset size from (u64)bitset_mask + 1 before passing the final
size to bpf_map_area_alloc(). This fixes the original under-allocation and
keeps the allocated storage consistent with the addressable bitset.
Exploitation note: local privilege escalation is possible on a 32-bit x86
kernel using the under-allocation bug from a binary with CAP_BPF.
Fixes: 9330986c0300 ("bpf: Add bloom filter map implementation")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/bpf/20260805060228.2703051-1-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Assisted-by: Codex:gpt-5
Author: Qu Wenruo <wqu@suse.com>
Date: Tue Jun 9 08:43:34 2026 +0930
btrfs: do not overwrite NODATASUM flag when removing NODATACOW flag
commit 15f7c86215e8d5f14b24127fa88af6c79363d50e upstream.
[TEST FAILURE]
The test case generic/628 will fail if MOUNT_OPTIONS is set to
"-o nodatasum":
FSTYP -- btrfs
PLATFORM -- Linux/x86_64 btrfs-vm 7.1.0-rc4-custom+ #383 SMP PREEMPT_DYNAMIC Sat May 30 07:35:42 ACST 2026
MKFS_OPTIONS -- -O bgt -K /dev/mapper/test-scratch1
MOUNT_OPTIONS -- -o nodatasum /dev/mapper/test-scratch1 /mnt/scratch
# generic/628 1s ... - output mismatch (see /home/adam/xfstests/results//generic/628.out.bad)
# --- tests/generic/628.out 2022-05-11 11:25:30.816666664 +0930
# +++ /home/adam/xfstests/results//generic/628.out.bad 2026-06-08 18:56:49.878542927 +0930
# @@ -8,8 +8,9 @@
# 310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
# 310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/d
# test reflink flag not set iflag
# +XFS_IOC_CLONE: Invalid argument
# 310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
# -310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/b
# +d41d8cd98f00b204e9800998ecf8427e SCRATCH_MNT/b
# ...
[CAUSE]
The direct cause is that after "chattr +S", the btrfs inode will lose its
NODATASUM flag inherited from the mount option. E.g.:
# mkfs.btrfs -f $dev
# mount $dev $mnt -o nodatasum
# touch $mnt/foobar
# sync
# btrfs ins dump-tree -t 5 $dev | grep "(257 INODE_ITEM 0) itemoff" -A 3
item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
generation 9 transid 9 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 1 flags 0x1(NODATASUM)
^^^^^^^^^ Proper NODATASUM flag
# chattr +S $mnt/foobar
# sync
# btrfs ins dump-tree -t 5 $dev | grep "(257 INODE_ITEM 0) itemoff" -A 3
item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
generation 9 transid 10 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 2 flags 0x20(SYNC)
^^^^ Only the new SYNC flag
This makes the inode drop the old NODATASUM flag, while the new reflink
destination will still inherit the NODATASUM flag. The mismatching
NODATASUM flags will cause the reflink to fail.
The root cause is that, inside btrfs_fileattr_set() if no FS_NOCOW_FL is
set, we remove both NODATASUM and NODATACOW flag.
However we should not touch NODATASUM flag, as data COW doesn't require
checksum. Only NODATACOW implies NODATASUM, but DATACOW doesn't imply
DATASUM.
The deeper problems are:
- Fileattr API is too binary
It either clears or sets a flag, there is no "do not change" option.
So that why "chattr +S" implies "chattr -C", and is forcing us to
change NODATACOW along with NODATASUM flag.
- No way to change NODATASUM through fileattr API
In fact NODATASUM can only be modified through mount option.
The deeper problems are much harder to attack.
[FIX]
Remove NODATACOW flag when FS_NOCOW_FL is not set, but only remove
NODATASUM if "nodatasum" mount option is not set.
This allows the existing "chattr +C" then "chattr -C" to remove
both NODATACOW and NODATASUM flags on a default mount.
But for a mount with "nodatasum" option, the NODATASUM inode flag will
persist through either "chattr +C" and "chattr -C".
Fixes: 7e97b8daf634 ("btrfs: allow setting NOCOW for a zero sized file via ioctl")
Cc: stable@vger.kernel.org
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guanghui Yang <3497809730@qq.com>
Date: Sun Jul 12 04:22:32 2026 +0000
btrfs: drop recovered reloc root refs on recovery failure
commit 6d8ba4572922e336f0b59a80751b018e1e135164 upstream.
During relocation recovery, each fs root gets a reference to its relocation
root. If loading or adding a later root fails, or if the first transaction
commit fails, btrfs_recover_relocation() jumps to out_unset before
merge_reloc_roots() and clean_dirty_subvols().
put_reloc_control() drops the list-owned relocation root references, but it
does not clear fs_root->reloc_root or drop the references owned by those
pointers. Mount cleanup only drops them when BTRFS_FS_ERROR is set, so an
error such as -ENOMEM while processing a later root can leave references
behind.
Keep temporary references to the fs roots associated during recovery. On
failure, clear their reloc_root pointers and drop the corresponding
references. Once the first transaction commit succeeds, drop only the
temporary fs root references and let the normal merge and cleanup paths
handle the relocation roots.
Fault injection on a pending-relocation image confirmed the cleanup gap.
With an injected first-commit failure, 25 fs roots had reloc_root set with
fs_error=0. With this fix, the same failure path drops that count to 0
before mount fails.
Fixes: f44deb7442ed ("btrfs: hold a ref on the root->reloc_root")
CC: stable@vger.kernel.org
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Date: Sun Jul 5 01:46:35 2026 -0400
btrfs: fix extent map leak in NOCOW direct I/O write
commit 3f950867c307c5413d628a153ac44915bd117ffd upstream.
btrfs_dio_iomap_begin() calls btrfs_get_extent(), which returns an
extent map reference that must be dropped on all exit paths.
For direct writes into a NOCOW range, btrfs_get_blocks_direct_write()
keeps using that extent map and asks btrfs_create_dio_extent() to
allocate the ordered extent. If that fails, for example because
btrfs_alloc_ordered_extent() fails, the function returns the error
without dropping the input extent map. The PREALLOC path avoided this by
dropping the input extent map before replacing it with the newly created
one.
Check the error from btrfs_create_dio_extent() before replacing the
map and drop the input extent map on failure.
Fixes: 5f9a8a51d8b9 ("Btrfs: add semaphore to synchronize direct IO writes with fsync")
CC: stable@vger.kernel.org
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jia Zhu <zhujia.zj@bytedance.com>
Date: Tue Jun 9 11:52:01 2026 +0800
buffer: avoid tail commit walk for uptodate folios
commit f10b9cc1eb20637351f4e33372bfb464f89de59b upstream.
block_commit_write() always walks every buffer_head attached to the
folio. That was cheap for order-0 folios, but large folios can contain
hundreds of buffer_heads. For a small buffered overwrite of an
already-uptodate large folio, the commit work is therefore proportional
to the folio size rather than the copied range.
This became visible with ext4 regular-file large folios, where cached
small overwrites reach block_commit_write() through block_write_end().
Before ext4 enabled large folios for regular files, this path was only
hit with order-0 folios for normal ext4 buffered writes, so the full walk
was bounded. The ext4 large-folio commit is therefore the regression
point for this generic helper cost.
The full walk is still needed when the folio is not uptodate, because
block_commit_write() uses per-buffer uptodate state to decide whether
the whole folio can be marked uptodate. Keep those folios on the old
full-buffer path.
For a folio that was already uptodate on entry, the commit no longer
needs tail buffers for folio-uptodate discovery. The copied range has
already been processed once block_start reaches @to, so stop there and
avoid the suffix walk.
Fixes: 7ac67301e82f0 ("ext4: enable large folio for regular file")
Suggested-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: stable@vger.kernel.org # v6.16+
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com>
Link: https://patch.msgid.link/20260609035202.90669-2-zhujia.zj@bytedance.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
Date: Fri Jul 24 02:27:12 2026 -0700
cdx: Fix double free when sysfs file creation fails
commit 6f4acc3a3c300e174e3f586b97b04ed8f5948c36 upstream.
In cdx_create_res_attr(), if sysfs_create_bin_file() fails, the code
frees res_attr but doesn't set cdx_dev->res_attr[num] to NULL. This
leaves a dangling pointer in the array. Then cdx_destroy_res_attr()
frees the already-freed memory. Fix the double free by initializing
cdx_dev->res_attr[num] after sysfs_create_bin_file() completes.
Fixes: aeda33ab8160 ("cdx: create sysfs bin files for cdx resources")
Cc: stable@vger.kernel.org
Signed-off-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
Acked-by: Nikhil Agarwal <Nikhil.agarwal@amd.com>
Acked-by: Nipun Gupta <nipun.gupta@amd.com>
Link: https://patch.msgid.link/20260724092712.2119149-1-ptsm@linux.microsoft.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Sat Jul 11 11:07:05 2026 -0400
ceph: bound copied dentry name length in NFS export get_name
commit eff8013c5a8916613c742ae5a2cc341cb605c0ae upstream.
ceph_get_name() copies the MDS-supplied name into the caller's
NAME_MAX-sized buffer with memcpy(name, rinfo->dname, rinfo->dname_len)
and then writes name[rinfo->dname_len] = 0, without checking dname_len
against NAME_MAX. A malicious or buggy MDS that returns a LOOKUPNAME reply
with dname_len > NAME_MAX overflows the buffer. __get_snap_name() copies
rde->name / rde->name_len the same unchecked way.
Impact: a malicious or compromised Ceph MDS overflows the NAME_MAX name
buffer in a client's NFS-export get_name path, a slab out-of-bounds write
reported by KASAN. Reachable when a CephFS mount is re-exported over NFS.
Add ceph_export_copy_name(), which rejects lengths above NAME_MAX with
-ENAMETOOLONG before the copy, and use it in both ceph_get_name() and
__get_snap_name().
Cc: stable@vger.kernel.org
Fixes: 19913b4eac4a ("ceph: add get_name() NFS export callback")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Tue Jul 7 14:05:58 2026 -0400
ceph: bound MDSCapAuth path and fs_name decode in handle_session()
commit 77933e22adfe813be2bd10be08d6e950103c3967 upstream.
handle_session() decodes the MDSCapAuth records carried by a
CEPH_SESSION_OPEN message (msg_version >= 6). For each record the
match.path and match.fs_name byte strings are read by first decoding a
32-bit length and then copying that many bytes with the bare
ceph_decode_copy(). Unlike the surrounding fields, which all use the
_safe decode variants, these two copies are not preceded by a
ceph_decode_need() bounds check, and the enclosing MDSCapAuth and
MDSCapMatch struct_len fields are skipped rather than enforced as an
upper bound. A length larger than the bytes remaining in the message
front makes ceph_decode_copy() read past the end of the front buffer.
The message front is a dedicated allocation (ceph_msg_new2() ->
kvmalloc), so the over-read runs off that object. A malicious or
compromised MDS can trigger this with the first post-connect message on
mount, with no client-side user interaction; under KASAN it is reported
as a slab-out-of-bounds read in handle_session().
Impact: a malicious MDS can force the kernel client to read up to 4 GiB
past the message front allocation during session setup, crashing the
client (out-of-bounds read).
Switch both copies to ceph_decode_copy_safe(), which performs the
ceph_decode_need() bounds check before the copy and branches to the
existing bad label, matching the rest of the decoder and the error path
that frees the partially decoded cap_auths array.
Cc: stable@vger.kernel.org
Fixes: 1d17de9534cb ("ceph: save cap_auths in MDS client when session is opened")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Tue Jul 7 14:05:59 2026 -0400
ceph: bound num_export_targets array for mds info v2/v3
commit a3eb169ee297aa99670ba927c659990bd1e453f3 upstream.
ceph_mdsmap_decode() in fs/ceph/mdsmap.c reads num_export_targets from
each per-mds info record and advances the decode cursor by
num_export_targets * sizeof(u32) without first checking that many bytes
remain. The only upper-bound check that catches a runaway cursor
(*p > info_end) is gated on info_v >= 4, because info_end is left NULL
for info_v 2 and 3. When the monitor sends an MDS map whose per-mds
info version is 2 or 3 with an oversized num_export_targets, the cursor
moves past the message front buffer and the later export-targets loop
calls the unchecked ceph_decode_32() on out-of-bounds memory.
A kernel client processes CEPH_MSG_MDS_MAP from its monitor session
(net/ceph/mon_client.c dispatches it; fs/ceph/super.c routes it to
ceph_mdsc_handle_mdsmap(), which sets end to the front buffer bound and
calls ceph_mdsmap_decode()). A malicious or compromised monitor, or an
on-path attacker on an unsigned/unencrypted messenger session, can
therefore drive an out-of-bounds read in the client kernel; on x86_64
with KASAN it is reported as a slab-out-of-bounds read in
ceph_mdsmap_decode(). The decoded values land in the internal
info->export_targets[] array, so the consequence is a kernel
out-of-bounds read, not an information leak to the attacker.
Impact: a malicious or compromised Ceph monitor sending an MDS map with
a per-mds info version of 2 or 3 and an oversized num_export_targets
field triggers an out-of-bounds read in the CephFS client kernel.
Add a ceph_decode_need() for the export-targets array before advancing
the cursor, so the bound is enforced for every info_v >= 2, not only
info_v >= 4. This mirrors the count-then-need idiom already used for
m_data_pg_pools later in the same function.
Compute the export-targets byte count with size_mul() and reuse that
checked length when advancing the cursor, so the attacker-controlled
num_export_targets multiplication fails closed on overflow rather than
relying on the later kcalloc() guard.
Cc: stable@vger.kernel.org
Fixes: d463a43d69f4 ("ceph: CEPH_FEATURE_MDSENC support")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Tue Jul 7 14:05:57 2026 -0400
ceph: bound xattr value length in __build_xattrs()
commit 68d541754d6cd3bb98d1fd8314f57e5eb533557d upstream.
__build_xattrs() decodes the MDS-supplied xattr blob one attribute at a
time. For each attribute it reads a 32-bit name length, advances past the
name bytes, reads a 32-bit value length, records the value pointer, and
advances past the value bytes. The two length fields are read with
ceph_decode_32_safe(), but the value bytes themselves are advanced over
with a bare "p += len" and no ceph_decode_need() check that "len" bytes
remain in the blob.
For every attribute except the last, the next iteration's
ceph_decode_32_safe() on the following name length implicitly verifies
that the previous value did not run past the blob end. The final
attribute has no successor, so its decoded value length is never checked
against the blob bounds. A malicious or compromised metadata server can
set the last attribute's value length larger than the bytes actually
present in the blob.
The blob is a dedicated kvmalloc() allocation sized to the wire length
(ceph_buffer_new() in ceph_fill_inode()). __set_xattr() records the
oversized length in xattr->val_len verbatim, and a later getxattr(2) runs
memcpy(value, xattr->val, xattr->val_len) into a user-supplied buffer,
copying bytes past the end of the allocation back to user space.
Impact: a malicious metadata server discloses adjacent kernel heap bytes
to a local user via getxattr(2) on a CephFS file. Add the missing
ceph_decode_need() so an out-of-bounds value length on the final
attribute fails the decode and returns -EIO instead of being stored.
Cc: stable@vger.kernel.org
Fixes: 355da1eb7a1f ("ceph: inode operations")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Max Kellermann <max.kellermann@ionos.com>
Date: Tue Jul 7 23:42:28 2026 +0200
ceph: do not repeat ceph_trim_dentries() if no progress possible
commit e7d7aa7b730178278109c41fa1b17b06873065d5 upstream.
ceph_cap_reclaim_work() re-queues itself for as long as
ceph_trim_dentries() returns -EAGAIN, which happens whenever a lease
walk exhausts its `nr_to_scan` budget. This creates a busy loop that
consumes CPU without making any progress when there is nothing to
reclaim: with no cap pressure (`count==0`) and every scanned lease
still valid, each pass runs the full scan budget down to zero and
returns `-EAGAIN`, only to be queued again immediately.
The dir-lease walk made this worse. When `expire_dir_lease` is
`false` (i.e. we have no intention of reclaiming dir leases),
__dir_lease_check() returned `TOUCH` for every valid lease. `TOUCH`
moves the dentry to the tail of the list and resets `di->time` via
__dentry_dir_lease_touch(), so a walk over N valid leases pointlessly
rewrote the list, refreshed the timestamps (preventing them from ever
aging out) and always drained `nr_to_scan`, guaranteeing the `-EAGAIN`
requeue.
Fix this in three steps:
- Return `KEEP` instead of `TOUCH` when `expire_dir_lease` is
`false`. If we are not going to reclaim the lease, leave it in
place instead of churning the list and resetting its timestamp; the
walk then terminates naturally (or via `STOP` at the first fresh
lease).
- Only return `-EAGAIN` from the first (dentry-lease) walk when something
was actually freed. A full batch that frees nothing means retrying
the same list immediately is futile; fall through to the dir-lease
walk instead.
- After both walks, bail out with success (0) when nothing was freed
and there is no cap pressure (`count==0`). There is no reason to
keep retrying when we are not over the cap limit and made no
progress.
Under real cap pressure (`count>0`) the reclaim path is unchanged and
still retries via `-EAGAIN`.
Without this patch, I saw 500 ceph_trim_dentries() calls per second on
our web servers. This is very visible in `/proc/lock_stat` (5 minute
capture):
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 126180 128218 0.04 8063.44 15986965.20 124.69 1573354 5296812 0.04 8291.28 74164526.48 14.00
-----------------------
&mdsc->dentry_list_lock 111736 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 2631 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8
&mdsc->dentry_list_lock 3878 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8
&mdsc->dentry_list_lock 9973 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0
-----------------------
&mdsc->dentry_list_lock 123621 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8
&mdsc->dentry_list_lock 1822 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 2720 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0
&mdsc->dentry_list_lock 55 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8
With this patch:
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 1203 1215 0.16 408.88 33082.88 27.23 4320501 7357389 0.04 500.64 1961578.00 0.27
-----------------------
&mdsc->dentry_list_lock 1029 [<000000003c9aea8a>] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 169 [<000000002038c577>] __dentry_lease_unlist+0x50/0xa0
&mdsc->dentry_list_lock 16 [<00000000c991106d>] __ceph_dentry_lease_touch+0x5c/0xa8
&mdsc->dentry_list_lock 1 [<00000000612fe15f>] __dentry_leases_walk+0x64/0x2c8
-----------------------
&mdsc->dentry_list_lock 158 [<000000002038c577>] __dentry_lease_unlist+0x50/0xa0
&mdsc->dentry_list_lock 858 [<000000003c9aea8a>] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 182 [<00000000612fe15f>] __dentry_leases_walk+0x64/0x2c8
&mdsc->dentry_list_lock 17 [<00000000c991106d>] __ceph_dentry_lease_touch+0x5c/0xa8
__dentry_leases_walk() is almost gone. The total wait time is reduced
by a factor of 483. That will give some latency gains to
ceph_readdir().
Cc: stable@vger.kernel.org
Fixes: 37c4efc1ddf9 ("ceph: periodically trim stale dentries")
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Matthew Brown <matthew@bargrove.com>
Date: Wed Aug 12 18:13:21 2026 +0100
ceph: fix leaked inode reference on writeback abort at umount
commit c25aee9c630fb86f98d79eccb75765067079b972 upstream.
ceph_dirty_folio() takes a wrbuffer claim on each newly dirtied folio: it
bumps i_wrbuffer_ref (taking an ihold() on the 0->1 transition) and
attaches the snap_context to folio->private. That claim is released only
by ceph_put_wrbuffer_cap_refs(), which for a submitted write runs from
writepages_finish().
In ceph_submit_write(), if ceph_inc_osd_stopping_blocker() fails -- which
happens during umount -- the request is aborted before submission: the
already-collected folios are only redirtied and unlocked, so
writepages_finish() never runs and the claim is leaked.
redirty_page_for_writepage() -> folio_redirty_for_writepage() ->
filemap_dirty_folio() sets PG_dirty directly and does not go through
->dirty_folio, so ceph_dirty_folio() is not re-entered to rebalance it.
Because every subsequent writeback also fails the osd_stopping_blocker,
i_wrbuffer_ref never returns to 0, the ihold() is never dropped, and the
inode cannot be evicted:
VFS: Busy inodes after unmount of ceph
kernel BUG at fs/super.c:650!
Release the orphaned claim in the abort path before redirtying, via
ceph_undo_wrbuffer_claim(): detach the snap_context, drop the wrbuffer
reference (letting i_wrbuffer_ref reach 0 and iput() the inode), and drop
the snap_context reference -- i.e. do what writepages_finish() would have
done for these never-submitted folios.
Only the locked_pages entries are undone; folios still in the fbatch were
never dirty-cleared by this call (folio_clear_dirty_for_io() is the
ownership-transfer point, and a successful move NULLs the fbatch slot), so
they hold no claim this call owns.
Cc: stable@vger.kernel.org
Fixes: fd7449d937e7 ("ceph: fix generic/421 test failure")
Signed-off-by: Matthew Brown <matthew@bargrove.com>
Reviewed-by: Xiubo Li <xiubo.li@clyso.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xiubo Li <xiubo.li@clyso.com>
Date: Tue Jul 14 16:13:43 2026 +0800
ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock
commit 7af4c4f01305b0935adf6d4301b1ec407025485d upstream.
list_for_each_entry() iterates ci->i_cap_flush_list but drops
i_ceph_lock to send cap messages. During the unlock window,
handle_cap_flush_ack() can acquire i_ceph_lock, detach cf entries
with tid <= flush_tid from the list, release i_ceph_lock, and free
them via ceph_free_cap_flush() outside any lock. When the original
thread reacquires i_ceph_lock and the for-loop macro advances via
cf = list_next_entry(cf, i_list), it dereferences cf->i_list.next
on freed memory.
The race timeline:
__kick_flushing_caps() handle_cap_flush_ack()
----------------------- -----------------------
holds i_ceph_lock <---
iterates to cf (tid=10)
prepares FLUSH message
drops i_ceph_lock <---
__send_cap() ── FLUSH(tid=10)
MDS sends FLUSH_ACK(tid=10)
---> acquires i_ceph_lock
cf->tid(10) <= flush_tid(10),
detaches cf from i_cap_flush_list
drops i_ceph_lock
ceph_free_cap_flush(cf) <- frees it!
acquires i_ceph_lock <---
for-loop advances:
cf = list_next_entry(cf, i_list)
-- UAF on freed cf->i_list.next
The cf was just sent by __kick_flushing_caps itself via __send_cap().
The MDS may respond with FLUSH_ACK quickly enough that
handle_cap_flush_ack() frees cf before __kick_flushing_caps can
finish the iteration.
Fix by converting to a manual while loop: save the next pointer
under i_ceph_lock before dropping it, then use the saved pointer
after reacquiring, so the potentially-freed cf is never accessed again.
Cc: stable@vger.kernel.org
Signed-off-by: Xiubo Li <xiubo.li@clyso.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Thu Aug 13 14:00:00 2026 +0200
ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode
commit aedc9053d909508a5f56c3f49f885fc030df4730 upstream.
MDSMap export_targets entries are monitor controlled. check_new_map()
uses each entry as a bit number in a fixed stack bitmap, so a rank
outside the protocol namespace can make set_bit() write past the end of
the array.
Reject ranks outside CEPH_MAX_MDS while decoding the map. Do not
validate against possible_max_rank here because maps may legitimately
reference ranks beyond a temporarily reduced max_mds.
Cc: stable@vger.kernel.org
Fixes: d517b3983dd3 ("ceph: reconnect to the export targets on new mdsmaps")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Frank Sorenson <sorenson@redhat.com>
Date: Thu Aug 6 21:41:56 2026 -0500
cifs: clear tcon after cifsFileInfo_put() in cifs_file_set_size()
commit b96db32fed8dfb2478d7c208f89bf383beed1535 upstream.
When the else branch of cifs_file_set_size() finds a writable file handle
via find_writable_file(), it borrows tcon and server from the handle's
tlink, attempts the handle-based set_file_size() RPC, and then releases
the handle with cifsFileInfo_put().
If set_file_size() fails, execution falls through to the path-based
fallback, which reuses the borrowed tcon and server under the
"if (tcon == NULL)" guard. Since tcon is not NULL at that point, the
guard is skipped. If cifsFileInfo_put() dropped the last reference on a
tlink that was already removed from the tlink tree (TCON_LINK_IN_TREE
cleared, as happens during reconnection or session teardown),
cifs_put_tlink() will have freed tcon; the subsequent set_path_size()
call is then a use-after-free.
Setting tcon = NULL after cifsFileInfo_put() causes the existing guard
to take the cifs_sb_tlink() path, which acquires a fresh reference for
the path-based operation or fails cleanly if the session is gone.
Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc: stable@vger.kernel.org
Cc: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Frank Sorenson <sorenson@redhat.com>
Date: Sat Aug 22 16:55:17 2026 -0500
cifs: fix loff_t underflow in cifs_remap_file_range() when len == 0
commit 6c322f5cf7476ded7a9a20f7be72462065a03c68 upstream.
With len == 0 (clone to EOF), the effective length is computed as:
len = src_inode->i_size - off;
If off > i_size, this is a negative loff_t, corrupting the ByteCount
in the FSCTL_DUPLICATE_EXTENTS_TO_FILE request and inverting the range
in filemap_write_and_wait_range(). The existing off >= i_size check
fires only after the ioctl has already been sent.
Snapshot i_size_read() once for both the bounds check and the length
calculation, eliminating the TOCTOU and 32-bit torn-read risk. Reject
off > src_size with -EINVAL. Treat off == src_size as a no-op,
consistent with __generic_remap_file_range_prep().
Fixes: 04b38d601239 ("vfs: pull btrfs clone API to vfs layer")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Frank Sorenson <sorenson@redhat.com>
Date: Fri Jul 31 12:12:28 2026 -0500
cifs: use cifs_invalidate_cache() in cifs_do_truncate() for O_TRUNC
commit 364b183230586a62660a7280c1eb20138338eeb5 upstream.
cifs_do_truncate() is invoked from cifs_open() without i_rwsem, so it
cannot use cifs_resize_file_locked() to perform a proper fscache cookie
resize. Instead, add cifs_invalidate_cache() after cifs_setsize().
cifs_invalidate_cache() calls fscache_invalidate(), which works without
holding i_rwsem: it unconditionally increments inval_counter and sets
FSCACHE_COOKIE_NO_DATA_TO_READ, ensuring that stale cached data is not
served once the cookie is later activated by fscache_use_cookie().
Truncation to zero leaves no valid cached data, making invalidation the
correct semantic here.
Fixes: fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()")
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: WenTao Liang <vulab@iscas.ac.cn>
Date: Sun Jun 28 21:07:00 2026 +0800
clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path
commit 05520e035f8332c8e33f3011b5ca016fde61793d upstream.
When cpuhp_setup_state fails after pit_clockevent_per_cpu_init has
successfully called request_irq, the error handling jumps directly to
out_pit_clocksource_unregister without freeing the registered IRQ.
This leaks the IRQ line and, since kfree(pit) follows, leaves a
dangling pointer registered as the interrupt handler's dev_id,
potentially leading to a use-after-free if the IRQ fires afterwards.
Fix it by calling pit_clockevent_per_cpu_exit to properly release the
IRQ before falling through to the existing cleanup chain.
Suggested-by: Greg KH <gregkh@linuxfoundation.org>
Fixes: bee33f22d7c3 ("clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support")
Cc: stable@vger.kernel.org
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
Link: https://patch.msgid.link/20260628130700.45680-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Felix Yan <felixonmars@archlinux.org>
Date: Thu Jun 25 06:04:34 2026 +0800
clocksource/drivers/timer-sun4i: Advertise a real minimum delta
commit d21808328225ab8cee46885bf9a0dffcefbe630e upstream.
sun4i_clkevt_next_event() compensates for the timer stop/start
synchronization delay by programming evt - TIMER_SYNC_TICKS into the
hardware interval register. The clockevent device currently advertises
TIMER_SYNC_TICKS as min_delta_ticks, so the clockevents core is allowed
to call set_next_event() with evt == TIMER_SYNC_TICKS.
That programs a zero-tick interval. With oneshot/highres/nohz timer
operation this can leave the next event stuck, which was observed as a
boot hang on Allwinner D1 after the clockevents core started reusing
forced minimum-delta events.
Advertise one extra tick instead, so the smallest event accepted by the
core still programs at least one hardware tick after the synchronization
compensation.
Fixes: 12e1480bcb49 ("clocksource: sun4i: Report the minimum tick that we can program")
Reported-by: Indrek Kruusa <indrek.kruusa@gmail.com>
Closes: https://lore.kernel.org/linux-riscv/CA+fTLhgLmTY+exGujKf8OYYQvcEW5X5NJ_5sLq2AYL6zER2c0A@mail.gmail.com/
Assisted-by: Codex:gpt-5.5
Signed-off-by: Felix Yan <felixonmars@archlinux.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
Tested-by: Indrek Kruusa <indrek.kruusa@gmail.com>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-riscv/CA+fTLhgLmTY+exGujKf8OYYQvcEW5X5NJ_5sLq2AYL6zER2c0A@mail.gmail.com/
Link: https://patch.msgid.link/20260624220434.4183732-1-felixonmars@archlinux.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kuan-Wei Chiu <visitorckw@gmail.com>
Date: Tue Dec 2 08:26:13 2025 +0000
coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior
commit 41fb4e925528aefa4b7a5f76c7f81db99c0d0f38 upstream.
The cntr_val_show() function was intended to print the values of all
counters using a loop. However, due to a buffer overwrite issue with
sprintf(), it effectively only displayed the value of the last counter.
The companion function, cntr_val_store(), allows users to modify a
specific counter selected by 'cntr_idx'. To maintain consistency
between read and write operations and to align with the ETM4x driver
behavior, modify cntr_val_show() to report only the value of the
currently selected counter.
This change removes the loop and the "counter %d:" prefix, printing
only the hexadecimal value. It also adopts sysfs_emit() for standard
sysfs output formatting.
Fixes: a939fc5a71ad ("coresight-etm: add CoreSight ETM/PTM driver")
Cc: stable@vger.kernel.org
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20251202082613.3265761-1-visitorckw@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hui Su <sh_def@163.com>
Date: Thu Aug 6 22:23:04 2026 +0800
cpufreq: schedutil: Fix rate limit overflow
commit 3bff8f8e95fdc6ad19c8a1a8f87029094747e4bf upstream.
rate_limit_us is an unsigned int, while NSEC_PER_USEC is defined as
1000L. On 32-bit systems, the multiplication is therefore performed
using 32-bit unsigned arithmetic before the result is assigned to
freq_update_delay_ns.
For example, writing 4294968 to rate_limit_us wraps the delay from
4294968000 ns to 704 ns. This makes schedutil update far more often
than configured.
Add sugov_update_rate_limit_us() to widen rate_limit_us to s64 before
converting it to nanoseconds. Use the helper when updating the tunable
through sysfs and when starting the governor, so both paths perform the
conversion without overflow.
Fixes: 9bdcb44e391d ("cpufreq: schedutil: New governor based on scheduler utilization data")
Signed-off-by: Hui Su <sh_def@163.com>
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Cc: All applicable <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260806142304.1761454-1-sh_def@163.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Eric Biggers <ebiggers@kernel.org>
Date: Mon Jun 15 15:41:29 2026 -0700
crypto: sun8i-ce - Remove crypto_rng interface
commit 011556f71d094da61379ae3672692cae2795304e upstream.
Since the crypto_rng interface for hardware PRNGs is unused and is
redundant with hwrng and the actual Linux RNG, it's being phased out.
Most drivers for it were already removed. Go ahead and remove the
sun8i-ce support which is one of the only remaining ones.
Note that the sun8i-ce support for hwrng remains in place. That is the
interface that actually matters.
As usual for crypto_rng, this driver was also buggy: its ->generate()
function had a use-after-free vulnerability due to using
wait_for_completion_interruptible_timeout() without handling shutting
down the DMA operation if a signal is sent. There's no point in fixing
this separately only to remove the code anyway, so this commit is marked
with Fixes and Cc stable.
Fixes: 5eb7e9468884 ("crypto: sun8i-ce - Add support for the PRNG")
Cc: stable@vger.kernel.org
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Eric Biggers <ebiggers@kernel.org>
Date: Mon Jun 15 15:41:30 2026 -0700
crypto: sun8i-ss - Remove crypto_rng interface
commit a78446ee6fae86ac8733f120e3ffce2e5d9384f5 upstream.
Since the crypto_rng interface for hardware PRNGs is unused and is
redundant with hwrng and the actual Linux RNG, it's being phased out.
Most drivers for it were already removed. Go ahead and remove the
sun8i-ss support which is one of the only remaining ones.
As usual for crypto_rng, this driver was also buggy: its ->generate()
function had a use-after-free vulnerability due to using
wait_for_completion_interruptible_timeout() without handling shutting
down the DMA operation if a signal is sent. Also, it had a buffer
overread bug in the line 'memcpy(ctx->seed, d + dlen, ctx->slen);'.
There's no point in fixing these bugs separately only to remove the code
anyway, so this commit is marked with Fixes and Cc stable.
Fixes: ac2614d721de ("crypto: sun8i-ss - Add support for the PRNG")
Cc: stable@vger.kernel.org
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhenhao Wan <whi4ed0g@gmail.com>
Date: Sat Jun 20 12:33:15 2026 +0800
cxl/features: bound fwctl command payload to the input buffer
commit f687394af983df5660b6afae7e0d06969f3af206 upstream.
fwctl_cmd_rpc() copies cmd->in_len bytes into inbuf = kvzalloc(cmd->in_len)
and passes inbuf and in_len to ->fw_rpc(). The CXL callback cxlctl_fw_rpc()
ignores in_len and never checks the user-controlled op_size against it.
cxlctl_set_feature() bounds op_size only from below
(op_size <= sizeof(feat_in->hdr)) and then reads op_size - sizeof(hdr)
bytes from feat_in->feat_data via cxl_set_feature(). With a small in_len
and a large op_size the first memcpy() already reads past the
kvzalloc(in_len) buffer; the out-of-bounds bytes are placed in the mailbox
payload and sent to the device, and a large enough op_size can walk into
unmapped memory and oops the kernel. The Get paths pin op_size to a fixed
size but likewise read the input struct without checking in_len.
Reject, at the single dispatch point, any request whose fixed header plus
op_size does not fit in the copied-in buffer. The lower-bound test guards
the subtraction and ensures op_size was copied in before it is read.
Fixes: eb5dfcb9e36d ("cxl: Add support to handle user feature commands for set feature")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
Cc: stable@vger.kernel.org
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://patch.msgid.link/20260620-cxl-fwctl-oob-v1-1-5758e34d784a@gmail.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Alison Schofield <alison.schofield@intel.com>
Date: Fri Jul 24 13:37:17 2026 -0700
cxl/pmem: Format the nvdimm serial number as unsigned decimal
commit 8a80d3d65cd06ee35b913d8517fb2f2319f8e70c upstream.
The CXL NVDIMM security passphrase key description and the nvdimm 'id'
sysfs attribute are both derived from the CXL device serial number,
but the serial number is not formatted consistently.
The key description is formatted in hexadecimal while the 'id'
attribute is formatted in decimal. As a result, ndctl stores the key
using a decimal description while the kernel later looks it up using
a hexadecimal description. For serial numbers of 10 and above, the
descriptions no longer match, preventing automatic unlock after
reboot.
The decimal formatting has a second problem: both the key description
and the 'id' attribute use the signed %lld format for a u64 PCIe
Device Serial Number. Devices whose vendor OUI sets bit 63, such as
Montage CXL devices, appear with negative decimal serial numbers.
Format the security key description and 'id' attribute as unsigned
decimal, %llu, and document that the 'id' attribute is an unsigned
decimal value.
The key lookup mismatch was exposed by CXL unit test cxl-security.sh
when cxl_test mock serial numbers were extended to 10 and above.
A work around is described for ndctl load-key users here:
https://github.com/pmem/ndctl/issues/299
Cc: stable@vger.kernel.org
Fixes: b5807c80b5bc ("cxl: add dimm_id support for __nvdimm_create()")
Acked-by: Dan Williams <djbw@kernel.org>
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Link: https://patch.msgid.link/2c673a5ba0a8fa93ad160578e193bd556091fa95.1784924949.git.alison.schofield@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xu Yang <xu.yang_2@nxp.com>
Date: Thu Jun 11 22:31:06 2026 +0200
device property: fix infinite loop in fwnode_for_each_child_node()
commit 1900692555826753adab8799a1a8d50bb1ee200c upstream.
When iterate over children of a fwnode that has a secondary fwnode,
fwnode_get_next_child_node() can enter an infinite loop if the secondary
fwnode has more than one child.
Parent Child
(Primary fwnode) FWa: {FWa1, FWa2, FWa3}
(Secondary fwnode) FWb: {FWb1, FWb2}
In this case:
┌─> fwnode_get_next_child_node(FWa, FWa1)
│ - fwnode_call_ptr_op(FWa, get_next_child_node, FWa1) returns FWa2
│
│ ...
│
│ fwnode_get_next_child_node(FWa, FWa3)
│ - fwnode_call_ptr_op(FWa, get_next_child_node, FWa3) returns NULL
│ - fwnode_call_ptr_op(FWb, get_next_child_node, FWa3) returns FWb1
│
│ fwnode_get_next_child_node(FWa, FWb1)
│ - fwnode_call_ptr_op(FWa, get_next_child_node, FWb1) returns FWa1
└────┘
This cause fwnode_for_each_child_node() to loop indefinitely, reapeatedly
output {FWa1, FWa2, FWa3, FWb1, FWa1, ...}.
The root cause is that when the current child (FWb1) belongs to the
secondary fwnode, calling get_next_child_node() on the parimary fwnode
incorrectly returns the first child (FWa1) again instead of NULL.
Fix this by dynamically checking the parent fwnode of the current child
before calling get_next_child_node(). This approach follows the pattern
established in commit b5b41ab6b0c1 ("device property: Check
fwnode->secondary in fwnode_graph_get_next_endpoint()").
Fixes: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://patch.msgid.link/20260611203537.1786399-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 31 17:54:55 2026 -0500
dm array: reject an array block whose value size is not the caller's
commit 4538a287bdf5d0f9a379c678e5262b9f5783f547 upstream.
array_block_check() can only compare the header against itself, so a block
with value_size 4 and max_entries 1018 is internally consistent and passes.
dm-cache keeps two arrays -- mappings at 8 bytes and hints at 4 -- and the
roots for both live in the superblock. Point the mappings root at a hint
block and __load_mappings() walks it through an info whose value size is 8,
so element_at() strides 8 bytes over 4-byte entries and reaches offset 8160
of a 4096-byte block.
get_ablock() and __shadow_ablock() are the two places that hold the block
and the caller at once. Reject there when the two value sizes disagree.
Arrays only ever read their own blocks, so this fires on crafted metadata
only.
Fixes: 6513c29f44f2 ("dm persistent data: add transactional array")
Suggested-by: Ming-Hung Tsai <mtsai@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Ming-Hung Tsai <mtsai@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 31 17:54:54 2026 -0500
dm array: validate array block headers on read
commit 2965787723084835b18dfe993cd450ebf5bd4540 upstream.
array_block_check() validates blocknr and csum and nothing else, while
node_check(), next to it, has bounded the structural fields since both
were written. dm_array_cursor_next() takes its loop bound from the
on-disk nr_entries and element_at() is unguarded pointer arithmetic, so
a count larger than the block holds keeps the cursor in one block while
the index grows past it and the read walks off the dm-bufio buffer --
dm_cache_load_mappings() drives it once per cache block at activation.
Check the header against itself: reject a zero value_size, require
max_entries to equal calc_max_entries() for that value_size and block
size, and require nr_entries to fit. Equality rather than an upper bound,
since a count below the real capacity trips BUG_ON() in fill_ablock() and
trim_ablock(). Metadata dm-array writes satisfies all three.
Fixes: 6513c29f44f2 ("dm persistent data: add transactional array")
Suggested-by: Ming-Hung Tsai <mtsai@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Ming-Hung Tsai <mtsai@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ilya Krutskih <devsec@tpz.ru>
Date: Sun Jul 19 13:01:03 2026 +0000
dm raid1: reserve space for NUL-terminator in build_constructor_string()
commit 73c37fe54cd056d07461b142ab0b8b81e1ef6ad8 upstream.
Reserve space for the termination NUL after the maximum 20 decimal
digits of a long long value to avoid buffer overflow in sprintf().
Fixes: f5db4af466e2 ("dm raid1: add userspace log")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Krutskih <devsec@tpz.ru>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: liyouhong <liyouhong@kylinos.cn>
Date: Fri Jul 31 10:08:49 2026 +0800
dm-era: fix shadowed superblock leak on take-snap failure
commit 39c5aa3bd8ec3912d2cd0b3fe092642b0d2b0713 upstream.
metadata_take_snap() bumps the live superblock refcount and then
dm_tm_shadow_block() allocates a new block for the metadata snapshot.
If the subsequent dm_sm_inc_block() of writeset_tree_root or
era_array_root fails, the function only unlocks the clone and
returns. The newly allocated shadow block is never returned to the
metadata space map, so each failed take-snap permanently leaks one
metadata block.
Free the clone with dm_sm_dec_block() on those error paths, matching
the final step of metadata_drop_snap().
Fixes: eec40579d848 ("dm: add era target")
Cc: stable@vger.kernel.org
Signed-off-by: liyouhong <liyouhong@kylinos.cn>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Keith Busch <kbusch@kernel.org>
Date: Tue Jun 16 08:05:53 2026 -0700
dm-io: clone the source bio instead of copying its biovec
commit 62dc37a819a5a5de5cba989ad9e96ee214b9253e upstream.
For DM_IO_BIO requests, do_region() built each destination bio by walking
the source bio's biovec and re-adding the pages one at a time, tracking
the remaining transfer in sectors. The vector lengths are byte granular
and need not be sector aligned (e.g. a misaligned O_DIRECT buffer split
across pages), so the sector-based accounting could lose a sub-sector
fragment: to_sector() truncated the remainder and the outer loop spun
forever submitting empty bios, hanging the I/O.
There is no need to rebuild the biovec at all. The destination reads into
(or writes from) exactly the same pages as the source bio, so the bio can
simply clone the source's biovec with bio_alloc_clone() and remap it to
the target device. The clone inherits the source's iterator and alignment,
and the block layer splits it to the target's limits on submission, so the
whole region maps to a single cloned bio with no manual page copying or
sector accounting.
This removes the per-page copy path (and its open-coded bvec dpages
helpers) for bio-backed I/O and fixes the hang on misaligned direct I/O to
a dm-mirror device. Page-list, vma and kmem sources keep the existing copy
path.
Fixes: 7eac33186957 ("iomap: simplify direct io validity check")
Fixes: 5ff3f74e145a ("block: simplify direct io validity check")
Cc: stable@vger.kernel.org
Reported-by: Dr. David Alan Gilbert <linux@treblig.org>
Reported-by: Vjaceslavs Klimovs <vklimovs@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mikulas Patocka <mpatocka@redhat.com>
Date: Mon Jul 27 23:09:28 2026 +0200
dm-io: report non-retryable errors separatedly
commit 47a5e62f39875f371bded6e34ffb9cf15ccd813d upstream.
The error codes BLK_STS_NOTSUPP and BLK_STS_INVAL should not cause leg
failure on dm-raid1. This patch changes the interface to dm-io, so that
it reports two error bitmaps - error_bits and unsup_bits. The unsup_bit
bitmap tracks BLK_STS_NOTSUPP or BLK_STS_INVAL errors, the error_bits
bitmap tracks all the other errors.
dm-raid1 is changed so that it won't fail a leg if it receives an error
in the unsup_bits bitmap.
This patch (with 62dc37a819a5) fixes misbehavior if the user uses
unaligned bio vectors on dm-raid1.
Fixes: 7eac33186957 ("iomap: simplify direct io validity check")
Fixes: 5ff3f74e145a ("block: simplify direct io validity check")
Cc: stable@vger.kernel.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:26:57 2026 -0500
dm-pcache: bound the persisted tail-position offset
commit d1898576090a10d2ac2715218a652e78fb65a6b0 upstream.
cache_pos_decode() takes the persisted key_tail and dirty_tail seg_off from
the cache device and addresses within the segment with it. A seg_off at or
past the segment data_size, controllable by whoever supplies the device
(CAP_SYS_ADMIN), reads past the segment data.
Reject a decoded seg_off that is not below the segment data_size.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:27:01 2026 -0500
dm-pcache: clamp the tail kset read to the segment data region
commit becf07e2b0053027495ecd671b1f82fb2e615f68 upstream.
The tail-kset read in cache_replay(), the writeback worker and the GC
worker bounds its length by PCACHE_SEG_SIZE - seg_off, the raw segment
size rather than the data region. A tail near the segment end reads past
the segment data into the following control area.
Clamp the read to cache_seg_remain(), the data region.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:26:59 2026 -0500
dm-pcache: detect a cycle in the last-kset chain during replay
commit 16c3b3a326e70f246a605b3dc27b7f83ba4743e3 upstream.
cache_replay() follows the on-media last-kset chain by next_cache_seg_id
with no cond_resched(). A forged chain that points back into a segment it
has already visited makes the replay loop follow it forever.
Cap the last-kset hops at cache->n_segs; a valid chain visits each segment
at most once.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jianyun Gao <jianyungao89@gmail.com>
Date: Mon Jul 20 17:46:48 2026 +0800
dm-pcache: fix implicit u8 truncation of gc_percent in message handler
commit fb9e17287a4ea1cbbcedc77e6866978ecc2a7b55 upstream.
When setting gc_percent via message, kstrtoul parses the input into an
unsigned long, which is then implicitly truncated to u8 when passed to
pcache_cache_set_gc_percent(). For example, value 266 (0x10A) silently
truncates to 10 (0x0A), successfully bypassing the > 90 upper bound
check in pcache_cache_set_gc_percent(), and setting a different value
than the user intended.
Use kstrtou8 directly instead of kstrtoul, so that overflow values are
properly rejected.
Cc: stable@vger.kernel.org
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Signed-off-by: Jianyun Gao <jianyungao89@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jianyun Gao <jianyungao89@gmail.com>
Date: Mon Jul 20 11:36:32 2026 +0800
dm-pcache: fix use-after-free and invalid seg operations in kset_replay()
commit c2e894eac398b258f12fdec73ed6ba081047f7b3 upstream.
In kset_replay, when key->seg_gen is stale (key->seg_gen <
key->cache_pos.cache_seg->gen), cache_key_put(key) is called but then
key->cache_pos.cache_seg is accessed as the argument to cache_seg_get().
This is a use-after-free on the freed key memory. Although mempool
recycled memory is not immediately reclaimed or overwritten in practice,
this is still a potential UAF bug.
Additionally, for expired invalid keys, setting the cache->seg_map bit
and calling cache_seg_get() is unreasonable since the corresponding
segment data is no longer valid.
Fix both issues by moving cache_seg_get() and __set_bit() after the
gen check, so they only execute for valid keys, and using continue to
skip invalid keys.
Cc: stable@vger.kernel.org
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Signed-off-by: Jianyun Gao <jianyungao89@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:27:04 2026 -0500
dm-pcache: only hand out initialized cache segments
commit 2df0fc042e299bae3c0f60ea5cd2af9285658e9f upstream.
get_cache_segment() scans the segment map up to cache->n_segs, the
physical device segment count, but cache_segs_init() only initializes
the first cache_info->n_segs segments. A crafted image with
cache_info->n_segs smaller than the device count leaves the remaining
pcache_cache_segment structs zeroed (segment.data == NULL), and the
allocator can hand one to cache_kset_close(), which writes through the
returned segment's data pointer with no NULL check.
Bound the allocator's search to cache_info->n_segs so only initialized
segments are ever returned. A conforming cache sets n_segs equal to the
device segment count, so this rejects nothing legitimate.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:26:55 2026 -0500
dm-pcache: validate geometry fields from on-disk cache_info
commit 32d1809da31094ef76fd98dc1f1a8b55ca1295dd upstream.
cache_segs_init() iterates cache_info->n_segs times indexing
cache->segments[], which is sized to the cache device geometry, and
get_seg_id() takes each segment id from the on-media cache_info and the
per-segment next_seg link. Both come from cache device metadata that is
only CRC-protected with a fixed public seed, so whoever supplies the
cache device on a table load (CAP_SYS_ADMIN) controls them: an oversized
n_segs or an out-of-range id drives an out-of-bounds access of
cache->segments[] and a wild CACHE_DEV_SEGMENT() pointer into the device
mapping -- an out-of-bounds read and write from on-disk data.
Reject an n_segs that exceeds the device segment count and a segment id
that is out of range before either is used. Valid metadata is unaffected.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:26:56 2026 -0500
dm-pcache: validate kset key_num and intra-segment bounds
commit f11deb032fd84081e7831cffcba895d893054a22 upstream.
Two more fields decoded from the cache device go unbounded. The kset
key_num drives cache_kset_crc() and the replay loop in cache_replay(),
the writeback worker and the GC worker, but only the magic and a
fixed-seed CRC are checked first, so a non-last kset whose key_num exceeds
the PCACHE_KSET_KEYS_MAX buffer reads past its end before the CRC compare.
A key's intra-segment offset and length in cache_key_decode() are taken
verbatim, so a key running past its segment is replayed into the cache
tree and the data CRC check and every later read hit then copy adjacent
persistent memory into the caller's bio -- an out-of-bounds read that
leaks to user space. Both fields are controlled by whoever supplies the
cache device (CAP_SYS_ADMIN); the CRC seed is public.
Add kset_onmedia_valid() to bound key_num before any kset read, and
reject a key whose offset plus length, computed in 64 bits, exceeds the
segment data_size. Valid metadata is unaffected.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Fri Jul 17 06:27:02 2026 -0500
dm-pcache: validate on-media seg_num against the cache device size
commit 62d92e45abe9e087370f9fc5d876b95673aced34 upstream.
seg_num is read from the crc32c-only superblock, so whoever supplies the
cache device on a table load (CAP_SYS_ADMIN) controls it. It sizes
cache->segments[] and is the value every later on-media segment id is
bounded against, yet it is never checked against the device. Because
cache_dev->mapping is the direct map of the pmem, CACHE_DEV_SEGMENT() for
a segment id past the device resolves to ordinary kernel memory beyond
the mapping; a new-cache init reaching such an id has cache_seg_init() ->
cache_dev_zero_range() memset() 12 KiB over that memory -- an
out-of-bounds write into the kernel heap at table load. A zero seg_num
makes the segment allocations ZERO_SIZE_PTR.
Reject a seg_num that is zero, larger than the device can hold, or larger
than PCACHE_CACHE_SEGS_MAX before it is used.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mikulas Patocka <mpatocka@redhat.com>
Date: Mon Aug 3 23:34:02 2026 +0200
dm-stats: fix a crash if allocation of per-cpu data fails
commit cc87e26d9cce22061dc21e51e11afef29dbbc36a upstream.
If "dm_kvzalloc(percpu_alloc_size, cpu_to_node(cpu))" fails, the code
jumps to the "out" label and calls dm_stat_free. dm_stat_free does
"for_each_possible_cpu(cpu) { dm_kvfree(s->stat_percpu[cpu][0].histogram,
s->histogram_alloc_size);", which crashes with NULL pointer dereference
if s->stat_percpu[cpu] is NULL.
This commit fixes the bug by testing s->stat_percpu[cpu] for NULL before
using it.
Reported-by: Junzhe Yu <junzheyu1@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Fixes: fd2ed4d25270 ("dm: add statistics support")
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Haotian Zhang <vulab@iscas.ac.cn>
Date: Sat Jul 11 22:21:55 2026 +0800
dm-switch: use WRITE_ONCE() in switch_region_table_write()
commit c7391ebe33162c7962b313caea4d8e6b0bc2a671 upstream.
switch_region_table_read() accesses the region table with READ_ONCE()
and is called from the lockless switch_map() IO path. However,
switch_region_table_write() stores to the same array with a plain
assignment. This results in an inconsistent access pattern for a
lockless shared variable and may trigger data race reports.
Use WRITE_ONCE() to pair with the existing READ_ONCE() in
switch_region_table_read().
Cc: stable@vger.kernel.org
Fixes: 99eb1908e643 ("dm switch: factor out switch_region_table_read")
Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Date: Mon Mar 23 13:02:09 2026 +0530
drm/amd/display: Avoid NULL dereference in dc_dmub_srv error paths
[ Upstream commit 4ae3e16f4b3bf64140f773629b765d605ee079a9 ]
In dc_dmub_srv_log_diagnostic_data() and
dc_dmub_srv_enable_dpia_trace().
Both functions check:
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
and then call DC_LOG_ERROR() inside that block.
DC_LOG_ERROR() uses dc_dmub_srv->ctx internally. So if
dc_dmub_srv is NULL, the logging itself can dereference a
NULL pointer and cause a crash.
Fix this by splitting the checks.
First check if dc_dmub_srv is NULL and return immediately.
Then check dc_dmub_srv->dmub and log the error only when
dc_dmub_srv is valid.
Fixes the below:
../display/dc/dc_dmub_srv.c:962 dc_dmub_srv_log_diagnostic_data() error: we previously assumed 'dc_dmub_srv' could be null (see line 961)
../display/dc/dc_dmub_srv.c:1167 dc_dmub_srv_enable_dpia_trace() error: we previously assumed 'dc_dmub_srv' could be null (see line 1166)
Fixes: 2631ac1ac328 ("drm/amd/display: add DMUB registers to crash dump diagnostic data.")
Fixes: 71ba6b577a35 ("drm/amd/display: Add interface to enable DPIA trace")
Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Jerry Zuo <jerry.zuo@amd.com>
Date: Tue Sep 1 10:22:18 2026 -0500
drm/amd/display: hide Apple Studio Display secondary tile
[ Upstream commit 49521be4809d63fe3efb6bc68ee11cb1e1ef3d63 ]
The Apple Studio Display exposes a 2x1 tiled panel over two SST DP
links. The primary tile advertises the full 5120x2880 mode (with DSC on
the bandwidth-sufficient link) while the secondary carries a per-tile
2560x2880 timing on a link without sufficient bandwidth. Report the
non-primary tile connector as disconnected during detect so compositors
only see the primary DP link and configure a single 5K mode instead of
driving both tiled streams independently.
Drive the behaviour from an EDID quirk: add a disable_second_tile panel
patch that apply_edid_quirks() sets for the affected Apple Studio
Display panel IDs (0xAE3A, 0xAE42, 0xAE46), and have detect() hide the
secondary tile when the sink carries that quirk.
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: Sun peng Li <sunpeng.li@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Adjust for lack of movement from amdgpu_dm.c to amdgpu_dm_connector.c
Adjust for lack of analog connector support.
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Fangzhi Zuo <jerry.zuo@amd.com>
Date: Tue Sep 1 10:22:19 2026 -0500
drm/amd/display: Prune per-tile Timing from Apple Studio Display Primary Tile
[ Upstream commit 7a4dd08c3f921576c6a7524f60e4f0e4601835d2 ]
[why]
The Apple Studio Display primary tile advertises both the full 5120x2880
mode and the per-tile 2560x2880 timing. With the secondary tile already
hidden from userspace, the stray 2560x2880 mode on the primary connector
can still be picked by compositors, defeating the single 5K stream goal.
[how]
Prune the per-tile timing from the primary connector during get_modes:
when the sink carries the disable_second_tile quirk and the connector is
the primary tile (tile_h_loc == 0 && tile_v_loc == 0), drop any probed
mode matching the advertised tile size (tile_h_size x tile_v_size) so
userspace only sees the full 5120x2880 mode.
Fixes: 49521be4809d ("drm/amd/display: hide Apple Studio Display secondary tile")
Reviewed-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Adjust for lack of movement from amdgpu_dm.c to amdgpu_dm_connector.c
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Timur Kristóf <timur.kristof@gmail.com>
Date: Tue Sep 1 10:22:17 2026 -0500
drm/amd/display: Refactor amdgpu_dm_connector_detect (v2)
[ Upstream commit 8223a605744bb471f31018eac9075a539415b16f ]
Prepare for polling analog connectors.
Document the function better.
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Roman Li <Roman.Li@amd.com>
Date: Tue Sep 1 10:22:16 2026 -0500
drm/amd/display: Skip PHY SSC reduction on some 8K panels
[ Upstream commit 144169e7be0831e09958a906d08d1856751aa6c6 ]
[Why]
Some 8K displays cannot tolerate the reduced phy ssc value
at high link utilization and show corruption or black screen.
[How]
Add an EDID panel-id quirk to utilize existing skip_phy_ssc_reduction flag.
To pass the link into the quirk handler, change the signature of
apply_edid_quirks() to take link as an argument. The dev local in
dm_helpers_parse_edid_caps() becomes unused and is removed.
Fixes: 5fa62c87cffd ("drm/amd/display: Add option to disable PHY SSC reduction on transmitter enable")
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Roman Li <Roman.Li@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Adjust for lack of HDMI 2.1 FRL in 6.18.y
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Pengpeng Hou <pengpeng@iscas.ac.cn>
Date: Mon Jul 20 19:56:24 2026 +0800
eCryptfs: bound the packet-length peek to the user buffer
commit 95540462e630edbc8504e9537d16453d6942d143 upstream.
ecryptfs_miscdev_write() accepts the minimum one-byte packet-length
encoding, but always copies the maximum two-byte encoding from userspace
before parsing it. A six-byte message therefore reads one byte beyond the
submitted user buffer.
Zero-initialize the peek buffer and copy only the packet-length bytes
present. The existing exact packet-size check still rejects truncated
two-byte encodings after the parser determines their encoded length.
Fixes: 8bf2debd5f7b ("eCryptfs: introduce device handle for userspace daemon communications")
Cc: <stable@vger.kernel.org>
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Wed Jul 15 13:20:05 2026 +0800
ecryptfs: fix tag 11 packet exact-fit size check
commit 8b2ec0f56f55477f547d332526c9ae2a8fabc0a5 upstream.
parse_tag_11_packet() rejects a packet when the already-consumed tag and
length bytes plus the packet body exceed the caller supplied maximum
packet size. The check currently adds one extra byte, even though
*packet_size already includes the tag byte before the length is parsed.
Remove the extra byte so a tag 11 packet that exactly fits the available
buffer is accepted while oversized packets are still rejected.
Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Sun Jun 28 11:37:25 2026 +0800
ecryptfs: hold msg ctx list lock when cleaning daemon queue
commit 779972513c2fa8c7938e54976f686091dafff22f upstream.
ecryptfs_exorcise_daemon() drops queued messages from a dying daemon
without holding ecryptfs_msg_ctx_lists_mux, but
ecryptfs_msg_ctx_alloc_to_free() requires that lock.
Take the list lock while moving the queued contexts back to the free
list to avoid racing with other global msg ctx list users.
Fixes: f66e883eb618 ("eCryptfs: integrate eCryptfs device handle into the module.")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Wed Jul 15 13:20:04 2026 +0800
ecryptfs: pass packet set buffer size to parser
commit 2602b79c5b3e2f6fce12e38a670f8e3fda4e46a2 upstream.
ecryptfs_parse_packet_set() receives a pointer into the file header, but
it calculates the remaining packet buffer size from PAGE_SIZE - 8. For
version 1 headers the packet set starts later in the header, so this can
overstate the available buffer.
Pass the actual packet set buffer length from the caller and calculate
per-packet limits from the remaining bytes in that buffer. Recompute the
remaining length after consuming a tag 3 packet before parsing the
following tag 11 packet.
Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HanQuan <eilaimemedsnaimel@gmail.com>
Date: Tue Jul 14 00:57:03 2026 +0000
ecryptfs: reject oversized encrypted_key_size in parse_tag_3_packet
commit 5babe9c177c364521e3e682b949c5a8c47f4a441 upstream.
parse_tag_3_packet() set encrypted_key_size from the Tag 3 packet body
without bounding it against ECRYPTFS_MAX_KEY_BYTES (64). When
encrypted_key_size > 64, decrypt_passphrase_encrypted_session_key()
sets decrypted_key_size = encrypted_key_size and performs two
out-of-bounds writes:
1. crypto_skcipher_decrypt() writes encrypted_key_size bytes into
decrypted_key[64] via scatterlist, overflowing into the parent
ecryptfs_auth_tok struct.
2. memcpy(crypt_stat->key, decrypted_key, decrypted_key_size) writes
into crypt_stat->key[64], corrupting root_iv, keysig_list, and
mutexes in ecryptfs_crypt_stat.
Only AES-192 (cipher code 0x08) enables this because it sets
crypt_stat->key_size = 24 independently of encrypted_key_size,
allowing crypto_skcipher_setkey() to succeed while encrypted_key_size
exceeds ECRYPTFS_MAX_KEY_BYTES.
The PKI decryption path (parse_tag_65_packet) already validates
decrypted_key_size <= ECRYPTFS_MAX_KEY_BYTES; the passphrase path
omits this check.
Bound encrypted_key_size against ECRYPTFS_MAX_KEY_BYTES (64) rather
than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES (512). The 64-byte limit also
protects the 512-byte encrypted_key[] buffer, so the former 512-byte
check is removed as redundant.
Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig")
Cc: <stable@vger.kernel.org>
Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com>
[tyhicks: Adjust the code comment to refer to macros representing the
buffer sizes rather than mentioning the buffer size values since they
may change in the future]
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Wed Jul 15 13:20:06 2026 +0800
ecryptfs: reject too-small tag 70 packets
commit e97bbe1b2bd82ec2ae37ad2e4965b4d3e78bbf7f upstream.
ecryptfs_parse_tag_70_packet() subtracts fixed metadata fields from the
parsed packet body size to derive the encrypted filename size. A
malformed packet with a body smaller than those fixed fields can underflow
that size calculation.
Reject tag 70 packets before the subtraction unless the body contains the
signature, cipher code, and at least one byte of encrypted filename data.
Fixes: 9c79f34f7ee7 ("eCryptfs: Filename Encryption: Tag 70 packets")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Wed Jul 1 13:34:06 2026 +0800
ecryptfs: release message context on send failure
commit 219644a3ad5518217b2d62cad6d2c36a2308c949 upstream.
ecryptfs_send_message_locked() moves a message context from the free
list to the allocated list before sending the request to the userspace
daemon.
If ecryptfs_send_miscdev() fails, the context is left on the
allocated list and cannot be reused. Move it back to the free list on
failure and clear the caller's pointer.
Fixes: f66e883eb618 ("eCryptfs: integrate eCryptfs device handle into the module.")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yichong Chen <chenyichong@uniontech.com>
Date: Thu Jul 2 13:29:58 2026 +0800
ecryptfs: show filename encryption options
commit 496ec2d0852a02d2e631771b5c439130b9c7dce7 upstream.
ecryptfs_show_options() prints most user-visible mount options but
omits the filename encryption cipher and key size.
Print ecryptfs_fn_cipher and ecryptfs_fn_key_bytes when filename
encryption is enabled so that the displayed mount options reflect the
active filename encryption settings.
Fixes: 87c94c4df014 ("eCryptfs: Filename Encryption: mount option")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ard Biesheuvel <ardb@kernel.org>
Date: Sat Aug 1 17:28:04 2026 +0300
efivarfs: Rate limit statfs() handler
commit b2326338dc683e8c1067c0cbf7a47986c4190902 upstream.
Ravi reports that statfs() may be called by unprivileged users on the
efivarfs mount point, which may result in a flood of calls to the
QueryVariableInfo() runtime service. These calls are disproportionately
costly on x86 systems where the variable store is backed by SMM, as each
SMM entry requires a rendez-vous of all the CPUs.
So rate limit the calls to QueryVariableInfo() at twice per second, and
return the most recently obtained value for calls that are elided.
Cc: <stable@vger.kernel.org>
Reported-by: Ravi Bangoria <ravi.bangoria@amd.com>
Fixes: d86ff3333cb1 ("efivarfs: expose used and total size")
Reviewed-by: Anisse Astier <anisse@astier.eu>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Deepanshu Kartikey <kartikey406@gmail.com>
Date: Mon Aug 24 20:16:53 2026 +0530
eventfs: Initialize ei->children and ei->list in init_ei()
commit 1704aaaf5d22bc765c168402350d191e24e245bc upstream.
eventfs_create_dir() allocates the eventfs_inode and initializes it with
init_ei(). But this does not initialize the eventfs_inode list_heads. If
the eventfs_create_dir() fails due to memory pressure, it will call
free_ei() before it initialized the lists, and that checks to make sure
the eventfs_inode has no children. But because the list wasn't
initialized, it will give a false warning.
Fix it by moving the list initialization into init_ei().
Cc: stable@vger.kernel.org
Fixes: 5790b1fb3d67 ("eventfs: Remove eventfs_file and just use eventfs_inode")
Reported-by: syzbot+3ef80b4ed02226d04a06@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=3ef80b4ed02226d04a06
Link: https://patch.msgid.link/20260824144653.54044-1-kartikey406@gmail.com
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
[ Rewrote change log ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chengfeng Ye <nicoyip.dev@gmail.com>
Date: Fri Jul 31 13:31:45 2026 +0200
fanotify: fix use-after-free of file range info
commit d7f1cf5be33ef0175a4e8ed8687aeb98fb00a851 upstream.
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.
Fixes: 870499bc1d4d ("fanotify: report file range info with pre-content events")
Cc: stable@vger.kernel.org
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://patch.msgid.link/20260730134316.2085087-1-nicoyip.dev@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yemu Lu <prcups@krgm.moe>
Date: Mon May 25 16:56:49 2026 +0800
fat: restore original value when fat_ent_write failed
commit 64d9183203eebe33de6188b70a8c1e91f52885db upstream.
fat_ent_write() may have committed the new link to the primary FAT but
then failed on the mirror copy, leaving the chain pointing to new_dclus
even though the caller will free it. Restore the original value to keep
the chain consistent.
Link: https://lore.kernel.org/20260525085649.781643-1-n05ec@lzu.edu.cn
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Yemu Lu <prcups@krgm.moe>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Christian Brauner <brauner@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Tue Aug 18 21:53:18 2026 +0800
fbdev: omapfb: panel-dsi-cm: initialize lock before registering display
commit f8e43fe0f22b7137ce456e6fe3581d3098174f74 upstream.
dsicm_probe() registers the display before initializing ddata->lock.
Once omapdss_register_display() publishes the display, another consumer
can reach a dsicm callback that takes this mutex while it is still
uninitialized.
Initialize the mutex before registering the display so the published
callbacks always see a valid lock.
Fixes: f76ee892a99e ("omapfb: copy omapdss & displays for omapfb")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Florian Fuchs <fuchsfl@gmail.com>
Date: Mon Jul 13 12:16:38 2026 +0200
fbdev: pvr2fb: correct user pointer annotation and sentinel initializer
commit 5dc2e70dd74b1f03e2e13bfb6922111d9e0adf90 upstream.
Add __user annotation to buf, as it is passed as a user pointer in
pin_user_pages_fast(). Use an empty initializer for the sentinel
board-table entry to avoid initializing a function pointer with an
integer literal.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607131247.fpQ6eTc7-lkp@intel.com/
Cc: stable@vger.kernel.org
Signed-off-by: Florian Fuchs <fuchsfl@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hui Su <sh_def@163.com>
Date: Tue Aug 4 02:39:57 2026 +0800
fbdev: ssd1307fb: defer I2C transfers from damage callbacks
commit 9ad709afdfa32509ed64938a6d9cd00db3cd54c2 upstream.
The fbdev damage callbacks may run from fbcon while printk has disabled
preemption. They currently update the display synchronously, which enters
the sleeping I2C transfer path from atomic context.
A complete report from an RK3566 system follows:
[ 258.129004] watchdog: watchdog0: watchdog did not stop!
[ 258.129067] BUG: scheduling while atomic: systemd/1/0x00000003
[ 258.129076] Modules linked in: algif_hash algif_skcipher af_alg bnep
binfmt_misc lz4hc lz4 zram snd_soc_hdmi_codec brcmfmac_wcc hci_uart
fb_ssd1306(C) fbtft(C) btqca btrtl btintel btsdio snd_soc_simple_card
motorcomm pwm_fan snd_soc_simple_card_utils ssd130x_spi nls_iso8859_1
ssd130x btbcm drm_shmem_helper display_connector brcmfmac ssd1307fb
brcmutil bluetooth cfg80211 rfkill snd_soc_rockchip_i2s_tdm
snd_soc_rk817 hantro_vpu snd_soc_core snd_compress snd_pcm_dmaengine
v4l2_vp9 snd_pcm v4l2_h264 rockchip_rga snd_timer rk_crypto2
spi_rockchip_sfc videobuf2_dma_contig snd sm3_generic v4l2_mem2mem
videobuf2_dma_sg dwmac_rk sm3 soundcore videobuf2_memops videobuf2_v4l2
stmmac_platform dw_hdmi_cec videodev videobuf2_common dw_hdmi_i2s_audio
stmmac rk817_charger pcs_xpcs mc cpufreq_dt sch_fq_codel ip_tables
x_tables autofs4
[ 258.129215] Preemption disabled at:
[ 258.129216] [<ffff80008012f96c>] vprintk_emit+0x11c/0x340
[ 258.129234] CPU: 0 PID: 1 Comm: systemd Tainted: G C
6.6.0-rc5-rockchip-rk356x #4
[ 258.129239] Hardware name: Rockchip RK3566 OPi 3B (DT)
[ 258.129243] Call trace:
[ 258.129245] dump_backtrace+0xa0/0x128
[ 258.129252] show_stack+0x20/0x38
[ 258.129256] dump_stack_lvl+0x60/0xb0
[ 258.129265] dump_stack+0x18/0x28
[ 258.129269] __schedule_bug+0xa0/0xc8
[ 258.129274] __schedule+0x9ac/0xd30
[ 258.129279] schedule+0x60/0x100
[ 258.129282] schedule_timeout+0x194/0x338
[ 258.129289] rk3x_i2c_xfer_common.isra.0+0x384/0x498
[ 258.129296] rk3x_i2c_xfer+0x20/0x60
[ 258.129300] __i2c_transfer+0x194/0x648
[ 258.129308] i2c_transfer+0x9c/0x130
[ 258.129313] i2c_transfer_buffer_flags+0x64/0x98
[ 258.129318] ssd1307fb_update_rect+0x42c/0x560 [ssd1307fb]
[ 258.129334] ssd1307fb_defio_imageblit+0x34/0x50 [ssd1307fb]
[ 258.129343] soft_cursor+0x13c/0x210
[ 258.129350] bit_cursor+0x2dc/0x550
[ 258.129354] fbcon_cursor+0xec/0x108
[ 258.129359] hide_cursor+0x44/0xc8
[ 258.129365] vt_console_print+0x398/0x3b0
[ 258.129370] console_flush_all.isra.0+0x17c/0x410
[ 258.129377] console_unlock+0x4c/0x100
[ 258.129382] vprintk_emit+0x1c8/0x340
[ 258.129386] vprintk_default+0x40/0x58
[ 258.129389] vprintk+0xb8/0xd0
[ 258.129392] _printk+0x68/0x98
[ 258.129398] watchdog_release+0x170/0x230
[ 258.129404] __fput+0xbc/0x288
[ 258.129409] __fput_sync+0x58/0x70
[ 258.129413] __arm64_sys_close+0x40/0x90
[ 258.129419] invoke_syscall+0x4c/0x118
[ 258.129426] el0_svc_common.constprop.0+0x48/0xf0
[ 258.129432] do_el0_svc+0x24/0x38
[ 258.129437] el0_svc+0x48/0x100
[ 258.129443] el0t_64_sync_handler+0xc0/0xc8
[ 258.129448] el0t_64_sync+0x190/0x198
[ 258.573087] ------------[ cut here ]------------
[ 258.573098] DEBUG_LOCKS_WARN_ON(val > preempt_count())
[ 258.573111] WARNING: CPU: 0 PID: 1 at kernel/sched/core.c:5871
preempt_count_sub+0x9c/0x148
[ 258.573130] Modules linked in: algif_hash algif_skcipher af_alg bnep
binfmt_misc lz4hc lz4 zram snd_soc_hdmi_codec brcmfmac_wcc hci_uart
fb_ssd1306(C) fbtft(C) btqca btrtl btintel btsdio snd_soc_simple_card
motorcomm pwm_fan snd_soc_simple_card_utils ssd130x_spi nls_iso8859_1
ssd130x btbcm drm_shmem_helper display_connector brcmfmac ssd1307fb
brcmutil bluetooth cfg80211 rfkill snd_soc_rockchip_i2s_tdm
snd_soc_rk817 hantro_vpu snd_soc_core snd_compress snd_pcm_dmaengine
v4l2_vp9 snd_pcm v4l2_h264 rockchip_rga snd_timer rk_crypto2
spi_rockchip_sfc videobuf2_dma_contig snd sm3_generic v4l2_mem2mem
videobuf2_dma_sg dwmac_rk sm3 soundcore videobuf2_memops videobuf2_v4l2
stmmac_platform dw_hdmi_cec videodev videobuf2_common dw_hdmi_i2s_audio
stmmac rk817_charger pcs_xpcs mc cpufreq_dt sch_fq_codel ip_tables
x_tables autofs4
[ 258.573268] CPU: 0 PID: 1 Comm: systemd Tainted: G WC
6.6.0-rc5-rockchip-rk356x #4
[ 258.573274] Hardware name: Rockchip RK3566 OPi 3B (DT)
** 37 printk messages dropped **
[ 258.574064] Preemption disabled at:
** 42 printk messages dropped **
[ 259.190237] Preemption disabled at:
Track damage in the driver's private data under a spinlock and merge
multiple updates into a bounding rectangle. Queue the existing
deferred-I/O work immediately for damage reported by fbdev drawing and
write helpers, so allocation and I2C transfers run from process context
without adding the configured mmap refresh delay. Keep full-screen
updates for dirty mmap pages, for which no precise rectangle is available.
Tested on an RK3566 board with a 128x64 OLED by running five rounds of 250
KERN_EMERG messages in total while issuing framebuffer writes every 15 ms.
No atomic-sleep, preemption, or lockdep warning occurred. Kprobe tracing
also confirmed that cursor-only damage remained an 8x16 partial update.
Fixes: a2ed00da5047 ("drivers/video: add support for the Solomon SSD1307 OLED Controller")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Myeonghun Pak <mhun512@gmail.com>
Date: Wed Jul 1 20:12:24 2026 +0900
fbdev: uvesafb: unregister connector callback on init failure
commit de8db23aa7c337e606fca9faf48b3ba72968597a upstream.
uvesafb_init() registers the v86d connector callback before registering
the platform driver. If platform_driver_register() fails, the function
returns the error directly and leaves the connector callback registered.
The later platform-device failure path already unregisters the callback.
Add the same cleanup before the final return when platform-driver
registration fails.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 8bdb3a2d7df4 ("uvesafb: the driver core")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Marek Czernohous <marek@czernohous.de>
Date: Sat Aug 15 21:54:38 2026 +0200
forcedeth: fix off-by-one when saving/restoring non-PCI config space
commit 9393f1d656a79693e0c123ff7bc7c5c0f708046d upstream.
nv_suspend() and nv_resume() walk the non-PCI configuration space with
for (i = 0; i <= np->register_size/sizeof(u32); i++)
which runs one iteration too many. saved_config_space is declared as
u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
and NV_PCI_REGSZ_VER3 is equal to NV_PCI_REGSZ_MAX (0x604), so on a VER3
device register_size/sizeof(u32) is exactly the array length and the last
iteration addresses one element past the end.
The element it lands on is np->name_rx[0..3]: saved_config_space[] is
followed immediately by char name_rx[IFNAMSIZ + 3], and char needs no
padding. Nothing observable is corrupted by that, because nv_request_irq()
rewrites name_rx with sprintf() before it is ever passed to request_irq().
The bug is the out-of-bounds access itself, which UBSAN reports and which
CONFIG_UBSAN_TRAP=y turns into a trap that aborts the running kernel code,
plus an MMIO read and, on resume, an MMIO writel() to base + 0x604, one
dword past the range the driver mapped:
np->base = ioremap(addr, np->register_size);
VER1 and VER2 devices stay inside the array, but they too get the stray
read and the stray write one dword past their own window.
Caught by UBSAN on an Apple Macmini3,1 (MCP79) during a deep S3 cycle.
The splat below is trimmed: the build path in the file name, the CPU
and taint lines, the Workqueue line, the "?" hint frames, and the
frames below device_suspend are all cut. The kernel was tainted, with
an out-of-tree nouveau and CPU_OUT_OF_SPEC; forcedeth itself was the
stock module.
UBSAN: array-index-out-of-bounds in drivers/net/ethernet/nvidia/forcedeth.c:6225:25
index 385 is out of range for type 'u32 [385]'
Call Trace:
dump_stack_lvl+0x5d/0x80
ubsan_epilogue+0x5/0x2b
__ubsan_handle_out_of_bounds.cold+0x54/0x59
__this_module+0xe398c/0xe9010 [forcedeth]
pci_pm_suspend+0x80/0x170
dpm_run_callback+0x51/0x160
device_suspend+0x1a2/0x4a0
...
Both loops are hit. UBSAN reports each source location only once per module
load (__ubsan_handle_out_of_bounds() calls suppress_report(), which does
test_and_set_bit(REPORTED_BIT, ...) on the struct source_location), so the
two splats land in the first S3 cycle after the module is loaded and later
cycles are silent even though the access still runs off the end every time.
In that first cycle line 6225 is reported from pci_pm_suspend and line 6240
from pci_pm_resume.
The same off-by-one was fixed in nv_get_regs() by commit ba9aa134287f
("forcedeth: fix buffer overflow") in 2012; these two loops were missed.
The suspend and resume side was reported on LKML in September 2013 by Marc
Weber, with the same analysis and the same one-character fix, but the patch
was attached rather than sent inline and the thread ended there.
Use < instead of <=, which saves and restores exactly register_size bytes.
Fixes: 1a1ca86158ee ("[netdrvr] forcedeth: save/restore device configuration space")
Cc: stable@vger.kernel.org
Signed-off-by: Marek Czernohous <marek@czernohous.de>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Link: https://patch.msgid.link/178682367885.3748309.10595890901761762683@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Daisuke Matsuda <matsuda@preferred.jp>
Date: Thu Jul 23 08:19:12 2026 +0000
fpga: altera-cvp: Avoid out-of-bounds read in trailing byte write
commit 9da70a43b5fea60d758137f7f0ccfe19356cb5bb upstream.
The trailing byte path in altera_cvp_send_block() dereferences a u32
pointer even when only 1-3 bytes remain in the input buffer. If the buffer
ends at a page or scatterlist boundary, this can read past the valid image
data and fault.
Copy the remaining bytes into a zero-initialized u32 before writing the
final word so only valid bytes are read from the input buffer.
Fixes: 34d1dc17ce97 ("fpga manager: Add Altera CvP driver")
Cc: stable@vger.kernel.org
Signed-off-by: Daisuke Matsuda <matsuda@preferred.jp>
Reviewed-by: Xu Yilun <yilun.xu@intel.com>
Link: https://lore.kernel.org/r/20260723081912.74082-1-dskmtsd@gmail.com
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Tien Sung Ang <tien.sung.ang@altera.com>
Date: Mon Jun 29 23:57:19 2026 -0700
fpga: stratix10-soc: Fix SVC mailbox handling during reconfiguration
commit c14a8b15c87b49efc3ef898cec8ac7c30336a080 upstream.
Fix incorrect stratix10_svc_done() usage during FPGA reconfiguration.
Do not call stratix10_svc_done() at the end of write_init() on success, so
the SVC session remains active through write() and write_complete(). Call
stratix10_svc_done() on failure in write_init() and write() so the shared
SVC mailbox is released when reconfiguration aborts, allowing coexistence
with other SVC clients such as soc64-hwmon.
Fixes: e7eef1d7633a ("fpga: add intel stratix10 soc fpga manager driver")
Cc: stable@vger.kernel.org # 5.1+
Signed-off-by: Tien Sung Ang <tien.sung.ang@altera.com>
Signed-off-by: Tze Yee Ng <tze.yee.ng@altera.com>
Reviewed-by: Xu Yilun <yilun.xu@intel.com>
Link: https://lore.kernel.org/r/8768ce3260489c9febdfce08e27d03f5f5ed9c33.1782801986.git.tze.yee.ng@altera.com
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Date: Fri Jul 24 13:42:28 2026 +0200
fs/ntfs3: bound page_lcns[] index by the log record
commit 6f7b9dbdc1b7520206abce0049bdd143eb536e75 upstream.
The copy_lcns loop and the redo shorten loop index page_lcns[] at j + i,
where i runs up to the log record's lcns_follow. That count is checked only
against the record's own length, not the target entry, so check_dp_table()
(which validates the entry's lcns_follow) does not cover it: the copy_lcns
entry may even be freshly allocated after that check, and find_dp() bounds j
but not i. A crafted record thus overflows page_lcns[] of an otherwise valid
entry.
Add dp_range_ok() and reject, before each loop, any record whose run does
not fit the entry. These are the only two page_lcns[] accesses indexed by
the record rather than the entry, so together with the entry validation
every access is now bounded.
Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Reported-by: Weiming Shi <bestswngs@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Xiang Mei <xmei5@asu.edu>
[almaz.alexandrovich@paragon-software.com: original patch contained changes to the problem already handled, applied partly]
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Samuel Page <sam@bynar.io>
Date: Tue Jun 23 21:00:57 2026 +0200
fs/ntfs3: fix info-leak on partial LZNT decompress in ni_read_frame()
commit 35d1ea92c7d946e2ebdbe36cdb2c969c8704bebd upstream.
ni_read_frame() decompresses an LZNT $DATA frame into the vmapped target
pages and then trusts decompress_lznt()'s return value:
unc_size = decompress_lznt(frame_ondisk, ondisk_size, frame_mem,
frame_size);
if ((ssize_t)unc_size < 0) err = unc_size;
else if (!unc_size || unc_size > frame_size) err = -EINVAL;
decompress_lznt() stops as soon as the compressed stream is exhausted
(e.g. a zero chunk header) and returns the number of bytes it actually
wrote, which may be far less than frame_size. The bytes between unc_size
and frame_size are never written. The only memset() that follows zeroes
the region beyond i_valid; when the frame lies entirely within the file's
valid size that memset() does not run, so the gap retains whatever was in
the just-vmapped pages. All pages are then marked uptodate and returned
to userspace, disclosing uninitialized (recently-freed) kernel page
memory. A crafted compressed file whose stream decompresses to only a few
bytes leaks the remainder of every frame on a plain read(2), which is
enough to recover kernel pointers and defeat KASLR.
Zero the [unc_size, frame_size) tail immediately after a successful LZNT
decompress so the remainder reads back as zero.
Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Cc: stable@vger.kernel.org
Assisted-by: Bynario AI
Signed-off-by: Samuel Page <sam@bynar.io>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xiang Mei <xmei5@asu.edu>
Date: Wed Jun 17 16:13:42 2026 -0700
fs/ntfs3: validate dirty page table on log replay
commit 006cb7713dec10368e699abc4367e5faa334c9a5 upstream.
Each DIR_PAGE_ENTRY ends in a page_lcns[] array whose length is the on-disk
lcns_follow field. check_rstbl() validates the table bookkeeping but never
checks that this array fits in the entry, so a crafted lcns_follow lets the
v0->v1 conversion memmove and later replay passes run off the entry.
Add check_dp_table() to reject, right after check_rstbl(), any entry larger
than its size claims via struct_size() (the same expression used to allocate
these entries, so the check is overflow-safe by construction). All consumers
can then trust lcns_follow as the real capacity. This covers every
page_lcns[] access whose index is bounded by the entry itself (the
conversion memmove, the HotFix store via find_dp(), and the self-bounded
scan loops). Accesses whose index comes from the log record need a separate
bound and are handled in a follow-up patch.
Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Reported-by: Weiming Shi <bestswngs@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Baokun Li <libaokun@linux.alibaba.com>
Date: Tue Aug 4 11:42:04 2026 +0800
fs: fix user path of nested backing files
commit f2381b546e7e6a35c9fcee0d0ccb6c042a9aeb5d upstream.
backing_file_open() derives the path to be stored in the new backing
file from user_file->f_path. This is incorrect when user_file itself
is a backing file, which is the case for nested stacking filesystems,
e.g. overlayfs mounts where the lowerdir of one overlayfs is the merged
directory of another. Since commit def3ae83da02 ("fs: store real path
instead of fake path in backing file f_path") the f_path of a backing
file holds the real path of the intermediate layer, not the path that
the user opened.
Commit 924577e4f6ca ("ovl: Fix nested backing file paths") fixed this
for such configurations by passing file_user_path() from
ovl_open_realfile(). However, commit 6af36aeb147a ("lsm: add
backing_file LSM hooks") changed the first argument of
backing_file_open() from the user path back to the user file and
derived the path from user_file->f_path again, silently re-introducing
the problem.
As a result, files mapped through a nested overlayfs show the wrong
path in /proc/<pid>/maps and in perf/ftrace mmap records. For example,
with two nested overlayfs mounts:
mkdir -p /ovl/{lower,upper,work,merged} /ovl/nested
echo hello > /ovl/lower/foo
mount -t overlay overlay \
-o lowerdir=/ovl/lower,upperdir=/ovl/upper,workdir=/ovl/work \
/ovl/merged
# at least two lowerdirs are needed when upperdir is nonexistent
mount -t overlay overlay \
-o lowerdir=/ovl/merged:/ovl/lower /ovl/nested
mapping /ovl/nested/foo shows a disconnected path instead of the user
path:
# readlink /proc/self/fd/3
/ovl/nested/foo
# grep foo /proc/self/maps
7f6e2c100000-7f6e2c101000 r--s 00000000 00:24 15813027 /foo
The bogus path is derived from the f_path of the intermediate backing
file, whose mount is a private clone that d_path() cannot resolve.
Fix this by using file_user_path(), which returns the outermost
user-visible path for backing files and falls back to
&user_file->f_path for regular files. This restores the behavior of
commit 924577e4f6ca ("ovl: Fix nested backing file paths") for
overlayfs and also fixes the same problem for the other
backing_file_open() callers, fuse passthrough and erofs ishare, when
their user file is itself a backing file.
backing_tmpfile_open() has the same pattern but is not affected: it is
only called by ovl_create_tmpfile() for the upper layer, and another
overlayfs is rejected as upperdir by the DCACHE_OP_REAL check in
ovl_mount_dir_check(), so its user_file can never be a backing file.
Fixes: 6af36aeb147a ("lsm: add backing_file LSM hooks")
Cc: stable@vger.kernel.org
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Link: https://patch.msgid.link/20260804034204.3487077-1-libaokun@linux.alibaba.com
Tested-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Rochan Avlur <rochan.avlur@gmail.com>
Date: Tue Sep 1 19:36:56 2026 -0600
fuse: wait for FR_FINISHED on abort_on_kill to prevent use-after-free
[ Upstream commit 64b0b5cacbd2fea88001464cb712c9dfc795b26e ]
The abort_on_kill path in request_wait_answer() calls fuse_abort_conn()
and returns without waiting for FR_FINISHED. If fuse_dev_do_write() is
concurrently processing the same request (FR_LOCKED set), the caller
frees req->args while it is still being accessed, causing a
use-after-free.
Fix this by jumping to the existing wait_event(FR_FINISHED) instead of
returning early. The wait will not hang because fuse_abort_conn()
ensures all requests are ended.
Reported-by: syzbot+d6540a3fa1626e11360d@syzkaller.appspotmail.com
Fixes: 204aa22a686b ("fuse: abort on fatal signal during sync init")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Rochan Avlur <rochan.avlur@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Andre Eikmeyer <dev@deq.rocks>
Date: Sat Jul 18 14:15:26 2026 +0200
HID: apple: preserve keyboard backlight across T2 resume
commit 2b5d1495bd101f3d9c13caf3923754f48ee7371a upstream.
The T2 virtual USB host controller re-enumerates the internal keyboard
after system resume. The butterfly keyboard backlight currently uses
LED_CORE_SUSPENDRESUME, so the LED core sends a blocking request to the
old HID device while it is disappearing. That request fails with -ENODEV
and the newly probed device starts with its backlight off.
To fix this, we cache the requested brightness when the old HID device is
removed and restore it when the replacement is probed. We let
re-enumeration handle restoration instead of issuing a request through the
stale device.
Fixes: 1f95a6cd5ad7 ("HID: apple: ensure the keyboard backlight is off if suspending")
Cc: stable@vger.kernel.org
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Date: Tue Jun 30 02:06:56 2026 +0100
HID: corsair-void: Check size of status and firmware events before reading them
commit 08d8814521885e67b1bdf6a3036ee264e3e58377 upstream.
Malformed status and firmware events could cause an out-of-bounds read since
the size wasn't being checked. Check the size and warn on unexpected values to
avoid this.
Fixes: 6ea2a6fd3872 ("HID: corsair-void: Add Corsair Void headset family driver")
Cc: stable@vger.kernel.org
Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guangshuo Li <lgs201920130244@gmail.com>
Date: Sat Aug 8 22:57:48 2026 +0800
HID: intel-thc-hid: intel-quicki2c: fix autosuspend cleanup during teardown
commit 42a941e39432ef6766402ef68f1389dcfec4ee37 upstream.
quicki2c_probe() calls pm_runtime_use_autosuspend(), but
quicki2c_remove() does not call the matching
pm_runtime_dont_use_autosuspend() during teardown.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped.
The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().
Add the missing pm_runtime_dont_use_autosuspend() call to the driver
remove path.
This issue was found by manual code inspection.
Fixes: 5f420e8215c6 ("HID: intel-thc-hid: intel-quicki2c: Add PM implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Thu Aug 6 23:56:19 2026 +0900
HID: intel-thc-hid: intel-quickspi: bound GET_REPORT response to the caller buffer
commit 035ec4a71cb8020a927c123bbe75c2f88d614986 upstream.
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.
Fixes: 4138f21115ae ("HID: intel-thc-hid: intel-quickspi: Complete THC QuickSPI driver")
Suggested-by: Sashiko AI <sashiko-bot@kernel.org>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guangshuo Li <lgs201920130244@gmail.com>
Date: Sat Aug 8 23:17:36 2026 +0800
HID: intel-thc-hid: intel-quickspi: fix autosuspend cleanup during teardown
commit 05dffa55fd6dbed4bf2421fae5accc2b857e668d upstream.
quickspi_probe() calls pm_runtime_use_autosuspend(), but
quickspi_remove() does not call the matching
pm_runtime_dont_use_autosuspend() during teardown.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped.
The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().
Add the missing pm_runtime_dont_use_autosuspend() call to the driver
remove path.
This issue was found by manual code inspection.
Fixes: 6912aaf3fd24 ("HID: intel-thc-hid: intel-quickspi: Add PM implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Fri Jul 17 18:16:22 2026 +0900
HID: intel-thc-hid: intel-quickspi: validate report size before copy
commit a59cf84441f9a17323c89452cec2bf16724c48a9 upstream.
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.
Fixes: 9d8d51735a3a ("HID: intel-thc-hid: intel-quickspi: Add HIDSPI protocol implementation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Reviewed-by: Even Xu <even.xu@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jiangshan Yi <yijiangshan@kylinos.cn>
Date: Tue Jul 28 21:14:40 2026 +0800
HID: mcp2221: stop device IO before hid_hw_stop
commit dca151633c0fde90935311c60e7cfc064aa56134 upstream.
Quiesce device IO at the start of the devm cleanup callback
mcp2221_hid_unregister() so that incoming HID reports cannot race with
hardware teardown during probe failure or device removal, addressing a
potential use-after-free.
Guard the call to hid_device_io_stop() with io_started. On normal
removal hid_device_remove() has already cleared io_started before the
devres group is released, so an unconditional call would otherwise hit
the !io_started path and emit a spurious "io already stopped" warning
on every removal. The guard preserves the probe-failure balancing,
where io_started is still set after hid_device_io_start(), while
staying silent on the normal removal path.
Fixes: d4b50ac06ea6 ("HID: mcp2221: Allow IO to start during probe")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jiangshan Yi <yijiangshan@kylinos.cn>
Date: Tue Jul 28 21:14:42 2026 +0800
HID: mcp2221: validate report size in mcp2221_raw_event()
commit 2c9a6998c19503626c57a2267bf279e204113079 upstream.
mcp2221_raw_event() never validates the size of incoming HID reports.
In the MCP2221_I2C_GET_DATA path it trusts the device-supplied data[3]
as the copy length without checking that 4 + data[3] bytes actually
exist in the received report. A malicious or misbehaving USB device can
send a short report with a large data[3], causing the memcpy to read
past the valid report data in the HID transfer buffer and leak
uninitialized kernel memory back to userspace through the I2C/SMBus
read path.
Add a minimum size check at entry and validate that the source range
fits within the received report before the copy.
Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ibrahim Hashimov <security@auditcode.ai>
Date: Wed Jul 15 13:53:01 2026 +0200
HID: picolcd: clamp eeprom debugfs read to bytes actually received
commit e9c667395ac1f8024f623250b32bae4c7af9caa0 upstream.
picolcd_debug_eeprom_read() trusts resp->raw_data[2] -- a length byte
supplied by the device in its REPORT_EE_DATA reply -- clamped only to
the caller's read() count:
ret = resp->raw_data[2];
if (ret > s)
ret = s;
if (copy_to_user(u, resp->raw_data+3, ret))
It never checks resp->raw_size, the number of bytes picolcd_raw_event()
actually copied into the 64-byte raw_data[] of the kmalloc'd struct
picolcd_pending. A device (or a spoofed picoLCD) returning a length byte
of 0xff, read with a count >= 255, makes copy_to_user() read past
raw_data[] into adjacent slab memory and return it to userspace through
the debugfs "eeprom" file:
BUG: KASAN: slab-out-of-bounds in _copy_to_user
Read of size 255 ... picolcd_debug_eeprom_read+0x214/0x2f0 [hid_picolcd]
The debug-dump path in the same file already validates the device length
byte against the received size before trusting it; this read does not.
The file is created S_IRUSR (root-only) and a crafted device is needed,
so it is neither unprivileged- nor remotely-triggerable.
Clamp the copy length to resp->raw_size - 3 (the payload actually
received, minus the 3-byte header), floored at 0 for short replies.
Fixes: 9bbf2b98ba11 ("HID: add experimental access to PicoLCD device's EEPROM and FLASH")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xu Rao <raoxu@uniontech.com>
Date: Fri Jul 31 16:49:26 2026 +0800
HID: roccat: free buffered reports when destroying device
commit bbff0ccbff360a5498075525005f6a913239a3d7 upstream.
roccat_report_event() duplicates each report with kmemdup() and stores
the allocation in a circular-buffer slot. The allocation is released only
when that slot is reused.
The device destruction paths free struct roccat_device without releasing
reports still stored in cbuf[]. This makes those allocations unreachable
and leaks up to ROCCAT_CBUF_SIZE report buffers per device.
Add a small destructor that frees every buffered report before freeing the
device, and use it in both paths that can destroy a registered device.
Fixes: 206f5f2fcb5f ("HID: roccat: propagate special events of roccat hardware to userspace")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xingrui Li <baka9@bakabaka9.tech>
Date: Wed Aug 5 18:57:53 2026 +0000
HID: sensor-hub: Fix out-of-bounds write in sensor_hub_get_feature
commit c92693f3ed099401d0383ef35ca1fe1e6ba033de upstream.
sensor_hub_get_feature() clamps its return value to the caller's buffer
size, but the copy loop still copies field->report_size / 8 bytes for
each report value. A malicious HID descriptor can advertise a large
feature field size while an IIO caller supplies a small stack buffer,
such as a single s32, causing an out-of-bounds write.
HID core stores parsed report values in __s32 slots and clamps extracted
values to 32 bits. Reject feature fields that require more than one slot
per value, guard the total byte count calculation, and clamp each
per-value copy to the remaining caller buffer.
Fixes: 5459ada2b3cd69 ("HID: sensor-hub: Fix packing of result buffer for feature report")
Cc: stable@kernel.org
Assisted-by: OpenAI:GPT-5.5-Cyber
Signed-off-by: Xingrui Li <baka9@bakabaka9.tech>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Haoxiang Li <haoxiang_li2024@163.com>
Date: Tue Jul 7 15:15:45 2026 +0800
HID: sensor: custom: Fix field sysfs group cleanup on failure
commit 3789d0802ddb4b3be04062caf4bfadd23496e9a7 upstream.
hid_sensor_custom_add_attributes() creates one sysfs group for each
custom sensor field. If sysfs_create_group() fails after some groups
have already been created, the function returns the error without
removing the previously created groups.
Add a local unwind path to remove the groups that were already created.
With enable_sensor exposed only after the field attributes are ready,
this path can free sensor_inst->fields without leaving enable_sensor
able to access pointers into that array.
Fixes: 4a7de0519df5 ("HID: sensor: Custom and Generic sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Doruk Tan Ozturk <doruk@0sec.ai>
Date: Fri Jul 24 16:27:03 2026 +0200
HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind
commit a26705bd2e2728833e7a538ce91e58a5eeff496a upstream.
For GHL (Guitar Hero Live) dongles, sony_probe() arms a periodic timer:
ghl_magic_poke() (the timer callback) submits sc->ghl_urb, and the URB
completion ghl_magic_poke_cb() re-arms the timer with mod_timer().
sony_remove() drained the timer with timer_delete_sync() and then freed
the URB with usb_free_urb():
timer_delete_sync(&sc->ghl_poke_timer);
usb_free_urb(sc->ghl_urb);
timer_delete_sync() does not block re-arming, and while the URB is in
flight the timer is not pending, so the sync delete is a no-op. A URB
completion that runs after the delete re-arms the timer, and usb_free_urb()
only drops a reference -- it does not kill an in-flight URB. sc is
allocated with devm_kzalloc() and freed once sony_remove() returns, so the
re-armed ghl_poke_timer (embedded in sc) then fires on freed memory, a
use-after-free from timer softirq. This is a disconnect/rmmod race.
Poison the URB first, then shut the timer down, before freeing the URB.
usb_poison_urb() kills any in-flight URB and permanently rejects further
submissions, so a poke timer that is still pending cannot re-submit the
URB from ghl_magic_poke() in the window before timer_shutdown_sync() runs.
usb_kill_urb() would not suffice: it only cancels the in-flight URB and
leaves it submittable once it returns, so the pending timer could
re-submit it and put a fresh URB in flight over the freed sc.
timer_shutdown_sync() then drains any last callback and blocks re-arming.
The probe error path is unaffected: it is only reached before the timer
is armed.
Reproduced under KASAN on next-20260710 via dummy_hcd + raw-gadget
emulation of the GHL PS4 dongle (VID 0x1430 / PID 0x07bb): hid-sony binds
and arms the poke timer, the poke URB is held in flight, the driver is
unbound (freeing sc), then the URB is released. The completion re-arms the
timer on the freed sc, and the re-armed timer fires ~8 s later:
BUG: KASAN: slab-use-after-free in ghl_magic_poke+0x98/0xb0
Read of size 8 at addr ffff88810b02fd50 by task swapper/0/0
ghl_magic_poke+0x98/0xb0
call_timer_fn+0x35/0x2b0
__run_timers+0x69c/0x9a0
run_timer_softirq+0x173/0x2a0
Allocated by task 169: sony_probe
Freed by task 338: devres_release_group <- hid_device_remove (sony_remove)
Found by 0sec (https://0sec.ai) using automated source analysis.
Fixes: cc894ac55360 ("HID: sony: support for ghlive ps3/wii u dongles")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Baul Lee <baul.lee@xbow.com>
Date: Wed Jul 29 23:24:32 2026 +0900
HID: universal-pidff: stop the device when force-feedback init fails
commit ce08c5555cabcd444d8b77fa69a7cb68bb05f611 upstream.
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>
Fixes: f06bf8d94fff ("HID: Add hid-universal-pidff driver and supported device ids")
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Date: Fri Jul 24 16:05:22 2026 +0300
hsi: omap_ssi_core: fix missing DMA mask setup for SSI controller device
commit e81250ec6b69248b00d38c523dc6a13efaf38aab upstream.
The OMAP SSI driver uses a synthetic HSI controller device allocated via
hsi_alloc_controller(), which does not go through the normal OF/platform
device initialization path.
As a result, the embedded struct device does not have a DMA mask
initialized by default.
After recent DMA API hardening changes, dma_map_sg() and related helpers
now require a valid dma_mask to be present, otherwise the driver may
crash or trigger warnings when attempting DMA mapping operations.
Fix this by explicitly initializing the DMA mask for the SSI controller
device and setting a 32-bit DMA mask, which matches the hardware
capabilities.
Cc: stable@vger.kernel.org
Fixes: f959dcd6ddfd ("dma-direct: Fix potential NULL pointer dereference")
Reported-by: Merlijn Wajer <merlijn@wizzup.org>
Closes: https://lore.kernel.org/linux-omap/4ed95c71-2066-6b4c-ad1b-53ef02d79d53@wizzup.org/
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Link: https://patch.msgid.link/20260724130522.706480-1-ivo.g.dimitrov.75@gmail.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guillaume Morin <guillaume@morinfr.org>
Date: Tue Jul 28 21:29:03 2026 +0200
hugetlb: only adjust reservation during unmapping if mapcount is 0
commit 5120b1e048d48596ffaec1a8412012a91adba73b upstream.
Since df7a6d1f6405, __unmap_hugepage_range can adjust reservations. In
the case of folio mapped in both a parent and a child, if the parent
unmaps the range first, the reservation adjustment will result in an
underflow of the reserved count. Once the child unmaps the range, the
count is restored. Change __unmap_hugepage_range() to check the mapcount
before adjusting the reservation.
Link: https://lore.kernel.org/all/alEJkwn5VlTTH_ZX@bender.morinfr.org/
Link: https://lore.kernel.org/amkC_1Ya6OiUoiLZ@bender.morinfr.org
Fixes: df7a6d1f6405 ("mm/hugetlb: restore the reservation if needed")
Signed-off-by: Guillaume Morin <guillaume@morinfr.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Rik van Riel <riel@surriel.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Cong Nguyen <congnt264@gmail.com>
Date: Mon Aug 10 11:28:39 2026 +0700
hwmon: (max6621) fix negative temperature offset and crit readings
commit acc52bd431e2d8698fae8d82a74ac45d79b62e0a upstream.
max6621_read() reads the CONFIG2 offset and the critical alert threshold
registers into a u32 and scales them without sign extension:
/* offset */ *val = (regval >> MAX6621_REG_TEMP_SHIFT) * 1000L;
/* crit */ *val = regval * 1000L;
Both attributes are writable and their write paths clamp to a negative
minimum and encode negative values, so a value written as negative is read
back as a large positive number. For example, writing a -10 degrees C
offset stores max6621_temp_mc2reg(-10000) = (-10 << 6) = 0xfd80; the read
then computes 0xfd80 >> 6 = 1014 -> 1014000 instead of -10000.
Cast the register value to s16 before scaling so the read preserves the
sign the write path encodes. The temperature input path already uses an s8
intermediate and is left unchanged.
Fixes: 92b64580f14b ("hwmon: (max6621) Add support for Maxim MAX6621 temperature sensor")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://lore.kernel.org/r/ad0baddbd6163cf73545c8e9273258136718585c.1786334038.git.congnt264@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Cong Nguyen <congnt264@gmail.com>
Date: Mon Aug 10 11:27:54 2026 +0700
hwmon: (max6621) fix temperature clamp range
commit 24fbeb83d9b750a36da42cb835a154d80fd3d495 upstream.
MAX6621_TEMP_INPUT_MIN and MAX6621_TEMP_INPUT_MAX are used to clamp the
writable offset and critical thresholds. They are defined as -127000 and
128000.
The driver decodes the temperature through an s8 and its own comment in
max6621_read() documents an 8-bit two's complement value, whose range is
-128 to +127 degrees C. The current limits therefore reject the valid
-128 degrees C and accept +128 degrees C, which does not fit the 8-bit
range.
Correct the limits to -128000 and 127000.
Fixes: 92b64580f14b ("hwmon: (max6621) Add support for Maxim MAX6621 temperature sensor")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://lore.kernel.org/r/9d3a4f1895a47794bb359a2a32fb1ccd6a15812c.1786334038.git.congnt264@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Can Peng <pengcan@kylinos.cn>
Date: Sat Jul 18 11:29:37 2026 +0800
hwrng: stm32 - Fix runtime PM cleanup on registration failure
commit 1163a476a568f6c0f852d469c8e4c5a5f805adac upstream.
stm32_rng_probe() enables autosuspend and runtime PM before registering the
hwrng. If devm_hwrng_register() fails, probe returns with runtime PM left
enabled and autosuspend still selected.
The remove callback also only disables runtime PM and does not undo
pm_runtime_use_autosuspend().
Use devm_pm_runtime_enable() so runtime PM is unwound automatically on
probe failure and driver detach. Since the managed cleanup also disables
runtime PM,drop the remove callback.
Fixes: c6a97c42e399 ("hwrng: stm32 - add support for STM32 HW RNG")
Cc: stable@vger.kernel.org
Signed-off-by: Can Peng <pengcan@kylinos.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Sanman Pradhan <psanman@juniper.net>
Date: Tue Apr 14 17:25:12 2026 +0000
hwtracing: hisi_ptt: Propagate DMA reset timeout in trace_start()
commit 75d42d990335322852ed5f7ce324b701c0949d79 upstream.
hisi_ptt_wait_dma_reset_done() discards the return value of
readl_poll_timeout_atomic(). If the DMA engine does not complete its
reset within the timeout, hisi_ptt_trace_start() proceeds to start
tracing regardless.
Return a bool from hisi_ptt_wait_dma_reset_done(), consistent with the
other wait helpers in this driver. On timeout, log an error, de-assert
the reset bit, and return -ETIMEDOUT. Move ctrl->started to the
successful path so a failed start does not leave the trace marked as
active.
Fixes: ff0de066b463 ("hwtracing: hisi_ptt: Add trace function support for HiSilicon PCIe Tune and Trace device")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Reviewed-by: Sizhe Liu <liusizhe5@huawei.com>
Reviewed-by: Yicong Yang <yangyccccc@gmail.com>
Tested-by: Sizhe Liu <liusizhe5@huawei.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20260414172451.14331-2-sanman.pradhan@hpe.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ruoyu Wang <ruoyuw560@gmail.com>
Date: Sat Aug 15 23:17:20 2026 +0800
i2c: mxs: fix DMA channel leak on probe error
commit 777979e627115734052b323d2721cdb500e81dcf upstream.
mxs_i2c_probe() requests an exclusive DMA channel before resetting the
controller and registering the I2C adapter. If either later operation
fails, probe returns without releasing the channel because the remove
callback is not invoked after a failed probe.
Use devm_dma_request_chan() so the device core releases the channel on
probe failure and driver detach. Remove the manual release from the
remove callback because the channel is now device-managed.
This issue was found by a static analysis checker and confirmed by
manual source review.
Fixes: 62885f59a261 ("MXS: Implement DMA support into mxs-i2c")
Assisted-by: unnamed:claude-opus-4.8 typestate
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Cc: <stable@vger.kernel.org> # v3.7+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260815151720.3757460-1-ruoyuw560@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Wed Jun 17 23:01:38 2026 +0800
i3c: master: adi: initialize the lock before enabling interrupts
commit 8a53f9102a0d3eeb8784999f925028acf339c276 upstream.
adi_i3c_master_probe() requests the IRQ and unmasks REG_IRQ_PENDING_CMDR
before the controller's IBI state, transfer queue list and transfer
queue lock are initialized. A pending CMDR interrupt can therefore run
adi_i3c_master_irq() and take master->xferqueue.lock before the dynamic
lock has been initialized.
This issue was found by our static analysis tool and then manually
reviewed against the current tree.
The grounded PoC kept the probe ordering and the IRQ path
adi_i3c_master_probe() -> adi_i3c_master_irq() -> xferqueue.lock, with a
pending CMDR interrupt arriving after REG_IRQ_PENDING_CMDR is unmasked.
Lockdep reported:
INFO: trying to register non-static key.
you didn't initialize this object before use?
lock_acquire+0xbb/0x290
_raw_spin_lock_irqsave+0x36/0x60
adi_i3c_master_irq+0x32/0x56 [vuln_msv]
adi_i3c_master_probe+0x5a/0xf47 [vuln_msv]
Initialize the transfer queue and IBI state before requesting and
unmasking the IRQ.
Fixes: a79ac2cdc91d ("i3c: master: Add driver for Analog Devices I3C Controller IP")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260617150138.628578-1-runyu.xiao@seu.edu.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Adrian Hunter <adrian.hunter@intel.com>
Date: Thu Jul 23 10:57:47 2026 +0300
i3c: master: Fix info leak and UAF in device unregister path
commit d2c743efd2d1ee64e94324664808f623dd865872 upstream.
i3c_master_unregister_i3c_devs() clears i3cdev->dev->desc before
calling device_unregister(). During device_unregister(),
device_del() emits a KOBJ_REMOVE uevent and unbinds the driver while
the device descriptor is still expected to be valid. As a result,
i3c_device_uevent() and a racing modalias_show() can observe a NULL
desc and fall back to an uninitialized stack struct i3c_device_info,
leaking kernel stack contents in the generated modalias. Driver
.remove() callbacks may also encounter an unexpected NULL desc during
unbind.
Keep desc valid until device_unregister() has completed. Since
device_unregister() drops the device reference and may free the device,
take an extra reference with get_device() before unregistering. Clear
desc afterwards and release the extra reference with put_device().
This preserves the release-time invariant that desc must be NULL while
avoiding both the information leak and a potential use-after-free from
writing desc after the device has been released.
Reported-by: sashiko-bot@kernel.org
Link: https://lore.kernel.org/linux-i3c/20260702190003.8BF741F000E9@smtp.kernel.org/
Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260723075747.34049-1-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Maoyi Xie <maoyixie.tju@gmail.com>
Date: Wed Jun 24 13:04:33 2026 +0800
i3c: master: svc: bound IBI payload to the requested max_payload_len
commit e2bda39d7f9f285ec803e200b5c1f17143d0b483 upstream.
svc_i3c_master_handle_ibi() reads the IBI payload from the RX FIFO into
the IBI slot. The loop is bounded by the hardware FIFO size
(SVC_I3C_FIFO_SIZE), not by the slot size.
slot->data points into the IBI pool, which i3c_generic_ibi_alloc_pool()
sizes at max_payload_len per slot. svc_i3c_master_request_ibi() only
rejects a max_payload_len larger than SVC_I3C_FIFO_SIZE, so a driver can
request a smaller one. mctp-i3c requests 1. Each readsb() then copies the
controller RXCOUNT bytes (up to 31) with no check against the slot size.
A device that sends more bytes than the slot holds writes past
slot->data, an out-of-bounds write into the IBI pool.
Bound the loop by dev->ibi->max_payload_len and clamp each read to the
space left in the slot, the same way dw-i3c does. A device can still send
more than the requested payload. Flush the leftover bytes from the RX FIFO
so they do not leak into the next transfer.
Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver")
Cc: stable@vger.kernel.org
Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/178227747353.2931373.15868718612134648277@maoyixie.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Date: Mon Jul 13 16:05:29 2026 +0300
i3c: renesas: Check that the transfer is valid before accessing it
commit 5f1a76ecfe90544a28d657306c9b3caa66ba0e63 upstream.
The Renesas I3C driver uses an asynchronous model to transfer data. It
prepares a struct renesas_i3c_xfer, enqueues it, and waits for completion.
The interrupt handler dequeues the transfer, updates/uses it, and signals
the waiting thread.
If the completion times out, the waiting thread dequeues the transfer and
free it. If an interrupt fires after that, the handler may access freed
memory, leading to crashes.
Check that the transfer is still valid before accessing it in the
interrupt handler. With it clear any status flags and disable all
the interrupts to avoid triggering the same interrupts again.
Fixes: d028219a9f14 ("i3c: master: Add basic driver for the Renesas I3C controller")
Cc: stable@vger.kernel.org
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Link: https://patch.msgid.link/20260713130545.568657-2-claudiu.beznea+renesas@tuxon.dev
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Date: Mon Jul 13 16:05:35 2026 +0300
i3c: renesas: Clean DATBAS register on detach
commit 797ed83c0cd495be4b345750c59e0363bf4d6207 upstream.
The controller uses DATBAS registers on TX/RX logic. Clean the DATBAS
register for the detached I3C device to avoid issues.
Fixes: d028219a9f14 ("i3c: master: Add basic driver for the Renesas I3C controller")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Link: https://patch.msgid.link/20260713130545.568657-8-claudiu.beznea+renesas@tuxon.dev
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Date: Mon Jul 13 16:05:32 2026 +0300
i3c: renesas: Reconfigure the DATBAS register on re-attach
commit 1364afd3e2e76e007a2c07ec95704d56980226f0 upstream.
During re-attach, the device may change its position in the i3c->addrs[]
array. As a result, it may use a different Device Address Table Basic
Register (DATBAS), which needs to be reconfigured.
Reconfigure the DATBAS register on re-attach. Along with it update
software caches.
Fixes: d028219a9f14 ("i3c: master: Add basic driver for the Renesas I3C controller")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Link: https://patch.msgid.link/20260713130545.568657-5-claudiu.beznea+renesas@tuxon.dev
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jordan R Abrahams-Whitehead <ajordanr@google.com>
Date: Fri Jul 31 20:15:19 2026 +0000
include/linux/list.h: mark list_add and __list_add as __always_inline
commit 2780860eddecba9ffe210bb9436eee3cf22bfcdd upstream.
This commit resolves an issue where modpost section verification fails due
to section mismatches between list_add and its callers.
At present, list_add (and its internal __list_add) are called from both
.text and .init code sections. Since inlining can vary per call site,
list_add can be 4 different states:
list_add in text with arguments to non-.init.data values
list_add in init with arguments to static .init.data values
list_add in init with arguments to non-.init.data values
list_add in text with arguments to static .init.data values
It is last instance that ends up causing the section mismatch caused by
constant propagation of the address of static libs inside the `dir_add` as
seen below (with the dir_list being defined statically in initramfs.c,
resting in .init.data).
WARNING: modpost: vmlinux.o: section mismatch in reference: __list_add
(section: .text.unlikely.) -> dir_list (section: .init.data)
Because of these section matching requirements, semantically, __list_add
and list_add MUST be inlined. This will then ensure callers inside .init
will receive a list_add that exists and refers to only .init data, and
list_add code in .text sections will only refer to non-init data.
This issue manifests predominently in AutoFDO with clang, which is very
hesitant to inline cold functions such as list_add even when marked
`inline`. Marking them as `__always_inline` therefore matches the
existing semantic constraints imposed by modpost's section mismatch
checks.
Link: https://lore.kernel.org/20260731-always-inline-list-add-v1-1-d29f54ce5477@google.com
Link: https://lore.kernel.org/all/CANn89iJVQe=wedLheJmjZjOTJsWHijT0jZs=iRxKssJZbjAxHw@mail.gmail.com/
Signed-off-by: Jordan R Abrahams-Whitehead <ajordanr@google.com>
Suggested-by: Nathan Chancellor <nathan@kernel.org>
Suggested-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reported-by: Giuliano Procida <gprocida@google.com>
Reported-by: Yabin Cui <yabinc@google.com>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2173
Cc: Bill Wendling <morbo@google.com>
Cc: Justin Stitt <justinstitt@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kuan-Wei Chiu <visitorckw@gmail.com>
Date: Thu Apr 16 19:08:40 2026 +0000
interconnect: Fix use after free in icc_get() and of_icc_get_by_index()
commit 25c7e242aca084fdc1098248194032317dca625d upstream.
In of_icc_get_by_index() and icc_get(), if the dynamic allocation for
path->name fails via kasprintf(), the error handling path directly
calls kfree(path) to free the path object and returns an error.
However, prior to this point, path_find() calls path_init(), which
already links the path's requests into the req_list of the respective
interconnect nodes via hlist_add_head(). Directly invoking kfree(path)
leaves dangling pointers in the hlist. A subsequent call to icc_get()
or icc_set_bw() will traverse or modify these corrupted lists, triggering
a slab use afterfree.
KASAN report showing the vulnerability when reproducing via debugfs:
BUG: KASAN: slab-use-after-free in path_find+0x6f8/0xcfc
Write of size 8 at addr fff000000d43f748 by task sh/1
...
Call trace:
kasan_report+0xac/0xfc
path_find+0x6f8/0xcfc
icc_get+0x148/0x380
icc_get_set+0xf8/0x2d0
...
Freed by task 1:
kfree+0x1a0/0x4a4
icc_get+0x2cc/0x380
icc_get_set+0xf8/0x2d0
Fix this by replacing kfree(path) with the proper teardown function,
icc_put(path), which safely removes the requests from the req_list using
hlist_del() and drops the provider usage references before freeing the
memory.
Additionally, in icc_get(), ensure that the icc_lock mutex is released
prior to calling icc_put(path) to avoid a deadlock, as icc_put()
internally acquires the same lock.
Fixes: 3791163602f7 ("interconnect: Handle memory allocation errors")
Cc: stable@vger.kernel.org
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Link: https://patch.msgid.link/20260416190840.1753468-1-visitorckw@gmail.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Date: Fri Aug 21 16:18:17 2026 +0545
io_uring/query: cap user size passed to copy_struct_to_user
commit ba77efee1b95b4ad7559b1cdbe7cd7fa36dca95b upstream.
io_handle_query_entry() clamps hdr.size for the inbound copy_from_user()
but keeps the original user value as usize. copy_struct_to_user() uses
that usize and, when it is larger than the kernel result, clear_user()s
the trailing bytes.
As hdr.size is a __u32, a query can request nearly 4 GiB of zeroing,
including on the error path where res_size stays 0. The interface is
reachable without a ring via IORING_REGISTER_QUERY.
Reject sizes larger than PAGE_SIZE, as recommended for copy_struct_*
interfaces.
Fixes: c265ae75f900 ("io_uring: introduce io_uring querying")
Cc: stable@vger.kernel.org # 6.18+
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://patch.msgid.link/20260821103317.91437-1-acharyalaxman8848@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuai Xue <xueshuai@linux.alibaba.com>
Date: Mon Jul 27 11:02:12 2026 +0800
iommu/amd: Put PCI device after handling PPR faults
commit af3b69b16383fbc8fe5f61b5b0150d2e41ede71f upstream.
iommu_call_iopf_notifier() looks up the requester with
pci_get_domain_bus_and_slot(), which returns a PCI device with its
reference count incremented.
Neither the successful iommu_report_device_fault() path nor the abort
path drops that reference, so every handled PPR request leaks a PCI
device reference.
This is the same ownership rule that was fixed for the old iommu_v2
ppr_notifier() path by commit 6cf0981c2233 ("iommu/amd: Fix pci device
refcount leak in ppr_notifier()"), but iommu_call_iopf_notifier() was
added later as a separate PPR/IOPF notifier path.
Drop the PCI device reference after handling the PPR entry.
Fixes: 978d626b8f1a ("iommu/amd: Add IO page fault notifier handler")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shameer Kolothum <skolothumtho@nvidia.com>
Date: Mon Jun 29 10:41:05 2026 +0100
iommu/arm-smmu-v3: Manage teardown with devm
commit 2bd22a0d40503a65d243b011de146603c8ce1cbc upstream.
arm_smmu_device_remove() manually frees the IOPF queue, destroys the
vmid_map and disables the device, while the IRQs and queues are devm
managed. devm unwinds only after remove() returns, so the cleanup runs
in the wrong order. The IOPF queue is freed before the event-queue IRQ
whose handler uses it.
Manage all of it with devm so the unwind order is correct. Free the IOPF
queue and vmid_map via devm actions, and disable the device from one
registered after arm_smmu_device_reset().
This is also a prerequisite for fixing a Tegra241 CMDQV CMD_SYNC
use-after-free in the subsequent patch.
Cc: stable@vger.kernel.org
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Weimin Xiong <xiongwm2026@163.com>
Date: Thu Jul 16 09:32:29 2026 +0800
iommu/msm: Unwind probe state on registration failure
commit 535a200220ca2c83bc8bf54bd2cbe045d6ee70c4 upstream.
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.
Fixes: 42df43b36163 ("iommu/msm: Make use of iommu_device_register interface")
Cc: stable@vger.kernel.org
Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuai Xue <xueshuai@linux.alibaba.com>
Date: Sun Jul 26 15:43:29 2026 +0800
iommu/sva: Set handle->dev before the SVA handle is visible
commit 530f8f9c3546cb3ebee1b135375aaee08a073ebb upstream.
iommu_attach_device_pasid() installs the new SVA attach handle in the
group PASID lookup before iommu_sva_bind_device() returns. A concurrent
bind can therefore find and reuse the same handle after iommu_sva_lock is
dropped.
handle->dev was initialized after dropping iommu_sva_lock. This leaves a
window where a racing bind can return a handle whose dev pointer is still
NULL. A subsequent iommu_sva_unbind_device() can then dereference it via
handle->dev->iommu_group.
Initialize handle->dev before releasing iommu_sva_lock so any visible SVA
handle is fully initialized.
Fixes: be51b1d6bbff ("iommu/sva: Refactoring iommu_sva_bind/unbind_device()")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nicolin Chen <nicolinc@nvidia.com>
Date: Tue Jul 14 13:55:04 2026 -0700
iommu/tegra241-cmdqv: Reject a vSID wider than the SID_MATCH field
commit 4379610c79bd88ddbea10e7f6c21e16d4b338c6b upstream.
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.
Fixes: 4dc0d12474f9 ("iommu/tegra241-cmdqv: Add user-space use support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kevin Tian <kevin.tian@intel.com>
Date: Wed Aug 5 07:42:59 2026 +0800
iommu/vt-d: Fix no_iommu to disable platform opt-in
commit 219cc978d69ce9b538d0d73936c569d4ca5b0a24 upstream.
If user explicitly requests to disable iommu (via "iommu=off" or
"intel_iommu=off"), there is no reason to force enabling it due
to platform opt-in (for external-facing devices). User should be
aware of any security implication of doing so.
"intel_iommu=off" implements this policy by setting no_platform_optin
to skip platform opt-in in platform_optin_force_iommu().
However, "iommu=off" (no_iommu=1) doesn't set no_platform_optin
hence is broken in this aspect:
- detect_intel_iommu() doesn't request ACS if no_iommu=1
- platform_optin_force_iommu() forces iommu on if external-facing
devices exist and no_platform_optin is not set
This leads to a bad configuration with ACS disabled while DMA
remapping is enabled.
Instead of setting no_platform_optin (will soon be removed) for
no_iommu=1, directly check no_iommu in platform_optin_force_iommu().
Fixes: 89a6079df791 ("iommu/vt-d: Force IOMMU on for platform opt in hint")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kevin Tian <kevin.tian@intel.com>
Date: Wed Aug 5 07:43:00 2026 +0800
iommu/vt-d: Force requesting ACS when tboot is enabled
commit 607432b2618b61df81134be0ef2562b8300c1216 upstream.
Currently the conditions of requesting ACS in detect_intel_iommu()
don't include tboot, leading to a possible misconfiguration with ACS
disabled (e.g. due to user opts) while iommu is later forced on by
tboot_force_iommu().
Fix it by checking tboot in detect_intel_iommu().
Fixes: 5d990b627537 ("PCI: add pci_request_acs")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Peiyang He <peiyang_he@smail.nju.edu.cn>
Date: Sat Jul 11 13:51:19 2026 +0800
iommu: Fix dev_iommu memory leak when device_add fails in iommu_mock_device_add
commit b7b0b3851474883d4aba6ed72da87141204b23e5 upstream.
iommu_mock_device_add() first calls iommu_fwspec_init(), which on
success allocates both dev->iommu (via dev_iommu_get()) and
dev->iommu->fwspec. If the subsequent device_add(dev) call fails,
the error path only calls iommu_fwspec_free(dev), which frees
fwspec but leaves dev->iommu still allocated.
This triggers the following kmemleak report when fuzzing with Syzkaller:
BUG: memory leak
unreferenced object 0xffff888011e0a200 (size 192):
comm "syz.1.1695", pid 24885, jiffies 4295222527
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de .............N..
ff ff ff ff 00 00 00 00 ff ff ff ff ff ff ff ff ................
backtrace (crc 25df5bb3):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4575 [inline]
slab_alloc_node mm/slub.c:4899 [inline]
__kmalloc_cache_noprof+0x47a/0x710 mm/slub.c:5415
kmalloc_noprof include/linux/slab.h:950 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
dev_iommu_get+0x10c/0x1a0 drivers/iommu/iommu.c:408
iommu_fwspec_init+0x288/0x4d0 drivers/iommu/iommu.c:3087
iommu_mock_device_add+0x46/0xb0 drivers/iommu/iommu.c:385
mock_dev_create drivers/iommu/iommufd/selftest.c:1025 [inline]
iommufd_test_mock_domain drivers/iommu/iommufd/selftest.c:1066 [inline]
iommufd_test+0x2f8a/0x6190 drivers/iommu/iommufd/selftest.c:2072
iommufd_fops_ioctl+0x367/0x540 drivers/iommu/iommufd/main.c:533
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fix this by calling dev_iommu_free(dev) instead of iommu_fwspec_free(dev)
in the device_add() failure path. dev_iommu_free() frees both fwspec
and the outer dev_iommu struct and clears dev->iommu.
Link: https://patch.msgid.link/r/76AC62D46B998556+20260711055119.1003477-1-peiyang_he@smail.nju.edu.cn
Reported-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Fixes: 2a918911ed3d ("iommufd: Register iommufd mock devices with fwspec")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuai Xue <xueshuai@linux.alibaba.com>
Date: Sun Jul 26 15:43:30 2026 +0800
iommufd: Avoid locking internal accesses during unmap
commit 0dbcdf4473a614adbd732d567c9b39ac0e040e0c upstream.
iommufd_access_notify_unmap() skips internal accesses because they do
not have an external unmap callback to invoke.
However, the current test calls iommufd_lock_obj() before checking
whether the access is internal. If iommufd_lock_obj() succeeds, the loop
then sees the internal access and continues, bypassing the matching
iommufd_put_object() used by the normal unmap path. This leaks the
object reference taken by iommufd_lock_obj().
Check for internal accesses first so skipped entries are never locked.
Fixes: 27b77ea5feaa ("iommufd/access: Bypass access->ops->unmap for internal use")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Peiyang He <peiyang_he@smail.nju.edu.cn>
Date: Tue Aug 11 17:55:51 2026 +0800
iommufd: Fix UAF in selftest IOPF reporting
commit 8c07df7cdfcf52f1ff276c588612aabc6c6b8399 upstream.
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.
Closes: https://lore.kernel.org/all/D5E3AA41600B2056+f4e15662-bd2b-43ea-91cb-518de429e72c@smail.nju.edu.cn/
Fixes: ddee19971081 ("iommufd/selftest: Add IOPF support for mock device")
Cc: stable@vger.kernel.org
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Assisted-by: Codex:gpt-5.6-terra
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Link: https://patch.msgid.link/38C8DF0A118B7176+20260811095551.2756745-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuai Xue <xueshuai@linux.alibaba.com>
Date: Sun Jul 26 15:43:31 2026 +0800
iommufd: Release current IOAS on xa_store() failure
commit 4ac2ce123824d5f885c868fa1f9f4d463141a2ba upstream.
iommufd_take_all_iova_rwsem() takes an object reference and the
iova_rwsem write lock before storing the IOAS in the temporary ioas_list
xarray.
If xa_store() fails, the current IOAS has not been inserted into
ioas_list yet. iommufd_release_all_iova_rwsem() only unwinds IOAS
objects already present in that xarray, so it cannot release the current
IOAS.
Release the current IOAS rwsem and object reference before unwinding the
previously stored entries.
Fixes: 051ae5aa73d7 ("iommufd: Lock all IOAS objects")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Thu Aug 13 00:22:34 2026 +0800
ip6_gre: fix hardware header length for NBMA tunnels
commit 505b6d296c486ef7d1274f279d4c43a172f63224 upstream.
ip6gre_tnl_link_config_route() accumulates the lower device's hardware
header length into dev->hard_header_len whenever header_ops is set. This
is incorrect for both users of header_ops.
ip6gretap and ip6erspan have a fixed Ethernet hardware header length.
For an NBMA ip6gre tunnel, ip6gre_header() creates only the GRE header,
the optional FOU or GUE header, and the outer IPv6 header. The lower
device header is headroom needed later, not part of the tunnel device's
hardware header.
Keep the lower device header in needed_headroom. Set hard_header_len to
the tunnel header length only for ARPHRD_IP6GRE devices with header_ops,
and leave the fixed Ethernet header length unchanged for tap and erspan
devices.
Fixes: 832ba596494b ("net: ip6_gre: set dev->hard_header_len when using header_ops")
Cc: stable@vger.kernel.org
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/64b46542bbe1701f07702aaa50273e2a87903db5.1786542637.git.zhilinz@nebusec.ai
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Tue Aug 11 21:31:11 2026 +0800
ip6_tunnel: use skb_cow_head() in ip6_tnl_xmit()
commit 87f21b59ddc618eff9670c174842964ad65fdade upstream.
ip6_tnl_xmit() may need to expand headroom before it can push the
outer IPv6 and optional encap headers. It currently does that with
skb_realloc_headroom(), copies skb->sk ownership, consumes the original
skb, and then continues processing with the replacement skb kept only in
its local variable.
That is safe only if the helper cannot fail afterwards. But this helper
still has post-reallocation error exits. collect_md tunnels reject
non-NONE encap after the replacement, and ip6_tnl_encap() can also fail
later. In those cases the helper returns an error to its callers while
the caller still only has the original skb pointer.
Both ip6_tnl_start_xmit() and the IPv6 GRE paths free the caller skb on
error, so they can end up freeing an skb that ip6_tnl_xmit() already
consumed.
Use skb_cow_head() instead. It provides the required headroom and
writability without privately replacing the caller-owned skb, so later
error returns cannot leave callers with a stale pointer.
The Ethernet users, ip6gretap and ip6erspan, clear IFF_TX_SKB_SHARING
and already call skb_cow_head() before entering ip6_tnl_xmit(). They do
not rely on the removed skb_shared() reallocation. This also makes the
IPv6 tunnel path consistent with ip_tunnel_xmit().
Fixes: 058214a4d1df ("ip6_tun: Add infrastructure for doing encapsulation")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Link: https://patch.msgid.link/30807a062ccc5c9c8a5ec2c5eb805ef279c50bdd.1786452593.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Thu Aug 13 00:36:38 2026 +0800
ip: orphan prefetched skbs before multicast forwarding
commit e36ce6e78fe3fc3c071a26750783b7ba081ce10d upstream.
IPv4 and IPv6 input preserve an skb->sk association installed by
bpf_sk_assign() so that local delivery can use the selected socket under
RCU. Both address families can also prefetch a socket in UDP early demux.
In both paths (BPF and UDP early demux) a reference is not guaranteed to
be held on the socket.
When a multicast packet is not locally deliverable, IPv6 hands the
original skb to ip6_mr_input(). IPv4's ip_mr_input() similarly keeps the
original skb when local delivery is not needed. Either path can put the
skb on an unresolved multicast route queue or forward it after the
receive-side RCU section ends.
After the prefetched socket is destroyed, a later skb free invokes
sock_pfree() and dereferences the stale skb->sk. Orphan the skb before
each non-local multicast forwarding path. Local delivery retains the
original skb; the existing skb_clone() calls provide multicast forwarding
with a socket-free clone.
Fixes: cf7fbe660f2d ("bpf: Add socket assign support")
Fixes: 08842c43d016 ("udp: no longer touch sk->sk_refcnt in early demux")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/0c52eb3d7532aaf8bccf37e0f7c922143c639735.1786552223.git.zhilinz@nebusec.ai
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Eric Dumazet <edumazet@google.com>
Date: Wed Mar 11 12:31:10 2026 +0000
ip_tunnel: adapt iptunnel_xmit_stats() to NETDEV_PCPU_STAT_DSTATS
[ Upstream commit 8431c602f551549f082bbfa67f3003f2d8e3e132 ]
Blamed commits forgot that vxlan/geneve use udp_tunnel[6]_xmit_skb() which
call iptunnel_xmit_stats().
iptunnel_xmit_stats() was assuming tunnels were only using
NETDEV_PCPU_STAT_TSTATS.
@syncp offset in pcpu_sw_netstats and pcpu_dstats is different.
32bit kernels would either have corruptions or freezes if the syncp
sequence was overwritten.
This patch also moves pcpu_stat_type closer to dev->{t,d}stats to avoid
a potential cache line miss since iptunnel_xmit_stats() needs to read it.
Fixes: 6fa6de302246 ("geneve: Handle stats using NETDEV_PCPU_STAT_DSTATS.")
Fixes: be226352e8dc ("vxlan: Handle stats using NETDEV_PCPU_STAT_DSTATS.")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/20260311123110.1471930-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Anton Danilov <littlesmilingcloud@gmail.com>
Date: Wed Aug 19 13:43:39 2026 +0300
ipip: fix skb leak in collect_md mode when metadata_dst allocation fails
commit 6776efe4a52f289a3fc18f8adf19b035a7d8e1bb upstream.
In collect_md mode ipip_tunnel_rcv() returns 0 without freeing the skb
when ip_tun_rx_dst() fails to allocate the metadata_dst. ipip_rcv() and
mplsip_rcv() are registered as xfrm_tunnel handlers, so tunnel4_rcv()
and tunnelmpls4_rcv() read the zero return as "the packet has been
consumed" and do not free it either. The skb is leaked.
The other tunnel drivers all dispose of the packet at this point:
ip6_tunnel.c jumps to its drop label, ip_gre.c and ip6_gre.c return
PACKET_REJECT, which makes gre_rcv() free the skb. Only ipip returns 0.
Jump to the existing drop label instead. It frees the skb and still
returns 0, so the packet keeps being reported as consumed, which is what
we want here: the outer header has already been pulled, and neither the
remaining handlers nor an ICMP unreachable have any use for it.
Triggering this needs an ipip or mplsip tunnel in collect_md mode and an
atomic allocation failure, which is why it has gone unnoticed.
Fixes: cfc7381b3002 ("ip_tunnel: add collect_md mode to IPIP tunnel")
Cc: stable@vger.kernel.org
Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Link: https://patch.msgid.link/20260819104338.432631-2-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yifei Gao <gyf161023@gmail.com>
Date: Tue Aug 25 23:46:29 2026 +0000
ipmi: Fix use-after-free of cmd_rcvr in _ipmi_destroy_user()
commit 05ec76cfbce653e07cec19b9b8b20e33449d5d87 upstream.
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.
Fixes: 9e91f8a6c868 ("ipmi:msghandler: Remove srcu for the ipmi_interfaces list")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Message-ID: <20260825234630.1196170-1-gyf161023@gmail.com>
Signed-off-by: Corey Minyard <corey@minyard.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>
Date: Wed Jun 24 19:53:53 2026 +0200
ipmi: ipmb: validate write message length
commit 53637506884dbd5c91a89b1a3547d99d80f8ed2c upstream.
ipmb_write() read message fields before validating the length byte.
A zero or short write can read uninitialized stack bytes.
A length smaller than the SMBus header underflows the block write length.
Require a non-empty buffer and the minimum IPMB request length.
Also require the length byte plus payload before parsing the message.
Fixes: 51bd6f291583 ("Add support for IPMB driver")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Message-ID: <20260624175353.8592-1-alhouseenyousef@gmail.com>
Signed-off-by: Corey Minyard <corey@minyard.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yuho Choi <dbgh9129@gmail.com>
Date: Sun Aug 2 21:55:50 2026 -0400
ipmi: Remove all sysfs files on registration failure
commit b6c46ab0bdee90c238e96ea4a74972118c97900d upstream.
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.
Fixes: 627118470fcc ("ipmi: Add a maintenance mode sysfs file")
Cc: stable@vger.kernel.org # 6.18
Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
Message-ID: <20260803015550.618808-1-dbgh9129@gmail.com>
Signed-off-by: Corey Minyard <corey@minyard.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Seiji Nishikawa <snishika@redhat.com>
Date: Wed Jul 1 02:43:48 2026 +0900
ipmi: si: Fix NULL pointer dereference after failed registration
commit 6d920a75df9a83ab096b3cde7a643b656e4fdfeb upstream.
try_smi_init() allocates new_smi->si_sm and later calls
ipmi_register_smi_mod(), which maps to ipmi_add_smi().
During ipmi_add_smi(), the upper IPMI message handler obtains the
initial BMC device information through __bmc_get_device_id(). This can
fail if the BMC does not return a successful response to the Get Device
ID command.
When the BMC returns a nonzero completion code, the device-id helper
retries the command and eventually returns -EIO if the device ID still
cannot be fetched.
On this failure path, ipmi_add_smi() logs "Unable to get the device id"
and goes to out_err_started, where it invokes the lower driver's
shutdown callback. try_smi_init() then logs the returned registration
failure:
ipmi_si IPI0001:00: IPMI message handler: Unable to get the device id: -5
ipmi_si IPI0001:00: Unable to register device: error -5
For ipmi_si, the shutdown callback is shutdown_smi(), which cleans up
the SI state machine data, frees smi_info->si_sm, and sets
smi_info->si_sm and smi_info->intf to NULL.
However, intf->in_shutdown is not set on this failed-registration
rollback path. Therefore, the asynchronous redo_bmc_reg work item can
still retry BMC device-id probing after the lower driver has already
cleared its SI state machine data. In the observed case, that retry path
reached start_next_msg(), which passed the NULL smi_info->si_sm pointer
to the selected KCS state machine handler:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
Workqueue: events redo_bmc_reg [ipmi_msghandler]
RIP: start_kcs_transaction+0x2c/0x190 [ipmi_si]
Call Trace:
start_next_msg+0x50/0x80 [ipmi_si]
check_start_timer_thread.part.9+0x3b/0x50 [ipmi_si]
sender+0x69/0x80 [ipmi_si]
i_ipmi_request+0x2ac/0x9d0 [ipmi_msghandler]
__get_device_id.isra.29+0xaa/0x180 [ipmi_msghandler]
__bmc_get_device_id+0xef/0x950 [ipmi_msghandler]
redo_bmc_reg+0x52/0x60 [ipmi_msghandler]
process_one_work+0x1a7/0x360
Set intf->in_shutdown on the out_err_started path before invoking the
lower driver's shutdown callback. This prevents later redo_bmc_reg
retries from using an interface whose lower driver state has been
cleaned up, and applies the same shutdown state to other IPMI interfaces
as well.
Fixes: 2512e40e48d2 ("ipmi: Rework SMI registration failure")
Cc: stable@vger.kernel.org
Signed-off-by: Seiji Nishikawa <snishika@redhat.com>
Message-ID: <20260630174348.1483814-1-snishika@redhat.com>
Signed-off-by: Corey Minyard <corey@minyard.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Corey Minyard <corey@minyard.net>
Date: Tue Aug 18 12:49:52 2026 -0500
ipmi:msghandler: Cancel work cleanly on an error
commit ae84a2536577057e97f23f75a202e26d0e86cf01 upstream.
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.
Reported-by: Nilay Shroff <nilay@linux.ibm.com>
Closes: https://sourceforge.net/p/openipmi/mailman/message/59375605/
Fixes: 62cd145453d5 ("ipmi:msghandler: Handle error returns from the SMI sender")
Cc: stable@vger.kernel.org # 7.0
Tested-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Corey Minyard <corey@minyard.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Andrea Mayer <andrea.mayer@uniroma2.it>
Date: Mon Aug 17 15:26:44 2026 +0200
ipv6: rpl: fix NULL dereference of idev in ipv6_rpl_srh_rcv()
commit f826df95332c07380206dbd54178b6eefb311aba upstream.
ipv6_rpl_srh_rcv() dereferences idev from __in6_dev_get() without a NULL
check when reading idev->cnf.rpl_seg_enabled.
When the device's MTU drops below IPV6_MIN_MTU, addrconf_ifdown() clears
dev->ip6_ptr through RCU_INIT_POINTER(). A packet that passed the idev
check in ip6_rcv_core() can then reach ipv6_rpl_srh_rcv() with
dev->ip6_ptr already NULL.
Reproduced by flooding the receiving interface with ping6 traffic while
flapping its MTU between 1500 and 1200:
BUG: KASAN: null-ptr-deref in ipv6_rpl_srh_rcv+0xb3/0x1070
Read of size 4 at addr 00000000000006b4 by task ping6/394
CPU: 2 UID: 0 PID: 394 Comm: ping6 Not tainted 7.2.0-rc7-micro-vm-dev-00095-g24ef02f934ee #240 PREEMPT(full)
Call Trace:
<IRQ>
kasan_report+0xc6/0x100
ipv6_rpl_srh_rcv+0xb3/0x1070
ip6_protocol_deliver_rcu+0x759/0x9a0
ip6_input_finish+0xa8/0x1b0
ip6_input+0xe1/0x490
ipv6_rcv+0x33d/0x460
__netif_receive_skb_one_core+0xd6/0x130
process_backlog+0x2cc/0xa00
__napi_poll.constprop.0+0x56/0x270
net_rx_action+0x327/0x730
handle_softirqs+0x11e/0x630
do_softirq+0xb3/0xf0
</IRQ>
Both ipv6_rpl_srh_rcv() and ipv6_srh_rcv() are called only from
ipv6_rthdr_rcv(), which already has an idev lookup.
Fix the NULL dereference on the RPL path by checking idev in
ipv6_rthdr_rcv(), before it calls either function. The callees take idev as
an argument and no longer call __in6_dev_get(), so the packet is now
dropped in one place, with SKB_DROP_REASON_IPV6DISABLED on both paths.
Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
Cc: stable@vger.kernel.org
Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Tested-by: Xiang Mei <xmei5@asu.edu>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260817132644.2223-1-andrea.mayer@uniroma2.it
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yuyang Huang <sigefriedhyy@gmail.com>
Date: Sat Aug 15 17:46:51 2026 +0900
ipv6: use RCU iterator to dump route exceptions
commit 47cdab0d51aaa9bd85f8e4904585bd5bd4df4488 upstream.
rt6_nh_dump_exceptions() uses hlist_for_each_entry() to iterate over
RCU-protected exception lists. The caller holds rcu_read_lock(), but does
not hold rt6_exception_lock, so rt6_insert_exception() can concurrently
add an entry with hlist_add_head_rcu().
KCSAN reports this race (irrelevant details omitted):
==================================================================
BUG: KCSAN: data-race in rt6_insert_exception / rt6_nh_dump_exceptions
write (marked) to 0xffff8a7c44c59620 of 8 bytes by interrupt on cpu 5:
rt6_insert_exception+0x3bb/0x760
__ip6_rt_update_pmtu+0x4fe/0x750
ip6_sk_update_pmtu+0x19a/0x3b0
udpv6_err+0x3ff/0x800
icmpv6_notify+0x1e1/0x440
icmpv6_rcv+0x8c0/0xab0
ip6_protocol_deliver_rcu+0x616/0x840
ip6_input_finish+0xb9/0x160
...
entry_SYSCALL_64_after_hwframe+0x77/0x7f
read to 0xffff8a7c44c59620 of 8 bytes by task 549 on cpu 14:
rt6_nh_dump_exceptions+0xb3/0x260
rt6_dump_route+0x53e/0x5f0
fib6_dump_node+0x6d/0xf0
fib6_walk_continue+0x290/0x2d0
fib6_dump_table+0x28d/0x360
inet6_dump_fib+0x37d/0x620
rtnl_dumpit+0x7b/0xd0
netlink_dump+0x3ae/0x7e0
...
entry_SYSCALL_64_after_hwframe+0x77/0x7f
4 locks held by dumper/549:
...
#1: (rcu_read_lock){....}-{1:3}, at: inet6_dump_fib+0x88/0x620
#2: (&tb->tb6_lock){+.-.}-{3:3}, at: fib6_dump_table+0x1e9/0x360
#3: (rcu_read_lock){....}-{1:3}, at: rt6_dump_route+0x483/0x5f0
value changed: 0xffff8a7c44e05700 -> 0xffff8a7c45d60100
Reported by Kernel Concurrency Sanitizer on:
CPU: 14 UID: 0 PID: 549 Comm: dumper Not tainted
7.2.0-rc7-virtme #38 PREEMPT(lazy)
...
Use hlist_for_each_entry_rcu() to safely iterate over the exception list.
Fixes: 1e47b4837f3b ("ipv6: Dump route exceptions if requested")
Cc: stable@vger.kernel.org
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260815084651.69477-1-sigefriedhyy@gmail.com
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Max Kellermann <max.kellermann@ionos.com>
Date: Mon Jul 13 12:22:29 2026 +0200
jbd2: bound shrinker scans by examined checkpoint buffers
commit 15cb16496446b94e67f7abcb049b8e2c75cd3d02 upstream.
The jbd2 shrinker currently accounts only checkpoint buffers that it
successfully releases against nr_to_scan. Busy buffers therefore do not
consume the scan budget.
If a checkpoint transaction contains mostly busy buffers, the shrinker
can scan its entire checkpoint list while holding journal->j_list_lock.
Large checkpoint lists can result in excessive lock hold times and leave
other CPUs spinning on j_list_lock, causing soft lockups or RCU stalls.
Pass nr_to_scan into journal_shrink_one_cp_list() and decrement it for
every buffer examined, including busy buffers. Pass NULL from checkpoint
cleanup paths so their existing full-list behavior is preserved.
This restores the scan-budget semantics that existed before
journal_shrink_one_cp_list() was changed to always scan a complete
checkpoint list.
Fixes: b98dba273a0e ("jbd2: remove journal_clean_one_cp_list()")
Cc: stable@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260713102229.1598812-3-max.kellermann@ionos.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Max Kellermann <max.kellermann@ionos.com>
Date: Mon Jul 13 12:22:28 2026 +0200
jbd2: check need_resched() when skipping busy checkpoint buffers
commit f213e12ff5c9590b1034ae8da0e6d09665c772d0 upstream.
journal_shrink_one_cp_list() skips busy checkpoint buffers when called
with JBD2_SHRINK_BUSY_SKIP. The continue statement on this path also
skips the need_resched() check at the end of the loop body.
Consequently, when a checkpoint list contains mostly busy buffers, the
shrinker can walk the entire list while holding journal->j_list_lock,
even when a reschedule has been requested. Large checkpoint lists under
memory pressure can therefore cause long lock hold times and leave other
CPUs spinning on j_list_lock, resulting in soft lockups or RCU stalls.
Route the busy-buffer path through the need_resched() check so that the
shrinker can release j_list_lock and reschedule promptly, restoring
parity with the clean-buffer path, which already checks need_resched().
This does not change which checkpoint buffers are eligible for removal.
Fixes: b98dba273a0e ("jbd2: remove journal_clean_one_cp_list()")
Cc: stable@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260713102229.1598812-2-max.kellermann@ionos.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hui Su <sh_def@163.com>
Date: Sat Aug 8 11:14:59 2026 +0800
kasan: fix cache shrink race with CPU hotplug
commit 8790303cbaac52a11dfed4aab261f8ea60682525 upstream.
kasan_quarantine_remove_cache() first invokes per_cpu_remove_cache() on
all online CPUs. Each callback moves objects belonging to the cache from
cpu_quarantine to the CPU's shrink_qlist, where they can later be freed
from task context.
kmem_cache_destroy() invokes the quarantine removal path while holding
cpus_read_lock(), but kmem_cache_shrink() does not. The latter can
therefore race with CPU offlining as follows:
kmem_cache_shrink() CPU hotplug
------------------- -----------
on_each_cpu()
CPU1 moves objects to
CPU1's shrink_qlist
on_each_cpu() returns
CPU1 goes offline
kasan_cpu_offline()
drains cpu_quarantine
leaves shrink_qlist untouched
for_each_online_cpu()
skips CPU1
The objects left on CPU1's shrink_qlist are not returned to the slab
allocator. This may prevent kmem_cache_shrink() from releasing slabs that
would otherwise become empty. If CPU1 remains offline, a later
kmem_cache_destroy() also skips the list and can report that the cache
still contains objects.
An intermittent occurrence was observed with a virtio-9p filesystem. The
mount and umount commands both returned 0, but the kernel logged the
following during the userspace-triggered teardown:
[ 2994.380134][ T111] BUG 9p-fcall-cache-1 (Tainted: G B ): Objects remaining on __kmem_cache_shutdown()
[ 2994.381140][ T111] Object 0xff11000004361118 @offset=4376
[ 2994.381607][ T111] Allocated in p9_fcall_init+0x201/0x400 age=19564 cpu=1 pid=104
[ 2994.382591][ T111] p9_fcall_init+0x201/0x400
[ 2994.382810][ T111] p9_tag_alloc+0x12f/0x700
[ 2994.382982][ T111] p9_client_prepare_req+0x102/0x3e0
[ 2994.383165][ T111] p9_client_rpc+0x1ab/0xa50
[ 2994.383334][ T111] p9_client_getattr_dotl+0xb0/0x1a0
[ 2994.383515][ T111] v9fs_vfs_getattr_dotl+0x115/0x360
[ 2994.383719][ T111] vfs_getattr_nosec+0x22c/0x3a0
[ 2994.383910][ T111] vfs_statx+0xd7/0x170
[ 2994.384062][ T111] vfs_fstatat+0x45/0x80
[ 2994.384215][ T111] __do_sys_newfstatat+0x84/0xe0
[ 2994.384386][ T111] do_syscall_64+0x115/0x6a0
[ 2994.384566][ T111] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2994.399720][ T111] WARNING: mm/slub.c:1244 at __kmem_cache_shutdown+0x363/0x500, CPU#0: busybox/111
[ 2994.405655][ T111] Call Trace:
[ 2994.406325][ T111] kmem_cache_destroy+0x73/0x1b0
[ 2994.406630][ T111] p9_client_destroy+0x271/0x3c0
[ 2994.407210][ T111] v9fs_session_close+0x3c/0x260
[ 2994.407409][ T111] v9fs_kill_super+0x48/0x90
[ 2994.407584][ T111] deactivate_locked_super+0xa3/0x160
[ 2994.407778][ T111] cleanup_mnt+0x1dd/0x3e0
Thus, a successful umount left objects in the 9p fcall cache and prevented
the cache from being destroyed cleanly.
Per-CPU shrink_qlist storage exists for every possible CPU, and each list
is protected by its own raw spinlock. Iterate over possible CPUs so that
a list populated before its CPU went offline is drained as well.
for_each_possible_cpu() can do more work than for_each_online_cpu(), but
this change only affects CONFIG_KASAN_GENERIC kernels. The extra work is
limited to cache shrink and cache destruction paths and does not affect
the normal allocation/free fast path. It adds one raw-spinlock-protected
scan of each possible CPU's shrink list. These lists are normally empty;
a non-empty list is traversed to remove objects belonging to the cache
being shrunk or destroyed.
Link: https://lore.kernel.org/20260808031459.3032812-1-sh_def@163.com
Fixes: 07d067e4f2ce ("kasan: fix sleeping function called from invalid context on RT kernel")
Signed-off-by: Hui Su <sh_def@163.com>
Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: "Zhang, Qiang1" <qiang1.zhang@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chengfeng Ye <nicoyip.dev@gmail.com>
Date: Tue Aug 11 02:56:03 2026 +0300
KEYS: trusted: Fix TPM teardown ordering
commit 5e2d672280d97d83de43031d93761b12dadd7b8a upstream.
trusted_tpm_exit() drops the TPM chip reference and frees the digest
array before unregistering the trusted key type. key_type_lookup()
holds key_types_sem for reading until the key operation finishes, while
unregister_key_type() takes it for writing. It therefore provides the
synchronization point that must precede backend teardown.
The current order permits this interleaving:
CPU 0 CPU 1
trusted_tpm_exit() key_type_lookup("trusted")
put_device(&chip->dev) trusted_tpm_seal()
kfree(digests) pcrlock()
unregister_key_type() tpm_pcr_extend(..., digests)
CPU 1 can consequently dereference the freed digest array. The chip can
also be released before callbacks stop using it.
KASAN reported:
BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200
Read of size 2 at addr ffff88810872d000 by task poc/89
Call Trace:
tpm_pcr_extend+0x1f0/0x200
pcrlock+0x42/0x70 [trusted]
trusted_tpm_seal+0x1b6/0x570 [trusted]
trusted_instantiate+0x293/0x340 [trusted]
__key_instantiate_and_link+0xb2/0x2b0
__key_create_or_update+0x61e/0xb50
__do_sys_add_key+0x1b8/0x310
Allocated by task 88:
__kmalloc_noprof+0x1a7/0x490
do_one_initcall+0xa1/0x390
do_init_module+0x2df/0x840
Freed by task 90:
kfree+0x131/0x3c0
trusted_tpm_exit+0x59/0xa0 [trusted]
__do_sys_delete_module+0x346/0x510
Move unregister_key_type() before releasing either resource. This stops
new lookups and waits for in-flight key operations to finish before the
backend state is destroyed.
Fixes: 0b6cf6b97b7e ("tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://lore.kernel.org/r/20260731140925.2973492-1-nicoyip.dev@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Günther Noack <gnoack@google.com>
Date: Thu Aug 13 11:31:53 2026 +0200
landlock: Require LANDLOCK_ACCESS_FS_MAKE_REG for whiteout creation
commit 672fa082d48b21e1fb62cdb184fee41513e53421 upstream.
Whiteout objects are used in the upper layer of an OverlayFS to
indicate that the file with this name does not exist in the unified
view, even if it is present in one of the lower layer file systems.
For the userspace implementations of OverlayFS (fuse-overlayfs),
whiteout objects can be created from userspace as well:
* mknod(2) with S_IFCHR and makedev(0, 0)
* renameat2(2) with RENAME_WHITEOUT,
creating the whiteout in the old place of the moved file.
This commit guards whiteout creation in both of these cases with
LANDLOCK_ACCESS_FS_MAKE_REG. Whiteout objects are *not* considered
character devices and are not bound to a driver.
LANDLOCK_ACCESS_FS_MAKE_REG describes the same permission class as a
whiteout object: creating one is the only S_IFCHR creation that the VFS
exempts from CAP_MKNOD, so it is as unprivileged as creating a regular
file, while LANDLOCK_ACCESS_FS_MAKE_CHAR and
LANDLOCK_ACCESS_FS_MAKE_BLOCK keep meaning the creation of devices that
expose a kernel interface [1].
For the mknod(2) case, introduce a Landlock erratum. The creation of
whiteout objects through mknod(2) was previously guarded using
LANDLOCK_ACCESS_FS_MAKE_CHAR, and it is now guarded using
LANDLOCK_ACCESS_FS_MAKE_REG.
For the renameat2(2) case, fix a bug: Before this commit, renameat2(2)
with RENAME_WHITEOUT would create a directory entry even when all
LANDLOCK_ACCESS_FS_MAKE_* rights were denied.
This does not affect normal renames within layered OverlayFS mounts:
When doing a regular rename() on a mounted fuse-overlayfs, it is the
fuse-overlayfs daemon that exercises renameat2() with RENAME_WHITEOUT,
and only the Landlock domain of that daemon is checked there.
Suggested-by: Christian Brauner <brauner@kernel.org>
Suggested-by: Mickaël Salaün <mic@digikod.net>
Cc: stable@vger.kernel.org
Fixes: cb2c7d1a1776 ("landlock: Support filesystem access-control")
Depends-on: 49c9e09d9610 ("landlock: Fix handling of disconnected directories")
Depends-on: fe72ce6710cb ("landlock: Add errata documentation section")
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://patch.msgid.link/20260720.chow9ohYie5b@digikod.net [1]
Link: https://patch.msgid.link/20260813093157.1436894-3-gnoack@google.com
[mic: Record why LANDLOCK_ACCESS_FS_MAKE_REG is the matching right, and
add link(2) to the user doc]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vincent Mailhol <mailhol@kernel.org>
Date: Thu Jul 23 21:40:31 2026 +0200
lib/ucs2_string.c: fix out-of-bounds read in ucs2_strnlen()
commit cec0d03fe785380540dc1b4d07c80f67ae2ffc78 upstream.
Patch series "lib/ucs2_string.c: fix out-of-bounds read in
ucs2_strnlen()", v2.
This series fixes an off-by-one out-of-bounds read in ucs2_strnlen().
The first patch is the real fix, the second patch comes as a bonus and
fixes the code indentation.
This patch (of 2):
ucs2_strnlen() checks the current character before checking whether the
caller-provided maximum length has been reached. If the input is not
NUL-terminated within that bound, the loop can read one ucs2_char_t past
the limit.
Test the length before dereferencing to prevent an off-by-one
out-of-bounds read.
Link: https://lore.kernel.org/20260723-fix-ucs2_strnlen-v2-0-9ea94e32a358@kernel.org
Link: https://lore.kernel.org/20260723-fix-ucs2_strnlen-v2-1-9ea94e32a358@kernel.org
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Sat Aug 15 21:46:37 2026 +0000
libceph: reject buckets with mismatched CRUSH ids
commit 3cde4a8302301679937474a5f7a851394cc1bd11 upstream.
crush_decode() stores bucket data by array slot, and the mapper later
derives the per-bucket workspace index from the decoded bucket id. A
malformed map can therefore make one bucket reuse another bucket's
workspace by encoding an id different from -1 - slot.
For uniform buckets, the second replica selection expands the source
bucket's permutation into that aliased workspace buffer. If the source
bucket is larger than the aliased bucket, the write runs past the smaller
permutation array and can escape the kvmalloc'd CRUSH workspace. KASAN
reports a slab OOB write of 4 bytes in bucket_perm_choose().
Reject buckets whose encoded id does not match their array slot. Valid
CRUSH maps already use the canonical negative id corresponding to the
bucket slot, so this restores the invariant expected by
work->work[-1 - in->id] without changing valid map behavior.
Cc: stable@vger.kernel.org
Fixes: 66a0e2d579db ("crush: remove mutable part of CRUSH map")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Tue Jul 14 07:51:39 2026 -0400
libceph: validate OSD extent maps before cursor advance
commit 9ec08b7499a62c6d4afa93d36ab47a43fcad57d1 upstream.
net/ceph/osd_client.c:osd_sparse_read() validates that the sparse-read
data length matches the summed extent lengths, but it does not validate
that each OSD-supplied extent is monotonic and lies inside the original
request range. A malformed authenticated OSD reply can advertise a
far-forward nonzero extent offset with a matching data length and make
the client advance the message-data cursor beyond the request buffer.
This reaches the BUG_ON(!*length) assertion in ceph_msg_data_next() from
the client receive path.
Impact: A malicious or compromised authenticated Ceph OSD peer can crash
a kernel Ceph client via a malformed sparse-read reply.
Reject sparse extent maps that overflow, move backwards, overlap, or
extend outside the original sparse-read request before advancing the
cursor.
[ idryomov: perform sparse_extent_map_valid() check a bit earlier,
in CEPH_SPARSE_READ_DATA_LEN instead of CEPH_SPARSE_READ_DATA_PRE
state ]
Cc: stable@vger.kernel.org
Fixes: f628d7999727 ("libceph: add sparse read support to OSD client")
Assisted-by: Codex:gpt-5-5-xhigh
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Wed Jun 24 01:03:45 2026 -0500
libnvdimm/labels: Prevent integer overflow in __nd_label_validate()
commit 037770686126155eafc44501312989e2837b9659 upstream.
The on-media namespace index field nslot is a u32 read from the DIMM
label storage area. __nd_label_validate() bounds it against the config
area size, but sizeof_namespace_label() returns unsigned, so the product
nslot * label_size is evaluated in 32-bit and wraps modulo 2^32 before
the comparison. A crafted nslot passes the bound and is then used as the
loop trip count in nd_label_data_init(), whose memset() walks off the end
of the config_size buffer: an out-of-bounds write.
The field is not trusted -- it comes from the medium, or from userspace
via ND_CMD_SET_CONFIG_DATA. Evaluate the product in 64-bit so the bound
check is exact; conforming labels are unaffected.
The check was safe when introduced by commit 4a826c83db4e ("libnvdimm:
namespace indices: read and validate"): it multiplied by sizeof(struct
nd_namespace_label), a size_t, so on a 64-bit build the product did not
wrap. Commit 564e871aa66f ("libnvdimm, label: add v1.2 nvdimm label
definitions") narrowed it to 32 bits when the label size became a runtime
value read via sizeof_namespace_label().
Fixes: 564e871aa66f ("libnvdimm, label: add v1.2 nvdimm label definitions")
Cc: stable@vger.kernel.org
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260624-b4-disp-d8279485-v3-1-cdb6cab28b41@proton.me
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Mon Sep 7 17:23:00 2026 +0200
Linux 6.18.50
Link: https://lore.kernel.org/r/20260904045747.813364717@linuxfoundation.org
Tested-by: Brett A C Sheffield <bacs@librecast.net>
Tested-by: Wentao Guan <guanwentao@uniontech.com>
Tested-by: Shuah Khan <skhan@linuxfoundation.org>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20260905115635.269562615@linuxfoundation.org
Tested-by: Brett A C Sheffield <bacs@librecast.net>
Tested-by: Ron Economos <re@w6rz.net>
Tested-by: Peter Schneider <pschneider1968@googlemail.com>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Date: Fri Jul 17 13:28:09 2026 -0400
lockd: fix NULL dereference on lockowner allocation failure
commit 4c7fc129db061c7daab841c4f3c342d894832362 upstream.
nlmclnt_locks_init_private() installs NLM file lock operations even when
nlmclnt_find_lockowner() fails to allocate a lockowner. nlmclnt_proc()
then returns -ENOMEM, but the VFS still tears down the partially
initialized file_lock and calls locks_release_private().
That invokes nlmclnt_locks_release_private(), which dereferences
fl->fl_u.nfs_fl.owner and crashes because the owner was never installed.
Clear fl_ops before attempting to initialize the NLM private state, and
install the NLM lock operations only after a lockowner has been allocated
successfully.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Sun May 24 07:55:27 2026 -0400
lockd: pin next file across nlm_inspect_file lock-drop
commit 526c49cff3f72c3ec74752016380c7567040581b upstream.
nlm_traverse_files() pins the current file with f_count++ across
a mutex_unlock for nlm_inspect_file(), but nothing pins the saved
next pointer. A concurrent nlm_release_file() can kfree the next
file during the unlock window, and the iterator dereferences freed
memory on the next loop step.
Pin both current and next before the lock-drop. Advance by
swapping the pinned cursors at the end of each iteration so next
is always held alive across the unlock.
Always call nlm_file_release() after dropping the iteration pin,
regardless of whether the file matched the predicate. Use
nlm_file_inuse(), which does a live walk of the inode lock list,
rather than the cached f_locks field, so skipped files that never
ran nlm_inspect_file() are evaluated correctly.
Because every file in a hash bucket is now pinned and released,
files skipped by the is_failover_file predicate that have no
locks, blocks, shares, or external references are deleted during
traversal. The old code never evaluated skipped files for
cleanup. The new behavior is intentional: such files are stale
and should not persist in the table.
Fixes: 01df9c5e918a ("LOCKD: Fix a deadlock in nlm_traverse_files()")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260524115527.1734251-1-michael.bommarito@gmail.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Anup Vishwakarma <anup.vishwakarma@oss.qualcomm.com>
Date: Wed Aug 5 14:34:07 2026 +0530
mailbox: qcom-ipcc: fix duplicate channel allocation across holes
commit 66c7bcad72430a02c860521031350b84b31ad9a8 upstream.
The IPCC of_xlate() both scans for a free mailbox channel and checks
for duplicate references to the same underlying IPCC channel. When a
channel has been shutdown it might have left a hole in the channel
list, which would terminate the search without considering duplicates
later in the list.
Continue the traversal of the channel list to detect and reject
duplicates, while keeping track of the first free channel.
Fixes: d6fbfdbc1274 ("mailbox: qcom-ipcc: Fix IPCC mbox channel exhaustion")
Cc: stable@vger.kernel.org
Signed-off-by: Anup Vishwakarma <anup.vishwakarma@oss.qualcomm.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yunye Zhao <yunye.zhao@linux.alibaba.com>
Date: Thu Jul 23 21:55:33 2026 +0800
md/raid10: fix still_degraded being inverted in raid10_sync_request()
commit 47f1441b281decde6954a2fa82b4131637d685ac upstream.
Commit fe6a19d40ceb ("md/md-bitmap: merge md_bitmap_start_sync() into
bitmap_operations") converted still_degraded from int to bool, but
inverted the assignment in the loop that checks whether the array will
still be degraded after the current device is recovered:
"still_degraded = 1" became "still_degraded = false".
As a result, recovering a device while another mirror is still missing
calls md_bitmap_start_sync() with degraded == false, which clears bitmap
bits that the still-missing device needs. When that device is re-added,
its bitmap-based recovery finds the bits already cleared and skips every
region written while the array was degraded, so it is marked In_sync
while holding stale data: silent corruption.
Reproducer (raid10 near=2, 4 disks, internal bitmap):
- fail and remove one disk of each mirror pair
- write to the degraded array
- re-add both disks and let recovery finish
- "check" reports mismatch_cnt=262272 after 256 MiB of degraded
writes and file contents differ; the second disk's "recovery"
completes in milliseconds because everything is skipped
The same conversion in raid1 got it right (still_degraded = true).
Restore the correct value.
Fixes: fe6a19d40ceb ("md/md-bitmap: merge md_bitmap_start_sync() into bitmap_operations")
Cc: stable@vger.kernel.org
Signed-off-by: Yunye Zhao <yunye.zhao@linux.alibaba.com>
Reviewed-by: Mykola Marzhan <mykola@meshstor.io>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Yu Kuai <yukuai@fygo.io>
Link: https://patch.msgid.link/20260723135535.101995-2-yunye.zhao@linux.alibaba.com
Signed-off-by: Yu Kuai <yukuai@fygo.io>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Coly Li <colyli@fygo.io>
Date: Mon Jul 20 19:14:00 2026 +0800
md: do overflow check for sb->bblog_shift in super_1_load()
commit 35d522bd32462afcf1981dab6da8a9256c26c1e0 upstream.
In super_1_load(), sb->bblog_shift is an __u8 type value loaded from on-
disk superblock. It is used for badblocks API badblocks_set() by the
following sequence,
1930 rdev->badblocks.shift = sb->bblog_shift;
1931 for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
1932 u64 bb = le64_to_cpu(*bbp);
1933 int count = bb & (0x3ff);
1934 u64 sector = bb >> 10;
1935 sector <<= sb->bblog_shift;
1936 count <<= sb->bblog_shift;
1937 if (bb + 1 == 0)
1938 break;
1939 if (!badblocks_set(&rdev->badblocks, sector, count, 1))
1940 return -EINVAL;
1941 }
bb->bblog_shit is in range of 0-255, variable sector is 64bit width, for
an invalid bb->bblog_shit, it is possible to make sector be overflowed
by the following calculation,
1935 sector <<= sb->bblog_shift;
Then in turn when call badblocks_set() at line 1939 with the invalid
rdev->badblocks.shift set at line 1930, may result an overflow inside
_badblocks_clear() in block/badblocks.c.
Although there are many places to call badblocks APIs, the non-zero
shift value is only used in super_1_load(), other places always use 0 as
the shift value. Therefore it is unnecessary to do a general shift value
overflow check inside badblock API, and just check here as the caller.
This may avoid unnecessary check, make the badblocks API code more simple
and elegant.
Fixes: 2699b67223ac ("md: load/store badblock list from v1.x metadata")
Fixes: 1726c7746783 ("badblocks: improve badblocks_set() for multiple ranges handling")
Cc: stable@vger.kernel.org
Cc: Ramesh Adhikari <adhikari.resume@gmail.com>
Signed-off-by: Coly Li <colyli@fygo.io>
Reviewed-by: Yu Kuai <yukuai@fygo.io>
Link: https://patch.msgid.link/20260720111400.2120834-1-colyli@fygo.io
Signed-off-by: Yu Kuai <yukuai@fygo.io>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Weigang He <geoffreyhe2@gmail.com>
Date: Thu Jun 11 23:22:48 2026 +1000
media: cec: stm32: prevent out-of-bounds write on RX overflow
commit fb9dda38d4b9e90db07ed9a0ee2d35bf85494035 upstream.
stm32_rx_done() appends each received CEC byte to rx_msg.msg[] using
rx_msg.len as the write index, incrementing it on every RXBR
(receive-byte-ready) interrupt without checking it against the buffer
size:
cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
rx_msg.msg[] is a fixed CEC_MAX_MSG_SIZE (16) byte array in struct
cec_msg, and rx_msg.len is only reset on RXACKE/RXOVR or after a
completed message (RXEND). The number of bytes received before RXEND is
decided by the remote CEC device (it sets EOM), not by the driver. A
peer that keeps sending bytes without ending the message drives RXBR
repeatedly, pushing rx_msg.len past 16 and writing peer-controlled bytes
out of bounds into the surrounding memory. This is reachable in normal
operation once the driver has probed and receiving is enabled, from the
IRQ thread, without any local privilege.
The length check in the CEC core runs on the consumer side, after the
byte has been stored, so it does not prevent the overflow. Bound the
index in the driver before the store, as the other platform CEC drivers
already do (e.g. tegra_cec), dropping the excess bytes of an overlong
frame.
Found by static analysis tool CodeQL.
Fixes: d69ae57453c8 ("[media] cec: add STM32 cec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Cong Nguyen <congnt264@gmail.com>
Date: Thu Jul 30 17:37:54 2026 +0700
media: staging/ipu7: fix async notifier UAF on probe error path
commit d7f48aa7d60c65d3e6d5312c27f17d5525a245fb upstream.
isys_register_devices() registers the V4L2 async notifier via
isys_notifier_init(). If a subsequent probe step such as
isys_fw_log_init() fails, isys_probe() jumps to the out_cleanup label
which only calls isys_unregister_devices(). That helper tears down the
video devices, subdevices, V4L2 device and media device, but never
unregisters or cleans up the async notifier.
As a result the notifier stays chained in the global notifier_list while
the enclosing struct ipu7_isys is freed by devres, leading to list
corruption and a use-after-free the next time the list is walked.
The remove path already does the right thing by calling
isys_notifier_cleanup() before isys_unregister_devices(). Mirror that on
the probe error path so the notifier is unregistered and cleaned up
before the device is torn down.
Fixes: a516d36bdc3d ("media: staging/ipu7: add IPU7 input system device driver")
Cc: stable@vger.kernel.org
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Junrui Luo <moonafterrain@outlook.com>
Date: Tue Jul 14 15:24:37 2026 +0800
media: vicodec: fix out-of-bounds write in FWHT encoder
commit cf4500ebf6fb57bf4ab83c3dd349a40257dbe2a9 upstream.
vidioc_s_fmt_vid_out() sizes the encoder CAPTURE buffer from the
compressed descriptor pixfmt_fwht, whose sizeimage_mult is 3:
coded_w * coded_h * 3 + sizeof(struct fwht_cframe_hdr). fwht_encode_frame()
encodes one plane per component, and an incompressible plane takes the
FWHT_FRAME_UNENCODED path in encode_plane(), copying the plane verbatim.
For a 4-component pixel format all four planes are full resolution
(width_div == height_div == 1), so a frame that forces every plane
through the unencoded fallback writes
sizeof(struct fwht_cframe_hdr) + 4 * coded_w * coded_h bytes, overrunning
the plane by coded_w * coded_h, which can result in corruption
of adjacent kernel heap memory.
Bump pixfmt_fwht.sizeimage_mult from 3 to 4, matching the largest
components_num among the supported raw formats, so the capture buffer is
always large enough for the unencoded fallback.
Fixes: 16ecf6dff97c ("media: vicodec: Add support for 4 planes formats")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thomas Richard <thomas.richard@bootlin.com>
Date: Mon Jul 13 16:43:43 2026 +0200
mfd: cgbc: Fix teardown ordering in cgbc_remove()
commit 2970c2db8ab3d97ea6250c14ca49b1e1731115ab upstream.
Release Board Controller session once children are removed by the core.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/cover.1783507945.git.u.kleine-koenig%40baylibre.com?part=19
Fixes: 6f1067cfbee7 ("mfd: Add Congatec Board Controller driver")
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20260713-cgbc-core-fix-cgbc-remove-v1-1-79274ad62b3a@bootlin.com
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Date: Mon Jul 20 17:08:32 2026 +0530
mfd: sm501: Fix potential memory leaks during remove
commit 83feedd9d83c0c5199f98c72df0a6196b4aefb4d upstream.
The memory allocated for struct sm501_devdata in sm501_pci_probe() and
sm501_plat_probe() is not freed by the corresponding remove functions
sm501_pci_remove() and sm501_plat_remove(). Fix that by adding a call to
kfree().
Fixes: b6d6454fdb66 ("[PATCH] mfd: SM501 core driver")
Cc: stable@vger.kernel.org
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Link: https://patch.msgid.link/20260720113836.73133-1-nihaal@cse.iitm.ac.in
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Sat Jun 20 21:42:11 2026 -0500
misc: nsm: bound the device-reported response length
commit 808e530654a5354e6df78863a5d61e4d44e67235 upstream.
nsm_sendrecv_msg_locked() stores the virtqueue used-ring length reported
by the NSM device into msg->resp.len without bounding it to the response
buffer. A malicious or buggy backend can report a length larger than the
response buffer; parse_resp_raw() then copies that many bytes out of the
fixed buffer to user space, disclosing adjacent kernel heap (an
out-of-bounds read). The request path already floors its length in
fill_req_raw(); the response path lacks the symmetric check.
Clamp the stored length to the size of the response buffer. Well-behaved
devices report no more than the posted buffer size, so conforming traffic
is unaffected.
Fixes: b9873755a6c8 ("misc: Add Nitro Secure Module driver")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Alexander Graf <graf@amazon.com>
Link: https://patch.msgid.link/20260620-b4-disp-a54b7dd6-v1-1-79d1f236a854@proton.me
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Breno Leitao <leitao@debian.org>
Date: Tue Aug 18 02:03:40 2026 -0700
mm, swap: ratelimit bad swap entry reports
commit f9dc428249ed962a70acf301f01eae8578449161 upstream.
A corrupt page table hands the same bogus entry to get_swap_device() on
every access to the mapping, and every rejection is logged. One machine
logged 6185620 copies of the same line in a few hours.
swap_dup_entry_direct() prints the same message from the fork path, once
per call: the WARN_ON_ONCE() guarding it warns once, the pr_err() inside
does not.
Rate limit all three prints.
Link: https://lore.kernel.org/20260818-swap_part_one-v1-1-a4fc58119fc0@debian.org
Fixes: 23b230ba8ac3 ("mm/swap: print bad swap offset entry in get_swap_device")
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Nhat Pham <nphamcs@gmail.com>
Acked-by: Kairui Song <kasong@tencent.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Chris Li <chrisl@kernel.org>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: David Hildenbrand (Arm) <david@kernel.org>
Date: Fri Jul 31 22:27:53 2026 +0200
mm/gup: fix always draining LRU caches in collect_longterm_unpinnable_folios()
commit 078e1a0fc41a42baaf113383b52dab8874c0b967 upstream.
folio_may_be_lru_cached() is currently only true for small folios, and
for small folios FOLL_PIN adds GUP_PIN_COUNTING_BIAS references instead
of 1 in try_grab_folio()/try_grab_folio_fast().
Consequently, our
folio_ref_count(folio) != folio_expected_ref_count(folio) + 1
check in collect_longterm_unpinnable_folios() will currently always
identify "reference mismatch" and first drain the local LRU cache to then
drain the LRU cache on all CPUs, as collect_longterm_unpinnable_folios()
is really called after pinning the folios with FOLL_PIN.
Add a comment because the current code is not quite intuitive: we used to
drain only to make sure the folio_isolate_lru() would succeed. But then we
also started draining to make later migration more reliable.
We'll refactor that code soon a bit, to also make it usable in other
context where we really want to remove any references from LRU caches.
Let's add CC stable, because having an easy way for excessive LRU cache
draining on all CPUs does not sound right. In common scenarios we
don't expect to ever have to drain.
Link: https://lore.kernel.org/20260731-check_and_migrate_movable_folios-v1-1-e0002d7b791e@kernel.org
Fixes: 98c6d259319e ("mm/gup: check ref_count instead of lru before migration")
Fixes: a09a8a1fbb37 ("mm/gup: local lru_add_drain() to avoid lru_add_drain_all()")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Ackerley Tng <ackerleytng@google.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Peter Xu <peterx@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Breno Leitao <leitao@debian.org>
Date: Mon Jun 15 10:49:06 2026 -0700
mm/kmemleak: avoid soft lockup when scanning task stacks
commit 5d10d4e19e6daa487f0cd0ea6cba472325de92f9 upstream.
Patch series "mm/kmemleak: avoid soft lockup when scanning task", v3.
kmemleak_scan() scans every task stack under one rcu_read_lock() with no
reschedule point, which can trip the soft lockup watchdog on hosts with
very many threads.
That prints the following message, depending on the workload+host
configuration:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537]
scan_block
kmemleak_scan
kmemleak_scan_thread
kthread
Patch 1 walks the tasks with find_ge_pid() so the scan reschedules between
tasks
Patches 2-3 let the scan loops stop early once a scan is interrupted.
This patch (of 3):
kmemleak_scan() walks every thread and scans its kernel stack under a
single rcu_read_lock() with no reschedule point. On a host with very many
threads -- amplified by KASAN/lockdep in debug builds -- this loop can hog
a CPU long enough to trip the soft lockup watchdog:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537]
scan_block
kmemleak_scan
kmemleak_scan_thread
kthread
A cond_resched() cannot be added directly: the loop runs inside an RCU
read-side critical section.
Walk the tasks one PID at a time with find_ge_pid(), taking the RCU read
lock only to look up and pin each task. The stack is then scanned with no
lock held, so cond_resched() runs between tasks and the scan stops early
on scan_should_stop(). This follows the next_tgid()/task_seq_get_next()
iteration pattern and keeps each RCU critical section short.
Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-0-acecd7d7fd92@debian.org
Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-1-acecd7d7fd92@debian.org
Fixes: c4b28963fd79 ("mm/kmemleak: rely on rcu for task stack scanning")
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Cc: Qian Cai <cai@lca.pw>
Cc: SeongJae Park <sj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Breno Leitao <leitao@debian.org>
Date: Mon Jul 27 06:50:19 2026 -0700
mm/migrate: report RCU-tasks quiescent states in migrate_pages_batch()
commit efe8f86c0916f0f74eea74ae21a3b37f728c6bad upstream.
migrate_pages_batch() unmaps each folio before moving it, and every
unmap runs the mmu_notifier invalidate callbacks. On KVM hosts
try_to_migrate() ends up in kvm_mmu_notifier_invalidate_range_start() ->
tdp_mmu_zap_leafs(), which is expensive, so unmapping a large batch keeps
the CPU busy for a long time.
The loop already calls cond_resched(), but on PREEMPTION kernels that is
a no-op, and involuntary preemption is not a Tasks-RCU quiescent state.
A long batch therefore never reports a quiescent state, and the
migrating task (e.g. kcompactd) becomes a Tasks-RCU holdout, stalling the
Tasks-RCU grace period for minutes, which is common at Meta fleet:
INFO: rcu_tasks detected stalls on tasks:
0000000055349ecc: .. nvcsw: 1157401/1157401 holdout: 1 idle_cpu: -1/56 task:kcompactd0 state:R running task
Call Trace:
tdp_mmu_zap_leafs
tdp_mmu_next_root
gfn_to_pfn_cache_invalidate_start
kvm_mmu_notifier_invalidate_range_start
__mmu_notifier_invalidate_range_start
try_to_migrate_one
try_to_migrate
migrate_pages_batch
migrate_pages
compact_zone
compact_node
kcompactd
kthread
Use cond_resched_tasks_rcu_qs() so a quiescent state is reported even
when cond_resched() does nothing.
This has also been discussed at [1]
Link: https://lore.kernel.org/20260727-kcompact-v1-1-bdfefddd6874@debian.org
Link: https://lore.kernel.org/all/amdWVTs0WKOxguxP@gmail.com/ [1]
Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Gregory Price <gourry@gourry.net>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Alexander Graf <graf@amazon.com>
Date: Fri Aug 7 03:12:43 2026 +0000
mm/mm_init: deferred_grow_zone(): fix out-of-range first_deferred_pfn
commit 97090500d776c3f6d08e857e3a0a7cf092999094 upstream.
With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled, deferred_grow_zone()
initializes struct pages early in boot to satisfy an allocation.
With a large CMA reservation in place, the ranges deferred_init_memmap()
finds may not add up to the allocation it was asked for, and the function
ends up initializing the memory map of the entire zone and still falls
short.
That is fine in itself: the function accounts for it and leaves the
caller to decide whether it now has enough memory.
However, the update of pgdat->first_deferred_pfn that tracks where
uninitialized memory map starts could overflow.
If the node's RAM end is not aligned on PAGES_PER_SECTION boundaries and
some deferred struct pages were initialized, pgdat->first_deferred_pfn
would point past the end of the node's memory.
deferred_init_memmap() later picks up from pgdat->first_deferred_pfn and
hits a BUG_ON(), because it expects a pfn within its node.
For example, when running a kernel with CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
and CONFIG_CMA=y using the following qemu command line
qemu-system-x86_64 -enable-kvm -m 8032M -kernel bzImage \
-append "nokaslr cma=4768M@0x100000000"
the kernel panics:
kernel BUG at mm/mm_init.c:2131!
CPU: 3 UID: 0 PID: 36 Comm: pgdatinit0 Not tainted 7.2.0-rc6 #1
RIP: 0010:deferred_init_memmap+0x1b8/0x1c0
RAX: 0000000000236000 R13: 0000000000238000
Call Trace:
kthread+0xdf/0x120
ret_from_fork+0x187/0x250
Make sure that the update of pgdta->first_deferred_pfn does not overflow
when the entire zone's (and therefore node's) memory map is initialized.
Fixes: 3acb913c9d5b ("mm/mm_init: use deferred_init_memmap_chunk() in deferred_grow_zone()")
Cc: stable@vger.kernel.org
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Alexander Graf <graf@amazon.com>
Link: https://patch.msgid.link/20260807031243.87904-1-graf@amazon.com
[rppt: massaged the changelog]
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hyunwoo Kim <imv4bel@gmail.com>
Date: Wed Aug 12 01:18:57 2026 +0900
mm/pagewalk: fix stale walk->action escaping walk_pmd_range()
commit aedf2efd18977e0cef7eb963166e2b1fcc0aa321 upstream.
If ->pmd_entry() sets walk->action = ACTION_AGAIN, the pmd_none() check is
retried. The PMD entry may be cleared at the point of retry.
In this case, if walk->ops->install_pte is not specified, the code
continues to the next PMD entry in the range without resetting
walk->action to ACTION_SUBTREE.
This leaves walk->action erroneously set to ACTION_AGAIN, which is
incorrect.
This was incorrect but not problematic up until commit 3b89863c3fa4
("mm/pagewalk: fix race between concurrent split and refault") which
updated walk_pud_range() to check for walk->action == ACTION_AGAIN upon
walk_pmd_range()'s return, causing the PUD walk to be retried.
In this case this results in duplicate walk callbacks being invoked,
which is erroneous and will break any caller that is not idempotent
with respect to this (and waste time for those which are). The result
is an out-of-bounds write, triggered by a local fuzzer:
[ 2.272695] ==================================================================
[ 2.273471] BUG: KASAN: slab-out-of-bounds in __mincore_unmapped_range+0x14f/0x190
[ 2.274302] Write of size 1 at addr ffff888008d9b000 by task poc/106
[ 2.274966]
[ 2.275154] CPU: 0 UID: 1000 PID: 106 Comm: poc Not tainted 7.2.0-rc6-00429-ga7c7074b58d2 #55 PREEMPT(lazy)
[ 2.275159] 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.275164] Call Trace:
[ 2.275170] <TASK>
[ 2.275172] dump_stack_lvl+0x53/0x70
[ 2.275200] print_report+0xd0/0x630
[ 2.275210] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 2.275219] ? irqentry_exit+0xd2/0x670
[ 2.275224] ? irqentry_exit+0xd2/0x670
[ 2.275226] ? __virt_addr_valid+0xef/0x1a0
[ 2.275239] ? __mincore_unmapped_range+0x14f/0x190
[ 2.275242] kasan_report+0xce/0x100
[ 2.275245] ? __mincore_unmapped_range+0x14f/0x190
[ 2.275248] __mincore_unmapped_range+0x14f/0x190
[ 2.275252] mincore_unmapped_range+0x45/0x70
[ 2.275254] walk_pgd_range+0xafc/0xfc0
[ 2.275261] ? __pfx_walk_pgd_range+0x10/0x10
[ 2.275264] ? __update_load_avg_se+0x3d1/0x670
[ 2.275275] __walk_page_range+0xc0/0x310
[ 2.275278] ? __pfx_find_vma+0x10/0x10
[ 2.275281] ? finish_task_switch.isra.0+0x16d/0x4f0
[ 2.275290] walk_page_range_mm_unsafe+0x26f/0x3a0
[ 2.275293] ? __pfx_mtree_load+0x10/0x10
[ 2.275298] ? __pfx_walk_page_range_mm_unsafe+0x10/0x10
[ 2.275302] ? __free_frozen_pages+0x54d/0x7e0
[ 2.275308] __do_sys_mincore+0x132/0x380
[ 2.275311] do_syscall_64+0xf9/0x540
[ 2.275316] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 2.275322] RIP: 0033:0x422ccd
[ 2.275326] Code: b3 66 2e 0f 1f 84 00 00 00 00 00 66 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
[ 2.275329] RSP: 002b:00007fffffffec18 EFLAGS: 00000287 ORIG_RAX: 000000000000001b
[ 2.275337] RAX: ffffffffffffffda RBX: 0000000000000066 RCX: 0000000000422ccd
[ 2.275339] RDX: 00000000004d0940 RSI: 0000000001000000 RDI: 00007ffff4000000
[ 2.275340] RBP: 00000000004d0940 R08: 0000000000000100 R09: 0000000000000100
[ 2.275342] R10: 0000000000000100 R11: 0000000000000287 R12: 20c49ba5e353f7cf
[ 2.275343] R13: 00000000004990d3 R14: 0000000000000000 R15: 0000000000000001
[ 2.275346] </TASK>
[ 2.275347]
[ 2.296904] The buggy address belongs to the object at ffff888008d9b000
[ 2.296904] which belongs to the cache sigqueue of size 80
[ 2.298151] The buggy address is located 0 bytes inside of
[ 2.298151] allocated 80-byte region [ffff888008d9b000, ffff888008d9b050)
[ 2.299408]
[ 2.299601] The buggy address belongs to the physical page:
[ 2.300191] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x8d9b
[ 2.301001] flags: 0x100000000000000(node=0|zone=1)
[ 2.301535] page_type: f5(slab)
[ 2.301884] raw: 0100000000000000 ffff888107e46780 dead000000000122 0000000000000000
[ 2.302687] raw: 0000000000000000 0000000800240024 00000000f5000000 0000000000000000
[ 2.303489] page dumped because: kasan: bad access detected
[ 2.304092]
[ 2.304276] Memory state around the buggy address:
[ 2.304801] ffff888008d9af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 2.305567] ffff888008d9af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 2.306340] >ffff888008d9b000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2.307115] ^
[ 2.307474] ffff888008d9b080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2.308237] ffff888008d9b100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2.308997] ==================================================================
A specific example of this breaking things is mincore which walks an
internal cursor data structure a byte at a time on assumption that page
table entry callbacks are called only once for each entry.
Fix the problem by resetting walk->action to ACTION_SUBTREE prior to the
none check.
The pattern also exists in walk_pud_range() so fix it there too.
This issue was found through AI-based fuzzing.
Link: https://lore.kernel.org/20260811161949.3879321-2-imv4bel@gmail.com
Fixes: 3b89863c3fa4 ("mm/pagewalk: fix race between concurrent split and refault")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Max Boone <mboone@akamai.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Dev Jain <dev.jain@arm.com>
Date: Thu Sep 3 19:56:31 2026 -0400
mm/rmap: use huge_ptep_get() in try_to_unmap_one()
[ Upstream commit f5407e9b697c940e78b27ff63c6e14d8d171adc3 ]
Patch series "Fix incorrect access of hugetlb pte entries", v3.
There are various places which use ptep_get() to get the pte entry
corresponding to a hugetlb folio. Some arches (like s390) have special
handling to compute the pteval, so they provide huge_ptep_get(). Use this
helper consistently.
Additionally, some code paths may provide huge_ptep_get with an unaligned
address. This is a problem on arm64 (I checked other arches and it looks
fine for them), which is fixed in patch 1. The fix is made to be
backport-friendly: the cleaner fix would be to perhaps pass the hstate to
huge_ptep_get() - that is wider churn and we can do that later.
This patch (of 5):
try_to_unmap_one() handles hugetlb folios when memory failure needs to
replace a poisoned hugetlb mapping with a hwpoison entry. In that case
page_vma_mapped_walk() returns the pte pointer to the hugetlb folio in
pvmw.pte, but the code reads it with ptep_get().
On arches which provide their own huge_ptep_get() to dereference a huge
pte pointer, accessing via ptep_get() would cause pte_pfn(), pte_present()
etc to misbehave.
It is not clear whether this has a trivially visible effect to userspace.
Just use huge_ptep_get() for dereferencing a huge pte pointer.
Link: https://lore.kernel.org/20260703114202.365553-1-dev.jain@arm.com
Link: https://lore.kernel.org/20260703114202.365553-3-dev.jain@arm.com
Fixes: c7ab0d2fdc84 ("mm: convert try_to_unmap_one() to use page_vma_mapped_walk()")
Signed-off-by: Dev Jain <dev.jain@arm.com>
Reported-by: David Hildenbrand <david@kernel.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Harry Yoo <harry@kernel.org>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Jann Horn <jannh@google.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Jun'ichi "Nick" Nomura <j-nomura@ce.jp.nec.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Ralph Campbell <rcampbell@nvidia.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Breno Leitao <leitao@debian.org>
Date: Mon Aug 10 02:57:36 2026 -0700
mm/vmscan: report RCU-tasks quiescent states in shrink_lruvec()
commit 25f52e81216884a7444bf07a606691feb09a94e3 upstream.
I am seeing some rcu_tasks stalls in the Meta fleet during reclaim.
INFO: rcu_tasks detected stalls on tasks:
0000000088620d09: .. nvcsw: 6735/6735 holdout: 1 idle_cpu: -1/8
task:GlobalCPUThread state:R running task pid:2552016 tgid:2524552
Call Trace:
shrink_lruvec
mem_cgroup_iter
shrink_node
do_try_to_free_pages
try_to_free_pages
__alloc_frozen_pages_noprof
alloc_pages_noprof
pte_alloc_one
__pte_alloc
handle_mm_fault
Nothing promises direct reclaim returns in bounded time, and the scan loop
in shrink_lruvec() only calls cond_resched(), which is a no-op on
PREEMPTION kernels. Involuntary preemption is not a Tasks-RCU quiescent
state, so the reclaiming task never reports one and becomes a holdout.
Upgrade it to cond_resched_tasks_rcu_qs(), which reports a quiescent state
even when cond_resched() does nothing.
PS: This has been discussed in [1]
Link: https://lore.kernel.org/20260810-rcu_task_shrink_lruvec-v1-1-4d9f7d5251cb@debian.org
Link: https://lore.kernel.org/all/amdWVTs0WKOxguxP@gmail.com/ [1]
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hao Jia <jiahao1@lixiang.com>
Date: Thu Aug 6 15:09:42 2026 +0800
mm/zswap: fix global shrinker when memory cgroup is disabled
commit dc8458f43fe964d8ade74c9b0fce54fe71d156de upstream.
Patch series "mm/zswap: Fixes and improves the zswap shrink", v4.
This series fixes and improves the zswap global shrinker
(shrink_worker()): Patch 1: Fix missing global shrinker when memory cgroup
is disabled. Patch 2: Extend shrink_memcg() to support batch writeback
and thereby improving the writeback efficiency in the shrink_worker() and
zswap_store() paths.
This patch (of 2):
Zswap writeback when the global pool limit is hit fails when memory cgroup
is disabled. The pool remains full until it is organically drained by
swapins or memory freeing, leading to zswap store failures and pages
bypassing getting written directly to the backing swap device, causing LRU
inversion (hotter pages with higher fault latency).
This happens because mem_cgroup_iter() always returns NULL when memory
cgroups are disabled. As a result, the global shrinker shrink_worker()
repeatedly takes empty walks. After MAX_RECLAIM_RETRIES failed attempts,
the worker gives up without writing back any pages.
Therefore, when memory cgroup is disabled, fall through with the !memcg
branch and shrink the root memcg directly.
With memcg disabled, shrink_memcg() only returns -ENOENT when the root LRU
is empty, which means the total pages are already below thr. In the
absence of heavy concurrent zswap stores, the loop then safely bails out
via the zswap_total_pages() <= thr check; otherwise, it will resume
shrinking the memcg after processing the reschedule check. For any other
return value from shrink_memcg(), the loop is guaranteed to terminate,
either after MAX_RECLAIM_RETRIES failures or once the threshold is met.
This is a potential performance regression for people using zswap
without memcg that was introduced by the commit in "Fixes".
Link: https://lore.kernel.org/20260806070943.95542-1-jiahao.kernel@gmail.com
Link: https://lore.kernel.org/20260806070943.95542-2-jiahao.kernel@gmail.com
Fixes: a65b0e7607cc ("zswap: make shrinking memcg-aware")
Signed-off-by: Hao Jia <jiahao1@lixiang.com>
Suggested-by: Nhat Pham <nphamcs@gmail.com>
Acked-by: Nhat Pham <nphamcs@gmail.com>
Acked-by: Yosry Ahmed <yosry@kernel.org>
Reported-by: Yosry Ahmed <yosry@kernel.org>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Tejun Heo <tj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Lorenzo Stoakes <ljs@kernel.org>
Date: Thu Sep 3 19:56:30 2026 -0400
mm: avoid unnecessary use of is_swap_pmd()
[ Upstream commit aa62204cb680d8ff32497181fc9e0dac4956f7e5 ]
PMD 'non-swap' swap entries are currently used for PMD-level migration
entries and device private entries.
To add to the confusion in this terminology we use is_swap_pmd() in an
inconsistent way similar to how is_swap_pte() was being used - sometimes
adopting the convention that !pmd_none(), !pmd_present() implies PMD 'swap'
entry, sometimes not.
This patch handles the low-hanging fruit of cases where we can simply
substitute other predicates for is_swap_pmd().
No functional change intended.
Link: https://lkml.kernel.org/r/8a1704b36a009c18032d5bea4cb68e71448fbbe5.1762812360.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Chris Li <chrisl@kernel.org>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jann Horn <jannh@google.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Kairui Song <kasong@tencent.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Mathew Brost <matthew.brost@intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: SeongJae Park <sj@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Xu <weixugc@google.com>
Cc: xu xin <xu.xin16@zte.com.cn>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: f5407e9b697c ("mm/rmap: use huge_ptep_get() in try_to_unmap_one()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johannes Weiner <hannes@cmpxchg.org>
Date: Wed Jul 22 10:56:45 2026 -0400
mm: compaction: support non-movable compaction for pageblock requests
commit 1b4b697a5743e624cc259d6c31a8d8716b796305 upstream.
While trying to fix a reclaim storm in defrag_mode, I noticed that
non-movable direct compaction is extremely inefficient.
When searching for space to evacuate, compaction only allows blocks of the
same type as the incoming request. This is to prevent migratetype
pollution, where a small non-movable request frees space in a movable
block and provokes the allocator to fall back and pollute it.
This protection is reasonable on one hand, but the downside is that it
makes non-movable direct compaction nearly useless: if we get the type
annotations right, by definition there aren't any movable pages inside the
non-movable blocks it is allowed to scan.
With defrag_mode, the goal is the production of whole blocks, which are
essentially type neutral: __rmqueue_claim() will convert them wholesale on
alloc. This makes type mixing and pollution a non-issue.
Fix the pollution gates to take the requested order into account, and
allow whole-block requests to scan blocks of other types.
The only exception is CMA blocks. That type is sticky and these blocks
cannot be claimed to other types. Continue to be strict with them, and
allow only explicit ALLOC_CMA requests and kcompactd to evacuate them.
Link: https://lore.kernel.org/20260722150006.3848560-3-hannes@cmpxchg.org
Fixes: e3aa7df331bc ("mm: page_alloc: defrag_mode")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Gregory Price <gourry@gourry.net>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guopeng Zhang <zhangguopeng@kylinos.cn>
Date: Tue Aug 11 11:08:43 2026 +0800
mm: memcg-v1: fix memsw and TCP failcnt accounting
commit 92192e9c5ee07efc657d3654bc264081fb0aa01b upstream.
Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
cgroups") made failcnt accounting conditional on track_failcnt. It
enabled the flag for memcg->memory, but not for memcg->memsw or
memcg->tcpmem.
Consequently, memory.memsw.failcnt remains zero when the memory+swap limit
is hit. memory.kmem.tcp.limit_in_bytes still sets memcg->tcpmem.max, but
TCP charge failures are not reflected in memory.kmem.tcp.failcnt.
Enable failcnt accounting for both v1 counters.
To reproduce memory.memsw.failcnt:
CG=/sys/fs/cgroup/memory/memsw-test
LIMIT=33554432
mkdir "$CG"
echo "$LIMIT" > "$CG/memory.limit_in_bytes"
echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
Start a child process in the cgroup and make it allocate and touch 96 MiB
of memory, causing a memcg OOM.
cat "$CG/memory.memsw.failcnt"
Without the patch, memory.memsw.failcnt is 0. With the patch,
memory.memsw.failcnt is greater than 0.
To reproduce memory.kmem.tcp.failcnt:
CG=/sys/fs/cgroup/memory/tcpmem-test
LIMIT=65536
mkdir "$CG"
echo "$LIMIT" > "$CG/memory.kmem.tcp.limit_in_bytes"
Start a child process in the cgroup, create a TCP socket, and reserve
1 MiB of socket memory with SO_RESERVE_MEM. The reservation fails with
ENOMEM.
cat "$CG/memory.kmem.tcp.failcnt"
Without the patch, memory.kmem.tcp.failcnt is 0. With the patch,
memory.kmem.tcp.failcnt is greater than 0.
Link: https://lore.kernel.org/20260811030843.109104-1-guopeng.zhang@linux.dev
Closes: https://sashiko.dev/#/patchset/20260810074247.52747-1-guopeng.zhang@linux.dev?part=1
Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.com>
Reviewed-by: Tao Cui <cuitao@kylinos.cn>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guopeng Zhang <zhangguopeng@kylinos.cn>
Date: Mon Jul 13 16:57:56 2026 +0800
mm: memcg-v1: fix wrong linux-mm list address in deprecation warnings
commit 45b1ec4887bdcc58af885540d9fefa8b67d17d57 upstream.
The deprecation warnings for memory.oom_control and memory.pressure_level
use linux-mm-@kvack.org instead of the linux-mm mailing list address.
Remove the extra hyphen.
Link: https://lore.kernel.org/20260713085756.2973549-1-guopeng.zhang@linux.dev
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guopeng Zhang <zhangguopeng@kylinos.cn>
Date: Fri Jul 24 10:18:05 2026 +0800
mm: memcg: stop reclaim when a limit update is superseded
commit 9477820c63cbf4d97114238f3d1ff10dfd6bee3f upstream.
kernfs serializes file operations only per open file, so separate open
files can update the same memory.high or memory.max file concurrently.
Both handlers store the new limit before synchronous reclaim, but continue
to use the writer's local target in the reclaim loop. If another writer
raises or removes the limit, the first writer can continue reclaiming
toward a stale target.
For memory.max, this can leave the writer looping indefinitely once
reclaim retries are exhausted. The OOM path sees sufficient margin under
the current limit and returns true without killing, while the writer still
compares usage against its stale target and records another OOM event.
Check the current limit at the start of each reclaim iteration and stop if
it no longer matches the writer's target.
Reproducer:
Populate a cgroup with anonymous memory and disable swapping. Lower
memory.max from one open file, then restore it to "max" through another
open file after the new limit becomes visible.
Without the patch, the first writer remains blocked and repeatedly
increments the OOM event counter. With the patch, it returns normally.
This was not motivated by a reported production workload. We found it
through automated randomized testing for our cgroup observability work
and reduced it to the reproducer above.
Link: https://lore.kernel.org/20260724021805.1234583-1-guopeng.zhang@linux.dev
Fixes: 8c8c383c04f6 ("mm: memcontrol: try harder to set a new memory.high")
Fixes: b6e6edcfa405 ("mm: memcontrol: reclaim and OOM kill when shrinking memory.max below usage")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Acked-by: Tao Cui <cuitao@kylinos.cn>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Guopeng Zhang <zhangguopeng@kylinos.cn>
Date: Mon Jul 13 16:50:53 2026 +0800
mm: memcontrol: update state_local when flushing NMI stats
commit 72f522bbf473f03a77e83547b677dc1505c5d41a upstream.
flush_nmi_stats() updates state[] for kmem and slab counters but leaves
the corresponding state_local[] counters unchanged. Local kmem and slab
statistics therefore miss updates collected through the NMI-safe atomic
path.
Update state_local[] together with state[].
Link: https://lore.kernel.org/20260713085053.2916813-1-guopeng.zhang@linux.dev
Fixes: 940b01fc8dc1 ("memcg: nmi safe memcg stats for specific archs")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Acked-by: Tao Cui <cuitao@kylinos.cn>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johannes Weiner <hannes@cmpxchg.org>
Date: Mon Jun 29 12:33:37 2026 -0400
mm: mempolicy: fix automatic numa balancing for shmem
commit d230991493b521eeff39f32434fddcbcdb109eb0 upstream.
Neha reports that mapped shmem aren't considered for NUMA balancing,
noting convergence problems and bandwidth bottlenecking for cachelib based
workloads on tiered memory systems.
Looking at the code and going through the git history, this doesn't
actually seem intentional:
Commit fc3147245d19 ("mm: numa: Limit NUMA scanning to migrate-on-fault
VMAs") added a vma_policy_mof() gate to task_numa_work() so VMAs whose
policy lacks MPOL_F_MOF are skipped from NUMA balancing scans. The
motivation was a real usecase: Oracle was pinning shared segments with
mbind(MPOL_BIND) so trapping faults was both expensive and pointless.
The handling of NULL from vm_ops->get_policy, however, treated "user
explicitly opted out" the same as "user never specified anything." For
VMAs whose shared policy is absent - the common case for shmem - the scan
was disabled too.
This issue is old. It probably hurts less in conventional NUMA. But it's
very noticeable on tiered systems, where entire tmpfs workingsets can get
stuck on lower-bandwidth memory.
Fix this by having vma_policy_mof() use __get_vma_policy() directly, and
thereby handle the fallback to task policy (-> preferred_node_policy() has
MPOL_F_MOF per default). Every other consumer of vm_ops->get_policy
already handles it this way, the scan-eligibility check was the outlier.
This preserves Mel's intended fix: don't scan stuff the user explicitly
pinned. But allow default policy vmas to participate in balancing.
Link: https://lore.kernel.org/20260629163337.1264881-1-hannes@cmpxchg.org
Fixes: fc3147245d19 ("mm: numa: Limit NUMA scanning to migrate-on-fault VMAs")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reported-by: Neha Gholkar <nehagholkar@gmail.com>
Tested-by: Neha Gholkar <nehagholkar@gmail.com>
Reviewed-by: Gregory Price <gourry@gourry.net>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Balbir Singh <balbirs@nvidia.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johannes Weiner <hannes@cmpxchg.org>
Date: Wed Jul 22 10:56:44 2026 -0400
mm: page_alloc: __GFP_FS lockdep annotation for direct compaction
commit 37864d0bf5a4d60da6109b9078cc78ef3fc81216 upstream.
Patch series "mm: fix reclaim storms in defrag_mode", v2.
As we deployed vm.defrag_mode=1 in Meta production, some workloads
regressed with recurring pressure spikes and swap storms (which in turn
triggered userspace OOM rules on pressure and swap utilization levels).
Tracing pinned this to non-movable requests spinning and reclaiming
unproductively when kswapd/kcompactd are overwhelmed. Direct reclaim
predominantly frees up pages in movable blocks, but those requests cannot
use that space under defrag_mode rules; and it is unlikely to free up
whole blocks incidentally for __rmqueue_claim() to work.
This series fixes it by making non-movable requests participate in
pageblock production in the allocator slowpath - meaning, they will invoke
direct reclaim and direct compaction with pageblock_order.
That requires some small-ish adjustments up front in the allocator and the
compaction code: three prep patches and the fix last.
The series has been in production against one of the affected workloads
for several weeks and restores the OOM kill rate to !defrag_mode baseline.
This patch (of 4):
A subsequent patch will have some order-0 allocations participate in
compaction under defrag_mode, to stave off extfrag events.
Since this is a sprawling expansion of entry points, and compaction can
enter filesystem paths, add lockdep annotations that catches __GFP_FS
passing errors.
Direct reclaim has had this annotation for a while, and since reclaim and
compaction are usually used in conjunction, this is unlikely to unearth
old bugs. It's more about future proofing and peace of mind.
Link: https://lore.kernel.org/20260722150006.3848560-1-hannes@cmpxchg.org
Link: https://lore.kernel.org/20260722150006.3848560-2-hannes@cmpxchg.org
Fixes: e3aa7df331bc ("mm: page_alloc: defrag_mode")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Gregory Price <gourry@gourry.net>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johannes Weiner <hannes@cmpxchg.org>
Date: Wed Jul 22 10:56:47 2026 -0400
mm: page_alloc: fix non-movable reclaim storm in defrag_mode
commit 7e8756d7ad22655b935c384f123071aa9de07a27 upstream.
As we deployed defrag_mode into Meta production, pressure spikes and
excessive swapping were observed on some workloads. Tracing confirmed
that this is unmovable/reclaimable requests spinning in the allocator and
direct reclaim, causing excessive amounts of swap.
The initial plan for defrag_mode was to rely on kswapd/kcompactd to
produce blocks, and if those are overwhelmed under high pressure, let the
allocator fall back (__rmqueue_steal()) after its retry loops. However,
that retrying results in more reclaim on some of these workloads than we'd
hoped, sometimes excessively so, spurred on by the !costly order
conditions in should_reclaim_retry().
The storms are dependent on the request type. Reclaim will inevitably
make room in existing movable blocks, since that's where the LRU pages
live. So if movable requests retry on reclaim, they make progress.
When non-movable requests spin in reclaim that isn't productive. They
cannot use the individually freed pages, and the process is unlikely to
accidentally free whole blocks to meet the ALLOC_NOFRAGMENT bar. They
spin and overreclaim excessively, which tanks performance and triggers
userspace guards like swap exhaustion or pressure based OOM.
To fix this, send non-movable requests, regardless of order, into
pageblock reclaim/compaction. This way, they help move things along to
meet the ALLOC_NOFRAGMENT bar. After this patch, the reclaim storms and
excess OOM rates are no longer observed in production.
The longer-term plan is still to have all requests, including the movable
ones, help make blocks to spread the cost of defragmenting more evenly and
fairly; combined with proper watermarking to reduce allocation latencies
in the common case. However, doing this naively unearths scaling and
concurrency limitations in compaction that need to be addressed first.
Promoting just non-movables for now is the minimally viable bug fix for
the above issue.
[brendan.jackman@linux.dev: fix try_to_compact_pages() kerneldoc]
Link: https://lore.kernel.org/DK7NM9RPUJOD.11PNJJ5N2OBED@linux.dev
Link: https://lore.kernel.org/20260722150006.3848560-5-hannes@cmpxchg.org
Fixes: e3aa7df331bc ("mm: page_alloc: defrag_mode")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: "Brendan Jackman" <brendan.jackman@linux.dev>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Gregory Price <gourry@gourry.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Date: Wed Jul 22 10:56:46 2026 -0400
mm: page_alloc: move capture_control to the page allocator
commit aee220f565cce38f0efcff940ae2b44bdc495408 upstream.
The compaction capturing code assumes the allocation request order and
compaction target order are the same. That won't be true once defrag_mode
promotes sub-block allocations to pageblock-order compaction: compaction
targets the larger order, while capture should remain at the original
allocation order.
Move the capture_control to the page allocator and give it its own copies
of what the page freeing path matches against - zone, migratetype and the
allocation order - rather than reaching into compaction's live
compact_control. __alloc_pages_direct_compact() fills in migratetype and
order, and installs and hides current->capture_control around the whole
compaction call; try_to_compact_pages() aims capc->zone at each zone while
it is being compacted. compact_zone_order() no longer deals with capture
at all.
Pass the capture_control through try_to_compact_pages() /
compact_zone_order() in place of the bare struct page **.
No functional change.
Link: https://lore.kernel.org/20260722150006.3848560-4-hannes@cmpxchg.org
Fixes: e3aa7df331bc ("mm: page_alloc: defrag_mode")
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Co-developed-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Gregory Price <gourry@gourry.net>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ridong Chen <chenridong@xiaomi.com>
Date: Thu Jul 23 11:24:34 2026 +0800
mm: vmscan: fix node reclaim ignoring swappiness parameter
commit 8a905195850d383c0465ab5bdd3c91d94269b242 upstream.
sc_swappiness() had two separate definitions depending on CONFIG_MEMCG.
The !CONFIG_MEMCG variant simply returned vm_swappiness, ignoring the
proactive_swappiness value passed through scan_control. This caused the
swappiness parameter written to /sys/devices/system/node/nodeX/reclaim to
have no effect when CONFIG_MEMCG is disabled.
Fix this by consolidating sc_swappiness() into a single definition that
checks sc->proactive_swappiness first, then falls back to
mem_cgroup_swappiness() which already handles both CONFIG_MEMCG and
!CONFIG_MEMCG.
Before fix (swappiness=max ignored, mostly file pages reclaimed):
# cat /proc/sys/vm/swappiness
60
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 1840
pgsteal_anon 25
pgsteal_file 1815
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 18013
pgsteal_anon 337
pgsteal_file 17676
After fix (swappiness=max honored, anon pages reclaimed as expected):
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 0
pgsteal_anon 0
pgsteal_file 0
# echo "64M swappiness=max" > /sys/devices/system/node/node0/reclaim
# cat /proc/vmstat | grep pgsteal
pgsteal_kswapd 0
pgsteal_direct 0
pgsteal_khugepaged 0
pgsteal_proactive 16283
pgsteal_anon 16283
pgsteal_file 0
Link: https://lore.kernel.org/20260723032434.2016749-3-ridong.chen@linux.dev
Fixes: b980077899ea ("mm: introduce per-node proactive reclaim interface")
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Acked-by: Qi Zheng <qi.zheng@linux.dev>
Tested-by: Song Hu <husong@kylinos.cn>
Reviewed-by: Song Hu <husong@kylinos.cn>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Chris Li <chrisl@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Kairui Song <kasong@tencent.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: <stable@vger.kernel.org> [6.17+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Thu Jul 23 11:28:42 2026 +0000
mmc: via-sdmmc: cancel card-detect work on remove
commit 57e5d877f898d5e5c9d672a77bb6bdd24f0d9bf5 upstream.
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.
Fixes: f0bf7f61b840 ("mmc: Add new via-sdmmc host controller driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Thu Jul 23 11:28:41 2026 +0000
mmc: via-sdmmc: stop card-detect handling on probe failure
commit 088eaa92fcebaa6b957ccf9635afdf39643a577d upstream.
request_irq() registers the SD card-detect interrupt and the probe enables
it before mmc_add_host() runs. If mmc_add_host() fails, the error path only
unmaps the registers and returns: the interrupt stays registered, so the
handler keeps running against the host once it is freed. via_sdc_isr()
dereferences sdhost and its MMIO base and schedules carddet_work, which
via_sdc_card_detect() also runs against freed memory through its
container_of() dereference.
Add a probe-error path that disables and frees the interrupt and cancels
carddet_work before unmapping. carddet_work can re-enable the device
interrupt via via_reset_pcictrl(), which restores PCIINTCTRL, so mask it
again after cancelling the work.
This issue was found by an in-house static analysis tool and confirmed by
manual code review.
Fixes: e4e46fb61e3b ("mmc: via-sdmmc: fix return value check of mmc_add_host()")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stanislaw Gruszka <stf_xl@wp.pl>
Date: Fri Mar 27 12:00:04 2026 +0100
module/kallsyms: fix nextval for data symbol lookup
commit 0e9f090a4e9bfae5a190ccf89eab3bf14f6b0f96 upstream.
The symbol lookup code assumes the queried address resides in either
MOD_TEXT or MOD_INIT_TEXT. This breaks for addresses in other module
memory regions (e.g. rodata or data), resulting in incorrect upper
bounds and wrong symbol size.
Select the module memory region the address belongs to instead of
hardcoding text sections. Also initialize the lower bound to the start
of that region, as searching from address 0 is unnecessary.
Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thiébaud Weksteen <tweek@google.com>
Date: Wed Jul 8 11:21:07 2026 +1000
module: validate string table section types
commit 9a5ff45689329835f874cefe5174e577d141d423 upstream.
In elf_validity_cache_sechdrs, section sizes and offsets are validated,
unless the section type is SHT_NULL or SHT_NOBITS.
Later, elf_validity_cache_secstrings and elf_validity_cache_index_str
access the section name table (.shstrtab) and symbol string table
(.strtab) headers without first ensuring that their types are
SHT_STRTAB. If a section type is SHT_NULL or SHT_NOBITS, sh_offset has
not been validated and may reference out-of-bounds memory when
dereferenced in elf_validity_cache_secstrings or
elf_validity_cache_strtab.
Validate that both string section headers are of type SHT_STRTAB before
caching them.
Cc: stable@vger.kernel.org
Signed-off-by: Thiébaud Weksteen <tweek@google.com>
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Qing Ming <a0yami@mailbox.org>
Date: Fri Aug 14 17:54:04 2026 +0800
mpls: reload header after pskb_may_pull()
commit 29e63b8d9fc150cc191b1c6eb7e16e1247e1b650 upstream.
mpls_select_multipath() calls mpls_multipath_hash() to choose a nexthop
when an MPLS route has multiple nexthops. While walking the MPLS label
stack, the hash routine caches hdr for the current label. After finding
the bottom-of-stack label, it calls pskb_may_pull() before reading the
inner IP header.
If an skb is constructed with the inner IP header in nonlinear data and
insufficient tailroom in the linear head, pskb_may_pull() calls
pskb_expand_head() to replace the skb head and free the old one. This
leaves hdr pointing to freed memory. The IPv6 path can invalidate hdr
again when it performs a second pull for the larger header.
The issue was found through static analysis. A reproducer sending a legal
Geneve packet through a bareudp/MPLS multipath setup triggered the same
KASAN report in 2 of 2 unpatched runs:
BUG: KASAN: slab-use-after-free in mpls_select_multipath
Read of size 1 at addr ffff88800ecc6e20 by task ksoftirqd/1/23
Call Trace:
mpls_select_multipath
mpls_forward
__netif_receive_skb_list_core
netif_receive_skb_list_internal
napi_complete_done
gro_cell_poll
__napi_poll
net_rx_action
Freed by task 23:
kfree
pskb_expand_head
__pskb_pull_tail
mpls_select_multipath
Reload hdr from the current skb head after each successful pull before
deriving the inner IPv4 or IPv6 header pointer.
Fixes: 9f427a0e474a ("net: mpls: Fix multipath selection for LSR use case")
Cc: stable@vger.kernel.org
Signed-off-by: Qing Ming <a0yami@mailbox.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260814095404.7205-1-a0yami@mailbox.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Harshit Varu <harshitvaru666@gmail.com>
Date: Sat Aug 15 17:22:05 2026 +0530
mptcp: fix uninitialized local_id in syncookie MP_JOIN reconstruction
commit b878dfdd12d7a5b8722a78d35e313506140ca3d9 upstream.
mptcp_token_join_cookie_init_state() restores remote_nonce, local_nonce,
backup, join_id, token and msk from the saved cookie entry when rebuilding
the request socket for a MP_JOIN 4th-ACK handled under SYN cookies, but it
does not restore local_id, even though the SYN path saved it.
subflow_ulp_clone() then reads that uninitialized field and stores it as
the joined subflow's address-ID. Because the request-sock slab is
SLAB_TYPESAFE_BY_RCU and not zeroed on allocation, the value is the stale
byte of a previously freed request socket, which an off-path peer can
influence by sending concurrent MP_JOIN SYNs. This corrupts the path
manager's id-based subflow bookkeeping for the connection.
Restore subflow_req->local_id from the cookie entry, as done for the other
fields.
Fixes: 9466a1ccebbe ("mptcp: enable JOIN requests even if cookies are in use")
Cc: stable@vger.kernel.org
Signed-off-by: Harshit Varu <harshitvaru666@gmail.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260815115205.197151-1-harshitvaru666@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Alexandra Winter <wintera@linux.ibm.com>
Date: Fri Aug 21 14:55:01 2026 +0200
net/iucv: filter frames in afiucv_hs_rcv() by ingress device
commit 80230a18c164a4b5bbc048fe2768b219ac17bc5a upstream.
afiucv_hs_rcv() selects a socket from iucv_sk_list by matching four 8-byte
name fields in the transport header alone. No check is made against the
net_device the frame arrived on.
This can cause a frame arriving on any netdev to be delivered to an AF_IUCV
socket. Three problems follow.
First, a frame arriving over HiperSockets can be delivered to a socket
bound to the classic z/VM IUCV transport, which has iucv->hs_dev == NULL.
iucv_sock_bind() takes the classic path whenever the requested userid
matches iucv_userid, even on a guest that also has a HiperSockets device
carrying the same identifier. The child socket created by
afiucv_hs_callback_syn() for such a match inherits hs_dev = NULL and
transport = AF_IUCV_TRANS_HIPER, so the first send() on it returns -ENODEV.
The socket delivered to accept() is unusable.
Second, a frame arriving on one netdev can be delivered to a socket bound
to a different IQD device. Which can lead to
- Accept-queue exhaustion (DoS)
- Attacker-controlled peer identity in the child socket
- Data injection into existing sockets
- Fabric noise on the IQD fabric, where bogus replies are sent
- killing established connections
Third, all AF_IUCV sockets live in init_net, as iucv_sock_alloc() calls
sk_alloc(&init_net, ...). But even frames arriving on netdev devices in a
namespace can be delivered to an IUCV socket. So a process in an
unprivileged user and network namespace holding only the CAP_NET_RAW
capability valid within that namespace can send a raw ETH_P_AF_IUCV frame
on its own lo device and have it matched against init_net sockets.
Fix all three by skipping any socket whose hs_dev does not match the
ingress device. A classic z/VM IUCV socket has hs_dev == NULL; the ingress
dev is never NULL, so classic sockets are skipped automatically. An unbound
HIPER socket also has hs_dev == NULL and is skipped. A bound HIPER socket
is only reachable from the exact IQD device it was bound to. Because hs_dev
is always a device in init_net (iucv_sock_bind() scans
for_each_netdev_rcu(&init_net, ...) exclusively), a frame whose ingress
device belongs to another namespace never matches any socket.
Note that AF_IUCV over HiperSockets provides no per-connection
authentication: no sequence numbers, no TLS, no nonce. The four name fields
identifying a connection are exchanged in plaintext on the shared
HiperSockets segment (VCHID). Any host on the same HiperSockets segment
could spoof any frame type against an existing connection. That is a
protocol-level property unchanged by this patch. The fix reduces the attack
surface to peers present on the same HiperSockets segment.
Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
Cc: stable@vger.kernel.org
Co-developed-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20260821125501.3718748-1-wintera@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Wed Aug 19 11:33:05 2026 +0900
net/smc: bound the peer rkey counts in SMC-Rv2 LLC messages
commit 2d1e7c5aaa3326e95e2058457f172ca99a9a4577 upstream.
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.502617] kthread+0x2c6/0x3b0
[ 2.502762] ret_from_fork+0x36e/0x5a0
[ 2.502925] ret_from_fork_asm+0x1a/0x30
[ 2.503103]
[ 2.503177] The buggy address belongs to the object at ffff888005640680
[ 2.503177] which belongs to the cache kmalloc-96 of size 96
[ 2.503692] The buggy address is located 22 bytes to the right of
[ 2.503692] allocated 72-byte region [ffff888005640680, ffff8880056406c8)
[ 2.504227]
[ 2.504300] The buggy address belongs to the physical page:
[ 2.504535] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5640
[ 2.504865] flags: 0x100000000000000(node=0|zone=1)
[ 2.505076] page_type: f5(slab)
[ 2.505221] raw: 0100000000000000 ffff888001041280 dead000000000122 0000000000000000
[ 2.505544] raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
[ 2.505867] page dumped because: kasan: bad access detected
[ 2.506102]
[ 2.506176] Memory state around the buggy address:
[ 2.506380] ffff888005640580: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
[ 2.506683] ffff888005640600: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
[ 2.506987] >ffff888005640680: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
[ 2.507291] ^
[ 2.507548] ffff888005640700: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
[ 2.507850] ffff888005640780: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
Whatever that read finds then bounds the ext->rt[] loop, so a peer that
declares 255 rkeys reads much further. smc_llc_rmt_delete_rkey() has the
same shape for llcv2->rkey[].
Bound both loops by the buffer they read from, and skip the extension
altogether when there is no shared v2 receive buffer. The extension
does arrive on the link, but smc_llc_enqueue() copies only
sizeof(union smc_llc_msg) into the queue entry, so what that code read
past the 44 inline bytes was heap and not peer data.
Fixes: 27ef6a9981fe ("net/smc: support SMC-R V2 for rdma devices with max_recv_sge equals to 1")
Cc: stable@vger.kernel.org
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260819023306.644849-3-yhlee@isslab.korea.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Fri Sep 4 01:26:02 2026 +0900
net/smc: carry oversized SMC-Rv2 LLC messages in the queue entry
[ Upstream commit 8d3c1ab82c11d4fadebf817a825fd221b3e197ea ]
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.
Fixes: 27ef6a9981fe ("net/smc: support SMC-R V2 for rdma devices with max_recv_sge equals to 1")
Cc: stable@vger.kernel.org
Suggested-by: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260819023306.644849-4-yhlee@isslab.korea.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Sat Aug 8 02:21:24 2026 -0500
net/smc: do not dereference an unset send buffer on the SMC-D teardown path
commit b395dd319cea422239cb45b998fb38d7e373af87 upstream.
smc_close_stream_wait() calls smc_tx_prepared_sends() from inside its
sk_wait_event() condition, and sk_wait_event() evaluates that condition
once with the socket lock released. smcd_buf_detach() clears
conn->sndbuf_desc from smc_conn_kill() under lock_sock(), so a link group
terminating while a socket waits there leaves the helper dereferencing
NULL, faulting out of close(). SIOCOUTQ reads the field by hand, and
smc_close_cancel_work() drops the lock across two cancel_*_sync() calls.
Sample the pointer once in the helper, report nothing prepared while it is
unset, and bound the ioctl the same way. The receive tasklet dereferences
the field directly in smc_cdc_msg_recv_action(), not through this helper;
1/2 is what keeps it from running that late.
Fixes: ae2be35cbed2 ("net/smc: {at|de}tach sndbuf to peer DMB if supported")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Link: https://patch.msgid.link/20260808-b4-disp-22f119e6-v2-2-61647601a6f3@proton.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hidayath Khan <hidayath@linux.ibm.com>
Date: Thu Aug 20 16:47:29 2026 +0200
net/smc: fix socket refcount leak in smc_switch_conns()
commit 719296c4aa8213d4ac8002e77d5956d436bc98d0 upstream.
smc_switch_conns() takes a reference on the SMC socket before dropping
lgr->conns_lock, so the connection stays alive while the CDC slot is
fetched:
sock_hold(&smc->sk);
read_unlock_bh(&lgr->conns_lock);
/* pre-fetch buffer outside of send_lock, might sleep */
rc = smc_cdc_get_free_slot(conn, to_lnk, &wr_buf, NULL, &pend);
if (rc)
goto err_out;
The err_out label only drops the wr_tx link reference, so this early exit
returns without the matching sock_put(). The second error exit is not
affected, because sock_put() has already run by then.
A leaked sk_refcnt means the smc_sock is never destroyed. Its send and
receive buffers stay allocated, and for a user socket the reference held
on the network namespace is never released, so the netns can no longer be
torn down.
smc_cdc_get_free_slot() fails when the target link goes down or when the
connection has been killed while the switch is in progress. Both are
reachable during the link failover this function implements, so the leak
is triggered by the same hardware events that make smc_switch_conns() run
in the first place.
Restructure so there is a single sock_put() covering both outcomes,
instead of adding a second one to the error path.
Fixes: 95f7f3e7dc6b ("net/smc: improved fix wait on already cleared link")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Link: https://patch.msgid.link/20260820144729.1019399-1-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hidayath Khan <hidayath@linux.ibm.com>
Date: Thu Aug 20 09:46:42 2026 +0200
net/smc: fix use-after-free in smc_rx_pipe_buf_release()
commit c924884743e948e25625b7fbf3ee2a9325a204a7 upstream.
smc_rx_splice() hands RMB pages to a pipe and takes a socket reference
per entry so the smc_sock stays alive until the reader finishes. The
connection does not: a concurrent close runs smc_conn_free(), which
releases the receive buffer back to the link group pool.
smc_rx_pipe_buf_release() tests sk_state before taking the socket lock.
The state can change between the test and the lock, and
smc_rx_update_cons() then dereferences conn->rmb_desc and walks
conn->lgr, which smc_conn_free() has already released. On the
is_reg_err path smcr_buf_unuse() frees the descriptor outright, so
this is a use-after-free.
Take the socket lock first and test conn->freed instead.
smc_conn_free() sets that flag before releasing anything, and every
caller holds the socket lock. The two paths exclude each other: either
the pipe release runs first with everything valid, or it sees the flag
and skips the update.
Fixes: 9014db202cb7 ("smc: add support for splice()")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260820074642.966856-3-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Wed Aug 19 11:33:04 2026 +0900
net/smc: fix use-after-free of the LLC qentry in smc_llc_srv_add_link()
commit a42a459ef0e54cb0c4b3e43e21cb0e658e664f64 upstream.
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.534078] process_one_work+0x633/0x1030
[ 2.534257] worker_thread+0x45b/0xd10
[ 2.534424] kthread+0x2c6/0x3b0
[ 2.534569] ret_from_fork+0x36e/0x5a0
[ 2.534737] ret_from_fork_asm+0x1a/0x30
[ 2.534907]
[ 2.534980] Freed by task 11:
[ 2.535112] kasan_save_stack+0x33/0x60
[ 2.535279] kasan_save_track+0x14/0x30
[ 2.535444] kasan_save_free_info+0x3b/0x60
[ 2.535625] __kasan_slab_free+0x43/0x70
[ 2.535798] kfree+0x121/0x380
[ 2.535935] smc_llc_srv_add_link+0x9a8/0x1e50
[ 2.536128] smc_listen_work+0x489e/0x4d00
[ 2.536305] process_one_work+0x633/0x1030
[ 2.536482] worker_thread+0x45b/0xd10
[ 2.536652] kthread+0x2c6/0x3b0
[ 2.536794] ret_from_fork+0x36e/0x5a0
[ 2.536958] ret_from_fork_asm+0x1a/0x30
[ 2.537133]
[ 2.537205] The buggy address belongs to the object at ffff888005219480
[ 2.537205] which belongs to the cache kmalloc-96 of size 96
[ 2.537719] The buggy address is located 94 bytes inside of
[ 2.537719] freed 96-byte region [ffff888005219480, ffff8880052194e0)
[ 2.538216]
[ 2.538289] The buggy address belongs to the physical page:
[ 2.538524] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5219
[ 2.538857] flags: 0x100000000000000(node=0|zone=1)
[ 2.539066] page_type: f5(slab)
[ 2.539210] raw: 0100000000000000 ffff888001041280 dead000000000122 0000000000000000
[ 2.539534] raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
[ 2.539863] page dumped because: kasan: bad access detected
[ 2.540098]
[ 2.540170] Memory state around the buggy address:
[ 2.540379] ffff888005219380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2.540684] ffff888005219400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 2.540988] >ffff888005219480: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
[ 2.541291] ^
[ 2.541548] ffff888005219500: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
[ 2.541857] ffff888005219580: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
The offset is past the 72-byte queue entry because the out-of-bounds read
fixed by the next patch is on the same line; what this patch removes is the
free at smc_llc_srv_add_link+0x9a8 happening before the read at +0xaa2.
Detach the entry instead of freeing it there, and free it at the single
exit label. The reject path has to detach as well, otherwise it would be
freed twice.
This changes only the lifetime of the entry. The same read still runs past
its end until the next two patches bound it, so a backport wants all three.
Fixes: 27ef6a9981fe ("net/smc: support SMC-R V2 for rdma devices with max_recv_sge equals to 1")
Cc: stable@vger.kernel.org
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260819023306.644849-2-yhlee@isslab.korea.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hidayath Khan <hidayath@linux.ibm.com>
Date: Thu Aug 20 09:46:41 2026 +0200
net/smc: stop killed, freed and out_of_sync sharing a byte
commit db51a8658c11a82432b64999519a269c3aabb447 upstream.
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.
Fixes: b286a0651e44 ("net/smc: handle incoming CDC validation message")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260820074642.966856-2-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Sat Aug 8 02:21:23 2026 -0500
net/smc: unregister the connection before draining the rx tasklet
commit 36cdf5d48ca191dcd71c28cadbe0981b1d25318d upstream.
smc_conn_free() calls smc_ism_unset_conn() only while the link group is
still on its device list, and never sets conn->killed.
smc_lgr_terminate_sched() unlinks the group immediately and defers killing
its connections to a work item, so a connection freed in that window keeps
its smcd->conn[] slot with both gates in smcd_handle_irq() open, and the
device can re-arm the receive tasklet after tasklet_kill() has returned. On
the DMB-nocopy path the ghost send buffer is freed right after that drain,
so the re-armed tasklet dereferences it.
Unregister unconditionally and drain before the detach at both teardown
sites, mirroring rmb_desc, which smc_buf_unuse() releases after the drain.
Clear conn->sndbuf_desc before freeing it as well, so a reader that samples
the pointer cannot get one that is already freed.
Fixes: ae2be35cbed2 ("net/smc: {at|de}tach sndbuf to peer DMB if supported")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
Link: https://patch.msgid.link/20260808-b4-disp-22f119e6-v2-1-61647601a6f3@proton.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Thu Aug 13 00:22:35 2026 +0800
net: cap advertised IP tunnel headroom
commit 6b222adeb9340306e2ff97127c76117abb9b3df8 upstream.
IP tunnel devices derive their advertised needed_headroom from lower
output devices. A stack of user-created devices can make the derived
value larger than the 16-bit skb header offsets can represent. Once IP
output reserves it, skb head expansion can wrap those offsets.
The runtime transmit path already caps a growing needed_headroom at 512.
Apply the same cap when tunnel configuration publishes needed_headroom
derived from a lower output device.
Capping the advertised value is safe: IP tunnel transmit still expands
the skb when a packet needs more headroom. A nonsensical stacked
configuration can therefore incur an extra reallocation, but it cannot
publish an unbounded reservation to upper layers.
Fixes: 1a37e412a022 ("net: Use 16bits for *_headers fields of struct skbuff")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/ba04a1fd6bfae2377607fad5d8f80f7eb80fd4c4.1786542637.git.zhilinz@nebusec.ai
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ahmad Fatoum <a.fatoum@pengutronix.de>
Date: Fri Aug 14 13:01:02 2026 +0200
net: dsa: realtek: use gpiod_set_value_cansleep for reset GPIO
commit fb58b6a696b30bcbfbe0cfc0a91b19c816a955fc upstream.
rtl83xx_reset_assert() and rtl83xx_reset_deassert() are only called from
the probe path, which may sleep and is not timing-critical. When the
reset GPIO is provided by a sleeping controller such as an I2C I/O
expander, gpiod_set_value() warns:
WARNING: drivers/gpio/gpiolib.c:4030 at gpiod_set_value+0x44/0x80, CPU#1: kworker/u16:4/61
Hardware name: B&O MAP CA33 Rev f (UNKNOWN) (DT)
Workqueue: events_unbound deferred_probe_work_func
pc : gpiod_set_value+0x44/0x80
lr : rtl83xx_probe+0x1d8/0x3a0
Call trace:
gpiod_set_value+0x44/0x80 (P)
rtl83xx_probe+0x1d8/0x3a0
realtek_mdio_probe+0x24/0xa0
mdio_probe+0x38/0x78
really_probe+0xc4/0x3e0
__driver_probe_device+0x15c/0x1b8
driver_probe_device+0xb4/0x120
__device_attach_driver+0xb8/0x1a0
bus_for_each_drv+0x88/0xf0
__device_attach+0xa0/0x1d8
device_initial_probe+0x54/0x68
bus_probe_device+0x38/0xa0
deferred_probe_work_func+0xb8/0x120
process_one_work+0x184/0x4e8
worker_thread+0x188/0x308
kthread+0x130/0x150
ret_from_fork+0x10/0x20
Switch both helpers to gpiod_set_value_cansleep() so such a reset GPIO can
be used without triggering the warning.
The reset GPIO has been driven with the non-sleeping gpiod_set_value()
since the driver was added in v4.19. The call has since been refactored
across several files - from realtek-smi.c / realtek-mdio.c into the common
rtl83xx.c module and then into the rtl83xx_reset_assert() and
rtl83xx_reset_deassert() helpers (both in v6.9). This patch therefore
applies as-is only to kernels that carry those helpers (v6.9+); older
stable kernels need the same gpiod_set_value_cansleep() conversion at the
corresponding open-coded call sites.
Fixes: d8652956cf37 ("net: dsa: realtek-smi: Add Realtek SMI driver")
Cc: <stable@vger.kernel.org> # 6.9.x
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Co-developed-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Alvin Šipraga <alvin.sipraga@analog.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Link: https://patch.msgid.link/20260814110102.2362246-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Breno Leitao <leitao@debian.org>
Date: Tue Aug 25 03:50:10 2026 -0700
net: fix spurious TX timeout after dev_activate()
commit 82aeed2400786bd3f79d88cb8b8f42e6127e5923 upstream.
While debugging another issue today, I found out that my TX queue is
reported as stopped for 4294907392 ms (49.7 days), on a machine that
had been up for four minutes.
bnxt_en 0002:01:00.0 eth0: NETDEV WATCHDOG: CPU: 28: transmit queue 23 timed out 4294907392 ms
4294907392 is not an elapsed time. It is the value of jiffies at that
moment: INITIAL_JIFFIES is 4294667296, which leaves jiffies 59 seconds
short of wrapping.
dev_activate() runs transition_one_qdisc() over every TX queue, which
resets trans_start to 0, and then stamps only queue 0 through
netif_trans_update().
Stamp jiffies instead. A queue stopped across dev_activate() now gets a
full watchdog_timeo of grace, and is still reported if it is stopped
that long.
Fixes: 9b36627acecd ("net: remove dev->trans_start")
Cc: stable@vger.kernel.org
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Link: https://patch.msgid.link/20260825-trans_start-v2-1-286b4d6d70cb@debian.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Tue Aug 11 15:08:13 2026 +0800
net: ibm: emac: mal: fix NAPI locking
commit 43b0213529c6ae2fd4cbf8dbb9baff87a34c27d7 upstream.
Since commit 413f0271f396 ("net: protect NAPI enablement with
netdev_lock()"), napi_enable() and napi_disable() take netdev_lock().
mal_register_commac() and mal_unregister_commac() call these helpers
while holding mal->lock with interrupts disabled. In the unregister
path, napi_disable() may also wait for polling to finish, while the poll
completion path takes mal->lock.
Take netdev_lock() before mal->lock, use the locked NAPI helpers, and
drop mal->lock before napi_disable_locked().
Fixes: 413f0271f396 ("net: protect NAPI enablement with netdev_lock()")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260811070813.377573-1-runyu.xiao@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Date: Sat Aug 15 06:03:02 2026 +0200
net: ipa: fix stalled modem TX queue after runtime resume
commit 3cbfd627ee720f3d2460d2cbe2fe9e4130240db6 upstream.
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.
Fixes: 688de12f080f ("net: ipa: kill the STARTED IPA power flag")
Cc: stable@vger.kernel.org
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260815040302.653650-1-jorijnvdgraaf@catcrafts.net
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zihan Xi <zihanx@nebusec.ai>
Date: Thu Aug 20 18:40:28 2026 +0000
net: l2tp: do not propagate multicast notification errors
commit af20e269f7459d2ce69887fdf2fad7caf986c865 upstream.
The tunnel create, tunnel modify, session create, and session modify
netlink handlers send multicast notifications through helpers that can fail
while allocating or encoding a message, or while multicasting it.
For tunnel and session create/modify, a notification is sent after the live
operation has completed. Returning a best-effort notification error as the
command result can therefore report failure for an operation that already
committed and can cause callers to retry and accumulate live objects.
Keep sending notifications for listener visibility, but do not propagate
their best-effort status as the command result. This also keeps the tunnel
modify command consistent with the other notification-only paths.
Fixes: 33f72e6f0c67 ("l2tp : multicast notification to the registered listeners")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/54f48e812ca0424c47ffdb9a8182180921f7e6b2.1787247008.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Thu Aug 20 02:25:38 2026 +0900
net: ntb_netdev: Avoid double-accounting netif_rx() drops
commit 82e15be2d8b9efa6fb1750528d9b6f40e6a8eea7 upstream.
netif_rx() already accounts packets it drops in the core rx_dropped
counter. ntb_netdev counts them again as both errors and drops.
Leave netif_rx() drops to the core. Count the packet and bytes
unconditionally since it was received successfully by the driver.
Fixes: 548c237c0a99 ("net: Add support for NTB virtual ethernet device")
Cc: stable@vger.kernel.org
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Link: https://patch.msgid.link/20260819172539.1450821-2-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Thu Aug 20 02:25:39 2026 +0900
net: ntb_netdev: Count packets dropped on RX refill failure
commit 31ded341c375bb2faac1d77ab0012a732ba3e2a6 upstream.
When replacement skb allocation fails, ntb_netdev drops a packet that
was received successfully and requeues the original buffer. The drop is
counted, but rx_packets and rx_bytes are not.
Count every good packet before allocating its replacement.
Fixes: d2121faf133a ("NTB: ntb_netdev: Preserve RX queue depth on allocation failure")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Link: https://patch.msgid.link/20260819172539.1450821-3-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Mon Aug 17 14:35:17 2026 +0900
net: ntb_netdev: Fix TX busy and drop handling
commit 8aaa47351db0f93a5c5297fbafdfa8bc75e8ae49 upstream.
Currently, ntb_netdev returns NETDEV_TX_BUSY for every enqueue error. It
also increments the drop and error counters while leaving the skb owned
by the qdisc, and may return BUSY with the subqueue still awake.
Retrying a permanent error cannot succeed either.
The unconditional BUSY return and premature accounting date back to the
initial driver. The error-path queue stop was later removed without
changing that return value. The current flow-control code includes a
resource check, but ntb_netdev does not honor its result before enqueue.
Honor the resource check before enqueue. For -EAGAIN and -EBUSY, stop
the subqueue, arm the existing reaper timer, and return BUSY without
touching the skb. For other errors, free the skb, increment tx_dropped,
and return NETDEV_TX_OK.
Fixes: 548c237c0a99 ("net: Add support for NTB virtual ethernet device")
Fixes: d723485cb4ca ("ntb_netdev: remove tx timeout")
Fixes: e74bfeedad08 ("NTB: Add flow control to the ntb_netdev")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260817053519.4135287-3-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ilya Maximets <i.maximets@ovn.org>
Date: Sat Aug 15 02:58:56 2026 +0200
net: openvswitch: fix flow mask use-after-free on flow deletion
commit 4e30317ff67a2eb12b4d890d39f72fd7e7117d48 upstream.
The commit in the Fixes tag below made so flow->mask free is scheduled
via RCU right after it is removed from the flow table. The pointer
stays in the flow structure and it can be accessible while in the same
RCU critical section. This is done to avoid requiring ovs_mutex for
the ovs_flow_free().
However, while removing the flow during processing of CMD_DEL, we do
not take RCU read lock before the removal, and ovs_flow_cmd_fill_info()
uses the flow->mask pointer afterwards. The RCU read lock is taken,
but it's already late at that point. The comment on that line
acknowledges that the lock is cosmetic and doesn't serve a real purpose.
This leads to use-after-free if the RCU grace period passes between
removal and the filling. It is a short race window, but it is there
and can lead to a real crash in case memory allocation for the info
takes a bit longer:
BUG: KASAN: slab-use-after-free in __ovs_nla_put_key
net/openvswitch/flow_netlink.c:1996
BUG: KASAN: slab-use-after-free in ovs_nla_put_key+0x2463/0x2e30
net/openvswitch/flow_netlink.c:2250
Read of size 4 at addr ffff88801ee89970 by task ovs_flow_del_ec/9487
Call Trace:
<TASK>
__ovs_nla_put_key net/openvswitch/flow_netlink.c:1996
ovs_nla_put_key+0x2463/0x2e30 net/openvswitch/flow_netlink.c:2250
ovs_flow_cmd_fill_info+0x420/0x9c0 net/openvswitch/datapath.c:930
ovs_flow_cmd_del+0x53a/0x970 net/openvswitch/datapath.c:1467
...
netlink_rcv_skb+0x156/0x420 net/netlink/af_netlink.c:2556
</TASK>
Allocated by task 9487:
mask_alloc net/openvswitch/flow_table.c:967
flow_mask_insert net/openvswitch/flow_table.c:1012
ovs_flow_tbl_insert+0xea2/0x1a90 net/openvswitch/flow_table.c:1084
ovs_flow_cmd_new+0x7e3/0xd90 net/openvswitch/datapath.c:1086
...
netlink_rcv_skb+0x156/0x420 net/netlink/af_netlink.c:2556
Freed by task 9485:
rcu_free_sheaf+0x1e/0x100 mm/slub.c:5978
rcu_do_batch kernel/rcu/tree.c:2645
rcu_core+0x59c/0x10c0 kernel/rcu/tree.c:2897
handle_softirqs+0x1e4/0x9a0 kernel/softirq.c:622
...
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062
ovs_flow_tbl_remove() must be called after the ovs_flow_cmd_fill_info()
to avoid this race. This also helps with cleaning up the forced cast
and the cosmetic RCU read lock. Before the commit in the Fixes tag the
order did not matter as long as the flow object itself was not freed.
A wider RCU critical section could be another option, but we have a
GFP_KERNEL allocation in the way.
Reported by Trend Micro's Zero Day Initiative as ZDI-CAN-32042.
Fixes: 56c19868e115 ("openvswitch: Make flow mask removal symmetric.")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260815005915.1097270-1-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ruoyu Wang <ruoyuw560@gmail.com>
Date: Sat Aug 15 23:17:29 2026 +0800
net: openvswitch: fix nf_connlabels leak in ovs_ct_init
commit f9de5db270a4c2641de87ee558c16a9bc6eb4cd8 upstream.
ovs_ct_init() acquires a connlabels reference before initializing the
conntrack limit state. If ovs_ct_limit_init() fails, its error is returned
directly. The pernet core does not invoke the exit callback for the
operation whose initialization failed, so ovs_ct_exit() cannot drop the
reference.
This leaves labels_used elevated when Open vSwitch pernet registration
fails for an existing network namespace. Subsequent conntrack entries in
that namespace may allocate label extensions even though Open vSwitch
failed to register.
Drop the connlabels reference before returning a conntrack limit
initialization error. ovs_ct_limit_init() already releases its partial
state, and the original error remains unchanged.
This issue was found by a static analysis checker and confirmed by
manual source review.
Fixes: 11efd5cb04a1 ("openvswitch: Support conntrack zone limit")
Cc: stable@vger.kernel.org
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/20260815151729.3757984-1-ruoyuw560@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon Aug 17 23:30:03 2026 +0200
net: phylink: correctly validate returned PCS in phylink_inband_caps
commit f2849b1fd059ec9b3281b771e6ac5aad9feee851 upstream.
In phylink_inband_caps(), the PCS returned by mac_select_pcs is only
checked if NULL but mac_select_pcs can also return an error pointer.
This can cause a kernel panic as phylink_pcs_inband_caps() only checks
if passed PCS is not NULL and directly dereference ops from the phylink_pcs
struct.
Use the IS_ERR_OR_NULL macro to address both case where the returned
PCS can be NULL or an error pointer and prevent a kernel panic.
Cc: stable@vger.kernel.org
Fixes: df874f9e52c3 ("net: phylink: add pcs_inband_caps() method")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Link: https://patch.msgid.link/20260817213009.13924-1-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Date: Tue Aug 11 18:37:32 2026 +0800
net: ravb: avoid dereferencing an invalid PTP clock
commit 1f77af0aaf277413ff32f6ff8c2c4282bd64c897 upstream.
The PTP clock is unavailable before the first open, so querying its
index can dereference a NULL pointer. Registration failures can also
leave an error pointer in priv->ptp.clock.
Cache the PHC index separately and report -1 while no clock is
registered. Normalize registration errors to NULL and preserve the
static timestamping capabilities.
Fixes: a0d2f20650e8 ("Renesas Ethernet AVB PTP clock driver")
Cc: stable@vger.kernel.org
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260811103733.62599-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Date: Tue Aug 11 18:37:33 2026 +0800
net: ravb: serialize PTP clock teardown
commit 1cb9663789c5b7a12fcd419fcca6d6254c398252 upstream.
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.
Fixes: a0d2f20650e8 ("Renesas Ethernet AVB PTP clock driver")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260811103733.62599-3-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Norbert Szetei <norbert@doyensec.com>
Date: Sat Aug 22 11:15:08 2026 +0200
net: skbuff: don't touch shared zerocopy state in skb_tx_error()
commit f66bdb1cc0fcd227a062378f8be0b5873aa5600a upstream.
skb_tx_error() completes the zerocopy uarg and clears
SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears
SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone
shares, while the caller only owns the reference it is about to drop.
Through a clone it tells the producer its pages are free and drops
SKBFL_SHARED_FRAG for an skb that is still in flight.
Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC:
clone_execute() sends a skb_clone() into ovs_dp_process_packet() while
do_execute_actions() keeps forwarding the original, and skb_clone()
does not privatise the frags here -- skb_orphan_frags() returns early
on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker
from the packet still being forwarded, and a later local ESP delivery
decrypts in place over frags it does not own privately.
Skip it for a cloned skb. Nothing is lost: skb_release_data() clears
the zerocopy state once the last reference to the shared data goes.
Fixes: 25121173f7b1 ("skb: api to report errors for zero copy skbs")
Cc: stable@vger.kernel.org
Suggested-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Tested-by: Jongmin Jang <payload.jang@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/CFAB292A-674B-4C14-BB2C-BB8830AD5659@doyensec.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Ye <fy15309206903@gmail.com>
Date: Tue Aug 11 13:20:50 2026 +0000
net: thunderbolt: Mark the connection down when bringing it up fails
commit 3c8b26ebf525ba5960510f48c6e9936a79ebe76f upstream.
Every failure path in tbnet_connected_work() undoes its own work and
returns without clearing login_sent, so the connection still looks
established. The next tbnet_tear_down() therefore takes its main branch
and repeats a teardown that already happened: it stops rings that are
already stopped, which is a dev_WARN() and fatal under panic_on_warn,
and it releases net->remote_transmit_path even on the HopID mismatch
path, where this connection never owned that id, silently freeing one
that someone else is still using.
Clear login_sent on those paths. That is enough for tbnet_tear_down() to
leave the unwound state alone, and login_received has to stay set: it
records that the peer has logged in and carries the transmit path it gave
us, which nothing on this side can make the peer send again. Two things
change beyond keeping the teardown out of the way: the logout request in
that block is no longer sent, and the peer's next login request now
re-queues our login work rather than connected_work, giving the
connection a fresh login instead of a retry on stale state.
Fixes: e69b6c02b4c3 ("net: Add support for networking over Thunderbolt cable")
Cc: <stable@vger.kernel.org> # 5.13+
Signed-off-by: Fan Ye <fy15309206903@gmail.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260811-b4-tbnet-hopid-v3-2-9e75d1b51331@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Ye <fy15309206903@gmail.com>
Date: Tue Aug 11 13:20:49 2026 +0000
net: thunderbolt: Release the Rx HopID that was handed out on mismatch
commit 2f1463554d0561a2fead81e3888604e5c1125e29 upstream.
tb_xdomain_alloc_in_hopid() passes the wanted HopID to ida_alloc_range()
as the lower bound, so a taken id is not an error there: the allocator
returns the next free one above it. tbnet_connected_work() asks for the
peer's transmit path, treats any other id as a failure and returns
without releasing what it got, so that allocation stays live for the rest
of the XDomain connection with nothing left holding a reference to it.
Release the id when it is not the one we asked for, the same way the
error unwind at the end of the function releases the expected one.
Fixes: 180b0689425c ("thunderbolt: Allow multiple DMA tunnels over a single XDomain connection")
Cc: stable@vger.kernel.org
Signed-off-by: Fan Ye <fy15309206903@gmail.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260811-b4-tbnet-hopid-v3-1-9e75d1b51331@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Asim Viladi Oglu Manizada <manizada@pm.me>
Date: Wed Aug 12 01:21:53 2026 +0000
net: tun: bound receive headroom
commit 447c9303942c439a117d9b76ce6d6e2116b38ee7 upstream.
tun_get_user() uses tun->align both as skb headroom and when choosing how
much packet data to keep linear. OVS can propagate an oversized headroom
request from another port to TUN or TAP.
When align is larger than the usable space in a one-page skb head,
SKB_MAX_HEAD(align) underflows and the result becomes negative when stored
in good_linear. That value later wraps when assigned to the size_t linear
variable, and tun_alloc_skb() can place skb->data outside the allocated
head.
Bound the headroom stored by TUN to the one-page skb-head budget and the
largest non-sentinel 16-bit skb header offset. Leave one linear byte for
raw TUN and a complete Ethernet header for TAP, including NET_IP_ALIGN.
Also pull the raw-TUN protocol byte and the TAP Ethernet header before
accessing them, so these checks remain safe for nonlinear skbs supplied by
other allocation paths.
Fixes: eaea34b23c46 ("net/tun: implement ndo_set_rx_headroom")
Cc: stable@vger.kernel.org
Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260812012139.2134643-1-manizada@pm.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fabio Porcedda <fabio.porcedda@gmail.com>
Date: Wed Aug 12 07:49:11 2026 +0200
net: usb: qmi_wwan: add Telit Cinterion FE990D50 composition
commit 1056e79fffd0841f43c6a1b25664b196b3caf1c6 upstream.
Add the followin Telit Cinterion FE990D50 composition:
0x0991: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + ADPL + adb
T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 10 Spd=480 MxCh= 0
D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=1bc7 ProdID=0991 Rev=06.06
S: Manufacturer=Telit Cinterion
S: Product=FE990
S: SerialNumber=2aa802d2
C: #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Cc: stable@vger.kernel.org
Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260812054911.447887-1-Fabio.Porcedda@telit.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: David Howells <dhowells@redhat.com>
Date: Tue May 12 13:33:39 2026 +0100
netfs: Fix missing locking around retry adding new subreqs
[ Upstream commit cce18c263e9623872327ba3c956012f73c1179cc ]
Fix netfs_retry_read_subrequests() and netfs_retry_write_stream() to take
the appropriate lock when adding extra subrequests into
stream->subrequests.
Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item")
Fixes: 288ace2f57c9 ("netfs: New writeback implementation")
Closes: https://sashiko.dev/#/patchset/20260425125426.3855807-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260512123404.719402-3-dhowells@redhat.com
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Chris Mason <clm@meta.com>
Date: Tue Jun 2 12:23:15 2026 -0400
NFS/localio: fix ref leak on nfs_uuid_add_file failure
commit ca018c19e0ba38975e5ddc3ef8117d5b734313aa upstream.
When nfs_uuid_add_file() races with nfs_uuid_put() tearing down
uuid->net, it returns -ENXIO without publishing nfl->nfs_uuid via
rcu_assign_pointer(). nfs_open_local_fh() then enters its error
branch and only releases the slot's file ref and its paired net
ref plus its own entry-time net ref, while the close path is a
no-op:
nfs_close_local_fh()
nfs_uuid = rcu_dereference(nfl->nfs_uuid);
if (!nfs_uuid) { rcu_read_unlock(); return; } /* always */
nfsd_open_local_fh() returns localio holding a caller-owned +1
nfsd_file reference (from nfsd_file_get() after
nfsd_file_acquire_local()) and an entry-time nfsd_net reference
(from its first nfsd_net_try_get()) embedded as nf->nf_net. Both
are leaked on the failure path, pinning one nfsd_file (and the
underlying struct file, dentry, inode) and one nfsd_net_ref per
occurrence, which blocks nfsd_net and netns teardown.
Fix by releasing the caller-owned file ref and its net ref through
the existing helper, using a stack-local RCU pointer so the helper
can xchg it out, then returning -ENXIO so callers do not
dereference a localio whose slot has been cleared:
struct nfsd_file __rcu *tmp = RCU_INITIALIZER(localio);
nfs_to_nfsd_file_put_local(pnf);
nfs_to_nfsd_file_put_local(&tmp);
localio = ERR_PTR(-ENXIO);
The trailing nfs_to_nfsd_net_put(net) continues to release the
outer net ref, so all three nfsd_net_try_get() increments are
balanced on the error branch.
Fixes: fdd015de7679 ("NFS/localio: nfs_uuid_put() fix races with nfs_open/close_local_fh()")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-3-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nate Prodromou <nate@prodromou.com>
Date: Tue Jul 14 18:58:46 2026 +0000
NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails
commit 2092f5b38f88be306140c77aeeeb43fc1adacacc upstream.
nfs4_server_common_setup() allocates server->delegation_hash_table
first, but server->destroy - the only path that frees the table via
nfs4_destroy_server() - is not assigned until the very end of the
function. If any intermediate step fails (the is_ds_only_client()
check, nfs4_init_session(), nfs4_get_rootfh(), or nfs_probe_server()),
the function returns with server->destroy still NULL, so the caller's
nfs_free_server() skips the destroy callback and the hash table is
leaked (4 KiB per attempt with the default delegation watermark).
This is trivially reachable from userspace: every failed NFSv4 mount
leaks one allocation. A client that persistently retries a mount that
cannot succeed leaks kernel memory without bound. Observed in
production where a Longhorn backup poller retried mount.nfs4 against
an NFSv3-only server roughly 10 times per second, leaking ~3.4 GiB of
unreclaimable slab (kmalloc-rnd-13-4k) per day; the node accumulated
12 GiB of leaked slab before the source was identified via the
kmem:kmalloc tracepoint (call_site=nfs4_delegation_hash_alloc).
Reproducer:
# server exports NFSv3 only (or export path absent for v4)
while :; do mount -t nfs4 <server>:/missing /mnt; done
# watch SUnreclaim in /proc/meminfo grow 4 KiB per iteration
Free the table on the error paths between the allocation and the
assignment of server->destroy.
Fixes: f5b3108e6a14 ("NFS: use a hash table for delegation lookup")
Cc: stable@vger.kernel.org
Signed-off-by: Nate Prodromou <nate@prodromou.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:54 2026 -0400
nfsd: add fh_want_write() for early-verified SETATTR in nfsd_proc_setattr()
commit 4e475be769aa9f7a2c1ce55a2b8592cfccacddcc upstream.
The BOTH_TIME_SET branch calls fh_verify() early so setattr_prepare()
can inspect the dentry. This causes nfsd_setattr() to skip
fh_want_write(), so notify_change() runs without a mount write
reference.
Add the missing fh_want_write() call after the early fh_verify().
Fixes: cc265089ce1b ("nfsd: Disable NFSv2 timestamp workaround for NFSv3+")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-11-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:49 2026 -0400
nfsd: add filehandle match check to nfsd4_delegreturn()
commit 04cce9d79f2b1a114f7128e08bf60a473e10f1ec upstream.
nfsd4_delegreturn() is the only stateful NFSv4 operation that does
not call nfs4_check_fh() to verify the delegation's file matches
cstate->current_fh. A client can DELEGRETURN with a mismatched
filehandle, destroying the correct delegation but waking the wrong
inode's waiters.
Add the missing nfs4_check_fh() call after the generation check.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-6-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:45 2026 -0400
nfsd: add missing read barrier to rpc_status_get dumpit seqcount retry
commit a71f161a857117e8e0264deb7d14fff5c98adcf5 upstream.
The hand-rolled seqcount-like protocol in nfsd_nl_rpc_status_get_dumpit()
is missing a read memory barrier (smp_rmb) before its second counter
check. The standard kernel read_seqcount_retry() includes smp_rmb()
to ensure that all data reads complete before the counter is re-checked.
Without this barrier, on weakly-ordered architectures (ARM, POWER),
the CPU may reorder field reads past the second counter check, making
the retry logic ineffective: it could observe a consistent counter pair
while reading fields that have been concurrently modified by the writer.
Add smp_rmb() before the second counter check to order the field reads
ahead of it, matching the barrier semantics of the standard seqcount
read-side. The begin-side smp_load_acquire() already pairs with the
smp_store_release() in nfsd_dispatch(); with the smp_rmb() now ordering
the field reads, the retry check no longer needs acquire semantics and
reads the counter with a plain READ_ONCE(), as read_seqcount_retry()
does.
Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: Use READ_ONCE instead of smp_load_acquire() ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-2-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Wed May 27 10:53:37 2026 -0400
nfsd: block non-SAVEFH ops after FOREIGN PUTFH to prevent NULL deref
commit c59738a00aa51b16adc1b5ceb7c80877168efb4d upstream.
When CONFIG_NFSD_V4_2_INTER_SSC is enabled, nfsd4_putfh() can return
success with fh_dentry and fh_export both NULL if fh_verify() returns
nfserr_stale and putfh->no_verify is true. The NFSD4_FH_FOREIGN flag
is set, but the compound dispatch loop only uses this flag to bypass
the nfserr_nofilehandle check -- it does not prevent subsequent ops
from running with a NULL fh_dentry.
A remote client can exploit this by crafting a COMPOUND that includes
an inter-SSC COPY (which causes check_if_stalefh_allowed() to set
no_verify=true on the saved PUTFH) with an additional op inserted
between the source PUTFH and SAVEFH. For example, SETATTR calls
fh_want_write() which dereferences fh_export->ex_path.mnt without
calling fh_verify() first, causing a NULL pointer dereference in the
nfsd kthread.
Fix this by gating the dispatch loop: when NFSD4_FH_FOREIGN is set
and fh_dentry is NULL, only OP_SAVEFH (needed for the inter-SSC flow)
and ops with ALLOWED_WITHOUT_FH (which don't need a resolved
filehandle) may proceed. All other ops receive nfserr_stale, per
RFC 7862 Section 15.2.3 which specifies that foreign filehandle
validation is deferred to the consuming operation and NFS4ERR_STALE
returned at that point.
Fixes: b9e8638e3d9e ("NFSD: allow inter server COPY to have a STALE source server fh")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260527-putfh_foreign_fh_null_deref_consumers-v1-1-1b8a5aa28c59@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Fri Jul 10 10:00:09 2026 -0400
nfsd: check client ownership when cancelling a copy-notify stateid
commit 6bdbfab96e0cf25e5f57dac5c09dc1749751a4bf upstream.
On the OFFLOAD_CANCEL path (clp != NULL), manage_cpntf_state() freed the
target cpntf state without checking ownership. The lookup key
st->si_opaque.so_id is allocated cyclically (guessable) and the embedded
clientid is the fixed per-net nn->s2s_cp_cl_id, so any authenticated
NFSv4.2 client could cancel and free another client's copy-notify
stateid.
Compare the creating clientid recorded in state->cp_p_clid against the
requesting client's cl_clientid and return nfserr_bad_stateid on a
mismatch instead of freeing the entry.
Fixes: ce0887ac96d3 ("NFSD add nfs4 inter ssc to nfsd4_copy")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-5-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Sat May 30 09:19:22 2026 -0400
NFSD: check truncate permission under inode lock
commit b778e0e0a16759f22a70579c3cf8d254a40d4a7f upstream.
nfsd_setattr() checks whether a size update needs NFSD_MAY_TRUNC
before it takes inode_lock(). The comparison uses the file size sampled
by that unlocked read, but the actual ATTR_SIZE update is applied later
under inode_lock() by notify_change().
This leaves a TOCTOU window for append-only files. If a client sends a
SETATTR that does not shrink the file at the time of the unlocked
sample, a concurrent append can extend the file before nfsd_setattr()
takes inode_lock(). notify_change() then applies a real truncation
without the NFSD_MAY_TRUNC check that rejects IS_APPEND(inode). The VFS
truncate syscall paths perform their own append-only checks before
calling notify_change(), so NFSD must make this decision against the
locked size it is about to change.
Split the write-count acquisition from the truncation permission check.
Keep get_write_access() before the locked setattr work, then recheck
whether the requested size is below i_size_read(inode) after inode_lock()
has been acquired and before notify_change(ATTR_SIZE). This also avoids
the plain unlocked inode->i_size load.
Fixes: 783112f7401f ("nfsd: special case truncates some more")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-nfsd-fixes-v2-6-f27e8eb4d974@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue May 26 12:38:46 2026 -0400
nfsd: clear CALLBACK_RUNNING on failed delegation recall queue
commit b036727d334b1b7cd4c1f1fba3b59ba93a6bbe96 upstream.
nfsd_break_one_deleg() sets NFSD4_CALLBACK_RUNNING via test_and_set_bit
at entry to serialize recall work, then calls nfsd4_run_cb() to queue
the recall. When the queue attempt fails the refcount bump is undone,
but the RUNNING bit is left set. The only site that clears the bit is
nfsd41_destroy_cb() (fs/nfsd/nfs4callback.c), which runs from the
workqueue and is therefore unreachable when nothing was queued.
The bit becomes a permanent latch on dp->dl_recall.cb_flags: every
subsequent break_lease() on the same delegation hits the early-return
guard in nfsd_break_one_deleg() and silently skips the recall, so the
delegation is never broken and the conflicting open or lock stalls.
Fix by clearing NFSD4_CALLBACK_RUNNING on the !queued branch alongside
the refcount_dec.
Fixes: 1054e8ffc5c4 ("nfsd: prevent callback tasks running concurrently")
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-cb_recall_any_callback_running_stuck-v1-2-310011a028f3@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:44 2026 -0400
nfsd: clear opcnt on compound arg release to prevent OOB read
commit ae4c38555e81563b8dc5eae55ffd70f0ea97aa5a upstream.
nfsd4_release_compoundargs() resets args->ops to the inline iops[8]
array when the dynamically-allocated ops buffer is freed, but leaves
args->opcnt at its original value (which can be up to 200 for NFSv4.1+
compounds).
If rq_status_counter is stuck at an odd value (which can happen when
nfsd_dispatch() hits an error path after setting it odd), the RPC
status dumpit handler reads min(opcnt, 16) entries from args->ops[].
Since iops only has 8 elements and is the last field in struct
nfsd4_compoundargs, reading indices 8-15 accesses adjacent slab memory
and leaks it to userspace via netlink.
Zero opcnt unconditionally in nfsd4_release_compoundargs() so stale
compound metadata is never exposed through the status interface.
Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: Remove the kvfree_rcu_mightsleep() sleep from the exposure window ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-1-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue May 26 12:38:45 2026 -0400
nfsd: defer setting NFSD4_CALLBACK_RUNNING in deleg_reaper
commit 108969960dc54de673869814c5f37c22f6cf404a upstream.
deleg_reaper() sets NFSD4_CALLBACK_RUNNING before checking the
5-second rate limit and cl_cb_state gates. When either gate fires
the loop continues without queuing callback work, so the bit's only
clear site in nfsd41_destroy_cb() is never reached and RECALL_ANY
dispatch is permanently disabled for the affected client.
Move the test_and_set_bit() below both non-queueing gates so the
bit is taken only when nfsd4_run_cb() will be called.
Fixes: 424dd3df1f99 ("nfsd: eliminate cl_ra_cblist and NFSD4_CLIENT_CB_RECALL_ANY")
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-cb_recall_any_callback_running_stuck-v1-1-310011a028f3@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue Jun 2 12:23:13 2026 -0400
nfsd: defer vfree of compound ops to fix rpc_status UAF
commit fca26a3fc19ed02278aa2a150af82d43db0302cb upstream.
The rpc_status netlink dumpit walks every in-flight svc_rqst under
rcu_read_lock and, for NFSv4 requests, reads opnums out of
args->ops[]. But args->ops is a separate vmalloc buffer freed
synchronously by vfree() in nfsd4_release_compoundargs() at the end
of every compound. The dumpit's rcu_read_lock pins the svc_rqst
struct itself (freed via kfree_rcu), but nothing defers the vfree
of the ops buffer across the RCU grace period. A concurrent compound
completion can therefore free the buffer while the dumpit is reading
it — a use-after-free on vmalloc memory.
The trailing seqcount recheck (smp_load_acquire of rq_status_counter)
cannot undo a load that already retired against freed memory.
Fix by replacing vfree(args->ops) with kvfree_rcu_mightsleep(), which
defers the free until after an RCU grace period. This makes the
existing rcu_read_lock in the dumpit sufficient to protect the read.
The tradeoff is that completed compound ops buffers (up to
200 * sizeof(struct nfsd4_op)) persist in memory slightly longer,
across one grace period, before being reclaimed.
Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-1-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue May 26 12:24:48 2026 -0400
nfsd: don't free session slots that are still in use
commit f5d22e372f4ac3eb287037a488c29691d52a6330 upstream.
nfsd4_sequence() can free the very slot it is currently processing.
When the session shrinker has reduced se_target_maxslots below
se_fchannel.maxreqs, the shrink path checks three conditions before
calling free_session_slots():
1. se_target_maxslots < maxreqs (shrink was advertised)
2. slot->sl_generation == se_slot_gen (slot is up-to-date)
3. seq->maxslots <= se_target_maxslots (client acknowledges)
However, seq->slotid is never checked against se_target_maxslots.
A client using a slot in the range [se_target_maxslots, maxreqs) can
satisfy all three conditions: its slot has the current generation
(set by a prior SEQUENCE), and it sends sa_highest_slotid <=
se_target_maxslots to acknowledge the reduction.
free_session_slots() then kfrees every slot at index >=
se_target_maxslots, including the caller's own slot. The function
continues to write sl_seqid, sl_flags, sl_generation, and stores the
dangling pointer in cstate->slot. Later, nfsd4_store_cache_entry()
copies up to maxresp_cached bytes of the compound reply into the freed
sl_data[] array, corrupting whatever slab object now occupies that
address.
Additionally, a concurrent thread processing SEQUENCE on a different
high-numbered slot can have its slot freed out from under it.
NFSD4_SLOT_INUSE is set under nn->client_lock before the lock is
released, so any concurrent thread past SEQUENCE will have its slot
marked. However, free_session_slots() does not check NFSD4_SLOT_INUSE
before freeing.
Fix both problems by:
1. Checking that the current request's slotid is below the shrink
boundary.
2. Scanning slots in the to-be-freed range for NFSD4_SLOT_INUSE and
deferring the shrink if any are active.
Fixes: fc8738c68d0b ("nfsd: add support for freeing unused session-DRC slots")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-nfsd4_sequence_shrink_uaf_on_loaded_slot-v2-1-74a89db0639e@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:01:04 2026 -0400
nfsd: drop the stateid, not the stateowner, on seqid_op replay retry
commit 5e4627d3513e60accfce9d5f4c7fa95251ef93d6 upstream.
In nfs4_preprocess_seqid_op() the stateid is obtained from
nfsd4_lookup_stateid(), which holds a reference on the nfs4_stid
(sc_count) but takes no reference on the stateowner. openlockstateid()
merely casts that stid and likewise takes no reference.
When nfsd4_cstate_assign_replay() returns -EAGAIN (the replay owner is
being torn down, RP_UNHASHED) it has not taken a stateowner reference on
that path. The error handling nevertheless called
nfs4_put_stateowner(stp->st_stateowner), dropping an so_count reference
the function never acquired -- risking a stateowner refcount underflow and
use-after-free -- while leaking the sc_count reference held on the stid.
The leaked stid reference can also stall a concurrent
nfsd4_close_open_stateid() waiting for sc_count to drop.
Drop the reference actually held -- the stid -- before retrying. The
stateowner stays alive through the reference held by the stid. This mirrors
the open path in nfsd4_process_open1(), where the put balances a reference
that path explicitly holds on the stateowner.
Fixes: eec762080008 ("nfsd: replace rp_mutex to avoid deadlock in move_to_close_lru()")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-21-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Sun Jul 12 11:09:11 2026 -0400
NFSD: Encode only the status in NFS-ACL v2 GETACL error replies
commit ed4edddad19babf76b56882ad9600f5646b167a0 upstream.
The NFSv2 ACL GETACL reply is a union that carries file attributes
and ACL data only when the status is NFS_OK. All error cases are
void results. However, currently the NFSv2 ACL GETACL result encoder
decides whether to append the "OK" body by testing only whether the
file handle resolved to a positive dentry, not the actual reply
status.
A GETACL request that resolves its file handle but then fails for
another reason (an unsupported mask value, a getattr failure, or an
ACL retrieval error) therefore appends file attributes and ACL data
after the error status on the wire. Worse, when the mask is
rejected, fh_getattr() hasn't been called at all, so those
attributes are serialized from a zero-filled kstat and are junk.
The logic before the xdr_stream conversion used the reply status.
Revert to that approach (but keep the xdr_stream conversion in
place).
Fixes: f8cba47344f7 ("NFSD: Update the NFSv2 GETACL result encoder to use struct xdr_stream")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260712150911.48461-1-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Sat May 30 09:19:17 2026 -0400
nfsd: fix BUG_ON in nfsd4_alloc_layout_stateid on racing delegation revoke
commit ca94ba36172046be6a694a7986f6931e47ed4d51 upstream.
nfsd4_alloc_layout_stateid reads fp->fi_deleg_file without holding
fi_lock when the parent stateid is a delegation. A concurrent delegation
revoke via the laundromat can clear fi_deleg_file under fi_lock, causing
nfsd_file_get() to return NULL and triggering the BUG_ON.
This race is client-reachable: two NFS clients can trigger it by having
one hold a delegation while another opens the same file to force a
recall. When the first client doesn't respond to the recall, the
laundromat revokes it. A concurrent LAYOUTGET from any client using the
delegation stateid hits the race window.
Fix this by taking fi_lock around the fi_deleg_file read in the
SC_TYPE_DELEG path, matching the locking discipline of the
find_any_file() arm, and replacing the BUG_ON with a graceful error
return that cleans up the partially-initialized layout stateid.
Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-nfsd-fixes-v2-1-f27e8eb4d974@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Fri Jul 10 10:00:05 2026 -0400
nfsd: fix cpntf publish race in nfs4_init_cp_state
commit be3a5c1d857b0dcbc11796cea603ef25834f75b2 upstream.
nfs4_alloc_init_cpntf_state() published the new cpntf entry into the
s2s_cp_stateids IDR (with cs_type set) in one s2s_cp_lock section, then
took the lock again to list_add() it onto p_stid->sc_cp_list. In the gap
the entry is reachable by so_id but cp_list is still {NULL,NULL} from
kzalloc. A racing OFFLOAD_CANCEL (so_id is echoed to the client as
cnr_stateid, so any NFSv4.2 client can drive it) reaches
manage_cpntf_state() -> _free_cpntf_state_locked() and does list_del() on
the zeroed list_head, oopsing the server.
Fold the cs_type assignment and the list_add() into the same critical
section as idr_alloc_cyclic(), so a concurrent lookup either misses the
entry or sees a fully linked cp_list. INIT_LIST_HEAD() the entry after
allocation and switch _free_cpntf_state_locked() to list_del_init() so a
stale unlink is a no-op. nfs4_init_copy_state() passes NULL p_stid and
skips the list_add, preserving NFS4_COPY_STID semantics.
Fixes: 624322f1adc5 ("NFSD add COPY_NOTIFY operation")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-1-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Sun May 31 08:07:01 2026 -0400
nfsd: fix dentry ref leak on V4ROOT export filehandle lookup
commit 6247023fbbec1325029f2d5f2a7cdc0f9f9ea15a upstream.
nfsd_set_fh_dentry() leaks the dentry reference from
exportfs_decode_fh_raw() when the NFS3_FHSIZE or NFS_FHSIZE
switch cases detect NFSEXP_V4ROOT and goto out. The out: label
calls exp_put() but never dput(dentry), and fhp->fh_dentry was
never assigned so fh_put() cannot compensate.
A crafted NFSv3 filehandle targeting a V4ROOT export's fsid
triggers the leak on every request.
Fixes: ef7f6c4904d0 ("nfsd: move V4ROOT version check to nfsd_set_fh_dentry()")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-4-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:53 2026 -0400
nfsd: fix FL_SLEEP being set unconditionally for all LOCK types
commit 246a90a5109bb2857db41f491277882ee2743b26 upstream.
The FL_SLEEP guard uses lk_type & (NFS4_READW_LT | NFS4_WRITEW_LT) which
computes lk_type & 7, non-zero for all valid lock types including
non-blocking ones. This was introduced by commit 7e64c5bc497c
("NLM/NFSD: Fix lock notifications for async-capable filesystems") when
refactoring from per-case switch arms.
Replace the bitmask test with explicit equality checks.
Fixes: 7e64c5bc497c ("NLM/NFSD: Fix lock notifications for async-capable filesystems")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-10-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:46 2026 -0400
nfsd: fix netlink dumpit error handling for rpc_status_get
commit e13d505af73a1e013aa81806652d4378b21cfca2 upstream.
nfsd_genl_rpc_status_compose_msg() returns -ENOBUFS on nla_put failure
without calling genlmsg_cancel(), leaving a partial message in the skb.
The caller then propagates -ENOBUFS directly, which the netlink dump
infrastructure treats as a fatal error, aborting the entire dump.
The correct netlink dump convention is:
- Cancel any partial message with genlmsg_cancel()
- If prior messages were added to the skb (skb->len > 0), save the
current iterator position and return skb->len to paginate
- Only return a negative errno when no messages fit at all
Fix compose_msg to cancel the partial message on all nla_put failure
paths, and fix the caller to paginate when possible rather than
returning a fatal error.
A second defect surfaces once pagination actually works: cb->args[1]
records the resume index within the pool named by cb->args[0], but the
inner loop applied it to every pool from cb->args[0] onward. After a
mid-pool pause, a later dump call drains the resume pool and continues
into subsequent pools within the same call, where the stale cb->args[1]
caused the first N threads of each following pool to be skipped. On
per-CPU or per-node pool configurations this silently dropped active
requests from the dump. Apply the saved thread index only to the pool
matching cb->args[0], and start every subsequent pool from thread 0.
Fixes: bd9d6a3efa97 ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: fold in 20/21 to avoid bisect hazard ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-3-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Sun May 31 08:07:00 2026 -0400
nfsd: fix nfsd_file leak on inter-server COPY setup failure
commit 88a76145451d703eedd867b5989bf73d17340399 upstream.
When nfsd4_setup_inter_ssc() fails, nfsd4_copy() returns
nfserr_offload_denied directly, bypassing the out: label where
release_copy_files() would drop the nf_dst reference taken by
nfs4_preprocess_stateid_op(). Each failed inter-server COPY
leaks one nfsd_file, pinning file/inode/dentry/vfsmount.
Fix by setting status and jumping to out: instead of returning
directly.
Fixes: ce0887ac96d3 ("NFSD add nfs4 inter ssc to nfsd4_copy")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-3-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nikol Kuklev <nikolk202@gmail.com>
Date: Sat Jun 13 11:24:20 2026 +0300
nfsd: fix null dereference in nfsd4_setattr for deleg timestamp attrs
commit fe456c8c0931bb3e8a03d429920e87fd85747fba upstream.
When a SETATTR request includes FATTR4_WORD2_TIME_DELEG_ACCESS or
FATTR4_WORD2_TIME_DELEG_MODIFY in the attribute bitmap, nfsd4_setattr()
sets deleg_attrs=true and calls nfs4_preprocess_stateid_op() to validate
the stateid.
If the client supplies the NFSv4 "one stateid" (all-0xFF bytes),
check_special_stateids() returns nfs_ok without populating the output
nfs4_stid pointer, because the special-stateid path in
nfs4_preprocess_stateid_op() jumps to done: with s==NULL, and the
"if (s)" block that would set *cstid is skipped. The local variable `st`
remains NULL.
Back in nfsd4_setattr(), the if (deleg_attrs) block then unconditionally
dereferences st->sc_type (at offset 4 from NULL), causing a kernel oops.
This is remotely triggerable by any NFSv4 client: send COMPOUND [PUTROOTFH,
SETATTR(ONE_STATEID, {bmval2=FATTR4_WORD2_TIME_DELEG_ACCESS, ...})].
No authentication, delegation, or prior state is required.
Fix by adding a NULL check before the dereference. A special stateid is
not a delegation stateid, so the existing nfserr_bad_stateid return value
is already correct; we only need to guard the pointer dereference itself.
Fixes: 7e13f4f8d27d ("nfsd: handle delegated timestamps in SETATTR")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Nikol Kuklev <nikolk202@gmail.com>
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Thu Jul 16 20:12:28 2026 -0400
NFSD: Fix off-by-one in DRC bucket pruning limit
commit d0728723c80dcb3432effd67c7e919b596004b1d upstream.
nfsd_prune_bucket_locked() evicts an entry before checking
the freed count against @max. The check uses "++freed > max",
which does not break until freed exceeds max, resulting in
max + 1 evictions. Use ">=" so the limit stated in the
function comment is honored.
Fixes: a9507f6af145 ("NFSD: Replace nfsd_prune_bucket()")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260717001232.438792-2-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue Jun 2 12:23:18 2026 -0400
nfsd: fix refcount leak in nfsd_file_lru_add on insertion failure
commit 30c2df3005c99819e117402dc492db4a2a696c2f upstream.
nfsd_file_lru_add() unconditionally increments nf_ref before attempting
to insert the nfsd_file into the LRU via list_lru_add_obj(). If the
insertion fails (the item is already linked), the incremented reference
is never released, permanently inflating the refcount.
The LRU shrinker callback (nfsd_file_lru_cb) uses refcount_dec_if_one()
to reclaim entries, which requires nf_ref == 1. An inflated refcount
therefore blocks eviction of the affected file cache entry for the
lifetime of the nfsd instance.
While this failure path is currently unreachable -- the sole caller in
nfsd_file_do_acquire() operates on freshly-allocated objects that cannot
already be on the LRU -- it represents a latent bug that would become
exploitable if a future change adds another call site or alters the
PENDING protocol.
Fix this by:
- Adding a compensating refcount_dec() on the failure path. Bare
refcount_dec (rather than nfsd_file_put) is correct here because
the caller in nfsd_file_do_acquire still holds its own construction
reference, so the count goes from 2 back to 1 without risk of
reaching zero.
- Changing WARN_ON(1) to WARN_ON_ONCE(1) to prevent log flooding if
this path is ever hit repeatedly.
- Returning early on failure to skip the unnecessary call to
nfsd_file_schedule_laundrette(), since no entry was added to the LRU.
Fixes: 56221b42d717 ("nfsd: filecache: don't repeatedly add/remove files on the lru list")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-6-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue Jun 16 07:59:00 2026 -0400
nfsd: fix reply size estimate for GET_DIR_DELEGATION
commit 46f929b907b3bc488593c006f0c97e35baba9ea4 upstream.
nfsd4_get_dir_delegation_rsize() returns its estimate in XDR words, but
the COMPOUND reply-size machinery works in bytes: every other op's
_rsize helper multiplies its word count by sizeof(__be32). Since
GET_DIR_DELEGATION is OP_MODIFIES_SOMETHING, this estimate is consulted
before the op executes to ensure the reply will fit. The ~4x too-small
estimate lets a compound near the session/reply limit pass the check,
grant a directory delegation, and then fail to encode the reply with
NFS4ERR_RESOURCE/REP_TOO_BIG, leaving the client without the returned
stateid.
Multiply the estimate by sizeof(__be32) like the other _rsize helpers.
Fixes: 33a1e6ea73e5 ("nfsd: trivial GET_DIR_DELEGATION support")
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260616-dir-deleg-v7-17-6cbc7eac0ade@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Fri Jul 10 10:00:07 2026 -0400
nfsd: fix stale s2s_cp_stateids IDR entry for async COPY
commit d0beaee498e11880e72826026db0e9c9890fc114 upstream.
For an async COPY, nfsd4_copy() called nfs4_init_copy_state() before
dup_copy_fields(), so the s2s_cp_stateids IDR was pointed at
&u->copy->cp_stateid -- memory in the per-rqstp COMPOUND buffer that is
reused by the next request. dup_copy_fields() copies only the value into
async_copy, so the IDR slot dangled at the transient buffer for the whole
background copy. Any IDR walker then dereferences reused request memory:
the laundromat reads cs_type from it and, if the bytes look like an
expired NFS4_COPYNOTIFY_STID, follows into
refcount_dec()/idr_remove()/kfree() on garbage; manage_cpntf_state() has
the same exposure via idr_find().
Duplicate the fields first, then register the stateid on the stable
async_copy. result->cb_stateid is unchanged.
Fixes: e0639dc5805a ("NFSD introduce async copy feature")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-3-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:52 2026 -0400
nfsd: fix version mismatch loops in nfsd_acl_init_request()
commit 9bc761051dcd9a4a8b59e64b2b185172d13c716d upstream.
The loops that compute the supported version range for PROG_MISMATCH
test nfsd_support_acl_version(rqstp->rq_vers) instead of
nfsd_support_acl_version(i), so every iteration fails and the
function returns rpc_prog_unavail instead of rpc_prog_mismatch.
Replace rqstp->rq_vers with the loop variable i, matching the
pattern used by the sibling nfsd_init_request() function.
Fixes: e333f3bbefe3 ("nfsd: Allow containers to set supported nfs versions")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-9-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu May 28 10:38:15 2026 -0400
nfsd: fix XDR length calculation in nfsd4_ff_encode_layoutget
commit f9868174af49d207fbaf0c5e055d088a983684af upstream.
The XDR buffer size calculation in nfsd4_ff_encode_layoutget() has
multiple errors that can result in either an out-of-bounds write or
leaking uninitialized kernel memory to the client:
- fh_len doesn't account for XDR padding on the file handle data
- uid and gid lengths use "8 + len" but xdr_encode_opaque() actually
writes "4 + xdr_align_size(len)" bytes
- ds_len omits the flags and stats_collect_hint fields (8 bytes),
while len's header constant overestimates by 8 bytes -- these
partially cancel but leave a net mismatch
The worst case occurs with short strings (e.g. uid=0, gid=0 with an
odd-sized file handle), where the function writes up to 5 bytes past
the reserved XDR buffer. Conversely, when string lengths happen to be
4-byte aligned, the reservation is too large and stale buffer content
is sent to the client.
Fix this by breaking out every encoded field explicitly in the ds_len
calculation, using xdr_align_size() for all variable-length opaque
fields, and correcting the header constants.
Fixes: 9b9960a0ca47 ("nfsd: Add a super simple flex file server")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-pnfs-fixes-v1-1-8a1255ae2f16@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Wed May 27 14:30:41 2026 -0400
nfsd: fix XDR padding calculation in ff_encode_getdeviceinfo
commit 8b989aaec85e1293a871d602590c951fe44b8647 upstream.
nfsd4_ff_encode_getdeviceinfo() computes the da_addr_body reservation
as 16 + netid_len + addr_len, but the subsequent xdr_encode_opaque()
calls emit 8 + round_up(netid_len, 4) + round_up(addr_len, 4) bytes.
The mismatch means the declared da_addr_body length exceeds the actual
encoded data by 2-8 bytes on every flexfile GETDEVICEINFO reply,
leaking stale reply-page content to the client and mis-aligning the
subsequent version list decode.
Use xdr_align_size() for each string length to match what
xdr_encode_opaque() actually writes.
Fixes: efcae97fa425 ("NFSD: da_addr_body field missing in some GETDEVICEINFO replies")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260527-pnfs-fixes-v1-1-784f39dc1eca@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Sat May 30 16:58:16 2026 -0400
nfsd: gate nfs2 setacl by argp->mask
commit a3a7e20ed66d3f04d37883c398da8a113b430769 upstream.
The NFSACL v2 SETACL path shares the decoder convention used by its
v3 sibling: nfsaclsvc_decode_setaclargs() fills in argp->acl_access
only when NFS_ACL is set in the request mask and argp->acl_default
only when NFS_DFACL is set, leaving the other pointer NULL because
the argument buffer is zeroed up to pc_argzero before decode.
nfsacld_proc_setacl() then hands both pointers to set_posix_acl()
unconditionally. set_posix_acl(idmap, dentry, type, NULL) is the VFS
"remove this ACL type" operation, so an omitted arm is
indistinguishable from an explicit request to delete that ACL. A
SETACL carrying only NFS_ACL silently strips the directory's default
ACL; mask=0 strips both.
This is the same defect just fixed in nfsd3_proc_setacl(); apply the
same remedy. Gate each set_posix_acl() call on its mask bit and
initialize error to 0 so that a request with neither bit set leaves
the on-disk ACLs untouched and returns success. The out_drop_lock
path and the unconditional posix_acl_release() in
nfsaclsvc_release_setacl() already tolerate the skipped arms.
Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.")
Cc: stable@vger.kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 30 09:19:21 2026 -0400
nfsd: gate nfs3 setacl by argp->mask
commit 453d7198a0ab07a12d46e0575861ac7b932da17e upstream.
nfsd3_proc_setacl() calls set_posix_acl() unconditionally for both
ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT, passing argp->acl_access and
argp->acl_default verbatim. The NFSv3 ACL decoder only populates
those pointers when the corresponding mask bit is set:
nfs3svc_decode_setaclargs()
if (args->mask & NFS_ACL) decode into acl_access
if (args->mask & NFS_DFACL) decode into acl_default
/* otherwise the pointer stays NULL (pc_argzero) */
nfsd3_proc_setacl()
set_posix_acl(.., ACL_TYPE_ACCESS, argp->acl_access)
set_posix_acl(.., ACL_TYPE_DEFAULT, argp->acl_default)
set_posix_acl(idmap, dentry, type, NULL) is the VFS "remove this
ACL type" operation. A NULL pointer that means "the client did not
send this arm" is therefore indistinguishable from "the client
asked to remove this ACL". A SETACL with mask=NFS_ACL silently
drops the directory's default ACL; mask=0 drops both.
The sibling nfsd3_proc_getacl() already consults argp->mask before
touching each arm; mirror that in setacl.
Fix by wrapping each set_posix_acl() call in the matching mask bit
check and initializing error to 0 before inode_lock so that a
request with neither bit set leaves the on-disk ACLs untouched and
returns nfs_ok. The out_drop_lock path and the unconditional
posix_acl_release() at out: are preserved; both NULL-tolerate the
skipped arms.
Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260530-nfsd-fixes-v2-5-f27e8eb4d974@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Tue Jun 2 12:23:16 2026 -0400
nfsd: guard nfsd_serv deref in nfsd_file_net_dispose
commit 9f1ddfc8cb9076592401a611eb3a44d36186d014 upstream.
nfsd_file_net_dispose() is the consumer side of l->freeme: the nfsd
service thread loop calls it to drain entries that the filecache
garbage collector and shrinker append via
nfsd_file_dispose_list_delayed(). During per-net teardown,
nn->nfsd_serv is cleared before the filecache laundrette is shut
down, so the service thread can still run a dispose pass that finds
more than eight entries on l->freeme and dereferences a NULL
svc_serv:
nfsd service thread loop
nfsd_file_net_dispose(nn)
if (!list_empty(&l->freeme)) {
...
svc_wake_up(nn->nfsd_serv); /* nn->nfsd_serv == NULL */
}
The sibling helper nfsd_file_dispose_list_delayed() already documents
this ordering and caches nn->nfsd_serv into a local before testing it
for NULL. nfsd_file_net_dispose() was introduced with the same raw
svc_wake_up(nn->nfsd_serv) call and never picked up the guard.
Fix by loading nn->nfsd_serv into a local svc_serv pointer and only
calling svc_wake_up() when it is non-NULL, matching the pattern in
nfsd_file_dispose_list_delayed().
Fixes: ffb402596147 ("nfsd: Don't leave work of closing files to a work queue")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-4-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Tue Jun 2 12:23:14 2026 -0400
nfsd: hold rcu across localio cmpxchg retry
commit 58884694978a3d7d111edb433d7fd6a6c5af2f34 upstream.
nfsd_file objects are freed via call_rcu (filecache.c:296), and
nfsd_file_slab is created without SLAB_TYPESAFE_BY_RCU
(KMEM_CACHE(nfsd_file, 0) at filecache.c:789), so the slab page
backing a freed nfsd_file becomes freely reclaimable once the RCU
grace period elapses.
The again: retry block in nfsd_open_local_fh() loads a pointer with
cmpxchg and then calls nfsd_file_get(new) (which is
refcount_inc_not_zero) without holding rcu_read_lock. The sole caller
nfs_open_local_fh() drops rcu_read_lock before invoking this helper,
so no outer reader-side critical section covers the load.
CPU 0 (nfsd_open_local_fh) CPU 1 (nfsd_file_put_local)
----- -----
new = cmpxchg(pnf, NULL, ...)
nf = xchg(pnf, NULL)
nfsd_file_put(nf)
last ref -> call_rcu()
/* grace period elapses;
slab page recycled */
nfsd_file_get(new)
refcount_inc_not_zero(&new->nf_ref)
/* operates on recycled memory */
A non-zero word at the nf_ref offset of the recycled object makes the
refcount bump appear to succeed, and the caller then dereferences
new->nf_net and new->nf_file out of freed memory.
Fix by taking rcu_read_lock() immediately before the cmpxchg and
releasing it on all three exits of the if (new) block: the goto-again
retry, the lost-race cleanup path, and the install-succeeded path.
nfsd_file_put() and nfsd_net_put() stay outside the RCU section so
they remain free to block.
Fixes: e6f7e1487ab5 ("nfs_localio: simplify interface to nfsd for getting nfsd_file")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-2-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Fri Jul 10 10:00:08 2026 -0400
nfsd: initialize copy-notify stateid before publishing it
commit 129643893b79f8a3c6b72045f933fbab5ee424ca upstream.
nfsd4_copy_notify() finished initializing the cpntf state after
nfs4_alloc_init_cpntf_state() had already linked it into the
s2s_cp_stateids IDR and the parent's sc_cp_list, with cs_count == 1 (the
membership reference) and none held for the caller. A racing
OFFLOAD_CANCEL (crafted cl_id == nn->s2s_cp_cl_id plus the guessable
so_id) could reach manage_cpntf_state() and free the entry, turning the
caller's subsequent cpn_cnr_stateid read and cp_p_stateid/cp_p_clid
writes into use-after-free. The owning clientid was also only recorded
after publication, so it could not gate an ownership check in that window.
Record cp_p_stateid and cp_p_clid inside nfs4_alloc_init_cpntf_state()
before nfs4_init_cp_state() publishes the entry, and return it with an
extra reference. The caller reads the stateid under that reference and
drops it with nfs4_put_cpntf_state(); on a late error the laundromat
reaps the entry.
Fixes: 624322f1adc5 ("NFSD add COPY_NOTIFY operation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-4-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:01:01 2026 -0400
nfsd: initialize DRC hash table before registering shrinker
commit b0c58934f5cc4f05b63ef6605dd10c1d0d489e88 upstream.
shrinker_register() precedes the INIT_LIST_HEAD loop and the
drc_hashsize store. On weakly-ordered architectures (arm64, ppc),
a shrinker scan can observe drc_hashsize before the bucket list
heads are initialized, causing a NULL deref in the DRC shrinker
callback.
Move bucket initialization and the drc_hashsize store before
shrinker_register() so the hash table is fully initialized before
it becomes visible to the shrinker.
Fixes: 8eea99a81c6f ("nfsd: dynamically allocate the nfsd-reply shrinker")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-18-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:01:00 2026 -0400
nfsd: move nfsd_debugfs_init() after nfsd4_init_slabs() in init_nfsd()
commit 2c390c8a1764d67095fe444401861fac4c049362 upstream.
nfsd_debugfs_init() runs before nfsd4_init_slabs() in init_nfsd().
If the slab allocation fails, the bare "return retval" bypasses
nfsd_debugfs_exit(), leaving orphan debugfs files with stale fops
pointers into the freed module text.
Move nfsd_debugfs_init() to after the slab init succeeds, so the
early return has no debugfs state to clean up.
Since debugfs is now the more recently initialized of the two, also
update the unwind paths to match reverse-initialization (LIFO) order:
run nfsd_debugfs_exit() before nfsd4_free_slabs() in both the
init_nfsd() error path and exit_nfsd(). The nfsd debugfs files only
reference module-global state and have no dependency on the slab
caches, so that reordering is a cleanup with no functional change.
Fixes: 9fe5ea760e64 ("NFSD: Add /sys/kernel/debug/nfsd")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-17-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Thu Jul 9 13:40:28 2026 -0400
NFSD: Prevent client use-after-free during NFSv4.0 revoked-state cleanup
commit 7b4f8a1586c42d3afc3c0ac779af2db7ab1a5c55 upstream.
nfs40_clean_admin_revoked() takes a stateid reference under
clp->cl_lock, drops nn->client_lock, and calls
nfsd4_drop_revoked_stid(), which dereferences the stateid's client
through s->sc_client->cl_lock. The stateid reference does not pin the
client, so a teardown racing the dropped lock can free the client
while nfsd4_drop_revoked_stid() is still using it.
This cleanup runs from the laundromat, so a periodic sweep can race
force_expire_client() driven by a write to the clients/<id>/ctl file.
Skip a client that is already expiring and otherwise pin it with
cl_rpc_users under client_lock before dropping the lock, matching
nfsd4_revoke_states().
Fixes: d688d8585e6b ("nfsd: allow admin-revoked NFSv4.0 state to be freed.")
Cc: stable@vger.kernel.org
Reviewed-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260709-cel-v4-5-1d519d9be0cb@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Thu Jul 9 13:40:24 2026 -0400
NFSD: Prevent lock owner use-after-free during client teardown
commit 5e2fa29d223a9a1e6a948e40b109d09081d1decd upstream.
__destroy_client() releases a client's open owners, but a lock owner
whose only reference is a blocked lock (nbl) stays on
cl_ownerstr_hashtbl. client_has_state() does not count a bare owner,
so DESTROY_CLIENTID can reach __destroy_client() with such owners
present.
__destroy_client() then walks the table, calling remove_blocked_locks()
on each owner without a reference. Freeing a blocked lock drops the
owner reference held via flc_owner. The per-net laundromat reaps
blocked locks from nn->blocked_locks_lru independently of client state.
The two paths share blocked_locks_lock only for the list splice, not
the owner's lifetime. The laundromat therefore frees the owner as
__destroy_client() dereferences it, a NULL dereference in
remove_blocked_locks().
nfsd4_release_lockowner() holds a reference across the same call;
__destroy_client() does not. Hold cl_lock across the walk, taking a
reference and unhashing each owner, then drop it before
remove_blocked_locks() and nfs4_put_stateowner(), which take
blocked_locks_lock and cl_lock.
Reported-by: Wolfgang Walter <linux@stwm.de>
Closes: https://lore.kernel.org/linux-nfs/6eccafaaaa60651ef091257c3439c46b@stwm.de/
Fixes: 68ef3bc31664 ("nfsd: remove blocked locks on client teardown")
Cc: stable@vger.kernel.org
Reviewed-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260709-cel-v4-1-1d519d9be0cb@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Sat May 30 09:19:18 2026 -0400
nfsd: RCU-protect cl_cb_session to fix use-after-free on session teardown
commit 01c5d5f58a5db9b0ee5afba2e49d3157788687b2 upstream.
After a DESTROY_SESSION the per-session teardown path can free a
session while rpciod still holds an inflight callback rpc_task that
dereferences clp->cl_cb_session. nfsd4_probe_callback_sync() flushes
cl_callback_wq, but once nfsd4_run_cb_work() has called
rpc_call_async() the rpc_task lives on rpciod; flushing the workqueue
does not wait for it. rpc_shutdown_client() does drain rpciod tasks,
but uses a 1-second wait_event_timeout — tasks stuck in rpc_delay()
(e.g. 2-second NFS4ERR_DELAY retries) can outlive the drain.
destroy path rpciod
------------ ------
unhash_session(ses)
nfsd4_probe_callback_sync(clp)
flush_workqueue(cl_callback_wq)
/* returns; rpc_task still live */
nfsd4_put_session_locked(ses)
free_session(ses) -> kfree(ses)
nfsd4_cb_sequence_done()
reads cb_clp->cl_cb_session
/* freed slab */
A second window exists in nfsd4_process_cb_update(). When
__nfsd4_find_backchannel() returns NULL because unhash_session() has
already removed the destroyed session from cl_sessions,
setup_callback_client() takes the v4.1 early return so
clp->cl_cb_session = ses never fires and the field retains a pointer
to the about-to-be-freed session.
Fix both by converting cl_cb_session to an RCU-protected pointer:
- Move the cl_cb_session = ses assignment in setup_callback_client()
to after rpc_create() succeeds, so it is only published when a
working backchannel exists. Clear cl_cb_session on the error
return in nfsd4_process_cb_update(). Both stores use
rcu_assign_pointer().
- Annotate cl_cb_session with __rcu. All rpciod-side readers use
rcu_read_lock()/rcu_dereference() and check for NULL, bailing to
the appropriate error or requeue path:
encode_cb_sequence4args(), decode_cb_sequence4resok(),
nfsd41_cb_get_slot(), nfsd41_cb_release_slot(),
nfsd4_cb_prepare(), and nfsd4_cb_sequence_done().
- Switch __free_session() from kfree() to kfree_rcu() so the
session slab is not reclaimed until after an RCU grace period,
guaranteeing that rpciod readers inside rcu_read_lock() never
dereference freed memory.
- Pass the session pointer to the nfsd_cb_seq_status and
nfsd_cb_free_slot tracepoints instead of having them re-read
cl_cb_session.
- nfsd4_cb_prepare() calls rpc_exit() when the session is NULL,
routing through the done/release path to requeue the callback.
Fixes: dcbeaa68dbbd ("nfsd4: allow backchannel recovery")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Chris Mason <clm@meta.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-nfsd-fixes-v2-2-f27e8eb4d974@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Robbie Ko <robbieko@synology.com>
Date: Tue Jun 16 13:39:59 2026 +0800
nfsd: reject out-of-range nseconds in NFSv3 SETATTR and create ops
commit eb0eca7720662ba5847df1510e73801f7f473094 upstream.
A client can send an NFSv3 SETATTR, CREATE, MKDIR, SYMLINK or MKNOD
carrying an atime or mtime whose nseconds field is out of range. The
value is well-formed on the wire and decodes cleanly into a valid
uint32, but it is not a valid timespec64: tv_nsec must be less than
NSEC_PER_SEC.
Nothing in the setattr path clamps it. notify_change() runs the time
through timestamp_truncate(), which does not reduce tv_nsec below
NSEC_PER_SEC when the filesystem supports nanosecond granularity
(s_time_gran == 1), and the inode atime/mtime setters store it verbatim
(only ctime is normalized, via inode_set_ctime_to_ts()). The
un-normalized value then corrupts on-disk metadata: ext4's
ext4_encode_extra_time() shifts tv_nsec left by EXT4_EPOCH_BITS, which
overflows the 32-bit extra field and clobbers the seconds-epoch bits, so
the stored seconds (and thus the year) are wrong on read-back. XFS with
bigtime mis-stores the timestamp for the same reason.
Validate the client-supplied atime/mtime in the proc handlers and return
NFS3ERR_INVAL before anything is changed. RFC 1813 lists NFS3ERR_INVAL
for SETATTR and describes it as the error for a value the server 'can
not store ... in its own representation'; the client maps it to EINVAL.
Checking in the proc handlers, rather than in nfsd_setattr(), keeps the
rejection in front of object creation. The create operations create the
object before nfsd_create_setattr() runs, so a late failure would leave
the new object behind and turn a non-idempotent request into a namespace
change that reports failure. The check is therefore done up front, for
the create operations before the object is created.
tv_nsec is a long, so the comparison casts it to unsigned long (the same
width) rather than to u32, matching timespec64_valid(). A u32 cast would
truncate on 64-bit; the unsigned long cast also rejects a value that
became negative when an out-of-range u32 wire nseconds was assigned to a
32-bit long.
Only client-supplied times are checked: SET_TO_SERVER_TIME requests
carry no client value. The sattrguard3 ctime is deliberately left alone:
an out-of-range guard simply never matches the object's ctime and yields
NFS3ERR_NOT_SYNC via the existing guardtime comparison, which is the
protocol-correct outcome rather than rejecting the request.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Robbie Ko <robbieko@synology.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260616054027.2360930-2-robbieko@synology.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Robbie Ko <robbieko@synology.com>
Date: Tue Jun 16 13:39:58 2026 +0800
nfsd: reject out-of-range useconds in NFSv2 SETATTR/CREATE
commit 26709c8ffe73772eb69e68d553ac71d91228dccc upstream.
The NFSv2 sattr decoder converts the wire useconds to nanoseconds in
svcxdr_decode_sattr():
iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC;
tmp2 is a u32 and NSEC_PER_USEC is 1000, so the product is computed in
unsigned long. On ILP32 that is 32 bits, and an out-of-range useconds
value such as 4294968 wraps to tv_nsec == 704. The corruption therefore
happens during decode, before any proc function can inspect the value,
and a later range check on tv_nsec would see an in-range result and
accept it. Rejecting in the decoder yields an RPC GARBAGE_ARGS reply.
NFSv2 defines no NFSERR_INVAL, so there is no NFS-level status to return
for a malformed time argument, and the check cannot move to the proc
function the way the v3/v4 nsec range checks do.
Guard the raw useconds before the multiplication and reject values
greater than 1000000. useconds == 1000000 is kept: it is the Sun
convention for "set to the current server time", and the in-tree Linux
NFSv2 client emits it in both the atime and the mtime field for a plain
touch / utimes(file, NULL) (see encode_sattr() and
xdr_encode_current_server_time() in fs/nfs/nfs2xdr.c). Rejecting 1000000
would turn that common operation into a hard decode failure for both
SETATTR and CREATE. 1000000 * NSEC_PER_USEC is 10^9, which does not wrap
on ILP32, so the Sun convention value passes through safely. Only
genuinely out-of-range values (> 1000000) are rejected. The atime and
mtime guards are therefore symmetric.
The decoder only applied the Sun convention in the mtime block, which
clears ATTR_ATIME_SET|ATTR_MTIME_SET when mtime useconds == 1000000. If a
client puts 1000000 in the atime field but not in the mtime field, the
atime block stored an out-of-range tv_nsec (10^9) and left ATTR_ATIME_SET
set, so the bogus value reached the filesystem. Apply the convention in
the atime block as well, clearing ATTR_ATIME_SET so the server uses its
current time and ignores the value. Only ATTR_ATIME_SET is cleared there.
The mtime block keeps its existing behavior, where 1000000 means "set
both atime and mtime to now".
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Robbie Ko <robbieko@synology.com>
[ cel: various tweaks, addenda, and clean-ups ]
Link: https://patch.msgid.link/20260616054027.2360930-1-robbieko@synology.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:57 2026 -0400
nfsd: reject reclaim LOCK after RECLAIM_COMPLETE
commit 2327ba1d9546727a35b17888777e991f68a9b305 upstream.
nfsd4_lock() only checks the namespace-wide grace flag when deciding
whether to accept a reclaim LOCK. It does not check the per-client
NFSD4_CLIENT_RECLAIM_COMPLETE bit. An NFSv4.1+ client that has
already sent RECLAIM_COMPLETE can submit lk_reclaim=1 while grace is
still active (e.g. lockd holds the grace list open), and the server
accepts it instead of returning NFS4ERR_NO_GRACE as required by
RFC 8881 section 18.51.3.
The OPEN path already enforces both tiers: the grace check plus the
per-client RECLAIM_COMPLETE check in nfs4_check_open_reclaim(). Add
the equivalent per-client check to the LOCK path.
Fixes: 3b3e7b72239a ("nfsd: reject reclaim request when client has already sent RECLAIM_COMPLETE")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: Correct the RFC citations in the commit message ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-14-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sun May 31 08:06:59 2026 -0400
nfsd: release path refs on follow_down() error
commit 6cba08dc1922140d260cfeb30bbda4ee1bf869d8 upstream.
nfsd_cross_mnt() initializes a local struct path with mntget() and
dget() before calling follow_down(). On a negative return the error
arm jumps to out without releasing those references:
err = follow_down(&path, follow_flags);
if (err < 0)
goto out;
follow_down() never drops the caller's entry-time refs on any error
sub-case; for example a pre-cross d_manage() failure leaves path
untouched, so the mntget()/dget() taken on entry survive the call.
Every other early-exit arm in nfsd_cross_mnt() (other-namespace
return, IS_ERR(exp2), and the success tail after the swap) already
calls path_put(&path); the err < 0 arm is the lone omission. The
leak inflates mnt_count and d_count on each failed cross-mount,
blocking umount and pinning dentries against the shrinker, and is
reachable by any authenticated NFS client through nfsd_lookup_dentry
or the NFSv4 READDIR encode path.
Fix by calling path_put(&path) before the goto out in the err < 0
arm so the entry-time refs are released on all follow_down() error
returns.
Fixes: cc53ce53c869 ("Add a dentry op to allow processes to be held during pathwalk transit")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-2-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mike Snitzer <snitzer@kernel.org>
Date: Fri Jun 12 15:14:10 2026 -0400
NFSD: remove flawed WARN_ON_ONCE from nfsd_mode_check
commit aa0cf48a448c5a9fe1a1e880899ecd589ce39e6e upstream.
The header for commit e75b23f9e323 ("nfsd: check d_can_lookup in
fh_verify of directories") details the assumption that justified
adding the WARN_ON_ONCE to nfsd_mode_check(), that assumption is
invalid (in the case of NFS reexport).
When NFSD exports an NFS filesystem it is very possible for
nfsd_mode_check() to encounter a @dentry that doesn't have
i_op->lookup (see nfs_fhget()'s NFS_ATTR_FATTR_MOUNTPOINT and
NFS_ATTR_FATTR_V4_REFERRAL handling, and d_flags_for_inode()).
So remove nfsd_mode_check()'s WARN_ON_ONCE(). The nfserr_notdir
return on that branch must stay. It guards the subsequent
lookup_one_unlocked() -> __lookup_slow() path, which calls
inode->i_op->lookup() with no NULL check, so returning nfserr_notdir
is what keeps a client LOOKUP into such a @dentry from dereferencing
a NULL method pointer.
Fixes: e75b23f9e323 ("nfsd: check d_can_lookup in fh_verify of directories")
Cc: stable@vger.kernel.org
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Link: https://patch.msgid.link/20260612191410.50177-1-snitzer@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Fri May 22 16:37:23 2026 -0400
nfsd: Reset write verifier when async COPY writeback fails
commit f5cb2276954cb80987a93ef9f9dfbfdbfc0f10b9 upstream.
Async COPY captures nn->writeverf at request time and reports it to
the client via CB_OFFLOAD after the worker kthread completes. When
the post-copy vfs_fsync_range() or filemap_check_wb_err() in
_nfsd_copy_file_range() reports an error, the worker correctly
leaves NFSD4_COPY_F_COMMITTED clear so that CB_OFFLOAD encodes
wr_stable_how as NFS_UNSTABLE, but the server's write verifier is
not rotated.
A client that receives NFS_UNSTABLE in CB_OFFLOAD follows up with
COMMIT to make the copied data durable. With the verifier
unchanged, COMMIT returns the same value the client just received
via CB_OFFLOAD, and the client concludes the copy is durable --
silently dropping the data whose writeback in fact failed. This
violates the UNSTABLE+COMMIT durability contract (RFC 7862 section
15.1, RFC 8881 section 18.32) and matches the bug just fixed in
nfsd_vfs_write() and nfsd_commit().
Rotate nn->writeverf at the writeback-failure site. The async COPY
worker has no svc_rqst, so commit_reset_write_verifier() is not
available here; calling nfsd_reset_write_verifier() directly
mirrors the trace-less reset already used by
nfsd_file_check_write_error() for the same purpose. Filter out
-EAGAIN and -ESTALE, matching commit_reset_write_verifier(), since
neither indicates a durable-storage failure.
Fixes: eac0b17a77fb ("NFSD add vfs_fsync after async copy is done")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260522203723.446841-1-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Michael Bommarito <michael.bommarito@gmail.com>
Date: Sun May 24 09:06:54 2026 -0400
NFSD: restart ssc_expire_umount walk after dropping nfsd_ssc_lock
commit 036c1b182f4da65363e79ec0ac276edc6b7296e5 upstream.
nfsd4_ssc_expire_umount() walks nn->nfsd_ssc_mount_list with
list_for_each_entry_safe(ni, tmp, ...). For each expired entry it
sets nsui_busy = true, drops nfsd_ssc_lock to run mntput() on the
source vfsmount, then reacquires the lock to list_del + kfree the
entry and continue iterating via the macro's saved tmp pointer.
The nsui_busy flag protects the current ni from concurrent
nfsd4_ssc_setup_dul() finders during the lock-drop window, but it
does not pin tmp. Another nfsd RPC thread that fails its source-
server mount and reaches nfsd4_ssc_cancel_dul() will, during that
same window, take nfsd_ssc_lock, list_del + kfree its own ssc_umount
item, and release the lock. If that item is the saved tmp of the
expire walk, the next iteration dereferences a freed
nfsd4_ssc_umount_item.
Restart the walk from the head after the mntput() unlock window so
no saved next pointer survives the lock-drop. The list is bounded
by the number of active inter-server source mounts (typically small)
and the expire delayed-work runs periodically rather than per-IO,
so the restart is cheap.
Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260524130654.1924556-1-michael.bommarito@gmail.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Fri Jul 10 10:00:11 2026 -0400
nfsd: return NFS4ERR_NOTSUPP for unsupported netloc4 types
commit 45b06a75086f331f52cbb81223a59421d43f8809 upstream.
nfsd4_decode_nl4_server() handled only NL4_NETADDR and returned
nfserr_bad_xdr for NL4_NAME and NL4_URL. Those forms are well-formed XDR,
so BADXDR is misleading -- the request is unsupported, not malformed.
Decode and discard the utf8str_cis for NL4_NAME and NL4_URL to keep the
stream consistent, and return nfserr_notsupp. nfsd4_proc_compound() honors
a decode-time op->status, so the op fails without executing.
Fixes: 84e1b21d5ec4 ("NFSD add ca_source_server<> to COPY")
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-7-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Fri Jul 10 10:00:10 2026 -0400
nfsd: revoke copy-notify stateids before dropping their reference
commit 3b0c3595db99bb4bebd7c8aa8a36f3c50e411bb7 upstream.
Copy-notify stateids live in the s2s_cp_stateids IDR and on their parent
stid's sc_cp_list, pinned by a single membership reference.
_free_cpntf_state_locked() only unlinks an entry once its refcount reaches
zero, so any revoke path that runs while a concurrent
find_cpntf_state()/manage_cpntf_state() holder has elevated cs_count drops
the reference without unlinking, leaving the entry discoverable with its
membership reference already consumed. A second revoke or a laundromat tick
then frees it while the reader still holds the pointer -- a
KASAN-detectable use-after-free at the reader's nfs4_put_cpntf_state().
This affected all three revoke paths:
- The parent-stid drain (nfs4_free_cpntf_statelist()) repeatedly called
_free_cpntf_state_locked() on the first list entry; a holder that had
bumped cs_count made it return early, so the next iteration
re-decremented and burned the holder's reference.
- OFFLOAD_CANCEL (manage_cpntf_state()) and laundromat expiry likewise
used _free_cpntf_state_locked() and could drop 2->1 without unlinking.
Add revoke_cpntf_state_locked(), which unhashes the entry from the IDR and
sc_cp_list first (deferring the final free to any holder), and use it from
all three revoke paths. The drain now walks with list_for_each_entry_safe()
and revokes each entry unconditionally, so it terminates in one pass per
entry regardless of cs_count. The unhash is gated on
!list_empty(&cps->cp_list); the idr_remove() gate matters because
idr_alloc_cyclic() may have recycled the so_id by then. Keep
_free_cpntf_state_locked() for the reference-holder put path only, where a
concurrent revoke may already have unlinked the entry (its list_del_init()
then a no-op).
Fixes: 624322f1adc5 ("NFSD add COPY_NOTIFY operation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260710-nfsd-testing-v3-6-a0ff7db6aa3e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Fri May 22 17:45:58 2026 -0400
nfsd: sample writeback error cursor before async COPY loop
commit 20a67a7d18221af736f124770c2c5e859b479046 upstream.
_nfsd_copy_file_range() samples dst->f_wb_err into "since"
after the copy loop, then uses it to detect writeback errors
via filemap_check_wb_err() once vfs_fsync_range() returns.
Because the nfsd_file cache reuses a single struct file
across requests targeting the same inode, a concurrent
COMMIT or stable WRITE on dst advances dst->f_wb_err to the
current mapping->wb_err via file_check_and_advance_wb_err()
during its own vfs_fsync_range(). If that advancement lands
between the writeback error appearing in mapping->wb_err
and the COPY worker sampling "since", the worker captures
the already-advanced cursor, errseq_check() sees cur ==
since and returns zero, and NFSD4_COPY_F_COMMITTED is set
even though writeback failed. CB_OFFLOAD then encodes
wr_stable_how = FILE_SYNC4, the client treats the copied
data as durable, and the failure becomes silent data loss.
Sample since once at the start of the function. The cursor
then reflects state in effect before this COPY issues any
writes, and filemap_check_wb_err() detects any error that
occurs during the copy regardless of which thread first
observes it. This matches the pattern used by
nfsd_vfs_write() and nfsd4_clone_file_range().
Closes: https://sashiko.dev/#/patchset/20260522194441.436065-1-cel@kernel.org?part=1
Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260522214558.460859-1-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhenghang Xiao <kipreyyy@gmail.com>
Date: Tue May 26 18:45:54 2026 +0800
nfsd: set SC_STATUS_FREED in nfsd4_drop_revoked_stid for delegations
commit 650d370cfbc66a96dd14d517bd704689b5bda4e5 upstream.
nfsd4_drop_revoked_stid() handles FREE_STATEID for admin-revoked
delegations but does not set SC_STATUS_FREED before releasing cl_lock.
revoke_delegation() uses this flag to detect whether FREE_STATEID has
already processed the delegation -- without it, the freed delegation is
added to cl_revoked via list_add(), producing a use-after-free when
cl_revoked is later traversed in __destroy_client().
The SC_STATUS_REVOKED path in nfsd4_free_stateid() (line 7983) already
sets SC_STATUS_FREED correctly. Apply the same pattern to the
SC_STATUS_ADMIN_REVOKED path in nfsd4_drop_revoked_stid().
Fixes: 8dd91e8d31fe ("nfsd: fix race between laundromat and free_stateid")
Cc: stable@vger.kernel.org
Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526104554.46262-1-kipreyyy@gmail.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sun May 31 08:06:58 2026 -0400
nfsd: size fh_verify server sockaddr slot by xpt_locallen
commit 71d068490098b1d23c63b2345e40675d3a1ca763 upstream.
The nfsd_fh_verify and nfsd_fh_verify_err tracepoints declare the
server sockaddr slot sized by xpt_remotelen but fill it from
xpt_local using xpt_locallen:
TP_STRUCT__entry(
...
__sockaddr(server, rqstp->rq_xprt->xpt_remotelen)
...
)
TP_fast_assign(
...
__assign_sockaddr(server, &rqstp->rq_xprt->xpt_local,
rqstp->rq_xprt->xpt_locallen);
...
)
When xpt_locallen exceeds xpt_remotelen, __assign_sockaddr's memcpy
writes past the reserved ring-buffer slot. In the reverse direction
(xpt_locallen < xpt_remotelen) the slot is oversized and the
unwritten tail leaks prior ring-buffer contents to trace consumers.
The write-past-end case is reachable on NFS/UDP. svc_xprt_set_remote()
is only called from svc_tcp_accept() (net/sunrpc/svcsock.c) and from
the RDMA connect path; svc_create_socket() for UDP calls only
svc_xprt_set_local(), so xpt_remotelen stays 0 for the xprt's
lifetime. Every fh_verify trace for an NFSv2/v3-over-UDP request
then copies 16 or 28 bytes from xpt_local into a zero-byte slot.
The other NFSD tracepoints that record the server address
(NFSD_TRACE_PROC_CALL_FIELDS, NFSD_TRACE_PROC_RES_FIELDS,
SVC_RQST_ENDPOINT_FIELDS) already size the server slot by
xpt_locallen; nfsd_fh_verify and nfsd_fh_verify_err were the only
exceptions.
Fix by sizing the server slot with xpt_locallen so the declared slot
matches the copy length. The client slot and its assignment already
agree on xpt_remotelen and are left untouched.
Fixes: 051382885552 ("NFSD: Instrument fh_verify()")
Fixes: 948755efc951 ("NFSD: Replace dprintk() call site in fh_verify()")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Link: https://patch.msgid.link/20260531-nfsd-testing-v1-1-7bfa481b0540@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:50 2026 -0400
nfsd: validate nseconds in TIME_DELEG decode paths
commit 0f4a767340fad392bd656115b8752005518c9065 upstream.
The xdrgen-based TIME_DELEG_ACCESS and TIME_DELEG_MODIFY decode arms
store a raw uint32_t nseconds directly into tv_nsec without enforcing
nseconds < NSEC_PER_SEC. The legacy nfsd4_decode_nfstime4 has this
check but the TIME_DELEG paths do not. A malformed timespec can
propagate through notify_change() to disk.
Add range checks in both nfs4xdr.c (SETATTR path) and
nfs4callback.c (CB_GETATTR path).
Fixes: 6ae30d6eb26b ("nfsd: add support for delegated timestamps")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-7-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Mon Jun 15 14:31:25 2026 -0400
nfsd: validate sockaddr length per family in listener_set
commit bdcc85c2b05a9378d8bd2d65f9fc41440a3cf464 upstream.
nfsd_sock_nl_policy declares NFSD_A_SOCK_ADDR as a bare NLA_BINARY
attribute with no minimum length. A CAP_NET_ADMIN caller can send a
16-byte NFSD_A_SOCK_ADDR with sa_family=AF_INET6, causing a 12-byte
OOB read across three consumers (rpc_cmp_addr_port, svc_find_listener,
kernel_bind).
nfsd_nl_listener_set_doit() also parsed and validated each listener
entry inline in two separate loops, interleaved with mutating the
running listener configuration. The validation was duplicated, used an
open-coded "nla_len < sizeof(struct sockaddr)" check that was too short
for AF_INET6, and handled a malformed entry inconsistently depending on
which loop noticed it.
Add an nfsd_nl_validate_listeners() helper that walks the entire list
once and confirms each entry parses, carries both an address and a
transport name, and is long enough for its address family
(sizeof(struct sockaddr_in) for AF_INET, sizeof(struct sockaddr_in6)
for AF_INET6, -EAFNOSUPPORT otherwise). Call it before taking
nfsd_mutex or creating the serv, so a malformed request fails cleanly
with no side effects.
Since every entry is known valid by the time the two existing loops
run, drop the redundant presence and per-family length checks from
both, leaving only the nla_parse_nested() call needed to extract the
data.
Fixes: 16a471177496 ("NFSD: add listener-{set,get} netlink command")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260615-nfsd-testing-v5-1-188d75aedda0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Sat May 30 09:19:25 2026 -0400
nfsd: validate symlink target length in NFSv4 CREATE
commit 041f57056e5fb9c80adc088269322d2c61074406 upstream.
nfsd4_decode_create() accepts an unbounded cr_datalen from the wire for
NF4LNK symlink targets, allowing a client to force a kmalloc of up to
the maximum RPC payload size (several MiB) per COMPOUND op that persists
until compound teardown. The VFS rejects oversized targets with
ENAMETOOLONG, but the allocation has already occurred.
Reject cr_datalen == 0 early with nfserr_inval and cr_datalen greater
than NFS4_MAXPATHLEN (PATH_MAX) with nfserr_nametoolong to bound the
allocation.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-nfsd-fixes-v2-9-f27e8eb4d974@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Junrui Luo <moonafterrain@outlook.com>
Date: Sun Aug 16 16:01:29 2026 +0800
NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path
commit ee5a386cfe60f3f8286de16a9db8e1a08f0bc124 upstream.
When the server returns a new layout stateid while a valid one is still
held, pnfs_layout_process() calls pnfs_mark_matching_lsegs_return() on
the on-stack free_me list and jumps to out_forget. Segments whose
reference count drops to zero are unlinked from lo->plh_segs and moved
to free_me by mark_lseg_invalid(); for an idle cached segment the layout
header holds the only reference, so this happens on the first decrement.
out_forget never drains free_me -- only the success path calls
pnfs_free_lseg_list().
Commit 814b84971388 ("pNFS/NFSv4: Fix a layout segment leak in
pnfs_layout_process()") added the drain; commit 08bd8dbe8882
("pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process()")
removed it while switching the destination to lo->plh_return_segs, which
is drained elsewhere. Commit fb700ef02676 ("NFSv4.1: Simplify layout
return in pnfs_layout_process()") switched the destination back to
free_me without restoring the drain.
Restore the pnfs_free_lseg_list() call.
Fixes: fb700ef02676 ("NFSv4.1: Simplify layout return in pnfs_layout_process()")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Assisted-by: Claude:claude-opus-5
Cc: stable@vger.kernel.org
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Date: Fri Jul 17 13:39:43 2026 +0900
nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncation
commit 45662dedb8f272ef7f16e69f13424c4bd0399240 upstream.
Shuangpeng Bai reported that KASAN detected a slab-out-of-bounds error
in nilfs_direct_propagate() during testing.
Analysis revealed that after truncating a file, a node block immediately
below the B-tree root was not deleted. Instead, it remained in the B-tree
node cache in a dirty state. The log writer subsequently detected this
block and incorrectly invoked nilfs_direct_propagate() on it, which is
designed to handle only data blocks in direct mapping.
B-tree nodes in the cache are managed by virtual block numbers, and their
logical keys typically exceed the range expected by direct mapping.
Consequently, processing such a node as a direct mapping entry triggers
a slab-out-of-bounds access.
The root cause is that when a B-tree mapping collapses into a direct
mapping during truncation, an intermediate node block pointed to by the
root node is left behind as garbage instead of being explicitly deleted.
This resolves the issue by adding a nilfs_btree_discard() operation
to delete the remaining intermediate node block during the conversion.
A 'deform' flag is added to the bop_delete interface to explicitly signal
that the deletion is part of a mapping transformation. This allows the
B-tree mapping implementation to perform the necessary cleanup and
discarding of the residual node structure that would be otherwise be left
orphaned after the transition.
Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Closes: https://lore.kernel.org/r/08A3603A-ADB6-484C-9015-9AC1340E6FB8@gmail.com
Fixes: 36a580eb489f ("nilfs2: direct block mapping")
Cc: stable@vger.kernel.org
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Dave Airlie <airlied@redhat.com>
Date: Fri Jun 12 12:06:58 2026 +1000
nouveau/gem: reserve the bo in the info ioctl around the vma lookup
commit 5e17160d41d92823f3379c1982e1369680c5ce4d upstream.
In the non-uvmm path, there could be a race between the info lookup
finding the vma, and the gem close path closing the vma leading
to a use-after-free.
Spotted with the help of Opus 4.6.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Fixes: e758a3111914 ("drm/nouveau: fixup gem_info ioctl to return client-specific bo virtual")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260612020658.3176270-1-airlied@gmail.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Christian Brauner <brauner@kernel.org>
Date: Thu Feb 26 14:50:10 2026 +0100
nsfs: tighten permission checks for handle opening
[ Upstream commit d2324a9317f00013facb0ba00b00440e19d2af5e ]
Even privileged services should not necessarily be able to see other
privileged service's namespaces so they can't leak information to each
other. Use may_see_all_namespaces() helper that centralizes this policy
until the nstree adapts.
Link: https://patch.msgid.link/20260226-work-visibility-fixes-v1-2-d2c2853313bd@kernel.org
Fixes: 5222470b2fbb ("nsfs: support file handles")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Cc: stable@kernel.org # v6.18+
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Mon Aug 17 14:35:18 2026 +0900
NTB: ntb_transport: Fail TX enqueue when the QP link is down
commit 873ce713fef5dde0939220f04f3484ec86a16fba upstream.
Commit f195a1a6fe41 ("ntb: Drop packets when qp link is down") meant to
make ntb_transport_tx_enqueue() drop packets submitted while the QP link
is down, but it only returns 0 without consuming the packet. Zero means
success by this function's contract, so ntb_netdev reports NETDEV_TX_OK
and forgets the skb: nothing queued it, nothing frees it, and it leaks,
one skb for every transmit racing a link-down.
Return -ENOLINK instead, restoring the contract that a non-zero return
leaves the buffer owned by the caller. With the preceding patch,
ntb_netdev frees the skb on non-retryable enqueue failures and returns
NETDEV_TX_OK, so a packet racing with link-down is dropped without leaking
or entering a busy retry loop.
Fixes: f195a1a6fe41 ("ntb: Drop packets when qp link is down")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260817053519.4135287-4-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Mon Aug 17 14:35:16 2026 +0900
NTB: ntb_transport: Recycle TX entries before client callbacks
commit 256496397287334a19ed80ec7be92bffcae76b9d upstream.
ntb_tx_copy_callback() invokes the client callback before returning the
entry to tx_free_q. The callback may wake a stopped client queue, only
for the next enqueue to find no local entry and return -EBUSY. The window
is narrow, but the retry is unnecessary.
Save the callback data and length, then return the entry to tx_free_q
before invoking the client. A completion callback then means both the
client buffer and transport entry are ready for reuse.
Fixes: fce8a7bb5b4b ("PCI-Express Non-Transparent Bridge Support")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260817053519.4135287-2-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Koichiro Den <den@valinux.co.jp>
Date: Mon Aug 17 14:35:19 2026 +0900
NTB: ntb_transport: Reject oversized TX buffers
commit a4f2387db6f1cc2f03abba7f3a6807ad61e26ff7 upstream.
ntb_process_tx() handles an oversized buffer by calling tx_handler()
with a NULL data pointer and returning success. ntb_netdev therefore
neither frees the skb in its completion callback nor takes its enqueue
error path, leaking it.
Reject oversized buffers in ntb_transport_tx_enqueue() before acquiring
a queue entry and return -EMSGSIZE. The caller retains ownership of the
buffer, and the preceding netdev patch frees the skb when enqueue
returns this permanent error.
Fixes: fce8a7bb5b4b ("PCI-Express Non-Transparent Bridge Support")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260817053519.4135287-5-den@valinux.co.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Myeonghun Pak <mhun512@gmail.com>
Date: Wed Jul 15 16:44:59 2026 +0900
nvme-pci: disable controller on admin queue IRQ setup failure
commit 08660a5c8d497f43191635d97efd31cd35051f15 upstream.
nvme_pci_configure_admin_queue() enables the controller and then requests
the admin queue interrupt. If queue_request_irq() fails it returns without
disabling the controller, and no caller compensates: nvme_pci_enable() only
frees the IRQ vectors and calls pci_disable_device(), after which
nvme_dev_disable() treats the controller as dead and skips nvme_disable_ctrl().
The controller is left enabled (CC.EN set) on this error path.
Disable it in the failure path, while the PCI device is still enabled so the
CC.EN clear handshake completes.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: b60503ba432b ("NVMe: New driver")
Cc: stable@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Sat Aug 1 17:18:18 2026 +0900
nvme-tcp: do not accept C2HData based on blk_rq_payload_bytes() alone
commit 3a4aa9e6ad3e35f8e24d5eaf38ee4d437075fb36 upstream.
Commit 25e5cb780e62 ("nvme-tcp: fix possible crash in write_zeroes
processing") established that blk_rq_payload_bytes() must not be read
without first checking blk_rq_nr_phys_segments(), and recorded the
result in nvme_tcp_setup_cmd_pdu() as req->data_len. The receive side
was left as it was.
The two differ for REQ_OP_WRITE_ZEROES, which has no physical segments
but a non-zero blk_rq_bytes(), so setup leaves req->iter untouched
while the receive gate lets a C2HData through and nvme_tcp_recv_data()
copies into whatever the previous command on that tag left there. The
driver-private area is zeroed only when the tag set is allocated.
Reproduced with a test target that leaves a residual iterator on a tag
and then sends a C2HData for a WRITE_ZEROES command on the same tag:
BUG: KASAN: wild-memory-access in _copy_to_iter+0x642/0x1330
Write of size 512 at addr ffe728c2175dfa81 by task kworker/0:1H/103
CPU: 0 UID: 0 PID: 103 Comm: kworker/0:1H Not tainted 7.2.0-rc5-NVMETCP-gf5098b6bae76 #1 PREEMPT(lazy)
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
Workqueue: nvme_tcp_wq nvme_tcp_io_work
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
kasan_report+0xce/0x100
? _copy_to_iter+0x642/0x1330
kasan_check_range+0x105/0x1b0
__asan_memcpy+0x3c/0x60
_copy_to_iter+0x642/0x1330
? __pfx_sock_has_perm+0x10/0x10
? worker_thread+0x45b/0xd10
? __pfx__copy_to_iter+0x10/0x10
? _raw_spin_lock_bh+0x83/0xe0
? __pfx__raw_spin_lock_bh+0x10/0x10
__skb_datagram_iter+0xf3/0x820
? __pfx_simple_copy_to_iter+0x10/0x10
? __asan_memcpy+0x3c/0x60
? skb_copy_bits+0x58d/0x830
skb_copy_datagram_iter+0x37/0x120
nvme_tcp_recv_skb+0xa07/0x4320
? __pfx_nvme_tcp_recv_skb+0x10/0x10
__tcp_read_sock+0x1ab/0x810
? __pfx_nvme_tcp_recv_skb+0x10/0x10
? __pfx_lock_sock_nested+0x10/0x10
? __pfx___tcp_read_sock+0x10/0x10
nvme_tcp_try_recv+0x152/0x1e0
? __pfx_nvme_tcp_try_recv+0x10/0x10
? __pfx_mutex_unlock+0x10/0x10
nvme_tcp_io_work+0x1e4/0x6c0
? __schedule+0x181a/0x49f0
? __pfx_nvme_tcp_io_work+0x10/0x10
process_one_work+0x633/0x1030
Keep the blk_rq_payload_bytes() test and add req->data_len to it. The
old test is what rejects a C2HData naming a tag that is no longer in
flight, because blk_update_request() zeroes rq->__data_len on
completion; req->data_len and req->curr_bio are driver-private and
survive completion, so they cannot stand in for it. Setup initialises
the iterator only when both req->curr_bio and req->data_len are set, so
the gate now tests the same two.
Fixes: 25e5cb780e62 ("nvme-tcp: fix possible crash in write_zeroes processing")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Wed Jul 29 14:46:02 2026 +0900
nvme-tcp: fix host memory disclosure on R2T for a read command
commit 6efbc52237facda35d2d874fe1765bb4839275d8 upstream.
nvme_tcp_handle_r2t() does not check the direction of the request the
R2T refers to. A malicious controller can send an R2T for a READ and
the host will answer it: nvme_tcp_setup_h2c_data_pdu() builds the
H2CData header and nvme_tcp_try_send_data() sends the request's data
buffer. That buffer is the READ destination, so its contents go to the
controller.
The command then completes normally and nothing is logged.
Against a test controller that answers every READ with an R2T, a 4096
byte buffered read returned all 4096 bytes, split over two R2Ts. The
pages contained stale kernel data, including an array of struct page
pointers.
Reject an R2T for a request that is not a write.
Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Sat Aug 1 17:18:17 2026 +0900
nvme-tcp: reject a read that transferred too few bytes
commit 7fa3f73f6c8ddc5f0425b50fb2a626a782ef7d12 upstream.
nvme_tcp_recv_data() completes a request once the current C2HData PDU
has been consumed. Nothing compares the total bytes received against
the length the command asked for: struct nvme_tcp_request has no
receive-side counter, queue->data_remaining is per queue, and
blk_mq_end_request() completes for blk_rq_bytes(rq) unconditionally
with no residual concept anywhere above.
A controller can therefore answer a 4096-byte read with 512 bytes and
have it reported as a complete read; user space then gets 4096 bytes of
which 3584 are whatever was already in the page. I reproduced that with
a test target.
Count the bytes received and refuse to complete a successful read whose
count does not match, at the two NVME_TCP_F_DATA_SUCCESS paths and in
nvme_tcp_process_nvme_cqe(). The success test shifts req->status right
by one, because the driver keeps the wire value there and shifts it on
completion, so the check must see what the completion path will see.
Only REQ_OP_READ is checked, because there the length comes from the
sectors the request covers; a passthrough command is built by its
submitter, which picks both command and buffer, so the kernel has
nothing to compare against.
Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ewan D. Milne <emilne@redhat.com>
Date: Wed May 13 15:25:51 2026 -0400
nvme: nvme-fc: Fix nvme_fc_create_hw_io_queues() queue deletion in error path
commit 22eb631bf86ee3246f47885e4fa94154a46863e4 upstream.
nvme_fc_create_hw_io_queues() will call __nvme_fc_delete_hw_queue() for the
last queue on which __nvme_fc_create_hw_queue() reported an error when deleting
all the io queues if they cannot all be created. This is incorrect since the
last queue did not actually get created.
The most recent change to this code was commit 17a1ec08ce70 ("nvme/fc: simplify
error handling of nvme_fc_create_hw_io_queues") which moved the cleanup to the
delete_queues: label and changed the loop bounds, however the code was not
correct prior to this change in a different way. The original commit
e399441de911 ("nvme-fabrics: Add host support for FC transport") had a
different error which called __nvme_fc_delete_hw_queue() on queue index 0 which
is used for the admin queue.
Fix this by correcting the initial loop index when deleting the io queues.
Fixes: 17a1ec08ce70 ("nvme/fc: simplify error handling of nvme_fc_create_hw_io_queues")
Fixes: e399441de911 ("nvme-fabrics: Add host support for FC transport")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Reviewed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Date: Thu Jul 30 20:36:24 2026 +0900
nvme: zero the discard fallback page
commit bededeaaeff404978a5a8e2a605a6c3017cddd3e upstream.
nvme_setup_discard() always maps sizeof(struct nvme_dsm_range) *
NVME_DSM_MAX_RANGES = 4096 bytes as the DSM payload however many ranges
the command declares, because some devices ignore the 'Number of Ranges'
field - the Fixes: commit records two that read past the declared ranges.
A single-range discard fills only the first 16 bytes.
Normally the buffer comes from kzalloc() and the other 4080 bytes are
zero. When that allocation fails the code falls back to the
per-controller ctrl->discard_page, which nvme_init_ctrl() obtains with
alloc_page(GFP_KERNEL) and nothing ever zeroes, so those 4080 bytes are
whatever the page last held and are handed to the controller. Reaching
it requires the kzalloc(GFP_ATOMIC | __GFP_NOWARN) to fail, that is
memory pressure; it is not remotely triggerable. Failing the allocation
under KMSAN reproduces it, with the leaked tail full of vmemmap struct
page pointers. The extent in the report is a partial transfer of the
payload, not the whole 4096 bytes; the 16-byte boundary in it is the one
declared range:
[ 11.991601] BUG: KMSAN: uninit-value in dma_map_phys+0x14c8/0x1900
[ 11.991969] dma_map_phys+0x14c8/0x1900
[ 11.992220] dma_map_page_attrs+0xcf/0x130
[ 11.992485] e1000_xmit_frame+0x4099/0x6d10
[ 11.992768] dev_hard_start_xmit+0x22f/0xa80
[ 11.993068] sch_direct_xmit+0x35c/0xcb0
[ 11.993315] __dev_queue_xmit+0x1ee5/0x5eb0
[ 11.993608] ip_finish_output2+0x1903/0x1c30
[ 11.993881] ip_finish_output+0x288/0x870
[ 11.994125] ip_output+0x15e/0x400
[ 11.994365] __ip_queue_xmit+0x1e85/0x1fb0
[ 11.994639] ip_queue_xmit+0x60/0x80
[ 11.994899] __tcp_transmit_skb+0x4e71/0x5fa0
[ 11.995210] tcp_write_xmit+0x3a36/0x9160
[ 11.995533] __tcp_push_pending_frames+0xc5/0x3c0
[ 11.995854] tcp_push+0x7dc/0x840
[ 11.996076] tcp_sendmsg_locked+0x766c/0x8400
[ 11.996371] tcp_sendmsg+0x4b/0x90
[ 11.996572] inet_sendmsg+0x134/0x2a0
[ 11.996823] __sock_sendmsg+0x265/0x360
[ 11.997076] sock_sendmsg+0x100/0x1e0
[ 11.997293] nvme_tcp_try_send+0x196f/0x6370
[ 11.997605] nvme_tcp_queue_rq+0x1d54/0x20b0
[ 11.997882] blk_mq_dispatch_rq_list+0x5ee/0x2e50
[ 11.998175] __blk_mq_sched_dispatch_requests+0x16dc/0x24a0
[ 11.998539] blk_mq_sched_dispatch_requests+0x11b/0x2c0
[ 11.998865] blk_mq_run_work_fn+0x13b/0x280
[ 11.999146] process_scheduled_works+0x966/0x1ad0
[ 11.999465] worker_thread+0xe44/0x1480
[ 11.999709] kthread+0x53b/0x600
[ 11.999927] ret_from_fork+0x29f/0x7c0
[ 12.000191] ret_from_fork_asm+0x1a/0x30
[ 12.000460]
[ 12.000558] Uninit was created at:
[ 12.000788] __alloc_frozen_pages_noprof+0x8bf/0xd30
[ 12.001096] alloc_pages_mpol+0x1d0/0x5f0
[ 12.001326] alloc_pages_noprof+0x102/0x290
[ 12.001627] nvme_init_ctrl+0x5a3/0x9f0
[ 12.001891] nvme_tcp_create_ctrl+0xd75/0x19b0
[ 12.002170] nvmf_dev_write+0x4c68/0x4fd0
[ 12.002426] vfs_write+0x587/0x1a10
[ 12.002636] __x64_sys_write+0x207/0x4f0
[ 12.002874] x64_sys_call+0x2ff0/0x3ea0
[ 12.003123] do_syscall_64+0x147/0x3b0
[ 12.003400] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 12.003680]
[ 12.003777] Bytes 16-2843 of 2844 are uninitialized
[ 12.004068] Memory access of size 2844 starts at ffff888109f82000
[ 12.004412]
[ 12.004530] CPU: 0 UID: 0 PID: 101 Comm: kworker/0:1H Not tainted 7.2.0-rc5-NVMECTL-gf5098b6bae76 #1 PREEMPT(lazy)
[ 12.005127] 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
[ 12.005762] Workqueue: kblockd blk_mq_run_work_fn
[ 12.006073] =====================================================
Allocate the page with __GFP_ZERO. The single allocation site covers
every use of it: bytes no discard has written stay zero, and bytes one
did write hold that controller's own range list, which it has already
been sent.
Fixes: 530436c45ef2 ("nvme: Discard workaround for non-conformant devices")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Dmitry Antipov <dmantipov@yandex.ru>
Date: Tue Jul 21 13:28:40 2026 +0300
ocfs2: always run deallocs on copy-on-write completion
commit 82ea9d4fc05fb7a387db547c6a7c0aa6a3719616 upstream.
Local fuzzing of 6.12.94 has found the following memory leak
caused by doing 'copy_file_range()' within the same filesystem:
unreferenced object 0xffff88812192c980 (size 32):
comm "syz.0.49", pid 12095, jiffies 4294964143
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................
c0 c5 92 21 81 88 ff ff 00 02 00 00 00 06 00 00 ...!............
backtrace (crc 7068d63f):
kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
slab_post_alloc_hook mm/slub.c:4152 [inline]
slab_alloc_node mm/slub.c:4197 [inline]
__kmalloc_cache_noprof+0x168/0x2c0 mm/slub.c:4358
kmalloc_noprof include/linux/slab.h:878 [inline]
ocfs2_find_per_slot_free_list fs/ocfs2/alloc.c:6618 [inline]
ocfs2_cache_block_dealloc+0x155/0x4b0 fs/ocfs2/alloc.c:6786
ocfs2_cache_extent_block_free fs/ocfs2/alloc.c:6819 [inline]
ocfs2_unlink_path+0x286/0x450 fs/ocfs2/alloc.c:2613
ocfs2_rotate_subtree_left fs/ocfs2/alloc.c:2779 [inline]
__ocfs2_rotate_tree_left+0x1f6f/0x2da0 fs/ocfs2/alloc.c:2985
ocfs2_rotate_tree_left+0x283/0xe00 fs/ocfs2/alloc.c:3237
ocfs2_try_to_merge_extent+0xf56/0x1a20 fs/ocfs2/alloc.c:3825
ocfs2_split_extent+0x15f4/0x2940 fs/ocfs2/alloc.c:5138
ocfs2_clear_ext_refcount+0x2f6/0x550 fs/ocfs2/refcounttree.c:3098
ocfs2_replace_clusters fs/ocfs2/refcounttree.c:3131 [inline]
ocfs2_make_clusters_writable fs/ocfs2/refcounttree.c:3255 [inline]
ocfs2_replace_cow+0x991/0x1660 fs/ocfs2/refcounttree.c:3349
ocfs2_refcount_cow_hunk fs/ocfs2/refcounttree.c:3427 [inline]
ocfs2_refcount_cow+0x5e1/0x9f0 fs/ocfs2/refcounttree.c:3470
ocfs2_prepare_inode_for_write fs/ocfs2/file.c:2340 [inline]
ocfs2_file_write_iter+0xbda/0x1880 fs/ocfs2/file.c:2451
iter_file_splice_write+0x890/0xf60 fs/splice.c:743
do_splice_from fs/splice.c:944 [inline]
direct_splice_actor+0x232/0x480 fs/splice.c:1167
splice_direct_to_actor+0x4b4/0xb60 fs/splice.c:1111
do_splice_direct_actor fs/splice.c:1210 [inline]
do_splice_direct+0x10f/0x1c0 fs/splice.c:1236
do_sendfile+0x430/0xbf0 fs/read_write.c:1388
unreferenced object 0xffff88812192c5c0 (size 32):
comm "syz.0.49", pid 12095, jiffies 4294964143
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
29 70 00 00 00 00 00 00 19 00 00 00 00 00 00 00 )p..............
backtrace (crc afec850f):
kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
slab_post_alloc_hook mm/slub.c:4152 [inline]
slab_alloc_node mm/slub.c:4197 [inline]
__kmalloc_cache_noprof+0x168/0x2c0 mm/slub.c:4358
kmalloc_noprof include/linux/slab.h:878 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
ocfs2_cache_block_dealloc+0x25c/0x4b0 fs/ocfs2/alloc.c:6793
ocfs2_cache_extent_block_free fs/ocfs2/alloc.c:6819 [inline]
ocfs2_unlink_path+0x286/0x450 fs/ocfs2/alloc.c:2613
ocfs2_rotate_subtree_left fs/ocfs2/alloc.c:2779 [inline]
__ocfs2_rotate_tree_left+0x1f6f/0x2da0 fs/ocfs2/alloc.c:2985
ocfs2_rotate_tree_left+0x283/0xe00 fs/ocfs2/alloc.c:3237
ocfs2_try_to_merge_extent+0xf56/0x1a20 fs/ocfs2/alloc.c:3825
ocfs2_split_extent+0x15f4/0x2940 fs/ocfs2/alloc.c:5138
ocfs2_clear_ext_refcount+0x2f6/0x550 fs/ocfs2/refcounttree.c:3098
ocfs2_replace_clusters fs/ocfs2/refcounttree.c:3131 [inline]
ocfs2_make_clusters_writable fs/ocfs2/refcounttree.c:3255 [inline]
ocfs2_replace_cow+0x991/0x1660 fs/ocfs2/refcounttree.c:3349
ocfs2_refcount_cow_hunk fs/ocfs2/refcounttree.c:3427 [inline]
ocfs2_refcount_cow+0x5e1/0x9f0 fs/ocfs2/refcounttree.c:3470
ocfs2_prepare_inode_for_write fs/ocfs2/file.c:2340 [inline]
ocfs2_file_write_iter+0xbda/0x1880 fs/ocfs2/file.c:2451
iter_file_splice_write+0x890/0xf60 fs/splice.c:743
do_splice_from fs/splice.c:944 [inline]
direct_splice_actor+0x232/0x480 fs/splice.c:1167
splice_direct_to_actor+0x4b4/0xb60 fs/splice.c:1111
do_splice_direct_actor fs/splice.c:1210 [inline]
do_splice_direct+0x10f/0x1c0 fs/splice.c:1236
do_sendfile+0x430/0xbf0 fs/read_write.c:1388
This happens when 'ocfs2_cache_block_dealloc()' called from
'ocfs2_cache_extent_block_free()' uses the suballocator to
schedule extent removal, so 'ocfs2_run_deallocs()' should
be run unconditionally to complete the removal with
'ocfs2_free_cached_blocks()'. An extra semi-automated static
analysis [1] suspects that the same scenario looks possible in
'ocfs2_attach_refcount_tree()' and 'ocfs2_reflink_remap_blocks()'
as well, but, since 'ocfs2_run_deallocs()' is a safe no-op for
an empty dealloc context, 'ocfs2_create_reflink_node()' and
'ocfs2_reflink_xattrs()' may be adjusted in the same way too,
thus keeping the code pattern consistent.
Link: https://lore.kernel.org/20260721102840.387663-1-dmantipov@yandex.ru
Link: https://lore.kernel.org/ocfs2-devel/f1d7e266-4b44-41b9-98c0-5b3868a8d9c3@yandex.ru [1]
Fixes: 6f70fa519976 ("ocfs2: Add CoW support.")
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Suggested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Mon Jun 29 00:01:43 2026 -0500
ocfs2: bound namelen in dlm_migrate_request_handler
commit ea5b5609305a8437bc955a0834a530c12246d78f upstream.
Patch series "ocfs2/dlm: bound peer-controlled lengths in the o2dlm".
The o2dlm receive handlers trust u8 length and count fields from the wire
without bounding them, so a node in a DLM domain can corrupt or panic any
other node with a malformed message. Three defects:
- dlm_migrate_request_handler() passes migrate->namelen unchecked to
dlm_init_mle(), which memcpy()s it into the 32-byte mname[] of an
o2dlm_mle slab object: a heap out-of-bounds write of up to ~215
attacker-controlled bytes.
- dlm_mig_lockres_handler() passes mres->lockname_len unchecked to
dlm_init_lockres(), which memcpy()s it into the 32-byte o2dlm_lockname
slab object: a heap out-of-bounds write of up to ~223 bytes.
- the same handler trusts mres->num_locks without checking that the
message is large enough to hold that many entries, so
dlm_process_recovery_data() walks mres->ml[] past the kmalloc(data_len)
copy and trips a BUG_ON (an out-of-bounds read ending in a panic).
The other o2dlm receive handlers already reject an oversized name; the
migration and recovery handlers have omitted it since the DLM was added
(see the Fixes tags). Patch 1 bounds namelen; patch 2 validates
lockname_len, num_locks, and the payload size. Conforming recovery and
migration traffic is unaffected.
o2net authenticates peers only by the DLM domain key, so any node that has
joined the domain -- including a compromised or malicious member -- can
send these messages. There is no local trigger; the attacker must already
be a member of the cluster.
Each sink was confirmed under KASAN with an out-of-tree module mirroring
it exactly -- a kmem_cache/kmalloc of the real destination size, then the
same unclamped memcpy/loop: slab-out-of-bounds Write for the two writes,
Read for the recovery walk, and a panic. A userspace AddressSanitizer
build faults identically under -m32 and -m64. Scrubbed logs are available
on request.
I reported this privately to security@kernel.org and the ocfs2 maintainers
on 2026-06-20; with no response after the standard embargo period I am
posting the fix publicly. I have no embargo requirement.
This patch (of 2):
A node receiving a DLM_MIGRATE_REQUEST message trusts the peer-supplied
name length (migrate->namelen) without bounding it. dlm_init_mle() then
copies that many bytes into the fixed DLM_LOCKID_NAME_MAX-byte mname[]
array of an o2dlm_mle slab object, so a malformed message from a cluster
peer overflows the slab object by up to ~215 bytes: a heap out-of-bounds
write of attacker-controlled data, reachable by any node in the domain.
Reject an oversized name, the way dlm_master_request_handler() and the
other o2dlm receive handlers already do; the migration handler omits the
check entirely. Conforming messages are unaffected.
Link: https://lore.kernel.org/20260629-b4-disp-94fb6521-v1-0-6953bcc0421f@proton.me
Link: https://lore.kernel.org/20260629-b4-disp-94fb6521-v1-1-6953bcc0421f@proton.me
Fixes: 6714d8e86bf4 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joseph Qi <joseph.qi@linux.alibaba.com>
Date: Wed Jul 22 20:49:32 2026 +0800
ocfs2: cluster: avoid lock order inversion in o2hb_region_pin() from drop_item
commit cd789996db3c87427343f54f509d17810bd7ba7c upstream.
o2hb_heartbeat_group_drop_item() is called from configfs rmdir with the
parent directory's inode_lock held. It calls o2hb_region_pin() ->
o2nm_depend_item() -> configfs_depend_item(), which acquires the configfs
root inode_lock. This creates a parent -> root inode_lock nesting that
could deadlock against paths taking root -> parent (e.g. subsystem
unregistration).
Fix this by using configfs_depend_item_unlocked() when o2hb_region_pin()
is called from a configfs callback context. This variant skips the root
inode_lock when caller and target are in the same subsystem, which is safe
because VFS already holds a lock preventing unregistration.
Add o2nm_depend_item_unlocked() wrapper and a from_callback parameter to
o2hb_region_pin() to select the appropriate variant.
Link: https://lore.kernel.org/20260722124933.430554-3-joseph.qi@linux.alibaba.com
Fixes: 58a3158a5d17 ("ocfs2/cluster: Pin/unpin o2hb regions")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joseph Qi <joseph.qi@linux.alibaba.com>
Date: Wed Jul 22 20:49:31 2026 +0800
ocfs2: cluster: don't sleep while holding o2hb_live_lock in o2hb_region_pin()
commit af09df89db9a68a1d76df0f75667998135bc8d65 upstream.
Patch series "ocfs2: cluster: o2hb_region_pin() fixes", v2.
This series fixes three related issues in o2hb_region_pin(), all are from
the original implementation in commit: 58a3158a5d17 ("ocfs2/cluster:
Pin/unpin o2hb regions"):
1) It is called with o2hb_live_lock (a spinlock) held, but the
underlying configfs_depend_item() sleeps (takes inode rwsem and
pins the filesystem). This triggers BUG under
CONFIG_DEBUG_ATOMIC_SLEEP.
2) When called from the configfs drop_item callback, it creates a
lock order inversion: parent inode_lock -> configfs root
inode_lock, which can deadlock against subsystem unregistration
paths taking root -> parent.
3) If pinning fails partway through o2hb_region_inc_user(), the
o2hb_dependent_users counter is leaked and partially-pinned
regions are never released, leaving heartbeat regions
unprotected on subsequent mounts.
Patch 1 reworks o2hb_region_pin() to drop o2hb_live_lock across each
sleeping configfs_depend_item() call, using a config_item reference to
keep the region alive while unlocked.
Patch 2 adds a from_callback parameter to select
configfs_depend_item_unlocked() when called from configfs context,
avoiding the inode_lock nesting.
Patch 3 fixes the error path in o2hb_region_inc_user() to unpin and
decrement the counter on failure.
This patch (of 3):
o2hb_region_pin() is always called with the o2hb_live_lock spinlock held
(from o2hb_region_inc_user() and o2hb_heartbeat_group_drop_item()), but it
calls o2nm_depend_item() -> configfs_depend_item(), which sleeps: it pins
the configfs filesystem and takes the configfs root inode rwsem. Under
CONFIG_DEBUG_ATOMIC_SLEEP this triggers:
BUG: sleeping function called from invalid context at kernel/locking/rwsem.c
in_atomic(): 1, ... name: mount.ocfs2
down_write
configfs_depend_item
o2hb_region_pin
o2hb_region_inc_user
o2hb_register_callback
dlm_register_domain_handlers
...
ocfs2_dlm_init
ocfs2_mount_volume
ocfs2_fill_super
Rework o2hb_region_pin() to pin one region at a time with the lock dropped
across the sleeping call: under o2hb_live_lock find the next eligible
region and take a config_item reference to keep it alive, drop the lock,
call o2nm_depend_item(), then retake the lock and record the pin. The
config_item_put() is done with the lock released as well, since
o2hb_region_release() also acquires o2hb_live_lock and can sleep. The
region list may change while unlocked, so the scan restarts from the top
after each pin. Local heartbeat still pins only the matching region;
global heartbeat pins all eligible regions.
The unpin path is unaffected: configfs_undepend_item() only takes a
spinlock and does not sleep.
Link: https://lore.kernel.org/20260722124933.430554-1-joseph.qi@linux.alibaba.com
Link: https://lore.kernel.org/20260722124933.430554-2-joseph.qi@linux.alibaba.com
Fixes: 58a3158a5d17 ("ocfs2/cluster: Pin/unpin o2hb regions")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joseph Qi <joseph.qi@linux.alibaba.com>
Date: Wed Jul 22 20:49:33 2026 +0800
ocfs2: cluster: fix o2hb_dependent_users leak on pin failure
commit 12c2ab42dbe227956c765e2674364bfca5de0533 upstream.
In o2hb_region_inc_user(), o2hb_dependent_users is incremented
unconditionally before calling o2hb_region_pin(). If the pin fails, the
counter is never decremented and any partially-pinned regions are never
unpinned, since the caller does not call o2hb_region_dec_user() on error.
The leaked counter causes subsequent o2hb_region_inc_user() calls to skip
pinning entirely (the > 1 check), leaving heartbeat regions unprotected.
Fix by rolling back on failure: call o2hb_region_unpin(NULL) to release
any partially-pinned regions and decrement o2hb_dependent_users to restore
the pre-increment state.
Link: https://lore.kernel.org/20260722124933.430554-4-joseph.qi@linux.alibaba.com
Fixes: 58a3158a5d17 ("ocfs2/cluster: Pin/unpin o2hb regions")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhan Xusheng <zhanxusheng1024@gmail.com>
Date: Thu Aug 6 10:20:44 2026 +0800
ocfs2: fix readdir position truncation on 32-bit kernels
commit a63308ab426f3a3c7e33b02c150ea59054620261 upstream.
In ocfs2_dir_foreach_blk_el(), the directory cookie position is
rebuilt with
ctx->pos = (ctx->pos & ~(sb->s_blocksize - 1)) | offset;
`ctx->pos` is loff_t (signed 64-bit), while `sb->s_blocksize` is
unsigned long. On 32-bit kernels unsigned long is 32-bit, so the mask
~(sb->s_blocksize - 1)
is computed as a 32-bit unsigned value (e.g. 0xfffff000 for a 4 KiB
block size). In the AND expression with the 64-bit `ctx->pos`, that
unsigned operand is zero-extended to 64 bits per the usual arithmetic
conversions, yielding 0x00000000fffff000. The high 32 bits of
`ctx->pos` are silently cleared, even though directory size is
allowed to exceed 4 GiB.
When readdir() crosses the 4 GiB boundary on a 32-bit kernel the
position is reset back into the first 4 GiB block, making the
re-validation path re-enumerate already-returned dirents indefinitely.
This is ocfs2_dir_foreach_blk_el(), the extent-list readdir path taken
for all non-inline directories, so a directory large enough to cross
4 GiB reaches it.
This is the same class of bug that commit 3dce5bb82c97 ("exfat: Fix
bitwise operation having different size") fixed in exfat, and the
fix mirrors the equivalent ext4 fix in this series. Cast the operand
to loff_t so the mask is 64-bit before the AND:
ctx->pos = (ctx->pos & ~((loff_t)sb->s_blocksize - 1)) | offset;
64-bit kernels are unaffected.
Link: https://lore.kernel.org/20260806022044.167962-3-zhanxusheng@xiaomi.com
Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jan Kara <jack@suse.cz>
Cc: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Ted Ts'o <tytso@mit.edu>
Cc: "zhangyi (F)" <yi.zhang@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Mon Jun 29 00:01:44 2026 -0500
ocfs2: validate lengths in dlm_mig_lockres_handler
commit b54e03d9b3697d25f4a0063cf717d459c5e3ad94 upstream.
A node receiving a DLM_MIG_LOCKRES message trusts several fields of the
peer-supplied dlm_migratable_lockres without validation. num_locks and
lockname_len are bounded only on the sending side, and the message is
never checked to actually carry num_locks migratable_lock entries. As a
result dlm_process_recovery_data() walks mres->ml[0..num_locks) past the
kmalloc(data_len) copy of the message (an out-of-bounds read that ends in
a BUG_ON panic), and dlm_init_lockres() copies lockname_len bytes into the
fixed 32-byte o2dlm_lockname slab object (a heap out-of-bounds write).
Both are reachable by any node in the domain.
Validate these fields right after dlm_grab(), before anything uses them --
including the not-joined error path, which already prints mres->lockname
with the unbounded lockname_len as a %.*s precision. Reject the message
unless lockname_len <= DLM_LOCKID_NAME_MAX, num_locks <=
DLM_MAX_MIGRATABLE_LOCKS (the bound the sender already asserts), and the
payload is large enough to hold the claimed locks. Conforming recovery
and migration messages are unaffected.
Link: https://lore.kernel.org/20260629-b4-disp-94fb6521-v1-2-6953bcc0421f@proton.me
Fixes: 6714d8e86bf4 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ibrahim Hashimov <security@auditcode.ai>
Date: Thu Jul 9 15:26:09 2026 +0200
ocfs2: validate rl_used against rl_count in refcount block validator
commit 4ca62df6bc0708947b48da3f6a712ecb8e73929c upstream.
ocfs2_find_refcount_rec_in_rl() walks the on-disk refcount record array
with:
for (; i < le16_to_cpu(rb->rf_records.rl_used); i++) {
rec = &rb->rf_records.rl_recs[i];
...
rl_recs[] lives in a single metadata block (4096 bytes on the common
configuration), so its real capacity is fixed by
ocfs2_refcount_recs_per_rb(sb) (247 records for a 4K block with the
16-byte ocfs2_refcount_rec). rl_used and rl_count are both read directly
off disk by ocfs2_validate_refcount_block() and are never checked against
that capacity, nor against each other, before any refcount/reflink/CoW
operation walks the array.
A crafted (or corrupted) refcount block with rl_used == 0xffff makes the
loop above walk far past the end of the block, dereferencing rl_recs[i]
for i up to 65534. The resulting index is then handed to the sibling
ocfs2_insert_refcount_rec(), whose insert-shift does:
if (index < le16_to_cpu(rf_list->rl_used))
memmove(&rf_list->rl_recs[index + 1],
&rf_list->rl_recs[index],
(le16_to_cpu(rf_list->rl_used) - index) *
sizeof(struct ocfs2_refcount_rec));
i.e. a memmove() of up to (0xffff - index) * 16 bytes (~1 MiB) from an
offset already past the block. This is reachable from an ordinary reflink
(FICLONE) against a crafted/corrupted ocfs2 image: attaching an extent
whose cpos sorts past every real record in the leaf forces the lookup to
run off the end instead of returning early on a match. The attacker model
is local: CAP_SYS_ADMIN mounting a crafted or corrupted ocfs2 image, or a
raw write to the block device backing an already-mounted ocfs2 filesystem.
ocfs2_validate_refcount_block() already validates the block's ECC,
signature, rf_blkno and rf_fs_generation, but never rl_count/rl_used
against the block's actual on-disk capacity. This is the same class of
gap that ocfs2_validate_extent_block() (fs/ocfs2/alloc.c) already closes
for the sibling extent-list header, which checks both the record capacity
and the "used" bound before any code walks h_list.l_recs[]:
if (le16_to_cpu(eb->h_list.l_count) != ocfs2_extent_recs_per_eb(sb)) {
rc = ocfs2_error(...);
goto bail;
}
if (le16_to_cpu(eb->h_list.l_next_free_rec) >
le16_to_cpu(eb->h_list.l_count)) {
rc = ocfs2_error(...);
goto bail;
}
Add the equivalent pair of checks to ocfs2_validate_refcount_block():
reject a refcount block whose rl_count does not match the fixed per-block
capacity returned by ocfs2_refcount_recs_per_rb(), and reject rl_used >
rl_count. Both checks are skipped when OCFS2_REFCOUNT_TREE_FL is set,
because in that case the same union bytes hold an ocfs2_extent_list
(rf_list), not the refcount record list (rf_records) -- that layout is
already validated separately by ocfs2_validate_extent_block() when the
referenced extent block is read. This mirrors the existing
"!(rb->rf_flags & OCFS2_REFCOUNT_TREE_FL)" guard used elsewhere in this
file (e.g. ocfs2_get_refcount_rec()) to decide whether rf_records or
rf_list is the live member of the union.
With this in place, a forged rl_used/rl_count is caught at block
validation time (ocfs2_error()), consistent with every other corruption
check in this function, instead of driving an out-of-bounds read in
ocfs2_find_refcount_rec_in_rl() and a subsequent out-of-bounds memmove()
in ocfs2_insert_refcount_rec().
Verified against a crafted image on a v6.19 KASAN (KASAN_GENERIC) build:
replaying the same reflink (FICLONE) reliably hit a KASAN report in
__ocfs2_increase_refcount()/ocfs2_insert_refcount_rec() before this patch,
and triggers no report once ocfs2_validate_refcount_block() rejects the
forged rl_used/rl_count.
Link: https://lore.kernel.org/20260709132609.44233-1-security@auditcode.ai
Fixes: f2c870e3b12e ("ocfs2: Add ocfs2_read_refcount_block.")
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Assisted-by: AuditCode-AI:2026.07
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Date: Wed Aug 5 13:31:00 2026 -0700
of: fix out-of-bounds read in of_alias_scan() stem parser
commit 5bb01c657ff9fc807c2c592ca18af34c4fc3bc6f upstream.
The stem parser tests isdigit(*(end - 1)) before checking end > start
and so reads one byte before the property name when the name is empty
or all digits. Check the bound first.
Fixes: 611cad720148 ("dt: add of_alias_scan and of_alias_get_id")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5 [Claude Code]
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260805-nh-of-alias-overlay-v6-1-74f21d440819@nexthop.ai
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ali Ahmet Memis <ali@iusegentoo.com>
Date: Fri Aug 21 01:45:27 2026 +0000
openrisc: fix arbitrary kernel memory access via or1k_atomic syscall
commit 78004e9a87f240df03e2f73120d291763c32e0a7 upstream.
sys_or1k_atomic() (syscall 244 in the "or1k" ABI) takes two user
pointers, v1 and v2, and swaps the words they point to in hand-written
assembly.
l.lwz r29,0(r4)
l.lwz r27,0(r5)
l.sw 0(r4),r27
l.sw 0(r5),r29
The pointers are not checked with access_ok(). The four memory
accesses also have no exception table entries.
A caller passes a kernel address as either pointer, and the syscall
reads from and writes to it directly.
This gives an unprivileged process a kernel read/write primitive. It
overwrites kernel data such as the sys_call_table, gaining code
execution in kernel context.
Check both pointers before entering the critical section. Add fixups
for the four memory accesses so faults on valid but unmapped user
addresses return -EFAULT.
[shorne@gmail.com: fix comment style]
Fixes: 9d02a4283e9c ("OpenRISC: Boot code")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Norbert Szetei <norbert@doyensec.com>
Date: Sat Aug 22 11:12:11 2026 +0200
openvswitch: only skb_tx_error() a packet we are about to drop
commit 0dbc2398fca3bb33eda963849f865ddb1b3aa05e upstream.
queue_userspace_packet() borrows the packet skb -- it only copies it into
a private netlink message (user_skb) and does not own it; on return
do_execute_actions() keeps forwarding it through the flow's remaining
actions. Its error path nevertheless calls skb_tx_error(skb), which via
skb_zcopy_clear() does skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY,
stripping SKBFL_SHARED_FRAG from that live skb (skb_tx_error()'s kerneldoc
says "skb must be freed afterwards").
For a MSG_ZEROCOPY skb carrying page-cache frags, SKBFL_SHARED_FRAG is
what makes esp_input() skb_cow_data() before in-place AEAD; once it is
stripped a later local ESP-in-UDP delivery decrypts in place over pages
the sender does not own -- an unprivileged page-cache write (the
"Fragnesia" primitive).
do_execute_actions() ignores output_userspace()'s return value, so any
action after a failed USERSPACE upcall inherits the stripped skb.
Move the skb_tx_error() to the flow-miss drop path - the "default"
branch of ovs_dp_process_packet()'s switch(error), before kfree_skb().
The call has been here since commit 36d5fe6a0007 ("core, nfqueue,
openvswitch: Orphan frags in skb_zerocopy and handle errors") but was
harmless until esp_input() began relying on SKBFL_SHARED_FRAG to gate
in-place decrypt; only then did stripping it on a still-forwarded skb
become a page-cache write primitive.
Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors")
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Tested-by: Jongmin Jang <payload.jang@gmail.com>
Link: https://patch.msgid.link/55A52703-7548-4A55-A9CE-2A37145BDCAD@doyensec.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yifei Gao <gyf161023@gmail.com>
Date: Mon Aug 3 01:07:55 2026 +0000
orangefs: fix double-free of trailer_buf on readdir copy failure
commit f574296be7f46eb60beca851240b526df232f480 upstream.
On a readdir downcall, orangefs_devreq_write_iter() frees
op->downcall.trailer_buf with vfree() when copy_from_iter_full() fails,
but does not clear the pointer before goto Efault. The waiter in
do_readdir() is then woken with a negative status and frees the same
pointer again on its r < 0 path, causing a deterministic double-free.
A client holding /dev/pvfs2-req triggers it by sending a readdir
downcall whose declared trailer_size exceeds the bytes it supplies.
Clear the pointer after freeing so the readdir-side vfree() becomes a
no-op.
Fixes: 382f4581e67f ("orangefs: rewrite readdir to fix several bugs")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Fri Jul 24 02:01:46 2026 +0800
orangefs: skip leading spaces before parsing client debug masks
commit d410cd5303ec59c7cf23dd61423752ce8e9ecb59 upstream.
orangefs_prepare_cdm_array() sizes each client debug keyword buffer
with strcspn(cds_head, " "), but then parses the keyword with %s. The
%s conversion skips leading whitespace, while strcspn() does not.
If a client debug entry starts with a space, the allocation can be sized
for an empty keyword while sscanf() copies the following non-empty token.
This can write past the end of the allocated keyword buffer.
Skip leading spaces before computing the keyword length so the allocation
matches the string parsed by sscanf().
Fixes: f7be4ee07fb7 ("Orangefs: kernel client part 4")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ralf Lici <ralf@mandelbit.com>
Date: Thu Sep 3 16:26:59 2026 +0300
ovpn: run deferred work on a module-owned workqueue
commit e9714db8041763f59dde152c812b96b3de05c6d9 upstream.
ovpn queues several work items whose callbacks execute module text.
These works currently run on the global system workqueues, so module
exit has no driver-owned drain point that guarantees the callbacks have
fully returned before the module text can be freed.
Object references protect the objects used by the callbacks, but they do
not prove that a workqueue function has returned. In particular, a
worker can drop the final reference that unblocks device teardown while
it is still executing ovpn code.
Add a module-owned workqueue and queue all ovpn work items on it. During
module exit, unregister rtnl and netlink first, flush the workqueue so
ordinary ovpn workers finish, run the final RCU barrier, and destroy the
workqueue last. This keeps the workqueue available for cleanup work
queued from RCU callbacks, while ensuring no ovpn work item can outlive
the module text.
The per-device delayed keepalive work remains explicitly disabled during
netdev teardown (disable_delayed_work_sync in ndo_uninit), since
flush_workqueue does not flush delayed work that is still only pending
on its timer.
Fixes: 3ecfd9349f40 ("ovpn: implement keepalive mechanism")
Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Signed-off-by: Alexander Martyniuk <alexevgmart@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Jiacheng Yu <yujiacheng3@huawei.com>
Date: Wed Jul 29 12:32:43 2026 +0000
params: fix charp corruption on allocation failure
commit 3dfaae04243cde460d82dfc2a7dd0bb6664d20ae upstream.
param_set_charp() stores charp parameters in allocated memory after slab is
available, and releases the previous value when the parameter is updated.
The previous value is released before the replacement allocation succeeds.
If kmalloc_parameter() fails, the setter returns -ENOMEM with the parameter
left as NULL.
Failing zswap's compressor update before zswap is initialized can later
trigger:
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:strcmp+0x10/0x30
Call Trace:
zswap_setup+0x3b1/0x490
zswap_enabled_param_set+0x5b/0xa0
param_attr_store+0x93/0xe0
module_attr_store+0x1c/0x30
kernfs_fop_write_iter+0x116/0x1f0
Allocate and copy the replacement first, then replace the parameter value
only after allocation succeeds.
Fixes: e180a6b7759a ("param: fix charp parameters set via sysfs")
Cc: stable@vger.kernel.org
Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Lukas Wunner <lukas@wunner.de>
Date: Fri Jul 24 17:24:04 2026 +0200
PCI/AER: Emit TLP Log only for unmasked errors
commit a8bf2dd750de7d682fdaa2127f4e3217ce9c4a82 upstream.
Per PCIe r7.0 sec 6.2.5, the prefix and header of an offending TLP is only
recorded for unmasked Uncorrectable Errors. Yet when the AER driver
determines whether a prefix and header has been logged, it does not take
the Uncorrectable Error Mask Register into account. Fix it.
Fixes: 6c2b374d7485 ("PCI-Express AER implemetation: AER core and aerdriver")
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v2.6.19+
Link: https://patch.msgid.link/2e712b96ba5bfc729d78bfc23f7fb7d285aa3d6d.1784905909.git.lukas@wunner.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Lukas Wunner <lukas@wunner.de>
Date: Fri Jul 24 17:24:01 2026 +0200
PCI/AER: Fix mapping of errors to agent & layer
commit 1017599755b8b578a671f8fac175bce56189d01c upstream.
PCIe r7.0 sec 6.2.7 documents the agent and layer of each Correctable and
Uncorrectable Error. Based on this spec section, the AER driver maps
detected errors to an agent and layer using a set of macros and logs them.
Most errors listed in sec 6.2.7 map to the "Receiver" agent and
"Transaction Layer", so the macros use these as defaults unless an error
maps to something else.
However the macros have not been amended since their introduction in 2006
with commit 6c2b374d7485 ("PCI-Express AER implemetation: AER core and
aerdriver"). They are still based on PCIe r1.0 sec 7.2.5 (renumbered to
6.2.7 in PCIe r1.1 and newer).
Amend the macros to map errors introduced since then to the appropriate
agent and layer.
PCIe r2.1 introduced a new "Component" agent and "General" layer for
Internal Errors and Header Log Overflow. Add them to the macros.
Unsupported Request is currently mapped to the "Requester" agent, even
though it is reported by the "Receiver". Fix the incorrect mapping.
Sec 6.2.7 neglects to list an agent for Data Link Protocol Error and
Surprise Down Error. Map the latter to "Component" because PCIe r7.0 sec
3.2.1 states that the error is "associated with the detecting Port". Map
the former to "Receiver" because every occurrence of Data Link Protocol
Error in the spec refers to it being logged in the Receiving Port. I have
had these errata reported to the PCI-SIG Protocol Working Group. (There's
also a layout erratum in the REPLAY_NUM Rollover row wherein columns are
shifted to the left, but that's already corrected in the PCIe r7.1 draft
as of 2026-04-07.)
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aec4820a75e949b332585a08cb1808fda7f40ea4.1784905909.git.lukas@wunner.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Max Lee <max.lee@canonical.com>
Date: Tue Jul 7 10:15:27 2026 +0800
PCI/ASPM: Avoid L0s for Realtek RTS525A
commit ec3d987fcaf92516d13ee18c305c82281557046d upstream.
The Realtek RTS525A PCIe card reader reports an AER Correctable Replay
Timer Timeout storm when ASPM L0s is enabled on its link. On an affected
HP ZBook Power 16 inch G11, the Root Port received tens of millions of AER
interrupts from the RTS525A even when the rtsx_pci driver was blacklisted
and the endpoint was not enabled by a driver.
For example:
pcieport 0000:00:1c.6: AER: Multiple Correctable error message received from 0000:58:00.0
rtsx_pci 0000:58:00.0: PCIe Bus Error: severity=Correctable, type=Data Link Layer, (Transmitter ID)
rtsx_pci 0000:58:00.0: device [10ec:525a] error status/mask=00001000/00006000
rtsx_pci 0000:58:00.0: [12] Timeout
pcieport 0000:00:1c.6: AER: Correctable error message received from 0000:58:00.0
Testing with OS-native AER control showed that disabling only L0s on the
RTS525A link stops new AER interrupt and counter growth while leaving L1
enabled. Disabling L1, L1 substates, or Clock PM alone did not stop the
storm.
Prevent the broken L0s configuration by removing L0s from the RTS525A
advertised ASPM capability. This avoids enabling the non-working ASPM
state instead of masking the resulting AER Replay Timer Timeout reports.
Signed-off-by: Max Lee <max.lee@canonical.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260707021527.639611-1-max.lee@canonical.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Farhan Ali <alifm@linux.ibm.com>
Date: Wed Aug 5 09:55:18 2026 -0700
PCI/MSI: Enable memory decoding before restoring MSI-X messages
commit 231c7a57d19304beb0931e6cbe3a4929daf49747 upstream.
The current MSI-X restoration path assumes the Command register Memory bit
is enabled when writing MSI-X messages. But it's possible the last saved
and restored state of a device may not have the Memory bit enabled, even if
a device driver later enables Memory bit and MSI-X. Attempting to access
Memory space without Memory bit enabled can lead to Unsupported Request
(UR) from the device. Fix this by enabling Memory bit and restore it
afterwards.
Fixes: 41017f0cac92 ("[PATCH] PCI: MSI(X) save/restore for suspend/resume")
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
[bhelgaas: comment]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260805165518.794-6-alifm@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Wed Jul 29 07:59:09 2026 +0000
PCI/proc: Avoid spurious runtime PM wakeup on config space accesses
commit 4ff664a81d729b37f2eb65de80a670abfb61c9a0 upstream.
Currently, proc_bus_pci_read() and proc_bus_pci_write() do not return early
for zero-length configuration space accesses at valid offsets.
Such an access invokes pci_config_pm_runtime_get() and
pci_config_pm_runtime_put() around transfer blocks that do nothing.
This is a problem because pci_config_pm_runtime_get() synchronously resumes
the upstream bridge through pm_runtime_get_sync(), and resumes the device
itself through pm_runtime_resume() when it is in D3cold, only for the
handler to return zero immediately afterwards. Such a spurious wakeup
wastes power and adds needless resume latency.
The sysfs core already returns early for in-range zero-length binary
attribute accesses before pci_read_config() or pci_write_config() is
invoked. In contrast, the VFS forwards zero-length requests to the procfs
callbacks, where they continue into runtime PM handling.
Return early from proc_bus_pci_read() and proc_bus_pci_write() when nbytes
is zero, before any runtime PM involvement.
The value returned to userspace at these offsets remains zero,
so the change is not visible to userspace.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
[bhelgaas: order tags]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260729075909.1219906-1-kwilczynski@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Mon Jul 20 20:41:45 2026 +0000
PCI/proc: Use file_ns_capable() when checking config space read access
commit f82f53e75eff382fc8f56b73279b54f7cf5a5c65 upstream.
proc_bus_pci_read() decides how much of the config space is readable based
on capable(CAP_SYS_ADMIN), which checks the credentials of the task calling
read(), not the credentials of the process that opened the file.
The sysfs equivalent, pci_read_config(), has checked the credentials of the
opening process since commit de139a339395 ("pci: check caps from sysfs file
open to read device dependent config space"), so a privileged process can
open the config space file and pass the file descriptor to an unprivileged
process (for example, a process running a KVM guest with an assigned
device), which can then read the entire config space. The check was
subsequently routed through the LSM framework in commit 47970b1b2aa6 ("pci:
use security_capable() when checking capablities during config space read")
and converted to the dedicated helper in commit ab0fa82b2df9 ("pci-sysfs:
use proper file capability helper function").
Thus, the two interfaces check the same capability against different
credentials. Checking the credentials of the task calling read() makes the
outcome depend on who reads rather than who opened, so the restriction is
bypassed whenever a more privileged process reads through the descriptor.
Checking the credentials recorded in file->f_cred settles the decision at
open() time and ties it to the file, where it cannot change with the
caller.
Use file_ns_capable() to check CAP_SYS_ADMIN against the credentials in
effect when the file was opened, bringing the procfs interface in line with
the sysfs behaviour.
As a result, a file descriptor opened by a privileged process and passed to
an unprivileged one now allows the entire config space to be read through
procfs, matching sysfs.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260720204145.1500105-1-kwilczynski@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Wed Jul 29 07:54:13 2026 +0000
PCI/proc: Warn on writes to kernel-exclusive config space regions
commit 3359e044d597dd5344f17613e4be6b6e12067f60 upstream.
Currently, a driver can claim a region of a device's config space as
exclusive using pci_request_config_region_exclusive(), after which a write
to that region originating from user space is expected to emit a warning
and taint the kernel. The check is advisory only, as the write itself is
still allowed to proceed.
Since commit 278294798ac9 ("PCI: Allow drivers to request exclusive config
regions"), the sysfs config space attribute performs this check in
pci_write_config(), but the procfs interface was never updated. A write
performed through /proc/bus/pci/BB/DD.F therefore bypasses the detection
entirely, even though both interfaces offer the same level of access.
Add the same resource_is_exclusive() check to proc_bus_pci_write().
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260729075413.1215821-1-kwilczynski@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Mon Jul 20 20:43:56 2026 +0000
PCI/sysfs: Avoid spurious runtime PM wakeup on config space accesses
commit b14b2bab88d7099ab4447560cbe4b40945e5c069 upstream.
Currently, the boundary checks in pci_read_config() and pci_write_config()
reject only offsets beyond the effective configuration space size.
An access at an offset exactly equal to that size passes the check, has its
length clamped to zero, and then invokes pci_config_pm_runtime_get() and
pci_config_pm_runtime_put() around transfer blocks that do nothing.
This is a problem because pci_config_pm_runtime_get() synchronously resumes
the upstream bridge through pm_runtime_get_sync() and resumes the device
itself through pm_runtime_resume() when it is in D3cold, only for the
handler to return zero immediately afterwards. Such a spurious wakeup
wastes power and adds needless resume latency.
The sysfs core already clamps accesses against the attribute size set
through the bin_size() callback, which reports either 256 or 4096 bytes.
As such, the affected accesses are reads at offset 64 (or 128 for CardBus
devices) through files opened without CAP_SYS_ADMIN, and reads and writes
at the exact configuration space size on devices where a quirk sets a
non-standard size.
Reject accesses at the boundary offset as well, so they return early before
any runtime PM involvement, matching the procfs implementations in
proc_bus_pci_read() and proc_bus_pci_write().
The value returned to userspace at these offsets remains zero, so the
change is not visible to userspace.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
[bhelgaas: tweak commit log, order tags]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260720204356.1501749-1-kwilczynski@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Tue Jun 16 16:31:30 2026 +0000
PCI/sysfs: Fix out-of-bounds read in pci_write_legacy_io()
commit dc76258d0132df1d831a5a29758bd448ca9c566e upstream.
pci_write_legacy_io() loads 4 bytes from the kernfs write buffer
regardless of how many bytes userspace wrote:
if (count != 1 && count != 2 && count != 4)
return -EINVAL;
return pci_legacy_write(bus, off, *(u32 *)buf, count);
kernfs_fop_write_iter() allocates the buffer with kmalloc(len + 1),
so a 1-byte write to the legacy_io sysfs file allocates 2 bytes and
the unconditional u32 load reads up to 2 bytes past the end of the
allocation, which KASAN reports as a slab-out-of-bounds read.
Similarly, a 2-byte write overreads by 1 byte.
Thus, read only the number of bytes requested using get_unaligned_le16()
and get_unaligned_le32() for the 2 and 4 byte cases, interpreting the
buffer as little-endian to match the byte ordering of PCI I/O port
space.
The PowerPC implementation previously compensated for the generic
code's native-endian 32-bit load by shifting the value into place
for the 1 and 2 byte cases. The shifts were only correct on
big-endian kernels.
On little-endian PowerPC (POWER8 and later), they extracted the wrong
bytes, so a 1-byte write wrote an out-of-bounds byte instead of the
requested value. On big-endian, the native load also caused out_le16()
and out_le32() to reverse the user's bytes on the wire for 2 and 4 byte
writes. The little-endian helpers resolve both issues, so the shifts
are removed.
No changes are needed for the Alpha platform.
The legacy_io file is root-only and exists only on Alpha and PowerPC,
the two architectures that define HAVE_PCI_LEGACY.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616163131.2763281-1-kwilczynski@kernel.org
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Krzysztof Wilczyński <kwilczynski@kernel.org>
Date: Tue Jun 16 16:31:31 2026 +0000
PCI/sysfs: Fix read byte order in pci_read_legacy_io()
commit 5b95212de6dcd7e0275cea7f894fe7226c7d9f29 upstream.
pci_read_legacy_io() passes the sysfs buffer directly to pci_legacy_read():
return pci_legacy_read(bus, off, (u32 *)buf, count);
The PowerPC implementation stores the result as a native-endian integer:
*((u16 *)val) = in_le16(addr);
On big-endian PowerPC this stores the bytes in the wrong order, so
a 2-byte read of a device register returns different bytes than two
1-byte reads at the same addresses. The same applies to 4-byte
reads. On little-endian the native byte order already matches PCI
I/O port byte order, so the conversion is a no-op.
Thus, let pci_legacy_read() store into a local u32 variable, then
copy the I/O port value to the sysfs buffer using put_unaligned_le16()
and put_unaligned_le32() for the 2 and 4 byte cases, converting from
the native integer to little-endian byte order matching PCI I/O port
space.
No changes are needed for the Alpha platform.
The legacy_io file is root-only and exists only on Alpha and PowerPC,
the two architectures that define HAVE_PCI_LEGACY.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616163131.2763281-2-kwilczynski@kernel.org
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Tim Harvey <tharvey@gateworks.com>
Date: Mon Jul 20 14:57:18 2026 -0700
PCI: Add ACS quirk for Pericom PI7C9X2G608 switches [12d8:2608]
commit 062fb7f816439da6bf3860386889343482a66bd4 upstream.
The Pericom PI7C9X2G608 6-port Gen2 PCIe switch is also affected by the
PI7C9X2G errata per the errata document:
E2: ACS P2P Request Redirect Is Not Functional
Apply the same quirk to this PCI ID as well to apply the workaround
required if using ACS.
Fixes: acd61ffb2f16 ("PCI: Add ACS quirk for Pericom PI7C9X2G switches")
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260720215718.2139510-1-tharvey@gateworks.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mohamad Raizudeen <raizudeen.kerneldev@gmail.com>
Date: Thu Jul 23 22:42:03 2026 +0530
PCI: Fix 32-bit config write in Intel PCH Root Port MPC ACS quirk
commit 23d7eed5974989de56273c964d7e510e4aad91e8 upstream.
pci_quirk_enable_intel_rp_mpc_acs() reads a 32-bit DWORD from the MPC
register, sets bit 26 (INTEL_MPC_REG_IRBNCE), but it writes it back using
pci_write_config_word().
Because bit 26 resides in the upper 16 bits of the 32-bit register, a
16-bit write drops the newly set bit. The quirk logs that it is enabling
IRBNCE, but the hardware never actually receives the command.
Use pci_write_config_dword() to ensure the full 32-bit value is written
back to the hardware.
Fixes: d99321b63b1f ("PCI: Enable quirks for PCIe ACS on Intel PCH root ports")
Signed-off-by: Mohamad Raizudeen <raizudeen.kerneldev@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260723171203.4892-1-raizudeen.kerneldev@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Naman Jain <namjain@linux.microsoft.com>
Date: Mon Aug 10 09:07:13 2026 +0000
PCI: hv: Set irq_retrigger callback for the Hyper-V PCI MSI irqchip
commit 86bdd16e8f390d51bae9e77a4bc4164ca2f580fe upstream.
The Hyper-V vPCI MSI irqchip never installs an irq_retrigger() callback.
On CPU hot-unplug fixup_irqs() migrates the interrupts which are affine to
the outgoing CPU to a new target. If an interrupt still has its pending bit
set in the outgoing CPU's IRR at that point, fixup_irqs() resends it on the
new target through the irqchip's irq_retrigger() callback. As the Hyper-V
PCI/MSI chip does not provide that callback, the pending interrupt is
silently dropped, which can result in lost interrupts, stalls and "No irq
handler for vector" messages during CPU hotplug.
Install irq_chip_retrigger_hierarchy() as the irq_retrigger() callback for
the Hyper-V PCI/MSI irqchip, so that a pending interrupt is resent on its
new target CPU via the parent x86 vector domain.
Fixes: 4daace0d8ce85 ("PCI: hv: Add paravirtual PCI front-end for Microsoft Hyper-V VMs")
Cc: stable@vger.kernel.org
Suggested-by: Long Li <longli@microsoft.com>
Suggested-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Aditya Garg <gargaditya@linux.microsoft.com>
Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ronald Claveau <linux-kernel-dev@aliel.fr>
Date: Tue Jun 16 09:07:25 2026 +0200
PCI: meson: Fix GPIO state while requesting PERST#
commit 40fb390cbcc11797c44c16dabdf763ec87643671 upstream.
Meson devicetree defines the PERST# GPIO as 'reset' GPIO. Commit
4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio descriptor")
inverted the PERST# assertion logic to use proper GPIO descriptor semantics
and moved the polarity configuration to the device tree as GPIO_ACTIVE_LOW.
However, the initial PERST# GPIO state "GPIOD_OUT_LOW" was not updated
accordingly.
This results in the enumeration failure of the endpoint devices as
PERST# would get deasserted while requesting the GPIO even before
power and REFCLK becomes stable.
Without this fix:
ahci 0000:01:00.0: enabling device (0000 -> 0002)
ahci 0000:01:00.0: SSS flag set, parallel bus scan disabled
ahci 0000:01:00.0: Controller reset failed (0xffffffff)
ahci 0000:01:00.0: probe with driver ahci failed with error -5
With this fix:
ahci 0000:01:00.0: enabling device (0000 -> 0002)
ahci 0000:01:00.0: AHCI vers 0001.0300, 32 command slots, 6 Gbps, SATA mode
ahci 0000:01:00.0: 1/1 ports implemented (port mask 0x1)
ahci 0000:01:00.0: flags: 64bit ncq led clo only pio ccc
Change the GPIO request flag from GPIOD_OUT_LOW to GPIOD_OUT_HIGH to get
the right behaviour.
Fixes: 4d3186a525b3 ("PCI: amlogic: Fix reset assertion via gpio descriptor")
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
[mani: CCed stable and commit log]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616-fix-meson-pcie-reset-gpio-v1-1-fca404b4c8be@aliel.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ali Tariq <alitariq45892@gmail.com>
Date: Thu Jul 23 19:28:24 2026 +0500
PCI: plda: Fix IRQ domain leaks in the error paths of plda_init_interrupts()
commit 19a30bbb6477bfd7e3109b7a2943e6597ee9de37 upstream.
plda_init_interrupts() initializes IRQ domains and creates IRQ mapping but
does not unwind them when later step fails.
If platform_get_irq() or either irq_create_mapping() fails
in plda_init_interrupts(), the domains are never deinitialized. If
irq_create_mapping() fails, port->intx_irq stays initialized.
Hence, remove the IRQ domains in the error path by calling
plda_pcie_irq_domain_deinit().
Since plda_pcie_irq_domain_deinit() now disposes of the intx_irq and
msi_irq mappings itself before removing their domains, the msi_irq
mapping failure path can go directly to err_irq_domain_deinit instead of
disposing of port->intx_irq separately first.
This issue was found by automated review of sashiko-bot
Fixes: 4602c370bdf6 ("PCI: microchip: Move IRQ functions to pcie-plda-host.c")
Fixes: 76c911396807 ("PCI: plda: Add host init/deinit and map bus functions")
Closes: https://lore.kernel.org/linux-pci/20260718120701.DF4111F000E9@smtp.kernel.org/
Signed-off-by: Ali Tariq <alitariq45892@gmail.com>
[mani: commit log]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260723142824.726655-1-alitariq45892@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ali Tariq <alitariq45892@gmail.com>
Date: Thu Jul 23 19:04:33 2026 +0500
PCI: plda: Fix use-after-free of event IRQs during teardown
commit 26b73bae01d6eb81a4a38f36101812f20b2639de upstream.
plda_pcie_irq_domain_deinit() removes pcie->event_domain via
irq_domain_remove(), but the per-event IRQs mapped from that domain
are requested with devm_request_irq() in plda_init_interrupts(). The
actual free_irq() for a devm-managed IRQ is deferred by devres until
after the calling probe()/remove() function returns.
This means irq_domain_remove() can free the domain's internal data
before the deferred free_irq() for IRQs still mapped into it has run.
When devres later processes that deferred cleanup, it can end up
dereferencing the already-freed domain.
Free each event IRQ explicitly with devm_free_irq() before removing
the domain. This triggers the free immediately and removes the IRQ
from the devres tracking list, so devres will not attempt to free it
a second time later.
Also dispose of the event, INTx, and MSI IRQ mappings with
irq_dispose_mapping() before their owning domains are removed.
Finally, guard the calls to irq_set_chained_handler_and_data() for
pcie->irq, pcie->msi_irq, and pcie->intx_irq so they only run when
those fields hold a valid (>0) IRQ number.
This is a pre-existing issue, flagged by automated review during work
on an earlier, unrelated patch to this driver.
Build-tested and boot-tested on StarFive VisionFive v1.2A board
Fixes: 76c911396807 ("PCI: plda: Add host init/deinit and map bus functions")
Closes: https://lore.kernel.org/linux-pci/20260714115343.4D49E1F000E9@smtp.kernel.org/
Signed-off-by: Ali Tariq <alitariq45892@gmail.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260723140434.675512-2-alitariq45892@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zide Chen <zide.chen@intel.com>
Date: Fri Mar 13 10:40:49 2026 -0700
perf/x86/intel/uncore: Fix die ID init and look up bugs
[ Upstream commit a16d1ec4dd0cdcf689f324adde6067083bce9099 ]
In snbep_pci2phy_map_init(), in the nr_node_ids > 8 path,
uncore_device_to_die() may return -1 when all CPUs associated
with the UBOX device are offline.
Remove the WARN_ON_ONCE(die_id == -1) check for two reasons:
- The current code breaks out of the loop. This is incorrect because
pci_get_device() does not guarantee iteration in domain or bus order,
so additional UBOX devices may be skipped during the scan.
- Returning -EINVAL is incorrect, since marking offline buses with
die_id == -1 is expected and should not be treated as an error.
Separately, when NUMA is disabled on a NUMA-capable platform,
pcibus_to_node() returns NUMA_NO_NODE, causing uncore_device_to_die()
to return -1 for all PCI devices. As a result,
spr_update_device_location(), used on Intel SPR and EMR, ignores the
corresponding PMON units and does not add them to the RB tree.
Fix this by using uncore_pcibus_to_dieid(), which retrieves topology
from the UBOX GIDNIDMAP register and works regardless of whether NUMA
is enabled in Linux. This requires snbep_pci2phy_map_init() to be
added in spr_uncore_pci_init().
Keep uncore_device_to_die() only for the nr_node_ids > 8 case, where
NUMA is expected to be enabled.
Fixes: 9a7832ce3d92 ("perf/x86/intel/uncore: With > 8 nodes, get pci bus die id from NUMA info")
Fixes: 65248a9a9ee1 ("perf/x86/uncore: Add a quirk for UPI on SPR")
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Tested-by: Steve Wahl <steve.wahl@hpe.com>
Link: https://patch.msgid.link/20260313174050.171704-4-zide.chen@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Felix Gu <ustc.gu@gmail.com>
Date: Fri Jul 31 16:11:19 2026 +0800
phy: fsl-imx8mq-usb: fix typec switch leak on probe error path
commit 87a1805b1c346b092c34f96f3806f207792910e1 upstream.
If probe fails after imx95_usb_phy_get_tca() succeeds, the typec
switch leaks because the only cleanup path was in .remove(), which
never runs on probe failure.
Use devm_add_action_or_reset() so the switch is cleaned up on both
probe failure and driver removal. The imx95_usb_phy_put_tca() is no
longer needed, it will be removed in .remove() too.
Fixes: b58f0f86fd61 ("phy: fsl-imx8mq-usb: add tca function driver for imx95")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Xu Yang <xu.yang_2@nxp.com>
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://patch.msgid.link/20260731-imx8mp-usb-phy-improvement-v8-1-2ec8d6b3854d@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jason Yang <jason98166@gmail.com>
Date: Tue Aug 11 16:10:22 2026 +0800
phy: rockchip-samsung-dcphy: fix out-of-range max_register
commit 4486e75ba647bd8b98fc1f053101b40caceeed4b upstream.
The PHY register block is 64KB, so with a register stride of 4 the
last accessible register sits at offset 0xfffc. max_register names
0x10000, one register past the end of the mapping: dumping the
registers through the regmap debugfs interface reads beyond the
ioremapped region and oopses on the unmapped page. The oops fires
with the regmap lock held, so later PHY operations deadlock.
Fixes: b2a1a2ae7818 ("phy: rockchip: Add Samsung MIPI D-/C-PHY driver")
Cc: stable@vger.kernel.org
Signed-off-by: Jason Yang <jason98166@gmail.com>
Assisted-by: Claude:claude-opus-5
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patch.msgid.link/20260811-dcphy-maxreg-v1-v1-1-aa63f6a63a64@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Thu Jun 18 00:46:28 2026 -0500
platform/chrome: sensorhub: Bound the EC-reported sensor number
commit 833740a2333c2e4db4e02e3d0ffba04e8718a5f3 upstream.
Each EC FIFO event carries an 8-bit sensor number (in->sensor_num).
cros_ec_sensorhub_ring_handler() validates the FIFO event count, the
per-read count and the ring bound, but not the sensor number, which
cros_ec_sensor_ring_process_event() then uses unchecked to index
sensorhub->batch_state[] - allocated with only sensorhub->sensor_num
entries. A sensor number of sensor_num or larger is an out-of-bounds
read and write of batch_state[].
Validate the sensor number in the ring handler, where each event is read
from the EC, and drop a malformed event before it is used.
Fixes: 145d59baff59 ("platform/chrome: cros_ec_sensorhub: Add FIFO support")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://lore.kernel.org/r/20260618-b4-disp-adb3f790-v3-1-3a164ed63cbd@proton.me
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Tzung-Bi Shih <tzungbi@kernel.org>
Date: Wed Jul 15 02:44:53 2026 +0000
platform/chrome: sensorhub: Fix dropped timestamp events and log spam
commit 9a3f43b30373c61477d0d3ab52946c05f9492bf9 upstream.
Commit 833740a2333c ("platform/chrome: sensorhub: Bound the EC-reported
sensor number") evaluated the `sensor_num` against the bounds limit even
for timestamp events. A timestamp event typically has a `sensor_num` of
0xff [1], causing the driver to flag it as invalid and skip to the next
event.
As a result, we'd see a flooding of "Invalid sensor number 255 from EC"
warning logs and these timestamp events were being dropped.
Move the bounds-check into cros_ec_sensor_ring_process_event() and
evaluate it only after standalone timestamp events have already been
processed and returned early.
[1] https://crrev.com/219ca6ef82ba266da788b673ee4ad50bd3ea1285/common/motion_sense_fifo.c#427
Fixes: 833740a2333c ("platform/chrome: sensorhub: Bound the EC-reported sensor number")
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Link: https://lore.kernel.org/r/20260715024454.4127571-1-tzungbi@kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mario Limonciello <mario.limonciello@amd.com>
Date: Tue Jul 21 13:17:55 2026 -0500
platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails
commit 76f650a76d6a36a4bee79d94db90a0e935a95477 upstream.
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.
Reported-by: Francis De Brabandere <francisdb@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221759
Tested-by: Francis De Brabandere <francisdb@gmail.com>
Fixes: 83ad6974dd3b ("platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init()")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-6-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mario Limonciello <mario.limonciello@amd.com>
Date: Tue Jul 21 13:17:53 2026 -0500
platform/x86/amd/pmc: Propagate SMU errors and validate S2D address
commit 0225c1d637687b03726f00ac65b6def843d2c464 upstream.
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().
Reported-by: Francis De Brabandere <francisdb@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221759
Tested-by: Francis De Brabandere <francisdb@gmail.com>
Fixes: 3d7d407dfb05 ("platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-4-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Mario Limonciello <mario.limonciello@amd.com>
Date: Tue Jul 21 13:17:51 2026 -0500
platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths
commit 9cef693bce96bb4c6952f48d855284cf7fa4f367 upstream.
dev->msg_port is switched to MSG_PORT_S2D before issuing the S2D SMU
commands but is only restored to MSG_PORT_PMC on the success path. The
early "return -EIO" and "return -ENOMEM" leave the port stuck on
MSG_PORT_S2D, so all subsequent SMU communication - including the s2idle
prepare/restore handlers - is directed at the wrong mailbox.
Consolidate the exit path through a single label so the message port is
always restored.
Fixes: 3d7d407dfb05 ("platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-2-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Sun Jun 14 13:53:53 2026 +0900
platform/x86: dell-wmi-sysman: Don't hex dump attribute security buffer
commit 83c80495e45eddf64c6525fb582d8db68f256b71 upstream.
set_attribute() populates the security area of the BIOS attribute request
buffer with the current admin password via populate_security_buffer(), then
dumps the whole request buffer with print_hex_dump_bytes(). This can expose
the plaintext admin password in the kernel log.
The same issue was fixed for the password attribute path by
commit d1a196e0a6dc ("platform/x86: dell-wmi-sysman: Don't hex dump
plaintext password data"). Remove the remaining dump from the BIOS
attribute path.
Fixes: e8a60aa7404b ("platform/x86: Introduce support for Systems Management Driver over WMI for Dell Systems")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260614045353.143500-1-sammiee5311@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Thu Jul 9 21:58:58 2026 +0500
platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS
commit 40e10e6cc8f70c041431a1e30186807e28ec46e0 upstream.
hp_init_bios_package_attribute() hard-fails when a WMI ACPI package
contains fewer elements than the type-specific expected count (e.g. 11
elements instead of 13 for INTEGER or ENUMERATION attributes). This
causes the entire hp_bioscfg driver to skip attribute enumeration on
older HP hardware whose BIOS returns shortened packages when optional
fields like prerequisites or possible values are absent.
Observed on HP EliteBook 840 G2 (BIOS M71 Ver. 01.31):
hp_bioscfg: ACPI-package does not have enough elements: 11 < 13
The element layout has two tiers:
- Elements 0-9 (SECURITY_LEVEL+1 = 10): common to all attribute types
- Elements 10-N: type-specific (bounds, values, encodings, ...)
The per-type populate functions (hp_populate_*_elements_from_package)
already handle sparse packages correctly via their own elem < count
loop guards and inner-loop bounds checks. The only unsafe case is when
we lack even the common elements needed to register the attribute.
Fix by introducing COMMON_ELEM_CNT to mark the hard minimum (10), and
splitting the check into two tiers:
- Fewer than COMMON_ELEM_CNT elements: hard fail, can't proceed.
- Fewer than expected type-specific elements: warn, but let the
populate function parse what is available.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Link: https://patch.msgid.link/20260709165900.30615-4-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:29 2026 +0500
platform/x86: hp-bioscfg: advance elem past consumed array elements
commit 05c808362e808e196f75696b8a64f7aa8b2245ce upstream.
The outer parsing loop in each attribute-type parser advances "elem"
(the index into the ACPI package element array) by exactly one per
iteration, but cases that consume multi-element arrays
(PREREQUISITES, ENUM_POSSIBLE_VALUES, PSWD_ENCODINGS) read "size"
consecutive elements without adjusting "elem" for the extra entries
consumed beyond the first. The next outer iteration then re-reads a
leftover element from the array just consumed instead of the next
real property, and the type check fails on that stale element,
aborting the parse with -EIO.
This produces exactly the failure visible in dmesg on the test
hardware, on every boot:
Error expected type 2 for elem 13, but got type 1 instead
hp_bioscfg: Returned error 0x3, "Invalid command value/Feature not
supported"
Fix by advancing "elem" by (size - 1) after each array-consuming
loop, so the outer loop's own "elem++" lands on the correct next
element. "eloc" is intentionally left alone: it indexes the logical
property schema, not the physical element array, and each array case
is still exactly one logical property regardless of how many physical
elements it spans.
The defect is identical across all five attribute-type parsers
(enum, integer, string, ordered-list, password), which were
copy-pasted from the same template when the driver was introduced.
Fixes: 6b2770bfd6f9 ("platform/x86: hp-bioscfg: enum-attributes")
Fixes: 6f2c06d5a467 ("platform/x86: hp-bioscfg: int-attributes")
Fixes: e6c7b3e15559 ("platform/x86: hp-bioscfg: string-attributes")
Fixes: 4b2672ec71a3 ("platform/x86: hp-bioscfg: order-list-attributes")
Fixes: 8646a3b5ee3a ("platform/x86: hp-bioscfg: passwdobj-attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-10-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Thu Jul 9 21:58:57 2026 +0500
platform/x86: hp-bioscfg: bound ordered-list parsing by the package count
commit 1d143d78299d0eb4536698bf98c1815ec69f22a9 upstream.
hp_populate_ordered_list_elements_from_package() differs from the other
per-type parsers: its main loop is bounded only by the fixed per-type
count and never checks elem against the number of elements actually
present in the package,
for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT; elem++, eloc++)
whereas the string, integer, enumeration and password parsers bound
their main loop with "elem < count" as well.
This is safe today because hp_init_bios_package_attribute() rejects any
package with fewer than ORD_ELEM_CNT elements before the parser runs.
An upcoming change, however, relaxes that check to accept shorter
packages.
Bound the loop by the validated element count as well, so it stops at
whichever comes first, the per-type count or the real package size,
for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT && elem < order_obj_count;
elem++, eloc++)
order_obj_count is the validated element count, now correctly forwarded
from the caller. No functional change for packages that enumerate
correctly today.
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260709165900.30615-3-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:22 2026 +0500
platform/x86: hp-bioscfg: fix heap OOB read in sk_store() and kek_store()
commit a7508c7959ff8d037327d377ed21a9c0eabe4674 upstream.
sk_store() and kek_store() strip a trailing newline from the sysfs
write before allocating the key buffer:
length = count;
if (buf[length - 1] == '\n')
length--;
bioscfg_drv.spm_data.signing_key = kmemdup(buf, length, GFP_KERNEL);
but then pass the original "count" (not "length") as the copy size to
hp_wmi_perform_query(), which memcpy()s that many bytes out of the
"length"-sized allocation, reading one byte past it whenever the write
ends in a newline, the normal case for a shell "echo" into sysfs.
KASAN confirms this directly:
BUG: KASAN: slab-out-of-bounds in hp_wmi_perform_query+0x1e9/0x460 [hp_bioscfg]
Read of size 28 at addr ffff88813c8e2b80 by task python3/16022
...
sk_store+0xa7/0x240 [hp_bioscfg]
kernfs_fop_write_iter+0x3e1/0x5d0
...
The buggy address is located 0 bytes inside of
allocated 27-byte region [ffff88813c8e2b80, ffff88813c8e2b9b)
Reproduced identically for kek_store, and at multiple write sizes
(28, 57, 201 bytes), each time reading exactly one byte past a
kmemdup() allocation one byte smaller than the write.
Fix by passing "length" instead of "count" to hp_wmi_perform_query()
in both functions.
Fixes: b2715aa2e135 ("platform/x86: hp-bioscfg: spmobj-attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-3-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:23 2026 +0500
platform/x86: hp-bioscfg: fix heap OOB read on empty password write
commit 2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab upstream.
validate_password_input() computes length = strlen(buf) and then
checks buf[length - 1] to strip a trailing newline, without checking
that length is nonzero first. Writing an empty string (a bare '\n')
to current_password or new_password gives length == 0, and
buf[length - 1] reads buf[-1], one byte before the heap allocation
holding the copied input.
KASAN confirms this directly:
BUG: KASAN: slab-out-of-bounds in store_password_instance.constprop.0+0x223/0x2a0 [hp_bioscfg]
Read of size 1 at addr ffff88811bd8da9f by task sh/13740
...
store_password_instance.constprop.0+0x223/0x2a0 [hp_bioscfg]
current_password_store+0x14/0x20 [hp_bioscfg]
...
The buggy address is located 23 bytes to the right of
allocated 8-byte region [ffff88811bd8da80, ffff88811bd8da88)
Reproduced identically via new_password_store. Execution continues
past the bad read (the garbage byte only affects whether "length" is
decremented by one), so the write completes and returns success; this
is a pure information read past the buffer, not a crash, but it is
still an out-of-bounds access KASAN correctly flags.
Fix by only checking buf[length - 1] when length is nonzero.
Fixes: 8646a3b5ee3a ("platform/x86: hp-bioscfg: passwdobj-attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-4-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:27 2026 +0500
platform/x86: hp-bioscfg: fix new_password_store() overwriting current_password
commit 2ea12a467a9cb12170417b30784fe26a243a75fe upstream.
current_password_store() and new_password_store() both call
store_password_instance() with is_current = true:
static ssize_t new_password_store(...)
{
return store_password_instance(kobj, buf, count, true);
}
so a write to new_password is routed to current_password instead, and
the new_password field is never written by either sysfs entry point.
Fix by passing false from new_password_store(), matching what the
is_current parameter is meant to select.
Fixes: 8646a3b5ee3a ("platform/x86: hp-bioscfg: passwdobj-attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-8-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:21 2026 +0500
platform/x86: hp-bioscfg: fix off-by-one write in hp_get_string_from_buffer()
commit dc03f05e419f3460342fb7564884f244622634b6 upstream.
hp_get_string_from_buffer() clamps the converted string length against
the destination buffer size with "size > dst_size", so when the
converted length is exactly equal to dst_size, conv_dst_size is left
at dst_size and the unconditional NUL terminator write
dst[conv_dst_size] = 0;
lands one byte past the destination buffer. This is the same shape of
bug as the previously fixed off-by-one in hp_convert_hexstr_to_str():
the buffer is sized correctly for the content, but the terminator
write is never checked against that size.
Fix by changing the comparison to ">=" so conv_dst_size is always left
with room for the terminator.
All fixed-size destinations that reach this function (path[512],
current_value[512], current_password/current_value[64], and the
per-entry buffers in encodings[][512] and prerequisites[][512]) are
affected.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-2-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Wed Aug 12 16:18:28 2026 +0500
platform/x86: hp-bioscfg: fix ORD_LIST_ELEMENTS never being parsed
commit cb6b1b0fb236a9581cae213c2a9182e68cc3ffe5 upstream.
The ACPI_TYPE_STRING case explicitly skips the string conversion for
elem == ORD_LIST_ELEMENTS:
if (elem != PREREQUISITES && elem != ORD_LIST_ELEMENTS) {
ret = hp_convert_hexstr_to_str(..., &str_value, &value_len);
if (ret)
continue;
}
so by the time the ORD_LIST_ELEMENTS case in the eloc switch runs,
str_value is NULL (it was freed and reset to NULL at the end of the
previous iteration). That case then does:
ret = hp_convert_hexstr_to_str(str_value, value_len, &tmpstr, &tmp_len);
hp_convert_hexstr_to_str() rejects a NULL input with -EINVAL, which
sends this function to exit_list, and exit_list unconditionally
returns 0. The net effect is that any ordered-list attribute with
elements present silently ends up with an empty elements list, with no
error surfaced anywhere.
Fix by converting the current element directly, order_obj[elem], the
same way the PREREQUISITES case already handles its own array
elements, instead of reusing the unrelated str_value/value_len left
over from earlier processing.
Fixes: 4b2672ec71a3 ("platform/x86: hp-bioscfg: order-list-attributes")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260812111829.172273-9-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Thu Jul 9 21:58:56 2026 +0500
platform/x86: hp-bioscfg: pass validated element count to package parsers
commit e0ddfd77c0c320b7d12b6c9169303b140b798775 upstream.
The per-type package parsers are handed the wrong element count.
hp_init_bios_package_attribute() validates obj->package.count and then
calls one of the five hp_populate_*_package_data() wrappers (string,
integer, enumeration, ordered list, password). Each wrapper forwards a
count to its hp_populate_*_elements_from_package() parser, but instead
of forwarding the validated obj->package.count it derives the count
from elements[0]. elements[0] is the NAME field and is always an
ACPI_TYPE_STRING, so reading ->package.count from it in fact reads
->string.length through the union acpi_object. The parsers thus bound
themselves against the length of the name string rather than against
the real number of elements in the package.
This is safe today because hp_init_bios_package_attribute() refuses any
package that has fewer than the type's element count, so a parser only
ever runs on a full package and never reads past it regardless of the
bogus bound.
An upcoming change relaxes that check to accept shorter packages. Once
a parser can receive fewer elements than its per-type count, a bound
taken from the name length no longer reflects the array size, and the
"elem < count" loop conditions and "elem + n >= count" sub-loop guards
read past the end of elements[] - an out-of-bounds heap read.
Forward the validated obj->package.count to every *_package_data()
wrapper so the parsers bound themselves against the real package size.
This does not change behaviour for the packages that enumerate
correctly today and is a prerequisite for accepting shorter packages
safely.
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260709165900.30615-2-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Muhammad Bilal <meatuni001@gmail.com>
Date: Thu Jul 9 21:58:59 2026 +0500
platform/x86: hp-bioscfg: warn on element type mismatch instead of failing
commit b0e2af3ec94e0431adb59d9f249ebbd3b7285158 upstream.
hp_populate_enumeration_elements_from_package() returns -EIO and aborts
enumeration of the entire attribute when any single element has an
unexpected ACPI type. This is observed on HP EliteBook 840 G2 when the
BIOS returns malformed ACPI data following a failed WMI query:
ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Index (0x000000032)
is beyond end of object (length 0x32)
ACPI Error: Aborting method \_SB.WMID.WQBE due to previous error
Error expected type 2 for elem 13, but got type 1 instead
hp_bioscfg: Returned error 0x3,
"Invalid command value/Feature not supported"
Aborting immediately discards the attribute entirely.
Warn about the unexpected element type, free the temporary string, skip
the offending element, and continue parsing the remaining package
instead of failing the whole attribute.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Link: https://patch.msgid.link/20260709165900.30615-5-meatuni001@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ma Ke <make_ruc2021@163.com>
Date: Wed Jun 24 09:49:09 2026 +0800
platform/x86: ishtp_eclite: Fix ACPI device reference leak in probe error path
commit 62b57396c26a1ce54963709928ea0d01fa522eea upstream.
ecl_ishtp_cl_probe() acquires a reference to an ACPI device via
acpi_find_eclite_device() but fails to release it in the error path
when acpi_opregion_init() fails. This results in a reference count
leak, preventing proper cleanup of the ACPI device.
Calling path: acpi_find_eclite_device() ->
acpi_dev_get_first_match_dev() -> acpi_dev_get_next_match_dev() ->
bus_find_device() -> get_device().
Found by code review.
Signed-off-by: Ma Ke <make_ruc2021@163.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Cc: stable@vger.kernel.org
Fixes: 7b6bf51de974 ("platform/x86: Add Intel ishtp eclite driver")
Link: https://patch.msgid.link/20260624014910.1226446-1-make_ruc2021@163.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:21:34 2026 -0700
platform/x86: ISST: Add a NULL check for sst_inst[]
commit 3de2776e9d7073765c10c2326c2bda5926811ea6 upstream.
To be consistent with other places, add a NULL check for failed socket
loading by checking isst_common.sst_inst[].
Fixes: d805456c712f ("platform/x86: ISST: Enumerate TPMI SST and create framework")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811222134.3912626-3-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:15:14 2026 -0700
platform/x86: ISST: Just allow 2 bits for SST feature enable
commit 0f377f2b47646abe6ec3616ae6a8670d9ff7eb86 upstream.
Currently only 2 features SST-TF and SST-BF are supported, so only allow
bit 0 and bit 1.
Fixes: ea009e4769fa3 ("platform/x86: ISST: Add SST-PP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-7-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:21:33 2026 -0700
platform/x86: ISST: Return error during profile addition
commit f9a647cb8d90c09633a49a1e766e140e78012444 upstream.
If sst_add_perf_profiles() fails for memory allocation, it continues
to allow SST-CP (core-power) feature. But in practice this is not
very useful as to achieve some frequencies via SST-CP, an SST-PP
(perf-profile) level change is required.
Fixes: 0ab147bb840f ("platform/x86: ISST: Parse SST MMIO and update instance")
Cc: HyeongJun An <sammiee5311@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811222134.3912626-2-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:15:13 2026 -0700
platform/x86: ISST: Use PP level enable mask
commit 9b9026943b19d06ebf520b1f4786621947cf43c8 upstream.
Add check for enabled levels only when reading MMIO. Some levels can be
disabled by BIOS. If the level is not enabled, return an error.
Reset the enable and allowed level masks if there is a failure to add a
perf level.
Fixes: ea009e4769fa3 ("platform/x86: ISST: Add SST-PP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-6-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Fri Aug 7 23:40:03 2026 +0900
platform/x86: ISST: Validate level in perf mask ioctls
commit 80e0d353c86a9a168ad6d213f494796294381538 upstream.
isst_if_get_perf_level_mask() and isst_if_get_base_freq_mask() use the
user-provided level as an index into perf_levels[] via
_read_pp_level_info() and _read_bf_level_info(), but neither helper
validates it first.
The adjacent level-info helpers reject levels above max_level before
reading the same per-level register block. Add the same bounds checks to
the mask helpers, and reject disabled SST-PP levels in
isst_if_get_perf_level_mask() to match isst_if_get_perf_level_info().
This prevents out-of-bounds reads from the per-level offset table on
invalid ioctl input.
Fixes: ea009e4769fa3 ("platform/x86: ISST: Add SST-PP support via TPMI")
Fixes: 06a61df83209 ("platform/x86: ISST: Add SST-BF support via TPMI")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260807144003.3498972-3-sammiee5311@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:15:09 2026 -0700
platform/x86: ISST: Validate logical CPU id and clos id
commit 124e2dbabe460c2a6e7440f4ad8af560131295c9 upstream.
Validate max CLOS ID and logical CPU ID for core power feature.
Reject any clos level or logical CPU number greater than the
supported maximum. These are used to calculate MMIO offset.
Fixes: 12a7d2cb811d ("platform/x86: ISST: Add SST-CP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-2-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:15:11 2026 -0700
platform/x86: ISST: Validate parameter for core power state
commit 1700b4f804555467b7eff58dff7acc11d508b3a1 upstream.
Allow only 0 or 1 for core_power enable and priority_type parameters.
Fixes: 12a7d2cb811d ("platform/x86: ISST: Add SST-CP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-4-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Date: Tue Aug 11 15:15:12 2026 -0700
platform/x86: ISST: Validate parameter for frequency and priority
commit 574b59bb4b6bfcfd1f639d02f1041b314d43a2e6 upstream.
Validate range for frequency and proportional priority while setting
CLOS parameters.
Fixes: 12a7d2cb811d ("platform/x86: ISST: Add SST-CP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-5-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Fri Aug 7 23:40:02 2026 +0900
platform/x86: ISST: Validate socket ID in clos_assoc ioctl
commit a89f07db0cb95c54dac4a8406c79a04e44a73c3c upstream.
isst_if_clos_assoc() validates the user-supplied socket_id with
'socket_id > topology_max_packages()', but isst_common.sst_inst[] is
allocated with topology_max_packages() entries, so the valid index range
is [0, topology_max_packages()). The '>' comparison lets
socket_id == topology_max_packages() pass and index one entry past the
array.
In addition, isst_common.sst_inst[socket_id] is NULL for an in-range
package that has no bound TPMI SST instance, and the pointer is used
without a NULL check. Both the out-of-bounds entry and the NULL pointer
are then dereferenced by map_partition_power_domain_id() and the
following power_domain_info access.
Reject socket_id >= topology_max_packages() and a NULL sst_inst, matching
the checks already performed by get_instance().
Fixes: 12a7d2cb811d ("platform/x86: ISST: Add SST-CP support via TPMI")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260807144003.3498972-2-sammiee5311@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Rong Zhang <i@rong.moe>
Date: Sun May 10 04:25:31 2026 +0000
platform/x86: lenovo-wmi-helpers: Fix memory leak in lwmi_dev_evaluate_int()
[ Upstream commit 0c3887a134f191723b53e2a47e501b534c8723ee ]
lwmi_dev_evaluate_int() leaks output.pointer when retval == NULL (found
by sashiko.dev [1]).
Fix it by moving `ret_obj = output.pointer' outside of the `if (retval)'
block so that it is always freed by the __free cleanup callback.
No functional change intended.
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Fixes: e521d16e76cd ("platform/x86: Add lenovo-wmi-helpers")
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260331181208.421552-1-derekjohn.clark%40gmail.com [1]
Signed-off-by: Rong Zhang <i@rong.moe>
Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
Link: https://patch.msgid.link/20260510042546.436874-2-derekjohn.clark@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Julian Haarmann <julian.haarmann@student.kit.edu>
Date: Sun Jun 14 22:30:26 2026 +0200
platform/x86: lenovo/ymc: Only match lower byte in WMI lid switch query response
commit bbc497b5231829d32c3a53b6e66be1add76c0064 upstream.
On newer Lenovo Yoga devices like the "Yoga 9 2-in-1 14IPH11 - Type 83SE",
the hinge switch WMI query returns extra data in the upper bits
(e.g. 0x50001 laptop mode, 0x50002 tablet mode, ect.).
The driver previously checked for exact matches (0x01 laptop, 0x02 tablet,
ect.) causing newer switches to not work.
Mask the WMI query result to only match the lower byte and ignore upper
bits.
Signed-off-by: Julian Haarmann <julian.haarmann@student.kit.edu>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260614203235.235724-1-julian.haarmann@student.kit.edu
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thorsten Blum <blum@kernel.org>
Date: Mon Aug 10 14:05:57 2026 +0200
platform/x86: think-lmi: Fix certificate thumbprint sysfs output
commit 4f3183f5ae9b8ddfe338d79a96146a05342bbe50 upstream.
cert_thumbprint() already returns the accumulated output length, but
certificate_thumbprint_show() adds that value to count again, making the
next line use the wrong offset. Errors returned by cert_thumbprint() are
also ignored and their negative values added to count.
Assign the total length to count instead and propagate errors correctly.
Fixes: b49f72e7f96d ("platform/x86: think-lmi: Certificate authentication support")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://patch.msgid.link/20260810120556.149416-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thorsten Blum <blum@kernel.org>
Date: Tue Aug 18 17:16:35 2026 +0200
platform/x86: think-lmi: Fix current password length check
commit 54745d563114b74f6fecebce68cd020d06c1772b upstream.
current_password_store() checks the password length before removing the
trailing newline, which can reject valid passwords that are exactly
->maxlen bytes long.
It also passes ->maxlen to strscpy(), which truncates passwords without
a newline.
Use strchrnul() to measure the password length up to the newline, then
copy that many bytes and add a trailing NUL terminator using strscpy().
Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
Cc: stable@vger.kernel.org
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260818151635.37094-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thorsten Blum <blum@kernel.org>
Date: Mon Aug 10 22:41:07 2026 +0200
platform/x86: think-lmi: Free system certificate signatures
commit abca989604f60fe29d7170431f819e28ec7d868a upstream.
Multi-certificate support also allows the system authentication object
to store ->signature and ->save_signature, which leak when the driver is
removed. Free the signatures to avoid leaking memory.
Fixes: 5dcb5ef12590 ("platform/x86: think-lmi: Multi-certificate support")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://patch.msgid.link/20260810204106.165895-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Shibo Zhu <3499129952@qq.com>
Date: Wed Aug 19 00:18:39 2026 +0800
PM: sleep: Unblock runtime PM when device prepare fails
commit cb258d651d747a7f7063d40f145418bee562ceaf upstream.
device_prepare() blocks runtime PM for a device with runtime PM disabled
before invoking its system-sleep ->prepare() callback. For a device that
has never enabled runtime PM, this changes dev->power.last_status from
RPM_INVALID to RPM_BLOCKED.
If the callback returns an error, dpm_prepare() does not move the device
to dpm_prepared_list. Consequently, the recovery path through
dpm_complete() never calls device_complete() for the failing device.
The error path drops the runtime PM usage reference, but does not clear
RPM_BLOCKED. A later legitimate pm_runtime_enable() then reports:
Attempt to enable runtime PM when it is blocked
before clearing the stale state.
Call pm_runtime_unblock() on the prepare error path before dropping the
runtime PM reference, matching the cleanup performed by device_complete().
The issue was reproduced with a platform test device whose ->prepare()
callback returns -EIO while runtime PM has never been enabled. Before
the fix, last_status remained RPM_BLOCKED after the failed suspend and
the first pm_runtime_enable() produced the warning above. With the fix,
last_status is restored to RPM_INVALID and the warning is absent.
Fixes: 3e5eee147b7b ("PM: Block enabling of runtime PM during system suspend")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Shibo Zhu <3499129952@qq.com>
Link: https://patch.msgid.link/tencent_C5AC0A02FC01F700E764F8C2E3ECE4F41009@qq.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Tim Menninger <tmenninger@everpuredata.com>
Date: Wed Aug 19 12:41:21 2026 +0000
pNFS: Fix EBUSY check in pnfs_layout_need_return
commit 20358201777496fd0bb7b4336fcb4d3fc13cad28 upstream.
Commit 41d0a8ead9720 ("NFSv4/pnfs: Add support for the
PNFS_LAYOUT_FILE_BULK_RETURN flag") replaced
pnfs_layout_segments_returnable() in pnfs_layout_need_return() with a
direct call to pnfs_mark_layout_stateid_return().
The old helper checked the return value against -EBUSY, but the
replacement compares against EBUSY. Since
pnfs_mark_layout_stateid_return() returns negative errno values, the
-EBUSY case is never detected.
Fix the comparison in pnfs_layout_need_return() to check against -EBUSY.
Fixes: 41d0a8ead9720 ("NFSv4/pnfs: Add support for the PNFS_LAYOUT_FILE_BULK_RETURN flag")
Cc: stable@vger.kernel.org
Signed-off-by: Tim Menninger <tmenninger@everpuredata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sat Aug 1 05:19:58 2026 +0000
power: supply: bq24257: fix use-after-free on remove
commit 9d34c9d660c3d0931d2cc749c46c47cf31f96e48 upstream.
The STAT-pin interrupt is devm-managed, so it stays armed until the devm
cleanup that runs after remove() returns. remove() cancels
bq->iilimit_setup_work while the threaded handler can still fire; that
handler reschedules the work and dereferences bq, so the work runs
against freed memory once devm frees bq.
Make the delayed work device-managed with devm_delayed_work_autocancel(),
registered before the interrupt request. The devm cleanup then releases
the interrupt first, so the handler can no longer reschedule the work,
and cancels the work before bq is freed. The explicit
cancel_delayed_work_sync() in remove() is no longer needed and is dropped.
Found by static analysis.
Fixes: 2219a935963e ("power_supply: Add TI BQ24257 charger driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260731143554.334179-1-fanwu01@zju.edu.cn
Link: https://patch.msgid.link/20260801051958.354528-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Tue Aug 4 14:55:11 2026 +0000
power: supply: bq256xx: drain usb_work before freeing the charger
commit 2dd6cd823777bea6d9a880a12a92a73ec76aee0b upstream.
The USB-PHY notifier queues usb_work, whose handler calls
power_supply_changed(bq->charger). The reset devm action only unregisters
the notifier and was registered before the power supplies, so devm frees
bq->charger on unwind before the action runs; a usb_work still queued can
then dereference it.
Register the reset action after the power supplies, so it unregisters
the notifiers and drains usb_work before the supplies are released.
Initialize usb_work and obtain the PHY references before registering
the notifiers, so the worker cannot run before the supplies exist.
Found by static analysis.
Fixes: 32e4978bb920 ("power: supply: bq256xx: Introduce the BQ256XX charger driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260804145511.103470-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ma Ke <make_ruc2021@163.com>
Date: Wed Jul 22 12:44:16 2026 +0800
power: supply: bq25890: Fix power_supply reference leak
commit 863c32a83e4235eb0cbf6106f2b124e645302156 upstream.
bq25890_fw_probe() acquires a reference to a secondary charger using
power_supply_get_by_name(), but the reference is not released on later
probe failures or on driver detach.
In particular, failures after bq25890_fw_probe() returns successfully,
such as a failure in bq25890_hw_init(), also leak the reference.
Register a device-managed cleanup action immediately after acquiring
the secondary charger. This releases the reference on all subsequent
probe failures and on driver detach.
Found by code review.
Signed-off-by: Ma Ke <make_ruc2021@163.com>
Cc: stable@vger.kernel.org
Fixes: d54bf877fd87 ("power: supply: bq25890: Add support for having a secondary charger IC")
Link: https://patch.msgid.link/20260722044416.1623621-1-make_ruc2021@163.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Tue Jul 28 03:01:23 2026 +0000
power: supply: charger-manager: register regulators before exposing sysfs
commit c57cb36f76eb7ced45f57af1a890d8f3a6d76342 upstream.
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.
Fixes: 3950c7865cd7 ("charger-manager: Add support sysfs entry for charger")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260728030123.230202-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Tue Jun 16 23:59:45 2026 -0500
power: supply: cros_usbpd-charger: bound the EC-reported port count
commit 48355ce49359740f52e94d3623f6fc557ce341f0 upstream.
cros_usbpd_charger_probe() reads two port counts from the EC and uses
one of them, num_charger_ports, as the loop bound when populating a
fixed-size array:
struct port_data *ports[EC_USB_PD_MAX_PORTS]; /* 8 entries */
...
for (i = 0; i < charger->num_charger_ports; i++)
charger->ports[charger->num_registered_psy++] = port;
Both num_usbpd_ports (from EC_CMD_USB_PD_PORTS) and num_charger_ports
(from EC_CMD_CHARGE_PORT_COUNT) are u8 values reported by the EC. The
only validation is a sanity check that compares the two EC-reported
values against each other:
if (num_charger_ports < num_usbpd_ports ||
num_charger_ports > num_usbpd_ports + 1)
return -EPROTO;
It never checks either count against EC_USB_PD_MAX_PORTS, the size of
the ports[] array. A malfunctioning, malicious or compromised EC that
reports num_usbpd_ports == num_charger_ports == N for any N > 8 (for
example both 255) passes this check, and the loop then writes N pointers
into the 8-entry ports[] array embedded in the devm_kzalloc()'d
charger_data, overflowing it by up to 255 - 8 = 247 entries (~1976
bytes): a slab out-of-bounds write.
Reject a port count larger than the ports[] array can hold.
Fixes: f68b883e8fad ("power: supply: add cros-ec USBPD charger driver.")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260616-b4-disp-5e197080-v2-1-8aa5bffce945@proton.me
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jameson Thies <jthies@google.com>
Date: Wed Jul 22 19:50:59 2026 +0000
power: supply: cros_usbpd: Limit port counts to EC_USB_PD_MAX_PORTS
commit 657cd3a42e937276262c0a8ae6b01a87004309de upstream.
Currently the cros_usbpd-charger driver probe iterates based on raw
charger port count returned by the embedded controller. The only check
is against the number of USB PD ports which the embedded controller
also defines. A malicious embedded controller could return an inaccurate
port count (up to 255) resulting in an out of bounds write and
subsequent memory corruption.
Update helper functions in cros_usbpd-charger to limit port counts to
EC_USB_PD_MAX_PORTS.
Fixes: 3af15cfacd1e ("power: supply: cros: add support for dedicated port")
Cc: stable@vger.kernel.org
Signed-off-by: Jameson Thies <jthies@google.com>
Reviewed-by: Benson Leung <bleung@chromium.org>
Link: https://patch.msgid.link/20260722195059.1420738-1-jthies@google.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Fri Aug 7 03:35:20 2026 +0000
power: supply: lp8727: fix use-after-free in lp8727_release_irq()
commit ceb6ac43b0f591722401922ceb958ce2616935e0 upstream.
lp8727_isr_func(), the threaded IRQ handler, is the only caller that arms
pchg->work via schedule_delayed_work(). lp8727_release_irq() currently
cancels the work before freeing the IRQ, so an IRQ delivered in between
can re-arm the work through the threaded handler. After .remove returns
the devm layer frees pchg while lp8727_delayed_func() may still run and
dereference it.
Free the IRQ first so the threaded handler is quiesced and can no longer
queue work, then cancel the delayed work to drain the final generation.
This issue was found by an in-house static analysis tool.
Fixes: d71fda016102 ("lp8727_charger: Clean up the interrupt handler")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260807033520.8551-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sun Aug 2 03:54:42 2026 +0000
power: supply: lp8788-charger: fix use-after-free on remove
commit 831c29a12d560f8a3225f43050b3fbb5dfd79c66 upstream.
lp8788_charger_remove() flushes charger_work before unregistering the
IRQs. An IRQ thread can queue charger_work after flush_work() has
returned. The work can then run after devres frees pchg and dereference
it in lp8788_charger_event().
Unregister the IRQs first. free_irq() waits for any running threaded
handler, so no handler can queue more work afterwards. Then use
cancel_work_sync() to cancel pending work or wait for running work to
finish.
This issue was found by an in-house static analysis tool.
Fixes: 98a276649358 ("power_supply: Add new lp8788 charger driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260802035442.421697-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jianing Li <m13940358460@163.com>
Date: Fri Jul 31 16:42:59 2026 +0800
power: supply: max17040: drop incorrect I2C functionality check
commit 4e4b9f5ce9dfb8ed4b8d1262a504b8043ac09d87 upstream.
max17040_probe() rejects adapters that do not advertise
I2C_FUNC_SMBUS_BYTE. The driver does not issue SMBus byte transactions,
however. Its regmap has 8-bit registers and 16-bit big-endian values, for
which regmap-i2c supports either raw I2C transfers or SMBus word-data
transactions.
Consequently, an adapter providing raw I2C transfers or SMBus word data
but not SMBus byte transactions is rejected even though regmap can access
the device. Conversely, the current check can pass an adapter that regmap
cannot use.
Drop the stale check and let devm_regmap_init_i2c() validate and select
the supported transfer method.
Fixes: 6455a8a84bdfd ("power: supply: max17040: Use regmap i2c")
Cc: stable@vger.kernel.org
Signed-off-by: Jianing Li <m13940358460@163.com>
Link: https://patch.msgid.link/20260731084259.916-1-m13940358460@163.com
[Fixed Fixes tag, so that it points to the regmap introduction instead of the initial driver addition]
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jianing Li <m13940358460@163.com>
Date: Mon Jul 27 14:48:25 2026 +0800
power: supply: max17040: propagate register read errors
commit 659cc3d8d5ef246263873fce72c8cadeeed073cc upstream.
max17040_get_vcell() and max17040_get_soc() ignore errors returned by
regmap_read(). When an I2C transfer fails, the uninitialized register
value is converted and reported to userspace as a valid voltage or state
of charge. The polling worker can also replace the cached state of charge
with the bogus value and emit a spurious change event.
Propagate read errors through the power supply get_property callback and
keep the last valid cached state of charge when polling fails.
Fixes: c6f4a42de60b ("Add MAX17040 Fuel Gauge driver")
Cc: stable@vger.kernel.org
Signed-off-by: Jianing Li <m13940358460@163.com>
Link: https://patch.msgid.link/20260727064825.948-1-m13940358460@163.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jianing Li <m13940358460@163.com>
Date: Mon Aug 10 08:47:01 2026 +0800
power: supply: max17040: synchronize work cancellation on suspend
commit 86a3a8a926aa5969c329d1df2d3259f189961bbc upstream.
max17040_work() requeues itself after every poll. cancel_delayed_work()
only cancels a pending instance and does not wait for a callback that is
already running.
If system suspend races with the polling callback, the callback can
continue accessing the fuel gauge and requeue itself after the suspend
callback returns.
Use cancel_delayed_work_sync() to ensure polling is quiesced before
suspend completes.
Fixes: c6f4a42de60b ("Add MAX17040 Fuel Gauge driver")
Cc: stable@vger.kernel.org
Signed-off-by: Jianing Li <m13940358460@163.com>
Link: https://patch.msgid.link/20260810004701.1683-1-m13940358460@163.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sat Aug 1 05:19:23 2026 +0000
power: supply: qcom_battmgr: fix use-after-free
commit 4e40befedfc8ed86f44e1f81df92d13c149c9f8d upstream.
qcom_battmgr_pdr_notify() queues enable_work when the PMIC GLINK service
comes up, and the worker recovers battmgr through container_of() to issue
firmware requests. The PMIC GLINK client stays on the client list until
its devres release action runs, so a PDR notification can keep queueing
the work, and a pending or running worker can access battmgr after devres
frees it.
Make enable_work device-managed with devm_work_autocancel(), registered
before the PMIC GLINK client is allocated. The devres cleanup then
releases the client first, so no further notification can queue the work,
and cancels the work before battmgr is freed.
This issue was found by an in-house static analysis tool.
Fixes: 29e8142b5623 ("power: supply: Introduce Qualcomm PMIC GLINK power supply")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260731022006.317192-1-fanwu01@zju.edu.cn
Link: https://patch.msgid.link/20260801051923.354496-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: HyeongJun An <sammiee5311@gmail.com>
Date: Mon Jul 27 16:41:19 2026 +0900
power: supply: qcom_battmgr: terminate the strings from firmware
commit ab1112df8f4ffa88cb024dd370c432ced80f77d8 upstream.
The qcom_battmgr_sc8280xp_strcpy() takes a Pascal-style string when the
firmware sends one. Otherwise it copies all BATTMGR_STRING_LEN bytes and
leaves the destination without a terminator.
Those destinations are model_number, serial_number and oem_info, each
BATTMGR_STRING_LEN and declared next to each other. They go out to user
space as val->strval, which power_supply_format_property() prints with
"%s", so a firmware string that fills the whole field makes that read run
into the following members.
Use strscpy() so the copy always terminates, the way the SM8350 path
already does for the same field.
Fixes: 29e8142b5623 ("power: supply: Introduce Qualcomm PMIC GLINK power supply")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260727074119.2585463-1-sammiee5311@gmail.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Thu Jul 23 22:53:10 2026 +0000
power: supply: rt9455: quiesce delayed work before teardown
commit 3e7a1ebc32fad5a558254a478efd401c17a24381 upstream.
The threaded IRQ handler can queue pwr_rdy_work,
max_charging_time_work and batt_presence_work. pwr_rdy_work and
batt_presence_work can also queue max_charging_time_work, while
batt_presence_work can requeue itself.
rt9455_remove() cancels max_charging_time_work before
batt_presence_work. The latter can therefore queue
max_charging_time_work after it has already been cancelled:
rt9455_remove() workqueue
cancel pwr_rdy_work
cancel max_charging_time_work
batt_presence_work queues
max_charging_time_work
cancel batt_presence_work
return
devres frees rt9455_info
max_charging_time_work dereferences
rt9455_info
The IRQ also remains registered until devres cleanup and can queue more
work after any of the cancellation calls. If rt9455_hw_init() fails
after the IRQ has been requested, probe returns without cancelling work
that may already have been queued. A pending callback can then access
rt9455_info after it has been freed.
Register rt9455_cancel_all_delayed_works() through
devm_add_action_or_reset() right after devm_power_supply_register().
devres invokes the action in reverse registration order, after the
managed IRQ has been freed and before rt9455_info is released, so the
delayed works are drained in both rt9455_remove() and the probe error
path. Cancel pwr_rdy_work and batt_presence_work before
max_charging_time_work because both can queue the latter.
This issue was found by an in-house static analysis tool.
Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260723225310.12663-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Maoyi Xie <maoyixie.tju@gmail.com>
Date: Sat Jul 25 15:25:40 2026 +0800
power: supply: twl4030_charger: cancel workers via devm
commit 6eba34732524067da2aad5ddfdfbc641ded10e9e upstream.
bci is devm-allocated. Two workers (bci->work and bci->current_worker)
dereference it. twl4030_bci_remove() disables charging and masks
interrupts. It cancels neither worker. A worker pending at remove() can
run after devm frees bci.
The USB transceiver comes from devm_usb_get_phy_by_node(). devm
unregisters its notifier only after remove() returns. A cancel_work_sync()
in remove() can then race a notifier reschedule. devm_work_autocancel()
and devm_delayed_work_autocancel() avoid that. They cancel the workers
during devm release, before bci is freed.
The current_worker is registered first, since devm will cancel in
reverse order and bci->work can reschedule current_worker.
Suggested-by: Sebastian Reichel <sre@kernel.org>
Fixes: d6ccc442b1210 ("twl4030_charger: Make the driver atomic notifier safe")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20260702172128.2001753-1-maoyixie.tju@gmail.com
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://patch.msgid.link/20260725072540.3092504-1-maoyixie.tju@gmail.com
[Move comment about order into the commit message]
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sun Aug 2 05:12:49 2026 +0000
power: supply: ucs1002: fix use-after-free on remove
commit 609af0ceeaefdfa42cd01dd060b20f2e41f9a232 upstream.
ucs1002 has no remove callback, so unbind runs entirely through devm.
The alert IRQ handler queues the health_poll delayed work, and the work
reschedules itself while the chip reports a bad-health condition. devm
frees the alert IRQ, which only synchronizes the handler; it does not
cancel the delayed work, which can then run after devm frees the driver
data and dereference it.
Register health_poll with devm_delayed_work_autocancel() before the
alert IRQ is requested. devm then frees the IRQ before cancelling the
work, so the handler can no longer queue it and the work is cancelled
before the driver data is freed.
This issue was found by an in-house static analysis tool.
Fixes: 81196e2e57fc ("power: supply: ucs1002: fix some health status issues")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Link: https://patch.msgid.link/20260802051249.424015-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Date: Mon Jul 6 14:44:13 2026 +0200
powerpc/powermac: fix OF node refcount
commit bd0abfe6b013aeb2a1aebc5fbc7ceeb50355bda3 upstream.
Platform devices created with platform_device_alloc() call
platform_device_release() when the last reference to the device's
kobject is dropped. This function calls of_node_put() unconditionally.
This works fine for devices created with platform_device_register_full()
but users of the split approach (platform_device_alloc() +
platform_device_add()) must bump the reference of the of_node they
assign manually. Add the missing call to of_node_get().
Cc: stable@vger.kernel.org
Fixes: 81e5d8646ff6 ("i2c/powermac: Register i2c devices from device-tree")
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260706-pdev-fwnode-ref-v3-1-1ff028e33779@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Gaurav Batra <gbatra@linux.ibm.com>
Date: Mon Aug 3 17:40:29 2026 -0500
powerpc/pseries/iommu: switch to Default DMA window during kdump
commit 1304643a1c20badbb91b86a5084dd76cb7620c05 upstream.
In PowerPC (pseries) a non-virtualized adapter will have 2 DMA windows -
2GB default and a larger Dynamic DMA Window (DDW). DDW is large enough to
map total RAM to a device.
During normal functioning of OS, since RAM is pre-mapped, 2GB default
window is not used. The only scenario it might get used is when buffers in
pmemory are mapped to the device for DMA.
As of today, during kdump, during early device discovery, pci_dma_find()
finds that the device has 2 DMA windows. It selects to use DDW. This is a
kdump path and DMA window is needed for IO to the device.
Although commit 09a3c1e46142 ("powerpc/pseries/iommu: IOMMU table is not
initialized for kdump over SR-IOV") fixed an issue during kdump with SR-IOV
case, but this also made the kdump prefer DDW over the default DMA window
when both are present (dedicated adapter case). Since the DDW is fully
mapped by the previous kernel, iommu_table_clear() can free only
KDUMP_MIN_TCE_ENTRIES (2048) TCEs for use by kdump kernel.
This is not enough when the dump device is NVMe over Fibre Channel.
Because nvme-fc driver DMA-maps the cmds and resp IUs of every
pre-allocated request and each such mapping consumes roughly:
32 (IO queues, one per cpus = nr_cpus) *
64 (queue_depth, blk-mq kdump limit) *
2 (cmd+resp) = 4096
This is already double of what we have without counting admin queues and
lpfc driver's own allocations / mapping requirement. Hence this results
into iommu_alloc failures like -
lpfc 0153:70:00.0: iommu_alloc failed,
tbl 0000000034ebcf5e vaddr 00000000d814df0b npages 1
lpfc 0153:70:00.0: FCP Op failed - cmdiu dma mapping failed.
lpfc 0153:70:00.0: iommu_alloc failed,
tbl 0000000034ebcf5e vaddr 000000009779e4d2 npages 1
lpfc 0153:70:00.0: FCP Op failed - cmdiu dma mapping failed.
iommu_map_phys+0x1c4/0x1f0 (unreliable)
dma_iommu_map_phys+0x54/0xa0
dma_map_phys+0x3f8/0x590
__nvme_fc_init_request+0x110/0x300 [nvme_fc]
nvme_fc_init_request+0x60/0xb8 [nvme_fc]
blk_mq_alloc_map_and_rqs+0x388/0x510
blk_mq_alloc_tag_set+0x2a4/0x5f0
nvme_alloc_io_tag_set+0xe0/0x1e0 [nvme_core]
nvme_fc_connect_ctrl_work+0x85c/0xdac [nvme_fc]
process_one_work+0x1e4/0x5a0
worker_thread+0x1ec/0x3e0
Increasing the number of free TCE entries in iommu_table_clear() will
increase the probability of hitting EEH since there could still be some
active IOs from the previous life of the kernel.
Hence this patch partially reverts the previous fixes commit and
switches the kdump's default back to 2GB default DMA window instead of
DDW window. This window will mostly be empty. Or, could be slightly used
if buffers in pmemory were mapped for IO.
Fixes: 09a3c1e46142 ("powerpc/pseries/iommu: IOMMU table is not initialized for kdump over SR-IOV")
Cc: stable@vger.kernel.org
Signed-off-by: Gaurav Batra <gbatra@linux.ibm.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260803224029.60538-1-gbatra@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdifatah Suruur <suruurism@gmail.com>
Date: Thu Aug 13 20:47:07 2026 +0300
ptp: vmclock: prevent read-only mappings from becoming writable
commit a5edadbae57e2298a56cf7a4e774a027905a331f upstream.
vmclock_miscdev_mmap() rejects writable mappings of the shared vmclock
ABI page with -EROFS, but leaves VM_MAYWRITE set. Userspace can map the
page read-only and then upgrade it to writable with mprotect(), after
which the guest can corrupt the host-written timekeeping data (sequence
counter, UTC time, TSC offset) that the vmclock ABI defines as read-only.
Clear VM_MAYWRITE on the read-only path so the mapping cannot be
upgraded, as i915 does for its read-only objects and as fixed in drm/vc4
(CVE-2026-68445) and drm/panthor (CVE-2024-53071).
Cc: stable@vger.kernel.org
Fixes: 205032724226 ("ptp: Add support for the AMZNC10C 'vmclock' device")
Signed-off-by: Abdifatah Suruur <suruurism@gmail.com>
Link: https://patch.msgid.link/20260813174707.14809-1-suruurism@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vaibhav Nagare <nagarevaibhav@gmail.com>
Date: Tue Aug 18 13:03:09 2026 +0530
qede: Fix NULL pointer dereference in TPA fragment processing
commit 06aa3d26327f24edd039ff249672fdf6f2ba5695 upstream.
Under memory pressure, the qede driver encounters NULL pointer
dereferences when processing TPA continuation fragments.
Commit 8a8633978b84 ("qede: Add build_skb() support.") accidentally
dropped the assignment of tpa_info->buffer.data in qede_tpa_start().
When memory pressure causes an SKB allocation failure in qede_tpa_start(),
the driver sets tpa_start_fail = true and attempts to recycle the physical
page later in qede_tpa_end() via qede_reuse_page(). However, because
buffer.data was left uninitialized (NULL), qede_reuse_page() pushes a
"ghost" BD (valid DMA mapping but NULL data pointer) back into the
active Rx ring.
The next time the hardware uses this ring slot, it passes a NULL page
to qede_fill_frag_skb(), causing a kernel panic.
Example crash from production system:
BUG: unable to handle kernel NULL pointer dereference at 0x8
RIP: qede_fill_frag_skb+0x96/0x430 [qede]
Call Trace:
qede_rx_int+0xb06/0x1de0
qede_poll+0x2f4/0x6c0
__napi_poll+0x2d/0x130
Fix the root cause by restoring the tpa_info->buffer.data assignment
in qede_tpa_start(), ensuring valid pages are correctly tracked and
recycled. Additionally, update the stale comment for
struct qede_agg_info::buffer to reflect its current usage.
Fixes: 8a8633978b84 ("qede: Add build_skb() support.")
Cc: stable@vger.kernel.org
Signed-off-by: Vaibhav Nagare <vnagare@redhat.com>
Link: https://patch.msgid.link/20260818073309.2266072-1-vnagare@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: James Kim <james010kim@gmail.com>
Date: Fri Jul 24 08:52:20 2026 +0900
rapidio: mport_cdev: fix use-after-free in dma_req_free()
commit 5cbef379a94b161726c5f504598bf4791d45cedc upstream.
dma_req_free() acquires buf_mutex through req->map, drops the mapping
reference with kref_put(), and then dereferences req->map again to unlock
the mutex.
If kref_put() drops the last reference, mport_release_mapping() frees the
mapping, and the subsequent mutex_unlock() dereferences a freed object.
This is a use-after-free.
Fix this by caching map and md before kref_put(), clearing req->map while
holding buf_mutex, and using the cached md for mutex unlocking.
The bug is reachable from userspace via the RapidIO mport character device
interface.
Link: https://lore.kernel.org/20260723235220.588424-1-james010kim@gmail.com
Fixes: e8de370188d0 ("rapidio: add mport char device driver")
Signed-off-by: James Kim <james010kim@gmail.com>
Reviewed-by: Dan Carpenter <error27@gmail.com>
Cc: Alexandre Bounine <alex.bou9@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Thu Aug 6 13:01:27 2026 +0000
RDMA/cxgb4: Cancel reg_work before freeing device on remove
commit a7100601aa1a39f799a566acce10db20eaf4b7f2 upstream.
c4iw_uld_state_change() queues reg_work to register the RDMA device.
c4iw_remove() can free ctx->dev while this work is pending or running,
leaving c4iw_register_device() accessing the freed device.
Cancel reg_work before removing the device. The registration work can
tear down ctx->dev when registration fails, so do not unregister or
deallocate it again in that case.
This issue was found by an in-house static analysis tool.
Fixes: 1c8f1da5d851 ("iw_cxgb4: Fix possible circular dependency locking warning")
Link: https://patch.msgid.link/r/20260806130128.465460-1-fanwu01@zju.edu.cn
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Brett Creeley <brett.creeley@amd.com>
Date: Wed Aug 5 11:02:53 2026 +0530
RDMA/ionic: Cap eq_count to the eth driver's interrupt vector budget
commit 1d0f877d593438a494ca5b05cc8699150409005a upstream.
ionic_fill_lif_cfg() reads eq_count from firmware uncapped, but the
eth driver only reserves ionic->neqs_per_lif MSI-X vectors for RDMA
event queues. Since ionic_rdma probes via the auxiliary bus before
the netdev is brought up, it can exhaust the shared interrupt bitmap,
causing ionic_open() to fail with -ENOSPC when allocating rx/tx
interrupts.
Cap RDMA eq_count to neqs_per_lif, which is populated by
ionic_lif_size() at PCI probe before the RDMA aux device registers.
Fixes: 8d765af51a09 ("RDMA/ionic: Register auxiliary module for ionic ethernet adapter")
Cc: stable@vger.kernel.org
Signed-off-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
Link: https://patch.msgid.link/20260805053254.4023262-1-abhijit.gangurde@amd.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Norbert Szetei <norbert@doyensec.com>
Date: Mon Jul 27 10:08:36 2026 +0200
RDMA/ucma: Lock the handler in ucma_set_ib_path()
commit ecbe7d36dc2de07e5dfbb4a8ff5b315ab43de820 upstream.
ucma_set_ib_path() calls ucma_event_handler() straight from the write()
path, without the handler lock that keeps ctx->file stable while a uevent
is queued. The handler re-reads ctx->file for every dereference:
mutex_lock(&ctx->file->mut); /* file A */
list_add_tail(&uevent->list, &ctx->file->event_list); /* file B */
mutex_unlock(&ctx->file->mut); /* file B */
wake_up_interruptible(&ctx->file->poll_wait); /* file B */
A concurrent ucma_migrate_id() reassigns ctx->file while the SET_OPTION
caller sleeps in mutex_lock(), so the list_add_tail() lands on file B's
event_list while only file A's mutex is held, racing every other user of
that list:
BUG: KASAN: slab-use-after-free in __list_add_valid_or_report+0x1aa/0x1c0
Read of size 8 at addr ffff888153c6a418 by task poc_corr/486
Call Trace:
__list_add_valid_or_report+0x1aa/0x1c0
ucma_event_handler+0x1be/0xc00
ucma_set_ib_path+0x45e/0x710
ucma_set_option+0x32e/0x590
ucma_write+0x1f9/0x330
Allocated by task 505:
ucma_write_cm_event+0x1a1/0x660
Freed by task 505:
kfree+0x1da/0x4c0
ucma_get_event+0x5d5/0x7e0
The freed object is a ucma_event that another thread dequeued from file B's
list under file B's mutex. File A's mut is left held on top of that,
wedging its next writer in uninterruptible sleep.
This path needs a bound and address-resolved cm_id, so it requires an RDMA
device to be present.
Take the handler lock around the call.
Fixes: 09e328e47a69 ("RDMA/ucma: Fix the locking of ctx->file")
Link: https://patch.msgid.link/r/2823D190-92D5-4714-8769-4FB643C64FF3@doyensec.com
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Norbert Szetei <norbert@doyensec.com>
Date: Mon Jul 27 10:06:12 2026 +0200
RDMA/ucma: Lock the handler in ucma_write_cm_event()
commit f4cc21c6a8e9d392871477f9fd98d68e5ad80272 upstream.
ctx->file may only be changed under the handler lock and the xa_lock, which
is what stops uevents being queued for a ctx while ucma_migrate_id() moves
it to another file. The CM core takes that lock before invoking
ucma_event_handler(), but the write() paths that queue uevents themselves
do not.
ucma_write_cm_event() re-reads ctx->file for each of its four dereferences,
so ucma_migrate_id() can swap it mid-sequence:
mutex_lock(&ctx->file->mut); /* file A */
list_add_tail(&uevent->list, &ctx->file->event_list); /* file B */
mutex_unlock(&ctx->file->mut); /* file B */
wake_up_interruptible(&ctx->file->poll_wait); /* file B */
The window is the mutex_lock() itself: the writer sleeps in it while the
migration reassigns ctx->file. The list_add_tail() then runs on file B's
event_list holding only file A's mutex:
list_add corruption. prev->next should be next (ffff888101320f30),
but was ffff88814a08c418. (prev=ffff88814a075c18).
kernel BUG at lib/list_debug.c:32!
Call Trace:
ucma_write_cm_event+0x36e/0x5e0
and file A's mut is left held forever, wedging its next writer in D state.
The uevent is also stranded on a list ucma_cleanup_ctx_events() will not
walk, so it outlives its context. /dev/infiniband/rdma_cm is 0666 and no
RDMA device is involved, so an unprivileged user reaches all of this.
Take the handler lock, as ucma_cleanup_mc_events() does; ctx->cm_id is
pinned by the ucma_get_ctx() reference.
Fixes: a3c9d0fcd371 ("RDMA/ucma: Support write an event into a CM")
Link: https://patch.msgid.link/r/60544A67-EFD6-4D5D-974C-D983445F1070@doyensec.com
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jason Gunthorpe <jgg@ziepe.ca>
Date: Thu Jul 2 13:47:10 2026 -0300
RDMA/uverbs: Add UVERBS_ATTR_UHW to UVERBS_METHOD_REG_MR
commit 011199f46f44a9fd93a9e5ab5d7fd1328d80e9bf upstream.
The original commit missed that three drivers (mthca, irdma, siw) have UHW
data associated with reg_mr that cannot be passed through the ioctl. They
also assume that the udata cannot be NULL, so failing to pass a valid
udata can trigger a NULL udata crash in those drivers.
This never happens in real systems since in rdma-core ibv_cmd_reg_mr_ex()
does not accept a udata and those three drivers don't use it, however a
malicious userspace could trigger it.
Cc: stable@vger.kernel.org
Fixes: 5b2e45049dc0 ("IB/core: Add UVERBS_METHOD_REG_MR on the MR object")
Reported-by: Jacob Moroni <jmoroni@google.com>
Closes: https://lore.kernel.org/all/CAHYDg1TOGxRGZrS69d4Y--Shj_DZv0nJuM73iHUBwBM70g_t3Q@mail.gmail.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: WenTao Liang <vulab@iscas.ac.cn>
Date: Sat Jun 27 00:01:50 2026 +0800
regulator: as3722_get_regulator_dt_data: fix premature of_node_put leaving dangling of_node pointer
commit f9324d670ae0b88cbfb0aa48fcaefa5baeb8da4c upstream.
In as3722_get_regulator_dt_data(), of_get_child_by_name() acquires a
reference on np, which is then assigned to pdev->dev.of_node. The
function immediately calls of_node_put(np), releasing the reference and
leaving pdev->dev.of_node as a dangling pointer.
Remove the of_node_put(np) call to let the device hold the reference.
Cc: stable@vger.kernel.org
Fixes: bc407334e9a6 ("regulator: as3722: add regulator driver for AMS AS3722")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260626160150.54291-1-vulab@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: WenTao Liang <vulab@iscas.ac.cn>
Date: Sat Jun 27 00:03:26 2026 +0800
regulator: max8998_pmic_dt_parse_pdata: of_node_put on reg_np after ownership transferred to rdata
commit 7c8cc25d8d86f9eb3979255935cfdc7d062ad746 upstream.
In max8998_pmic_dt_parse_pdata(), of_get_child_by_name() acquires a
reference on reg_np which is then stored in rdata->reg_node, transferring
ownership to the regulator data array. The subsequent of_node_put(reg_np)
at the end of the function releases the last matched regulator node's
reference, leaving rdata->reg_node as a dangling pointer for the last
entry.
Remove the spurious of_node_put(reg_np) call.
Cc: stable@vger.kernel.org
Fixes: 156f252857df ("drivers: regulator: add Maxim 8998 driver")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260626160326.54457-1-vulab@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
Date: Wed Jun 17 23:08:43 2026 +0530
regulator: qcom-refgen: correct the regulator type to CURRENT
commit 05dfeb2d0ccf87a7b92cd149a393b8423a26a04e upstream.
As per the REFGEN IP team, this block supplies the reference current to
the PHYs in the SoC. So, correct the regulator type to REGULATOR_CURRENT
to match with the HW behavior.
Fixes: 7cbfbe237960 ("regulator: Introduce Qualcomm REFGEN regulator driver")
Cc: stable@vger.kernel.org
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
Link: https://patch.msgid.link/20260617-ipq9650_refgen-v4-1-c505ea6c6661@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johan Hovold <johan@kernel.org>
Date: Mon Jul 6 08:56:14 2026 +0200
remoteproc: scp: Fix device reference leak on failed lookup
commit 22f9efb3ae07f966a1901d929d16df1388cce65c upstream.
Make sure to drop the reference taken to the SCP device when attempting
to look up its driver data before the driver has been bound.
Note that holding a reference to a device does not prevent its driver
data from going away.
Fixes: 63c13d61eafe ("remoteproc/mediatek: add SCP support for mt8183")
Cc: stable@vger.kernel.org # 5.6
Cc: Erin Lo <erin.lo@mediatek.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20260706065614.389412-1-johan@kernel.org
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Oren Klopfer <oklopfer37@gmail.com>
Date: Fri Jul 3 16:10:10 2026 -0400
Revert "arm64: dts: rockchip: Further describe the WiFi for the Pinephone Pro"
commit 5f19535351bf28f28d702f452d11a1216ec2bd28 upstream.
This reverts commit 096bd8c679185f898cae9933c6a68650fa26ea4f.
Just as with the Pinebook Pro, there are multiple chipset variants for
the Pinephone Pro, and multiple firmware binaries for different
distributions. The change causes issues with some of these combinations,
and reverting it resolves the issues. See the Closes below for the full
report.
Similarly with the Pinebook Pro adjustment, the original commit only
indicates "further description" and not indicative of fixing any
existing issues, so reverting should not kick any back up.
Fixes: 096bd8c67918 ("arm64: dts: rockchip: Further describe the WiFi for the Pinephone Pro")
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Peter Robinson <pbrobinson@gmail.com>
Cc: Thorsten Leemhuis <regressions@leemhuis.info>
Cc: stable@vger.kernel.org
Closes: https://lore.kernel.org/r/20260607225901.64019-1-oklopfer37@gmail.com/
Signed-off-by: Oren Klopfer <oklopfer37@gmail.com>
Link: https://patch.msgid.link/20260703201010.67311-1-oklopfer37@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hans Verkuil <hverkuil+cisco@kernel.org>
Date: Fri Jul 17 15:42:45 2026 +0200
Revert "media: v4l2-dev: fix error handling in __video_register_device()"
commit e7600f5cee5de14065f950807931d6e6d40fb2d7 upstream.
This reverts commit 2a934fdb01db6458288fc9386d3d8ceba6dd551a.
The intentions of that patch were good, but it doesn't work.
The idea is that if device_register fails, you have to do a put_device
to let the ref counter release resources.
However, the V4L2 API says that if video_register_device() fails, then
you have to call video_device_release(), which kfree()s the video_device
struct.
But the put_device() will already have freed the struct, so you end
up in a double-free scenario.
There is not really a good way of fixing this without breaking
video_register_device() into two parts, one that initializes everything,
and one that does the actual device_register, and then converting all
V4L2 drivers to this new model.
That is a massive job, and it is very unlikely that device_register
will fail.
So rather than ending up in a double-free scenario, just revert this
patch, and in that case we'll have a small memory leak. Which is a lot
more robust.
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Fixes: 2a934fdb01db ("media: v4l2-dev: fix error handling in __video_register_device()")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-media/20260520090624.1071139-1-lgs201920130244@gmail.com/
Link: https://lore.kernel.org/all/2026042058-charm-storable-4ad8@gregkh/
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vincent Donnefort <vdonnefort@google.com>
Date: Thu Aug 13 14:11:46 2026 +0100
ring-buffer: Fix subbuf resize race with ring buffer readers
[ Upstream commit 8a5f63637890f03177146efddaba5ec7a1b4d61f ]
trace_buffer subbuf_size is read lockless in ring_buffer_read_page() and
ring_buffer_read_start(), while it can simultaneously be resized with
ring_buffer_subbuf_order_set().
Instead of trace_buffer::subbuf_size, use bpage::order in
ring_buffer_read_start() and ring_buffer_read_page().
In ring_buffer_read_start(), even with resize_disabled, there is still a
possibility of a race with a buffer modification. Hold the trace_buffer
mutex to synchronise with any pending ring buffer order modification.
trace_buffer::subbuf_size is now actually useless, remove it. Also,
create accessors rb_subbuf_capacity() and rb_page_capacity() which
return the actual size available for storing events, while
rb_subbuf_size() returns the actual subbuf page-size.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-5-vdonnefort@google.com
Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260805153225.2096152-1-vdonnefort%40google.com # patch 1
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Vincent Donnefort <vdonnefort@google.com>
Date: Thu Aug 13 14:11:47 2026 +0100
ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()
commit e743527c5bfdceda1095bc0a9e596e2aebb6a9c3 upstream.
ring_buffer_alloc_read_page() is racy with ring_buffer_subbuf_order_set,
it can allocate a reader page with an outdated order. This isn't a big
issue, the user can still re-allocate a new reader page and try again.
However, what is more problematic is if the value of subbuf_order
changes in the middle of ring_buffer_alloc_read_page(). In that case,
bpage->order might not match the actual allocated memory.
Use bpage->order for the allocation to prevent this race.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-6-vdonnefort@google.com
Fixes: bce761d75745 ("ring-buffer: Read and write to ring buffers with custom sub buffer size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vincent Donnefort <vdonnefort@google.com>
Date: Thu Aug 13 14:11:43 2026 +0100
ring-buffer: Free cpu_buffer::free_page with subbuf_order
commit 234b1a72e9706fe20c08c96f4374ec8e83b934cb upstream.
When sub-buffers use an order greater than 0, cpu_buffer->free_page is
allocated with subbuf_order. Use the correct order for
cpu_buffer->free_page.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-2-vdonnefort@google.com
Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260806211306.3704194-1-vdonnefort%40google.com # patch 3
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vincent Donnefort <vdonnefort@google.com>
Date: Thu Aug 13 14:11:44 2026 +0100
ring-buffer: Hold cpu_buffer::lock when resizing a subbuf
commit 24974bd0da1b47fd56c975533ead50abf754e74d upstream.
Because, ring_buffer_subbuf_order_set() can clear cpu_buffer->free_page,
hold cpu_buffer->lock to prevent races with
ring_buffer_alloc_read_page() and ring_buffer_free_read_page().
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-3-vdonnefort@google.com
Fixes: 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260810125633.3344684-1-vdonnefort%40google.com # patch 3
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Peixin Xie <peixin.xie@linux.spacemit.com>
Date: Fri Aug 7 19:24:32 2026 -0600
riscv: acpi: Handle LPI architectural context loss flags
commit 7e4cb63d61a7e0bef20f0d00e831c7fac06e4a1c upstream.
Commit 4785aa802853 ("cpuidle, ACPI: Evaluate LPI arch_flags for
broadcast timer") replaced the generic nonzero check for LPI
architectural context loss flags with arch_get_idle_state_flags().
RISC-V does not implement the helper, so it falls back to the stub
that returns 0. Consequently, CPUIDLE_FLAG_TIMER_STOP is not set when
an LPI state loses the hart timer context, preventing cpuidle from
using a broadcast timer for that state.
Implement the RISC-V helper and map the hart timer context loss flag
to CPUIDLE_FLAG_TIMER_STOP.
Fixes: 4785aa802853 ("cpuidle, ACPI: Evaluate LPI arch_flags for broadcast timer")
Cc: stable@vger.kernel.org
Acked-by: Sudeep Holla <sudeep.holla@kernel.org>
Reviewed-by: Yixun Lan <dlan@kernel.org>
Reviewed-by: Sunil V L <sunilvl@oss.qualcomm.com>
Reviewed-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Peixin Xie <peixin.xie@linux.spacemit.com>
Link: https://patch.msgid.link/20260803-riscv-acpi-lpi-timer-v3-1-520fa13732f5@linux.spacemit.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nam Cao <namcao@linutronix.de>
Date: Fri Aug 7 19:24:30 2026 -0600
riscv: unaligned: stop using kthread for check_vector_unaligned_access()
commit 34c9cfcde29b938c416924ee6ec3519270bc2238 upstream.
A kthread is used to run check_vector_unaligned_access() to optimize boot
time, allowing the kernel to continue booting without waiting for the
unaligned vector speed probe to finish.
However, this asynchronous approach introduces several complications.
First, the kthread may not complete before a user reads vDSO data,
resulting in incorrect values. This was previously addressed by
commit 5d15d2ad36b0 ("riscv: hwprobe: Fix stale vDSO data for
late-initialized keys at boot"), which added complex synchronization
between the kthread and vDSO reads.
Second, it was discovered that the kthread may not finish before
vec_check_unaligned_access_speed_all_cpus() (marked with __init) is freed,
triggering a page fault.
These issues raise the question of whether the kthread is worth the added
complexity. A past boot time regression report was actually unrelated to
synchronous probing; it was caused by the probe running serially. Since
switching to a parallel probe, no further complaints have been made.
Furthermore, the unaligned scalar access speed probe takes the same amount
of time, runs synchronously, and has caused no issues.
Testing shows no noticeable boot time slowdown when running the vector
probe synchronously (0.464474s with kthread vs. 0.457991s without).
Remove the kthread usage and run the probe synchronously. This simplifies
the boot flow and allows for the revert of commit 5d15d2ad36b0 ("riscv:
hwprobe: Fix stale vDSO data for late-initialized keys at boot")
Reported-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Closes: https://lore.kernel.org/linux-riscv/20260612-vec_unaligned_drop_init-v1-1-df969210ae34@oss.tenstorrent.com/
Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
Cc: stable@vger.kernel.org
Signed-off-by: Nam Cao <namcao@linutronix.de>
Acked-by: Jesse Taube <jtaubepe@redhat.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Link: https://patch.msgid.link/1c378963f27c5960e8a57c50b8b444d30954cb54.1781666867.git.namcao@linutronix.de
[pjw@kernel.org: updated to apply; adjusted Fixes: tag; fixed my own manual patch application error]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chunkai Deng <chunkai.deng@oss.qualcomm.com>
Date: Thu Jun 18 00:16:39 2026 -0700
rpmsg: glink: smem: order FIFO read after availability check
commit 786439ad58763e04b91bc2ec5f590e463939f197 upstream.
glink_smem_rx_peek() reads the RX FIFO payload after the caller has
determined data is available via glink_smem_rx_avail(), which reads the
remote-updated head index. A control dependency between the head read
and the subsequent payload read does not order the two loads, so the
CPU may speculatively read the FIFO before observing the head update
and consume stale data the remote has not yet published.
Add rmb() in glink_smem_rx_peek() before the memcpy_fromio() so the
availability (head) read is ordered ahead of the FIFO payload read,
matching the consumer pattern in
Documentation/core-api/circular-buffers.rst.
Fixes: caf989c350e8 ("rpmsg: glink: Introduce glink smem based transport")
Cc: stable@vger.kernel.org
Signed-off-by: Chunkai Deng <chunkai.deng@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260618-rpmsg-glink-smem-mb-v1-1-68a026453a69@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: FUJITA Tomonori <fujita.tomonori@gmail.com>
Date: Sat Aug 8 11:26:08 2026 +0900
rust: bug: skip arch-specific asm in `testlib` builds
commit 5d9668f3930609ead91f39b059ef4fe53db04942 upstream.
Running `make rusttest` with `ARCH=` set to an architecture other than
the host's fails, e.g. `ARCH=arm64` on an x86_64 host:
error: invalid instruction mnemonic 'brk'
--> rust/kernel/bug.rs:63:17
|
63 | / concat!(
64 | | "/* {size} */",
65 | | include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
66 | | include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
| |_______________________________________________________________________________________________________^
|
note: instantiated into assembly here
--> <inline asm>:1:115
|
1 | /* 8 */.pushsection __bug_table,"aw"; .align 2; 14470: .long 14471f - .;.short 2305;.align 2; .popsection; 14471:brk 0x800
| ^^^
The reason is that `rusttest` builds the `kernel` crate as a host
library: it passes the `CONFIG_*` cfgs of the configured architecture,
but not `--target`, so code generation happens for the
host. `warn_flags!` then selects the arch-specific inline asm arm
based on `CONFIG_*`, and the host assembler rejects it.
This does not happen with the current `master` because `warn_on!` has
no user inside the `kernel` crate itself yet, but it will as soon as
one is added.
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/all/CANiq72n4=fz=JNKY0Jdm8BnLa=RmHB2B7s0bO47YTJ7hygqBZg@mail.gmail.com/
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Cc: stable@vger.kernel.org
Fixes: dff64b072708 ("rust: Add warn_on macro")
Link: https://patch.msgid.link/20260808022608.1125174-1-tomo@flapping.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Nikolai Grlica <nikolai@nikolaigrlica.dev>
Date: Mon Aug 10 15:03:35 2026 +0000
rust: kernel: list: fix incorrect pop_back example comment
commit a5c7d35e2fd3e24c411816c91f8f6cc78e652e0c upstream.
The example uses pop_back(), but the accompanying comment says
pop_front(). Update the comment to match the example.
Signed-off-by: Nikolai Grlica <nikolai@nikolaigrlica.dev>
Cc: stable@vger.kernel.org
Fixes: bf87a41b85d6 ("rust: list: Add an example for `ListLinksSelfPtr` usage")
Link: https://patch.msgid.link/20260810150322.61809-1-nikolai@nikolaigrlica.dev
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Miguel Ojeda <ojeda@kernel.org>
Date: Thu Sep 3 20:18:37 2026 +0200
rust: rust_is_available: warn for `bindgen` < 0.72.1 && libclang >= 22
[ Upstream commit dc01dfb37b34beeefcfe1c3055364d41a4070c7e ]
Starting with LLVM 22, `clang_getTypeDeclaration()` may return a forward
declaration instead of the type definition. This made `bindgen` generate
opaque types [1][2], which in turn made us fail with e.g.
error[E0609]: no field `__bindgen_anon_1` on type `bindings::kernel_param`
--> rust/kernel/module_param.rs:78:46
|
78 | let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) };
| ^^^^^^^^^^^^^^^^ unknown field
|
= note: available field is: `_address`
This was fixed in `bindgen` 0.72.1 [3].
In order to clarify what is going on and avoid confusion [4][5], add
a warning to `rust_is_available.sh` about it when the versions match,
similar to past warnings like the one removed in:
commit ae64324ad5c1 ("rust: rust_is_available: remove warning for `bindgen` < 0.69.5 && libclang >= 19.1")
In addition, even if the versions match, check if the issue appears to
not reproduce with the given binaries, to avoid a warning in such a case.
Finally, include tests.
[ Nathan, in parallel, updated the instructions of the LLVM+Rust
kernel.org toolchains [6] so that `--version` is not passed to
`cargo` for `bindgen`, and thus the latest `bindgen` is installed
by default, which should help to avoid some of these situations.
Thanks!
- Miguel ]
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust-bindgen/issues/3264 [1]
Link: https://github.com/Rust-for-Linux/linux/issues/353 [2] # "Missing fields in nested class with LLVM 22."
Link: https://github.com/rust-lang/rust-bindgen/pull/3278 [3]
Reported-by: Burak Emir <burak.emir@gmail.com>
Link: https://github.com/Rust-for-Linux/linux/issues/1247 [4]
Link: https://lore.kernel.org/rust-for-linux/CABwQupNfMAJOGqRM9ke6tj4f53dCCsBDKU7Vp+zf8mwk7bqt8Q@mail.gmail.com/ [5]
Link: https://mirrors.edge.kernel.org/pub/tools/llvm/rust/ [6]
Tested-by: Burak Emir <burak.emir@gmail.com>
Link: https://patch.msgid.link/20260719120514.159914-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: FUJITA Tomonori <fujita.tomonori@gmail.com>
Date: Fri Aug 7 22:05:31 2026 +0900
rust: time: fix as_micros_ceil() rounding near i64::MAX
commit ec90dfcf05f02206c280bb59af660bbb3ae177d0 upstream.
The ceiling adjustment used saturating_add(NSEC_PER_USEC - 1) before
dividing. Once the nanosecond value gets within NSEC_PER_USEC - 1 of
i64::MAX the addition saturates to i64::MAX, which drops the ceiling
bias and can yield a result one microsecond too small.
Fixes: fae0cdc12340 ("rust: time: Introduce Delta type")
Reported-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
Closes: https://lore.kernel.org/rust-for-linux/CANiq72mtS0ABA2JnT5tpz6J9c_mnxY+vyPvghV_ukngWvN8F2w@mail.gmail.com/
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260807130531.1056209-1-tomo@flapping.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thomas Richter <tmricht@linux.ibm.com>
Date: Tue Aug 11 15:39:01 2026 +0200
s390/cpum_cf: Handle CPU hotplug via prepare/dead callbacks
commit 337bd95507a16063687cfc286ea90de5cca48c37 upstream.
The command 'perf stat -e cycles -- <command>' crashes the kernel
when CPUs are hotplug added during that run.
Root cause is the allocation of struct cpu_cf_events at first
event initialization. The allocation is dynamic and the first
event that has task context creates such a structure for
each online CPU. This is not sufficient. CPUs may be offline
during event creation and can be set online during the
perf run time. For example commands
# echo 0 > /sys/devices/system/cpu/cpu1/online
# perf stat -e cycles -i -- stress-ng -t10s --matrix X
# sleep 1
# echo 1 > /sys/devices/system/cpu/cpu1/online
create an event for CPUs 0,2-X. Since the events are created with
task-context, the scheduler will eventually schedule the program
on CPU1. This CPU has not created and initialized any per
CPU event infrastructure as that CPU was not online at the time
of the perf invocation. Thus when the scheduler runs stress-ng
on CPU1, the function cpumf_pmu_add() refers to a NULL pointer:
struct cpu_cf_events *cpuhw = this_cpu_cfhw();
This function call is invoked after the task stress-ng has been
made runnable on CPU1. And this_cpu_cfhw() returns NULL.
The result is a panic:
Unable to handle kernel pointer dereference in virtual kernel address space
Failing address: 0000000000000000 TEID: 0000000000000483
....
Krnl PSW : 0404d00180000000 000003ef8291fd0c (cpumf_pmu_add+0x3c/0x80)
....
Call Trace:
[<000003ef8291fd0c>] cpumf_pmu_add+0x3c/0x80
[<000003ef82bb5e3e>] event_sched_in+0xae/0x190
[<000003ef82bb60d6>] merge_sched_in+0x1b6/0x390
[<000003ef82bb65b8>] visit_groups_merge.constprop.0.isra.0+0x308/0x5b0
[<000003ef82bb689a>] pmu_groups_sched_in+0x3a/0x50
[<000003ef82bb6a30>] ctx_sched_in+0x180/0x260
[<000003ef82bb780c>] perf_event_context_sched_in+0x11c/0x2d0
[<000003ef82bb79ee>] __perf_event_task_sched_in+0x2e/0xc0
[<000003ef82994834>] finish_task_switch.isra.0+0x1a4/0x250
....
Last Breaking-Event-Address:
[<000003ef8291f1d8>] this_cpu_cfhw+0x38/0x40
The issue arises only in per-task context when the CPUMF facility is
used and the scheduler picks a random CPU for such a process to run on.
The scheduler enables the CPUMF infrastructure via PMU callback
functions pmu::add() and pmu::del().
Introduce a CPU hotplug prepare/dead callback pair which creates and
removes the per CPU counter data while the CPU is offline. Count the
users which track every CPU (cpu == -1), that is perf_event_open()
events with task context and /dev/hwctr device sessions, in the new
counter cpu_cf_root::tskcnt, protected by pmc_reserve_mutex.
This ensures the infrastructure is available when
new CPU is selected to run the per-task context process.
In cpum_cf_free_root() and cpum_cf_free_cpu() ensure the reference
pointer to data structures is set to NULL before the data is freed
to prevent interrupt handlers to access stale data.
[gor@linux.ibm.com: change commit message]
Fixes: 9b9cf3c77e7e ("s390/cpum_cf: rework PER_CPU_DEFINE of struct cpu_cf_events")
Cc: stable@vger.kernel.org # v6.5+
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Suggested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stefan Haberland <sth@linux.ibm.com>
Date: Wed Aug 5 13:15:54 2026 +0200
s390/dasd: Do not complete a failed ESE read as successful
commit cddb447c62466f3076938ce120028d7b591f9f37 upstream.
dasd_int_handler() completes an NRF read of an unallocated ESE track by
calling ese_read() and unconditionally marking the request
DASD_CQR_SUCCESS. dasd_eckd_ese_read() can return an error before it has
zeroed the destination buffer: a failed sense-data parse or a current
track outside the requested range both return early, leaving the
destination pages untouched. The request is still completed successfully,
so the block layer is handed stale / uninitialized memory instead of
zeros.
Check the ese_read() return value and fail the request through the normal
error path instead of forcing DASD_CQR_SUCCESS.
Fixes: 5e6bdd37c552 ("s390/dasd: fix data corruption for thin provisioned devices")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://patch.msgid.link/20260805111612.1285190-2-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stefan Haberland <sth@linux.ibm.com>
Date: Wed Aug 5 13:15:56 2026 +0200
s390/dasd: Guard sysfs discipline callbacks against unallocated private data
commit 2a1780f9fc2493bd34c418a0be6fc58943afcecf upstream.
Several sysfs show/store handlers call a discipline callback that
dereferences device->private, either directly or through the
DASD_DEFINE_ATTR() macro. During dasd_generic_set_online() the discipline
is assigned before check_device() allocates device->private, so an
unprivileged read of one of these world-readable attributes in that window
dereferences a NULL pointer and panics.
Guard the dereference inside each callback that actually touches
device->private.
Fixes: c729696bcf8b ("s390/dasd: Recognise data for ESE volumes")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://patch.msgid.link/20260805111612.1285190-4-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stefan Haberland <sth@linux.ibm.com>
Date: Wed Aug 5 13:15:55 2026 +0200
s390/dasd: Propagate partial completion length across ERP recovery
commit 6fb5ba2e7e43173a3761e46f091070a8185efa14 upstream.
dasd_default_erp_postaction() copies the timing and device state from
the finished ERP request back to the original request but drops
proc_bytes. A request that was partially completed, an ESE read of a
not-yet-allocated track returns fewer bytes than requested, and then
recovered through the ERP chain loses its partial-completion length.
__dasd_cleanup_cqr() then sees proc_bytes == 0 and completes the whole
request instead of requeueing the remainder, silently returning zeroed
data for the part that was never read.
Carry proc_bytes over to the original request like the other
per-request state.
Fixes: 5e6bdd37c552 ("s390/dasd: fix data corruption for thin provisioned devices")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://patch.msgid.link/20260805111612.1285190-3-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Petr Vaganov <p.vaganov@ideco.ru>
Date: Mon Jun 29 01:52:21 2026 +0700
scsi: core: Fill in DMA padding bytes in scsi_alloc_sgtables()
commit 626147717bea776b61ed3631d2c26283760c4cc4 upstream.
During fuzz testing, the following issue was discovered:
BUG: KMSAN: uninit-value in __dma_map_sg_attrs+0x217/0x310
__dma_map_sg_attrs+0x217/0x310
dma_map_sg_attrs+0x4a/0x70
ata_qc_issue+0x9f8/0x1420
__ata_scsi_queuecmd+0x1657/0x1740
ata_scsi_queuecmd+0x79a/0x920
scsi_queue_rq+0x4472/0x4f40
blk_mq_dispatch_rq_list+0x1cca/0x3ee0
__blk_mq_sched_dispatch_requests+0x458/0x630
blk_mq_sched_dispatch_requests+0x15b/0x340
__blk_mq_run_hw_queue+0xe5/0x250
__blk_mq_delay_run_hw_queue+0x138/0x780
blk_mq_run_hw_queue+0x4bb/0x7e0
blk_mq_sched_insert_request+0x2a7/0x4c0
blk_execute_rq+0x497/0x8a0
sg_io+0xbe0/0xe20
scsi_ioctl+0x2b36/0x3c60
sr_block_ioctl+0x319/0x440
blkdev_ioctl+0x80f/0xd70
__se_sys_ioctl+0x219/0x420
__x64_sys_ioctl+0x93/0xe0
x64_sys_call+0x1d6c/0x3ad0
do_syscall_64+0x4c/0xa0
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Uninit was created at:
__alloc_pages+0x5c0/0xc80
alloc_pages+0xe0e/0x1050
blk_rq_map_user_iov+0x2b77/0x6100
blk_rq_map_user_io+0x2fa/0x4d0
sg_io+0xad6/0xe20
scsi_ioctl+0x2b36/0x3c60
sr_block_ioctl+0x319/0x440
blkdev_ioctl+0x80f/0xd70
__se_sys_ioctl+0x219/0x420
__x64_sys_ioctl+0x93/0xe0
x64_sys_call+0x1d6c/0x3ad0
do_syscall_64+0x4c/0xa0
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
Bytes 14-15 of 16 are uninitialized
Memory access of size 16 starts at ffff88800cbdb000
When processing the last unaligned element of the scatterlist, it is
supplemented with missing bytes in the amount of pad_len. These bytes
remain uninitialized, which leads to a problem.
Extend last_sg->length by pad_len first, then use sg_zero_buffer() to
zero those pad_len bytes. sg_zero_buffer() uses sg_miter internally,
which correctly handles sg entries spanning multiple pages and padding
that crosses a page boundary.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 40b01b9bbdf5 ("block: update bio according to DMA alignment padding")
Cc: stable@vger.kernel.org
Signed-off-by: Petr Vaganov <p.vaganov@ideco.ru>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260628185229.37957-1-p.vaganov@ideco.ru
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jun Yang <junvyyang@tencent.com>
Date: Mon Aug 24 16:18:19 2026 +0800
sctp: distinguish sequence zero from wildcard in reconf lookup
commit 63f44178f0a0f86060c9b576d6efab8a3ffa403e upstream.
Zero is a valid response sequence after strreset_outseq wraps, but
sctp_chunk_lookup_strreset_param() currently treats it as a wildcard.
Add match_seq so response lookups match zero exactly while the one
type-only lookup can still ignore the sequence.
Fixes: 50a41591f110 ("sctp: implement receiver-side procedures for the Add Outgoing Streams Request Parameter")
Cc: stable@kernel.org
Suggested-by: Simon Horman <horms@kernel.org>
Acked-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Link: https://patch.msgid.link/20260824081832.98717-2-juny24602@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hyunwoo Kim <imv4bel@gmail.com>
Date: Wed Aug 19 10:38:37 2026 +0900
sctp: drop a chunk if its transport was removed
commit 03a9d10ecf71f54b2af8020935f2033d4a132be5 upstream.
sctp_rcv() resolves the transport once per packet and leaves it in
chunk->transport. The lookup reference, or the one sctp_add_backlog() takes
if the socket is owned by userspace, keeps it around until the chunk has
been processed.
An authenticated ASCONF DEL-IP can remove it in the meantime.
sctp_assoc_rm_peer() takes the transport out of the association and calls
sctp_transport_free(), which tags it dead and drops the reference the
association held. There is a window on both paths: the packet can sit on
the socket backlog, and on the direct path the lookup completes before
bh_lock_sock().
The DATA chunk in that packet puts the removed transport back into
asoc->peer.last_data_from. Once the packet is done that reference goes
away and the transport is freed by RCU, so the next delayed SACK carries
the pointer into the SACK chunk and sctp_outq_select_transport() reads the
freed transport's state.
Drop the chunk in sctp_inq_push(), next to the existing rcvr->dead check.
Both paths reach it with the association's socket lock held. The peer
retransmits it.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/aoUJHQmxL0LFIMCw@v4bel
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Weiming Shi <bestswngs@gmail.com>
Date: Mon Aug 24 01:28:58 2026 +0800
sctp: fix NULL deref on untransmitted RECONF completion
commit 2db9bfa3e27bdea15e05ea70b56bad3d21e570ec upstream.
sctp_process_strreset_outreq(), sctp_process_strreset_addstrm_out() and
sctp_process_strreset_resp() complete a pending stream reconfiguration
request by stopping the reconf timer on the transport it was sent on:
t = asoc->strreset_chunk->transport;
if (timer_delete(&t->reconf_timer))
sctp_transport_put(t);
chunk->transport is assigned by __sctp_packet_append_chunk() when the
chunk is appended to an outbound packet, and sctp_outq_flush_ctrl() arms
the reconf timer at that same point. A request already published in
asoc->strreset_chunk but not yet transmitted has neither, so completing
it dereferences NULL.
Two ways to get there. sctp_send_asconf_del_ip() sets
asoc->src_out_of_asoc_ok without sending anything when the address being
removed is the association's last one, and sctp_outq_flush_ctrl() then
leaves every non-ASCONF control chunk queued; as only
sctp_process_asconf_ack() clears that flag, it persists. An unprivileged
process that removes such an address and then asks for a stream reset
panics the kernel from softirq. A peer needs neither ASCONF nor local
help: sctp_cmd_interpreter() uncorks the outqueue only once the whole
packet has been processed, so a reply built while walking a RECONF chunk
stays untransmitted for the rest of that walk, and one RECONF chunk
carrying [Incoming SSN Reset Request, Outgoing SSN Reset Request,
Response] -- or two RECONF chunks in one packet -- reaches the same
dereference.
KASAN: null-ptr-deref in range [0x00000000000001e8-0x00000000000001ef]
RIP: 0010:timer_delete+0x67/0x110
Call Trace:
<IRQ>
sctp_process_strreset_addstrm_out (net/sctp/stream.c:832)
sctp_sf_do_reconf (net/sctp/sm_statefuns.c:4212)
sctp_do_sm (net/sctp/sm_sideeffect.c:1172)
sctp_assoc_bh_rcv (net/sctp/associola.c:1044)
sctp_rcv (net/sctp/input.c:243)
ip_local_deliver (net/ipv4/ip_input.c:262)
process_backlog (net/core/dev.c:6680)
</IRQ>
A response can only acknowledge a request that was actually sent, so do
not match asoc->strreset_chunk while chunk->transport is NULL. Guarding
the lookup covers all three completion sites.
Fixes: 810544764536 ("sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter")
Cc: stable@vger.kernel.org
Reported-by: Xiang Mei <xmei5@asu.edu>
Suggested-by: Xin Long <lucien.xin@gmail.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260823172857.896146-2-bestswngs@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jun Yang <junvyyang@tencent.com>
Date: Mon Aug 24 16:18:20 2026 +0800
sctp: fix stream->outcnt underflow on duplicate RECONF responses
commit 3faf13aff243ca9f78d08b1a2956ef5a6fc77b6e upstream.
A cached RECONF chunk may contain more than one request parameter. A
duplicate response can therefore find and process the same ADD_OUT request
again while another parameter is still outstanding, rolling back outcnt
twice and possibly underflowing it.
Track outstanding request types as bits and clear each bit after its first
response. Later responses for the same request are then ignored.
Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter")
Cc: stable@kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Link: https://lore.kernel.org/netdev/20260730110225.37371-1-juny24602@gmail.com/
Suggested-by: Xin Long <lucien.xin@gmail.com>
Assisted-by: tencentos-corvus-ai:kimi-k3
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Link: https://patch.msgid.link/20260824081832.98717-3-juny24602@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hyunwoo Kim <imv4bel@gmail.com>
Date: Sat Aug 15 07:36:18 2026 +0900
sctp: stop processing a packet once its association is deleted
commit 47e15a8d12e366d0d261bcbc394394f44418938d upstream.
sctp_endpoint_bh_rcv() looks the association up only when chunk->asoc is
NULL, and caches the result in chunk->asoc and chunk->transport without
taking a reference.
A packet that matches no association is handed to the endpoint, so a peer
can bundle COOKIE ECHO, SHUTDOWN and SHUTDOWN ACK in one packet. The
COOKIE ECHO creates the association, the SHUTDOWN chunk caches it, and
with the outqueue empty the SHUTDOWN ACK reaches sctp_sf_do_9_2_final(),
so the association and its transports are freed.
The endpoint loop has no counterpart to the asoc->base.dead check in
sctp_assoc_bh_rcv(). The next chunk writes to last_time_heard in the freed
transport and is then passed to sctp_do_sm() with the freed association.
The transport is freed through RCU, so this needs the packet to come off
the socket backlog, where the loop runs in task context.
The endpoint loop cannot do the same check: it holds no reference on the
association, so reading asoc->base.dead would itself be a use-after-free.
Mark the packet for discard in the command interpreter, just before it
deletes the association. That is also before sctp_inq_free() releases the
chunk on the association receive path.
sctp_sf_do_5_2_4_dupcook() issues SCTP_CMD_DELETE_TCB for the temporary
association, while the one the packet belongs to stays alive. A restarting
peer can bundle DATA behind its COOKIE ECHO, so compare against
chunk->asoc and leave that case alone.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/an-YYtoqw1QpTXUL@v4bel
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhiling Zou <zhilinz@nebusec.ai>
Date: Sat Aug 22 16:49:27 2026 +0800
seg6: reset IP6CB after IPv6 decapsulation
commit f967455fb2a5a2079b9eb5823e9ccf359174bf9f upstream.
decap_and_validate() pulls the outer SRv6 headers and makes the inner
packet the skb network header. The IPv6 control block still contains
values collected while parsing the outer packet, including nhoff and
extension-header flags.
End.DX6 and End.DT6 route the inner IPv6 packet directly to the IPv6
input path. An unprivileged user can reach End.DT6 from a user and net
namespace by installing a local SID and injecting an outer packet with
Hop-by-Hop and Destination Options headers followed by an SRH and a
minimal inner IPv6 packet.
The outer extension headers leave a large nhoff in IP6CB. After
decapsulation, ip6_protocol_deliver_rcu() uses that stale offset on the
inner packet and reads beyond the skb head. KASAN reports:
BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu
ip6_protocol_deliver_rcu+0x1118/0x1450
ip6_input_finish+0x11b/0x240
seg6_local_input_core+0xed/0x2e0
lwtunnel_input+0x1e9/0x4e0
ipv6_rthdr_rcv+0x525f/0x6c50
ip6_protocol_deliver_rcu+0xcb7/0x1450
Before clearing IP6CB for an inner IPv6 packet, save its incoming
interface index and L3 slave state. Restore both after the clear and set
nhoff to the inner IPv6 base-header nexthdr field.
Use IP6CB(skb)->iif rather than skb->skb_iif because VRF processing can
replace skb_iif with the L3 master while IP6CB keeps the receiving
interface. Preserve IP6SKB_L3SLAVE for the same reason.
Fixes: d7a669dd2f8b ("ipv6: sr: add helper functions for seg6local")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Injae Ryou <injaeryou@gmail.com>
Date: Mon Jul 13 18:27:00 2026 +0900
selftests/mm: fix on-fault-limit false failure under sudo-rs
commit 98df164036bed307a16e7c124ad023c2c13c4b76 upstream.
run_vmtests.sh runs on-fault-limit as the nobody user via "sudo -u nobody
./on-fault-limit", guarded by a check that nobody can access the binary
("sudo -u nobody ls ./on-fault-limit").
The guard resolves the relative path from the inherited working directory,
which only requires search permission on the test directory itself.
Classic sudo passes the relative path through to execve() the same way, so
the two agree. However, sudo-rs (the default sudo implementation since
Ubuntu 25.10) canonicalizes the command to an absolute path before
executing it, which requires search permission on every ancestor
directory. When the kernel tree lives under a private home directory
(mode 0750, the Ubuntu default for new users since 21.04), the guard
passes but the execution fails with "command not found", and the test is
reported as a false FAIL:
# running sudo -u nobody ./on-fault-limit
sudo: './on-fault-limit': command not found
# [FAIL]
Wrap the command in "sh -c" so that sudo only resolves the shell binary,
and the relative path is resolved by nobody's shell from the inherited
working directory, matching what the guard checks. This is the only "sudo
-u nobody" invocation in the script; uid, cwd, rlimits (including
RLIMIT_MEMLOCK, which this test exercises) and the exit status are
unchanged through sh.
Verified on Ubuntu 26.04 (sudo-rs 0.2.13): the test now runs and passes
instead of failing. Verified on Ubuntu 24.04 (sudo 1.9.15p5): behavior is
unchanged.
Link: https://lore.kernel.org/20260713092700.464376-1-injaeryou@gmail.com
Fixes: 5d2146a3354f ("selftests/mm: skip mlock tests if nobody user can't read it")
Signed-off-by: Injae Ryou <injaeryou@gmail.com>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Karl Mehltretter <kmehltretter@gmail.com>
Date: Fri Jul 31 20:18:44 2026 +0200
serial: imx: serialize imx_uart_ports[] lifetime
commit 8b0b29fdcb47907ae0296b8fe829e918e05e300f upstream.
imx_uart_probe() publishes its devm-allocated port in imx_uart_ports[]
before uart_add_one_port() because console setup uses the table. The entry
is not cleared when adding the port fails or after removal, leaving a
dangling pointer.
A sibling probe can register the shared console through that stale entry.
This was reproduced under KASAN on QEMU mcimx6ul-evk by unbinding a
sibling UART, unbinding the console UART and rebinding the sibling.
Keep the entry valid through uart_remove_one_port(), then clear it. Protect
port addition and removal together with their table updates so sibling
operations cannot interleave. Reject an occupied slot rather than
clobbering an active port during a duplicate-line probe.
Fixes: dbff4e9ea2e8 ("IMX UART: remove statically initialized tables")
Fixes: 9f322ad064f9 ("imx: serial: handle initialisation failure correctly")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/all/20260719162850.043B41F000E9@smtp.kernel.org
Link: https://lore.kernel.org/all/20260719222501.CB4CB1F000E9@smtp.kernel.org
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260731181844.11330-6-kmehltretter@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bradley Morgan <include@grrlz.net>
Date: Mon Jun 22 20:25:08 2026 +0000
signal: avoid shared siginfo namespace rewrites
commit d19cdc167e696714509e87d3f7ae765b6e164589 upstream.
send_signal_locked() rewrites sender ids for the target namespace. Group
sends reuse the same siginfo, so one recipient can affect the next.
Copy the siginfo before changing it.
Link: https://lore.kernel.org/86a8857d58d43ee26a8b365b837fd24830343494.1782159692.git.include@grrlz.net
Fixes: 7a0cf094944e ("signal: Correct namespace fixups of si_pid and si_uid")
Signed-off-by: Bradley Morgan <include@grrlz.net>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Adrian Huang <adrianhuang0701@gmail.com>
Cc: Aleksandr Nogikh <nogikh@google.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Marco Elver <elver@google.com>
Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Aleksandr Khromov <haa@amicon.ru>
Date: Mon Aug 24 13:05:47 2026 +0300
slip: fix use-after-free in sl_sync()
commit 2c4e7c42d77e78ad595dbb9e4b5886b58b45d89d upstream.
slip_devs[] stores bare net_device pointers and takes no reference on
them. sl_sync() and sl_alloc() walk that table from slip_open() under
rtnl_lock(), while an entry is dropped by sl_free_netdev(), which
sl_setup() installs as dev->priv_destructor.
priv_destructor is called from netdev_run_todo(), which deliberately
runs with the RTNL semaphore released so that it can sleep while waiting
for the device refcount to drop:
/* Snapshot list, allow later requests */
list_replace_init(&net_todo_list, &list);
__rtnl_unlock();
...
if (dev->priv_destructor)
dev->priv_destructor(dev); /* slip_devs[i] = NULL */
if (dev->needs_free_netdev)
free_netdev(dev);
...
/* Free network device */
kobject_put(&dev->dev.kobj);
So rtnl_lock() does not serialise slip_open() against the teardown at
all. sl_sync() can load slip_devs[i] while the entry is still published
and dereference it after netdev_run_todo() has run the destructor and
released the device:
CPU0 (slip_open) CPU1 (slip_close)
unregister_netdev()
rtnl_unlock()
netdev_run_todo()
__rtnl_unlock()
rtnl_lock()
sl_sync()
dev = slip_devs[i]
priv_destructor(dev)
slip_devs[i] = NULL
kobject_put(&dev->dev.kobj)
/* dev is freed */
sl = netdev_priv(dev)
if (sl->tty || sl->leased) /* use-after-free */
BUG: KASAN: use-after-free in sl_sync drivers/net/slip/slip.c:730 [inline]
BUG: KASAN: use-after-free in slip_open+0xef4/0x1210 drivers/net/slip/slip.c:806
Read of size 1 at addr ffff8880712dac71 by task syz-executor.2/6506
CPU: 2 PID: 6506 Comm: syz-executor.2 Not tainted 6.1.134-syzkaller-00260-g0c8fc3469765 #0
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Call Trace:
sl_sync drivers/net/slip/slip.c:730 [inline]
slip_open+0xef4/0x1210 drivers/net/slip/slip.c:806
tty_ldisc_open+0xa2/0x120 drivers/tty/tty_ldisc.c:433
tty_set_ldisc+0x324/0x720 drivers/tty/tty_ldisc.c:564
tiocsetd drivers/tty/tty_io.c:2428 [inline]
tty_ioctl+0x5f0/0x1530 drivers/tty/tty_io.c:2712
Allocated by task 6502:
alloc_netdev_mqs+0x98/0xfe0 net/core/dev.c:10719
sl_alloc drivers/net/slip/slip.c:756 [inline]
slip_open+0x36d/0x1210 drivers/net/slip/slip.c:817
tty_ldisc_open+0xa2/0x120 drivers/tty/tty_ldisc.c:433
tty_set_ldisc+0x324/0x720 drivers/tty/tty_ldisc.c:564
Freed by task 6497:
device_release+0xa2/0x240 drivers/base/core.c:2507
kobject_put+0x179/0x280 lib/kobject.c:729
netdev_run_todo+0x6c8/0xef0 net/core/dev.c:10509
slip_close+0x166/0x1c0 drivers/net/slip/slip.c:906
tty_ldisc_close+0x113/0x1a0 drivers/tty/tty_ldisc.c:456
tty_ldisc_kill+0x94/0x160 drivers/tty/tty_ldisc.c:614
tty_ldisc_release+0xe3/0x2b0 drivers/tty/tty_ldisc.c:782
tty_release+0xbcc/0xe70 drivers/tty/tty_io.c:1860
Commit e58c19124189 ("slip: Fix use-after-free Read in slip_open") fixed
a different source of stale entries - a device left in slip_devs[] after
slip_open() freed it on the registration error path - and does not
address this race, which is why the report survives it.
Drop the entry from ndo_uninit instead. unregister_netdevice() calls
ndo_uninit under RTNL, before the device is queued to netdev_run_todo(),
so an entry that sl_sync() can still see while holding RTNL belongs to a
device that cannot be freed until RTNL is dropped. sl_free_netdev()
stays only for the slip_open() error path, where register_netdevice()
may have failed before ndo_init and ndo_uninit is then not called
either. Both running for the same device is harmless: they run under
the same RTNL section, so the slot cannot have been reused in between.
This also removes the second symptom of the missing exclusion: a
destructor running after sl_alloc() had already handed the slot out to
another channel used to clear a live entry, so sl_sync() stopped at that
NULL, sl_alloc() returned the same index again, and
register_netdevice() failed with -EEXIST because slN was still there.
Reproduced on x86_64 with several threads looping over
open("/dev/ptmx") + ioctl(TIOCSETD, N_SLIP) + close().
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 5342b77c4123 ("slip: Clean up create and destroy")
Cc: stable@vger.kernel.org
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Aleksandr Khromov <haa@amicon.ru>
Link: https://patch.msgid.link/20260824100547.164773-1-haa@amicon.ru
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jann Horn <jannh@google.com>
Date: Thu Aug 6 21:41:35 2026 +0200
smack: fix cred UAF in smack_file_send_sigiotask()
commit fedc88e38ce979a720cd2de042578cb5df3dc8de upstream.
When inspecting the credentials of another task, objective credentials
(->real_cred, accessed with __task_cred()) must always be used.
Accessing ->cred on a non-current task is forbidden unless that task is
being created or destroyed; a task is allowed to change its own ->cred
pointer with no synchronization, and changing ->cred should only affect the
current syscall.
smack_file_send_sigiotask() was accessing both sets of credentials: First
tsk->cred, then __task_cred(tsk).
Fix it, always access the objective credentials here.
I have tested that this bug can lead to a KASAN-reported UAF of struct cred
in smack_file_send_sigiotask(), and that this fix prevents the race.
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fredric Cover <fredric.cover.lkernel@gmail.com>
Date: Fri Jul 24 15:01:46 2026 -0700
smb: client: clear ce->tgthint in free_tgts()
commit b1b741cf8e7ce1b91d937e23decd3d3358748700 upstream.
When free_tgts() frees all structures in ce->tlist, ce->tgthint
is left pointing to one of the freed cache_dfs_tgt structures.
If ce->tgthint is not reset before it is used later, it results
in a use-after-free.
Set ce->tgthint to NULL in free_tgts() after the elements are
freed to reflect that no elements remain.
Fixes: 54be1f6c1c37 ("cifs: Add DFS cache routines")
Cc: stable@vger.kernel.org # depends on: smb: client: harden DFS cache against invalid target hints
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Frank Sorenson <sorenson@redhat.com>
Date: Mon Aug 17 12:16:51 2026 -0500
smb: client: fix ALIGN() overflow in symlink_data() error context loop
commit 62656b024efc21c3230eade1a847f25871c3d2bb upstream.
The check added by commit 7d9a7f1f96cd ("smb/client: fix possible
infinite loop and oob read in symlink_data()") compared the post-ALIGN
length against the remaining buffer, but ALIGN() itself can overflow:
for ErrorDataLength near UINT32_MAX (e.g. 0xFFFFFFF9), ALIGN(x, 8)
wraps to 0, so the subsequent bounds check passes, and the loop
advances by zero bytes leaving 'p' pointing into stale data.
Fix by checking the raw ErrorDataLength against the remaining space
before applying ALIGN(), then checking again after. Since raw_len is
bounded by the buffer, raw_len + 7 cannot overflow, so the second check
is an exact post-alignment bounds guard.
Fixes: 76894f3e2f71 ("cifs: improve symlink handling for smb2+")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Frank Sorenson <sorenson@redhat.com>
Date: Thu Aug 20 16:22:10 2026 -0500
smb: client: fix copy-paste error in WSL EA length accounting for $LXDEV
commit 5d14030b46af1a958fd104b020fbb93631c98822 upstream.
The LXDEV block in cifs_query_path_info() uses SMB2_WSL_XATTR_MODE_SIZE
(4) instead of SMB2_WSL_XATTR_DEV_SIZE (8), undercounting eas_len by 4
bytes per $LXDEV EA.
eas_len is used only as a zero/non-zero presence flag so there is no
current functional impact, but the value is incorrect and misleading.
Fixes: 97db41604555 ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Cc: stable@vger.kernel.org
Cc: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fredric Cover <fredric.cover.lkernel@gmail.com>
Date: Fri Jul 24 15:01:45 2026 -0700
smb: client: harden DFS cache against invalid target hints
commit bf86c08123c6ab8c61cc0be1dad7540db93738ff upstream.
Currently, get_tgt_name() returns ERR_PTR(-ENOENT) when ce->tgthint is
NULL, and dfs_cache_noreq_update_tgthint() assumes ce->tgthint is always
valid.
In preparation for clearing ce->tgthint in free_tgts(), harden callers
of get_tgt_name() against ERR_PTR results and harden
dfs_cache_noreq_update_tgthint() against NULL pointer dereferences.
Cc: stable@vger.kernel.org
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hao-Qun Huang <alvinhuang0603@gmail.com>
Date: Sat Jul 4 16:16:13 2026 +0800
staging: greybus: hid: fix SET_REPORT return value
commit 6d45195a9626d8aaaaed212c55638829a9c624a3 upstream.
__gb_hid_output_raw_report() stores the result of gb_hid_set_report()
in ret and even adjusts it to account for the report ID byte, but then
always returns 0.
This hides Greybus transport errors from HID_REQ_SET_REPORT callers,
and makes hidraw report zero bytes written to user space on success,
although hid_hw_raw_request() is expected to return the number of
bytes transferred or a negative errno. The sibling GET_REPORT path,
__gb_hid_get_raw_report(), already follows this convention.
Return ret like the other HID transport drivers do.
Fixes: 96eab779e198 ("greybus: hid: add HID class driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
Link: https://patch.msgid.link/20260704081613.434445-1-alvinhuang0603@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hao-Qun Huang <alvinhuang0603@gmail.com>
Date: Tue Jul 7 23:03:26 2026 +0800
staging: media: tegra-video: fix of_node_put() on VIP parse errors
commit 7393372f79db940acff206b43e2905685a0c57ad upstream.
tegra_vip_channel_of_parse() initializes np from dev->of_node without
taking a reference, but its error paths drop one through the
err_node_put label. This underflows the refcount of the VIP device's
OF node when endpoint parsing fails on a malformed device tree.
The only reference the function takes on np is the success-path
of_node_get() stored in vip->chan.of_node, and that one is already
released by the tegra_vip_init() error path and by tegra_vip_exit().
Return errors directly instead of jumping to the bogus cleanup label.
Fixes: e740d199cf0f ("staging: media: tegra-video: add support for Tegra20 parallel input")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hao-Qun Huang <alvinhuang0603@gmail.com>
Date: Tue Jul 7 23:24:25 2026 +0800
staging: media: tegra-video: vi: fix probe failure on skipped last port
commit ae15adeed9f7ec54989175fe3c9e0815186821bc upstream.
tegra_vi_channels_alloc() iterates over port nodes and skips those
whose reg property cannot be read or whose remote endpoint fails
v4l2_fwnode_endpoint_parse(), leaving the negative result of the
failed call in ret. If that happens on the last port node, the loop
ends with ret still negative and tegra_vi_init() fails the whole VI
probe.
The same defective port earlier in the ports node is skipped silently,
so probing succeeds or fails depending on the order of the port nodes.
The CSI equivalent, tegra_csi_channels_alloc(), returns 0
unconditionally after its loop and does not have this problem.
Use a separate variable for the per-port checks so that only fatal
errors end up in ret.
Fixes: 1ebaeb09830f ("media: tegra-video: Add support for external sensor capture")
Fixes: 2ac4035a78c9 ("media: tegra-video: Add support for x8 captures with gang ports")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Hao-Qun Huang <alvinhuang0603@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Helge Deller <deller@gmx.de>
Date: Thu Aug 6 17:04:15 2026 +0200
sticon/parisc: Detect default STI graphics card for console output
commit de508ece1d37cdbbbfa52f074954310f9b066b13 upstream.
If a machine has multiple graphic cards, detect the graphic card which is used
to display firmware messages and use that one as the default graphic card for
sticon and fbcon.
On parisc machines the default graphic card used for BCH (boot console
handler, aka BIOS menu) is stored in the stable storage (equivalent to CMOS
storage on x86) or in the console path in page zero. Extract that path and
store it as default STI path for later comparism. Take care that the graphic
card can be a GSC or a PCI card which use different path strings.
Increase max string size for default_sti_path to 32 chars as the
print_pa_hwpath() function formats a hardware path using unbounded sprintf
calls for up to 6 bus converter components and 1 module component (e.g.,
255/255/...), which can produce a string up to 28 bytes long.
Signed-off-by: Helge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Tue May 26 15:35:06 2026 -0400
SUNRPC: always drain cache_cleaner before destroying a cache_detail
commit f42d0fda0c67695db6bc704b04b7c10240805377 upstream.
sunrpc_destroy_cache_detail() only cancels the global cache_cleaner
delayed_work when cache_list is empty. During per-netns teardown
cache_list is never empty because init_net's caches remain registered,
so the cancel never fires. After unlink, the caller proceeds to
cache_destroy_net() which kfrees the cache_detail while cache_clean()
may still hold a dangling pointer to it. The result is a
use-after-free: cache_dequeue() takes cd->queue_lock on freed memory,
and cache_put() dereferences cd->cache_put as a function pointer from
freed slab.
Drop the list_empty guard so that cancel_delayed_work_sync() always
runs, ensuring any in-flight cache_clean() completes before the
cache_detail is freed. Re-arm the cleaner afterwards if other caches
are still registered.
Fixes: 820f9442e711 ("SUNRPC: split cache creation and PipeFS registration")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-cache_cleaner_vs_destroy_no_sync-v1-1-a707a6fcfd32@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Sat May 30 20:42:53 2026 -0400
SUNRPC: Check svc pool percpu counter allocation
commit 43e11e164704dde975c9edb370de1a06bec67270 upstream.
__svc_create() initializes three per-pool percpu_counter stats and
ignores every return value. On SMP, percpu_counter_init() fails when
__alloc_percpu_gfp() cannot satisfy the allocation, leaving the failed
counter with fbc->counters == NULL and its embedded raw_spinlock_t,
list_head, and count never initialized. __svc_create() returns the
half-constructed svc_serv to nfsd, lockd, or the NFS callback service
anyway.
Once that service is live, the hot-path increments in
svc_xprt_enqueue(), svc_handle_xprt(), and
svc_pool_wake_idle_thread() reach a counter whose backing pointer is
NULL. The pointer is a per-cpu offset, so the access does not fault:
it resolves to offset zero of the current CPU's per-cpu area and
silently corrupts whatever variable lives there. A
/proc/fs/nfsd/pool_stats read walks the same NULL per-cpu storage and
returns garbage, and on CONFIG_DEBUG_SPINLOCK or lockdep it splats on
the never-initialized lock.
Creating the broken service requires a percpu allocation failure during
RPC server startup, so it is reachable only by a local administrator
under memory pressure or fault injection; a remote peer cannot induce
the bad state on its own.
Check each percpu_counter_init() return value in __svc_create() and
fail when an allocation fails, unwinding the counters already set up
in the current pool and in every pool initialized before it. A
discrete percpu_counter_destroy() per counter at teardown frees each
per-cpu allocation exactly once.
Fixes: ccf08bed6e7a ("SUNRPC: Replace pool stats with per-CPU variables")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-tier2-local-v2-2-5a0fd532db57@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Thu Jun 11 16:00:47 2026 -0400
sunrpc: defer rq_argp and rq_resp free until after RCU grace period
commit c479bde671cbe2f9e152834a8b0eb7c3c295bbaf upstream.
svc_rqst_free() frees rqstp->rq_argp and rqstp->rq_resp synchronously
via kfree(), but defers the rqstp struct free via kfree_rcu(). After
svc_exit_thread() calls list_del_rcu() and svc_rqst_free(), there is
a window where RCU readers that started before list_del_rcu() can still
traverse the thread list and find the rqstp. These readers (e.g.
nfsd_nl_rpc_status_get_dumpit()) dereference rqstp->rq_argp, which has
already been freed — a use-after-free.
Fix this by moving the kfree of rq_argp and rq_resp into an explicit
call_rcu() callback alongside the struct free. Resources not accessed
by RCU readers (bvec, buffer pages, scratch folio, auth_data) remain
synchronously freed.
Fixes: 812443865c5f ("sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-4-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Luxiao Xu <rakukuip@gmail.com>
Date: Tue Jul 7 13:20:47 2026 +0800
sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir
commit 932a8cf6abb2b2f8677b79153a823108d8861fe2 upstream.
Normal client creation goes through rpc_setup_pipedir(), which records
clnt->pipefs_sb, but the mount-event path in __rpc_clnt_handle_event()
calls rpc_setup_pipedir_sb() directly and never refreshes that field.
The umount path also removes the directory without clearing
clnt->pipefs_sb.
After a late pipefs mount or any remount, rpc_clnt_remove_pipedir()
compares the current superblock against a stale pipefs_sb pointer and
skips cleanup, leaving pipefs dentries whose inode private data still
points at a freed rpc_clnt, leading to a potential use-after-free during
subsequent rpc_info_open() or rpc_show_info() calls.
Fix this by properly updating clnt->pipefs_sb upon mount events and
clearing it during unmount or failure paths.
Fixes: bfca5fb4e97c ("SUNRPC: Fix RPC client cleaned up the freed pipefs dentries")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Xin Liu <dstsmallbird@foxmail.com>
Reviewed-by: Ren Wei <enjou1224z@gmail.com>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Thu May 28 15:32:11 2026 -0400
SUNRPC: Guard svcauth_gss_release() dispatch on rq_auth_stat
commit f8870b9b75afb77986bc65940a231d54068ff2b1 upstream.
svcauth_gss_release() reads gc_proc and switches on gc_svc before
consulting rq_auth_stat. On the SVC_DENIED path after a failed
svcauth_gss_accept(), those fields may hold stale values from a
prior request or uninitialized slab residue: svcauth_gss_accept()
allocates gss_svc_data with non-zeroing kmalloc and clears only
gsd_databody_offset and rsci per request, not clcred.
Because RPC_GSS_PROC_DATA is zero, a zeroed or stale-zero gc_proc
passes the existing guard and falls through into the gc_svc switch,
which can dispatch to svcauth_gss_wrap_integ() or
svcauth_gss_wrap_priv(). Both wrap helpers call
svcauth_gss_prepare_to_wrap() before any rsci->mechctx dereference,
and that helper already returns early when rq_auth_stat is not
rpc_auth_ok, so the downstream NULL dereference is blocked. The
dispatch itself remains structurally wrong: it reads scalars that
the caller has no contract to have initialized after a failed
authentication.
Mirror the existing rq_auth_stat gate in
svcauth_gss_prepare_to_wrap() one frame up, so
svcauth_gss_release() skips the clcred dispatch entirely when
authentication has not succeeded. The cleanup tail that releases
rq_client, rq_gssclient, cr_group_info, and rsci still runs.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-4-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 23 21:02:13 2026 -0400
SUNRPC: harden gss_krb5_unwrap_v2 against short tokens
commit 6959297aaa9572783d620a226d73c3fb94494888 upstream.
gss_krb5_unwrap_v2() reads the EC and RRC header fields at ptr+4 and
ptr+6 before validating that the token is at least GSS_KRB5_TOK_HDR_LEN
(16) bytes long, and its rotate_left() helper passes buf->len - base
to xdr_buf_subsegment() without verifying that base <= buf->len. When
a caller hands in a sub-16-byte token, or a token whose declared len
leaves base past the end of the buffer, three distinct failures follow:
gss_krb5_unwrap_v2(offset, len, buf)
ptr = buf->head[0].iov_base + offset
ec = *(ptr + 4) /* OOB read on short head */
rrc = *(ptr + 6) /* OOB read on short head */
rotate_left(offset + 16, buf, rrc)
xdr_buf_subsegment(buf, &subbuf,
base, buf->len - base) /* u32 wrap when base > len */
_rotate_left(&subbuf, shift)
shift %= buf->len /* divide-by-zero when base == len */
After decryption, the cleanup arithmetic has the same shape:
movelen = min_t(unsigned int, buf->head[0].iov_len, len);
movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip;
BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen >
buf->head[0].iov_len);
The BUG_ON re-adds the value just subtracted, so it reduces to
min(A, B) > A and is permanently false; it cannot catch the unsigned
underflow of movelen, which then drives a ~UINT_MAX-byte memmove().
Add four defense-in-depth guards inside the unwrap core so it is safe
regardless of what its callers validate:
- reject tokens with len - offset < GSS_KRB5_TOK_HDR_LEN before
touching ptr+4/ptr+6;
- bail from rotate_left() when buf->len <= base, covering both the
underflow and zero-length cases;
- return early from _rotate_left() when buf->len is zero, so the
shift %= buf->len modulo cannot fault;
- replace the dead BUG_ON with a live check that returns
GSS_S_DEFECTIVE_TOKEN before the movelen subtraction.
Fixes: de9c17eb4a91 ("gss_krb5: add support for new token formats in rfc4121")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260524010213.557424-5-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 23 21:02:11 2026 -0400
SUNRPC: harden gss_unwrap_resp_priv length checks
commit 87831b92112c81db251d46756d65daa4f91af6a2 upstream.
gss_unwrap_resp_priv() validates the RPCSEC_GSS opaque length with
offset = (u8 *)(p) - (u8 *)head->iov_base;
if (offset + opaque_len > rcv_buf->len)
goto unwrap_failed;
maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset,
offset + opaque_len, rcv_buf);
Both operands are u32 and the sum is computed in u32. A reply with
opaque_len near 0xffffffff makes offset + opaque_len wrap to a small
value that is below rcv_buf->len, so the bound check passes and
gss_unwrap() is called with end < begin. The check also lacks a
lower bound, so any opaque_len in [0, GSS_KRB5_TOK_HDR_LEN) is
accepted and forwarded to gss_krb5_unwrap_v2(), whose pre-decrypt
header reads at ptr+4 and ptr+6 then run past the token.
A krb5p NFS server returning a crafted RPCSEC_GSS reply can drive
the client into out-of-bounds reads in gss_krb5_unwrap_v2() and the
rotate_left() loop that follows.
Fix by replacing the single combined check with three guards that
are safe in u32 arithmetic and that enforce the RFC 4121 minimum
outer token length:
if (offset > rcv_buf->len)
goto unwrap_failed;
if (opaque_len > rcv_buf->len - offset)
goto unwrap_failed;
if (opaque_len < GSS_KRB5_TOK_HDR_LEN)
goto unwrap_failed;
The first guard makes the subtraction in the second guard
unconditionally safe; offset is derived from a successful
xdr_inline_decode() in the head kvec, so in practice it already
satisfies the bound. The floor mirrors the server-side check added
in commit 5b757c2e57a5 ("SUNRPC: svcauth_gss: enforce krb5 token
minimum length").
Fixes: 2d2da60c63b6 ("RPCSEC_GSS: client-side privacy support")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260524010213.557424-3-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 30 20:42:52 2026 -0400
sunrpc: init gssp_lock before publishing proc entry
commit 5ce1ed6159731a41fdd0b03eedbed4e147036a5a upstream.
create_use_gss_proxy_proc_entry() publishes /proc/net/rpc/use-gss-proxy
via proc_create_data() before init_gssp_clnt() runs mutex_init() on
sn->gssp_lock. Once the dentry is linked under proc_subdir_lock it is
immediately reachable from userspace, so a write that lands in the
window drives set_gssp_clnt() into mutex_lock() on a zero-initialized
struct mutex.
create_use_gss_proxy_proc_entry(net)
proc_create_data("use-gss-proxy", ...) /* dentry live */
init_gssp_clnt(sn)
mutex_init(&sn->gssp_lock) /* too late */
write_gssp()
set_gssp_clnt(net)
mutex_lock(&sn->gssp_lock) /* uninitialized */
gssp_rpc_create(...)
sn->gssp_clnt = clnt
mutex_unlock(&sn->gssp_lock)
The window spans only the two statements between proc_create_data()
returning and init_gssp_clnt(), so a writer reaches it only if the
registering thread is preempted there while another task is already
opening the freshly published file. register_pernet_subsys() runs in
preemptible context under pernet_ops_rwsem, so that preemption is
possible, and the window widens on auth_rpcgss module load, when the
proc entry is created for every live net namespace whose tasks are
already running. A writer that wins the race locks a zero-filled
struct mutex. On CONFIG_DEBUG_MUTEXES the missing magic value trips a
"lock used without init" splat; on a production kernel the fast path
acquires the lock via CMPXCHG(owner, 0, current). In the latter case
a second writer that arrives before init_gssp_clnt() re-zeroes owner
can enter set_gssp_clnt() concurrently, shut down the first writer's
clnt while it is still in use, and leak the loser's clnt.
Fix by initializing sn->gssp_lock in sunrpc_init_net() so its lifetime
matches the sunrpc_net it lives in. sn->gssp_clnt is already NULL from
the kzalloc that backs net_generic storage, so the lazy helper is no
longer needed; drop init_gssp_clnt(), its prototype, and the call from
create_use_gss_proxy_proc_entry(). sunrpc.ko is a build-time
dependency of auth_rpcgss.ko, so sunrpc_init_net() has always run on
every netns before any auth_gss pernet init can publish the proc
entry.
Fixes: 030d794bf498 ("SUNRPC: Use gssproxy upcall for server RPCGSS authentication.")
Cc: stable@vger.kernel.org
Assisted-by: kres:claude-opus-4-7
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260530-tier2-local-v2-1-5a0fd532db57@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Thu May 28 15:32:10 2026 -0400
SUNRPC: reject duplicate CREDS_VALUE options
commit 2e4ce62385c1b8a887c5370af058ac7b52a8eaf9 upstream.
gssx_dec_option_array() walks the wire-supplied option array and, for
every entry whose name matches CREDS_VALUE, calls
gssx_dec_linux_creds() on the same struct svc_cred. That helper
unconditionally installs a fresh groups_alloc() result into
creds->cr_group_info without releasing whatever pointer was already
there:
for (i = 0; i < count; i++) {
... decode name ...
if (length == sizeof(CREDS_VALUE) &&
memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
err = gssx_dec_linux_creds(xdr, creds);
...
}
}
A reply that carries two CREDS_VALUE entries therefore overwrites
cr_group_info on the second iteration and orphans the group_info
allocated by the first call. The earlier free_creds path only
releases the last cr_group_info via free_svc_cred(), so the first
allocation's refcount stays at one and its kvmalloc-backed storage
is leaked. No in-tree caller of gssp_accept_sec_context_upcall()
expects more than one CREDS_VALUE per reply.
Fix by tracking whether a CREDS_VALUE option has already been
decoded and returning -EINVAL on any subsequent match, so the
free_creds path releases the single group_info that was installed.
Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-3-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Thu May 28 15:32:08 2026 -0400
SUNRPC: Reject krb5 v2 wrap tokens with oversized ec field
commit ad484748eec0a66eac0f13ab53b3fbedb7333c91 upstream.
gss_krb5_unwrap_v2() sets buf->len to a logical
length, which can be much smaller than head[0].iov_len
(the allocated receive-page capacity). It then calls
xdr_buf_trim() with a trim length derived from the 16-bit
"extra count" (ec) field in the Kerberos v2 token header.
The ec field is authenticated by the post-decrypt memcmp()
against the encrypted header copy, so a randomly-mutated
value is rejected. However, any peer holding a valid GSS
context can legitimately encrypt a token whose ec exceeds
the plaintext length. Per RFC 4121, such a token is
structurally malformed.
Although xdr_buf_trim() now clamps the buf->len subtraction
to avoid unsigned underflow, the buffer is still left in a
semantically invalid state (zero length, inconsistent iov
lengths) when ec is oversized.
Reject these tokens before calling xdr_buf_trim(), giving
callers a well-defined GSS_S_DEFECTIVE_TOKEN error and
keeping the xdr_buf internally consistent. The wrapped blob
begins at a nonzero offset -- both callers pass len as
offset + opaque_len -- so buf->len still counts the offset
bytes that precede the blob. Compare the trim length
against the remaining wrapped segment, buf->len - offset,
rather than the whole buffer; comparing against buf->len
alone leaves an offset-wide window in which an oversized ec
passes the test and xdr_buf_trim() cuts into the bytes ahead
of the blob.
Fixes: cf4c024b9083 ("sunrpc: trim off EC bytes in GSSAPI v2 unwrap")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-1-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ameer Hamza <ameer.hamza@truenas.com>
Date: Wed Jul 22 23:20:11 2026 +0500
SUNRPC: Restore NUMA_NO_NODE for svc thread allocations in global mode
commit 0574da29ae12be7714df217c4ce7ff6ba9b0c23b upstream.
Commit d57e43b72bf2 ("SUNRPC: Update svcxdr_init_decode() to call
xdr_set_scratch_folio()") changed svc_pool_map_get_node() to return
numa_mem_id() instead of NUMA_NO_NODE, because __folio_alloc_node()
cannot accept NUMA_NO_NODE. That return value is not equivalent: it
is evaluated in the context of the task creating the nfsd threads,
once per thread created, and it is passed to kthread_create_on_node()
and to the per-thread allocations in svc_prepare_thread().
Since commit d1a89197589c ("kthread: Default affine kthread to its
preferred NUMA node"), the node argument of kthread_create_on_node()
no longer only places the task structure and stack: a kthread created
with a real node id normally affines itself to that node's CPUs when
it is first woken to run its thread function. All nfsd threads are
typically started together, by one task writing to
/proc/fs/nfsd/threads, so under the default pool_mode=global each
nfsd thread is now affined to the local-memory node of the CPU its
creating iteration happened to run on - typically the same node for
every thread. The CPUs of the other nodes are then unable to run
nfsd at all, and the threads' allocations - svc_rqst structures,
page pointer arrays, newly allocated task stacks, and the per-RPC
pages allocated at run time - all prefer that one node.
Restore the NUMA_NO_NODE behaviour that global mode has had since
commit 11fd165c68b7 ("sunrpc: use better NUMA affinities"), and
handle NUMA_NO_NODE at the one call site that cannot take it by
resolving it to numa_mem_id() there, exactly as alloc_pages_node()
did for the scratch page before the conversion. The mapped percpu
and pernode branches are unchanged. Unpooled services such as lockd
and the NFS client callback service also take this fallback when no
percpu or pernode map is active, restoring their thread placement in
that case.
A bisect of a 2x NFS READ throughput regression between v6.17 and
v6.18 converged on d57e43b72bf2. On the affected 4-node server every
nfsd thread comes up with its CPU affinity restricted to the CPUs of
a single node; with this change the threads are runnable on all CPUs
again and the observed regression is resolved.
Fixes: d57e43b72bf2 ("SUNRPC: Update svcxdr_init_decode() to call xdr_set_scratch_folio()")
Cc: stable@vger.kernel.org
Signed-off-by: Ameer Hamza <ameer.hamza@truenas.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260722182012.2063936-1-ameer.hamza@truenas.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeff Layton <jlayton@kernel.org>
Date: Mon Jul 6 09:29:21 2026 -0400
sunrpc: route to a populated pool in svc_pool_for_cpu()
commit f6310491c4cdb88af73aa551ec9df1f10a90c709 upstream.
svc_set_num_threads() spreads the requested threads evenly across the
service's pools (base = nrservs / sv_nrpools). When a service runs
fewer threads than it has pools -- e.g. an nfsd configured with fewer
threads than the host has NUMA nodes while running in "pernode" or
"percpu" mode -- the trailing pools are left with no threads at all.
svc_xprt_enqueue() selects a pool from the CPU servicing the transport,
queues the transport on that pool's sp_xprts, and only wakes a thread
from the same pool. Each thread services exclusively its own pool, so a
transport that lands on a threadless pool is enqueued on sp_xprts and
never picked up: the connection hangs indefinitely.
Have svc_pool_for_cpu() skip pools that currently have no threads,
falling back to the next populated pool. This trades NUMA locality for
a guarantee that the work is actually serviced. sp_nrthreads is only
updated under the service mutex; the lockless read here is a best-effort
routing hint, so annotate it with data_race().
Fixes: bfd241600a3b ("[PATCH] knfsd: make rpc threads pools numa aware")
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260706-sunrpc-pool-mode-v5-1-6c4ee7cd89aa@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 23 21:02:10 2026 -0400
SUNRPC: svcauth_gss: enforce krb5 token minimum length
commit a919c5c88769cf8fb3ec071e6078d830bf512489 upstream.
svcauth_gss_unwrap_priv() validates only an upper bound on the
wire-supplied opaque length before handing the buffer to
gss_unwrap():
if (len > xdr_stream_remaining(xdr))
goto unwrap_failed;
offset = xdr_stream_pos(xdr);
...
maj_stat = gss_unwrap(ctx, offset, offset + len, buf);
The wire value `len` flows unchanged as the upper bound into the
krb5 unwrap path, so a len in [0, 16] passes this check and is
handed to gss_unwrap(). For a krb5 v2 context that lands in
gss_krb5_unwrap_v2(), which reads the 16-byte RFC 4121 token
header fields at ptr+4 and ptr+6 and then calls rotate_left()
before any integrity check. With a sub-header length the header
reads run past the token, and _rotate_left()'s `shift %= buf->len`
path can divide by zero when buf->len has been driven to zero by
the truncated token. A header-only token (len == 16) is equally
invalid: with a non-zero RRC field and the opaque blob ending at
the XDR buffer boundary, rotate_left() builds a zero-length
subbuffer, reaching the same division.
Reject the token at the server entry point before it reaches the
krb5 unwrap core. A valid sealed RFC 4121 token must contain
the 16-byte header plus at least some encrypted payload.
Fix by adding a minimum-length check immediately after the
existing upper-bound check:
if (len <= GSS_KRB5_TOK_HDR_LEN)
goto unwrap_failed;
Fixes: 7c9fdcfb1b64 ("[PATCH] knfsd: svcrpc: gss: server-side implementation of rpcsec_gss privacy")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260524010213.557424-2-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Sun Aug 9 17:07:48 2026 +0000
SUNRPC: wait for in-flight client TLS handshake callback
commit a89dd597458848b463d284b15e42a8078beeb046 upstream.
xs_tls_handshake_sync() gives xs_tls_handshake_done() a reference to the
lower transport before submitting the handshake request. On timeout or
signal, the synchronous waiter drops that reference after calling
tls_handshake_cancel().
handshake_req_cancel() returns false when handshake_complete() has
already marked the request complete. In that case the completion callback
can still be running, so dropping the callback-owned reference in the
waiter can free the lower transport before xs_tls_handshake_done() stores
xprt_err or drops its own reference.
If cancellation loses to completion, wait until xs_tls_handshake_done()
signals handshake_done and let the callback release its reference. This
mirrors the server-side handshake lifetime handling and keeps the timeout
or signal return value unchanged.
Fixes: 75eb6af7acdf ("SUNRPC: Add a TCP-with-TLS RPC transport class")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Sat May 23 21:02:12 2026 -0400
SUNRPC: xdr_buf_trim: clamp buf->len to avoid underflow
commit 3f491306dcb673ff5e78e1044ba450c58978774e upstream.
xdr_buf_trim() trims `len` bytes from the tail of an xdr_buf by
walking the tail, pages, and head iovecs. Each per-section step
uses min_t() so it never removes more bytes than that section
holds, but the final accounting at the fix_len label subtracts the
total bytes actually consumed from buf->len without any clamp:
fix_len:
buf->len -= (len - trim);
When the caller has set buf->len to a value smaller than the sum
of the iov_lens, (len - trim) can exceed buf->len and the unsigned
subtraction wraps to near UINT_MAX. gss_krb5_unwrap_v2() reaches
xdr_buf_trim() in exactly that state:
buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip);
xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
buf->len is a small wire-derived value while the iov_lens are at
page scale, so the per-section loops legitimately consume far more
bytes than buf->len records. The wrapped buf->len then propagates
as the authoritative stream bound into every downstream XDR
decoder.
Fix by clamping the decrement so buf->len bottoms out at zero:
buf->len -= min_t(unsigned int, buf->len, len - trim);
On the normal path where the iov_lens sum to buf->len, (len - trim)
is always <= buf->len and the result is identical to before. No
callers change behavior outside the underflow case.
Fixes: 4c190e2f913f ("sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260524010213.557424-4-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Thu May 28 15:32:12 2026 -0400
SUNRPC: Zero rpc_gss_wire_cred at svcauth_gss_decode_credbody() entry
commit 11539e8fcce0b0af062ae5fecf7b3676c2f7aeed upstream.
svcauth_gss_decode_credbody() writes the caller's
rpc_gss_wire_cred field by field and assigns gc_ctx.len only on
the success tail. The caller storage is svcdata->clcred, which
lives in the per-svc_rqst gss_svc_data and is reused across
requests. Early decode failures leave partially decoded state
mixed with residue from the prior request.
The trailing body_len tightness check is the sharpest case:
xdr_stream_decode_opaque_inline() has already written gc_ctx.data
with a borrowed inline pointer into the current request's XDR
pages, but gc_ctx.len retains its prior value. Once the request
pages are released the pooled clcred carries a dangling pointer
paired with a stale length.
Zero the caller's rpc_gss_wire_cred at function entry so that
every early-return path leaves a deterministic all-zero cred.
On the trailing tightness-check path, gc_ctx.len is now zero
instead of stale, which neuters length-driven consumers such as
gss_svc_searchbyctx() that would otherwise walk the dangling
data pointer.
Fixes: b0bc53470d1a ("SUNRPC: Convert the svcauth_gss_accept() pre-amble to use xdr_stream")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <clm@meta.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260528-tier2-v1-5-d026a1415e0b@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Tue May 26 09:35:56 2026 -0400
svcrdma: Fix offset arithmetic in read_chunk_range
commit 4a44c140cc2f3643a39e258bb0c0ab9d0f494f5e upstream.
svc_rdma_read_chunk_range() walks a Read chunk's segment list to
build a sub-range starting at byte offset and spanning length bytes
for a Position-Zero or Call chunk. Two arithmetic defects in the
per-segment loop produce wrong DMA lengths and a u32 underflow:
pcl_for_each_segment(segment, chunk) {
if (offset > segment->rs_length) {
offset -= segment->rs_length;
continue;
}
dummy.rs_handle = segment->rs_handle;
dummy.rs_length = min_t(u32, length,
segment->rs_length) - offset;
dummy.rs_offset = segment->rs_offset + offset;
First, the skip predicate uses '>' instead of '>='. When offset
equals the segment's full rs_length, the segment is fully consumed
and should be skipped, but the loop falls through into the body.
The resulting dummy.rs_length is min_t(u32, length, rs_length) -
rs_length, which underflows to a near-UINT_MAX u32 when length is
smaller than rs_length, or is zero otherwise.
Second, the length formula subtracts offset from the min_t() result
rather than from segment->rs_length before the cap. For offset > 0
the segment's residual is rs_length - offset, not rs_length, so the
cap must be applied to the residual. With the current bracketing,
whenever length is smaller than rs_length - offset the per-segment
length becomes length - offset instead of length, silently dropping
offset bytes from the rebuilt chunk. Combined with the boundary
case above it also enables the u32 underflow path, which propagates
a huge nr_bvec into svc_rdma_build_read_segment() and a multi-MiB
kmalloc_array_node() in svc_rdma_get_rw_ctxt().
Additionally, svc_rdma_read_call_chunk() can invoke this function
with length == 0 when the last Read chunk ends exactly at the end
of the Call chunk. With the corrected >= predicate, every segment
is skipped and the function returns the initial -EINVAL, rejecting
a valid request. Return success immediately when length is zero.
Also break out of the loop once length is fully consumed to avoid
passing zero-length segments to svc_rdma_build_read_segment().
Fix by using '>=' so a fully-consumed segment is skipped, by
moving '- offset' inside min_t() so the cap is applied to the
segment's residual length, by returning success for zero-length
requests, and by stopping iteration when the requested range has
been consumed.
Fixes: d7cc73972661 ("svcrdma: support multiple Read chunks per RPC")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-rpc-kernel-bugs-v1-2-e251306ccca9@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Tue May 26 09:35:58 2026 -0400
svcrdma: Fix pcl_for_each_segment for empty chunks
commit b7713a784c59515d0aba558c8f5df6a0164dd3a9 upstream.
When a parsed chunk list contains a chunk whose ch_segcount is zero,
pcl_for_each_segment computes its inclusive upper bound as
&chunk->ch_segments[ch_segcount - 1]. ch_segcount is u32, so the
subtraction wraps to 0xFFFFFFFF and the bound lands far past the
ch_segments flex array. The loop body then walks unrelated memory at
sizeof(struct svc_rdma_segment) stride until it faults.
A zero-segcount chunk is reachable from the wire:
xdr_check_write_chunk() only rejects segcount values greater than
rc_maxpages, and pcl_alloc_write() links a freshly allocated chunk
onto rc_write_pcl/rc_reply_pcl before its segment-fill loop runs,
so a Write or Reply chunk advertising zero segments leaves
ch_segcount == 0 on the list. When the transport has negotiated
Send-With-Invalidate, svc_rdma_get_inv_rkey() iterates all four
PCLs with pcl_for_each_segment and dereferences segment->rs_handle
on each iteration, turning the underflow into an out-of-bounds read
and a general protection fault.
xdr_check_write_list / xdr_check_reply_chunk
pcl_alloc_write()
chunk = pcl_alloc_chunk(...) /* ch_segcount = 0 */
list_add_tail(&chunk->ch_list, &pcl->cl_chunks)
/* fill loop iterates zero times for wire segcount 0 */
svc_rdma_get_inv_rkey()
pcl_for_each_chunk(rc_write_pcl)
pcl_for_each_segment(segment, chunk)
pos <= &ch_segments[0u - 1u] /* 0xFFFFFFFF */
segment->rs_handle /* OOB read -> GPF */
Fix by switching the macro to a half-open upper bound that uses
ch_segcount directly. For ch_segcount == 0 the loop start equals the
loop end and the body is skipped; for ch_segcount > 0 the iteration
range is unchanged. All six existing call sites in
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c and
net/sunrpc/xprtrdma/svc_rdma_rw.c remain correct under the new bound,
so no caller changes are needed.
Fixes: 78147ca8b4a9 ("svcrdma: Add a "parsed chunk list" data structure")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-rpc-kernel-bugs-v1-4-e251306ccca9@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Wed May 27 11:00:11 2026 -0400
svcrdma: Fix unmatched rn_unregister on failed accept
commit 26190394c64c9429481fc88a4738f70bb92fb352 upstream.
When svc_rdma_accept() takes the errout path before
rpcrdma_rn_register() has succeeded, the existing cleanup block
calls rpcrdma_rn_unregister(dev, &newxprt->sc_rn) unconditionally.
svcxprt_rdma is kzalloc'd, so on that path sc_rn.rn_index is 0 and
sc_rn.rn_done is NULL; the unregister therefore xa_erase()s another
caller's slot 0 and performs an unmatched kref_put() on the
rpcrdma_device's rd_kref.
The same errout also brackets the cleanup with svc_xprt_get()/
svc_xprt_put() around the kref_init() birth reference. The kref
goes 1 -> 2 -> 1 and never reaches 0, so the svcxprt_rdma (and the
net/ns_tracker it pinned) is leaked on every failed accept.
rpcrdma_rn_register() writes rn->rn_done last, only after xa_alloc()
and kref_get() have both succeeded, so rn_done == NULL is a natural
"never registered" sentinel. Guard rpcrdma_rn_unregister() with an
early return when rn_done is NULL, and clear rn_done before the
matching xa_erase() so a repeated unregister is also a no-op.
With that guard in place, the accept errout drops the kref_init()
birth reference via svc_xprt_put(), which dispatches svc_rdma_free().
Teardown of sc_qp, sc_sq_cq, sc_rq_cq, and sc_pd runs under existing
IS_ERR/NULL guards in svc_rdma_free(); sc_rn is covered by the new
rn_done sentinel; sc_cm_id is non-NULL on every errout path because
svc_rdma_accept() dereferences it above the first goto errout.
svc_xprt_free() drops the module reference associated with the freed
transport, and svc_handle_xprt() drops its pre-acquired reference
when ->xpo_accept() returns NULL. Take a replacement module reference
before svc_xprt_put() so the two module_put()s remain balanced.
The rn_done guard also covers svc_rdma_free()'s non-listener call
to rpcrdma_rn_unregister() for transports whose register attempt
failed or never ran.
Fixes: 8ac6fcae5dc0 ("svcrdma: Unregister the device if svc_rdma_accept() fails")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260527-rdma-follow-on-v1-1-1b09bd87b6cd@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Wed May 27 11:00:14 2026 -0400
svcrdma: Reject connection when transport allocation fails
commit 0944462247dcb7de7622cdaaadf5f05c52707dab upstream.
handle_connect_req() returns without action when
svc_rdma_create_xprt() fails to allocate the new transport.
The CM core returns 0 for CONNECT_REQUEST events, so it does
not destroy the new rdma_cm_id. Each allocation failure under
memory pressure leaks one rdma_cm_id, and a remote peer driving
connection attempts can amplify this.
Reject the connection by returning a non-zero status from the
CM event handler, which tells the CM core to destroy the
orphaned cm_id.
Fixes: 377f9b2f4529 ("rdma: SVCRDMA Core Transport Services")
Cc: stable@vger.kernel.org
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260527-rdma-follow-on-v1-4-1b09bd87b6cd@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Mon Jun 22 21:47:28 2026 -0400
svcrdma: Reject inline replies that overflow the pull-up buffer
commit 0fbe20dfe74b783d255bf389a6ea77aa25dc7860 upstream.
An RPC-over-RDMA client can request a reply, such as an NFS READ
payload, without providing a Write list or a Reply chunk to carry
it. When such a reply needs more scatter/gather entries than the
device's Send Queue supports, svc_rdma_pull_up_needed() selects
pull-up and svc_rdma_pull_up_reply_msg() linearizes the whole
reply into sctxt->sc_xprt_buf. That buffer is only sc_max_req_size
bytes, while the reply on this path is bounded only by the client's
request, so svc_rdma_xb_linearize() copies past the end of the
buffer and corrupts adjacent slab memory. The oversized length is
then stored in sc_sges[0].length and posted, so the device also
reads beyond the mapped region.
The SGE-exhaustion branch is the only pull-up path that can exceed
the buffer: the threshold branch pulls up only replies smaller
than RPCRDMA_PULLUP_THRESH, and replies that fit the device's SGE
budget are sent directly without linearization. Make
svc_rdma_pull_up_needed() report -E2BIG when the reply it would
pull up cannot fit sc_max_req_size, and fail the request with
ERR_CHUNK as RFC 8166 Section 4.5.3 directs rather than dropping
the connection.
The helper no longer answers a simple yes/no question: it now
reports pull-up, no pull-up, or -E2BIG for a reply too large to
linearize. Rename svc_rdma_pull_up_needed() to
svc_rdma_check_pull_up() so its name no longer implies a boolean
predicate.
Fixes: e248aa7be86e ("svcrdma: Remove max_sge check at connect time")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <clm@meta.com>
Assisted-by: kres:claude-opus-4-7
Link: https://patch.msgid.link/20260623014728.826032-1-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chris Mason <clm@meta.com>
Date: Tue May 26 09:35:59 2026 -0400
svcrdma: Reject Write/Reply chunks with segcount 0
commit 9808eb7656666acc7291bae9ab6b987bd16e47e0 upstream.
A peer can send a Write or Reply chunk whose segcount field is zero.
xdr_check_write_chunk() only rejects segcount > rc_maxpages, so zero
passes the range check, and xdr_inline_decode(stream, 0) returns the
current (non-NULL) cursor without advancing. The function returns
true and pcl_alloc_write() then links a struct svc_rdma_chunk with
ch_segcount == 0 onto rc_write_pcl or rc_reply_pcl.
An earlier patch in this series made pcl_for_each_segment() safe for
ch_segcount == 0, so this no longer drives the memory walk it used
to. Rejecting the malformed frame at the decode boundary is still
worthwhile as defense in depth: it keeps degenerate zero-segment
chunks off the parsed chunk lists entirely, so any future consumer
that walks ch_segments directly cannot observe one, and it makes the
zero-floor easy to backport to trees where the macro change is more
intrusive. RFC 8166 has no meaning for a Write/Reply chunk that
describes no remote buffer, so no legitimate client is affected.
xdr_check_reply_chunk() funnels Reply chunks through
xdr_check_write_chunk() and inherits the same rejection.
pcl_alloc_write() also links each chunk onto the parsed chunk list
before filling its segment array. If a future change weakens the
segcount-0 rejection, an incomplete chunk is visible to consumers
during the fill loop. Reorder so that list_add_tail() follows the
segment fill loop, ensuring only fully-populated chunks appear on
the list.
Fixes: 78147ca8b4a9 ("svcrdma: Add a "parsed chunk list" data structure")
Cc: stable@vger.kernel.org
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-rpc-kernel-bugs-v1-5-e251306ccca9@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chuck Lever <cel@kernel.org>
Date: Tue May 26 09:35:55 2026 -0400
svcrdma: Validate Read chunk positions before reconstruction
commit 3779b7b9e7d1c8ba4738f9d327de3b0288cefe9b upstream.
The RPC/RDMA Read chunk position field is supplied by the remote
client and stored verbatim in the parsed chunk list.
xdr_count_read_segments() checks only 4-byte alignment; it never
compares the position against the received inline body length.
In the single-chunk path, svc_rdma_read_complete_one() splits the
head and tail kvecs at ch_position. A position past the inline
body underflows the tail length, exposing adjacent slab memory to
the upper XDR decoder.
In the multi-chunk path, svc_rdma_read_multiple_chunks() computes
gap lengths between chunks as unsigned subtractions from
ch_position. Overlapping Read chunks cause these subtractions to
underflow. A final position past the inline body likewise
underflows the trailing gap length. svc_rdma_copy_inline_range()
then copies past the receive buffer into request pages that are
returned to the client through the Reply channel.
Bound inline-range copies in svc_rdma_copy_inline_range() against
the decoded inline RPC body saved in rc_saved_arg. Reject a
single Read chunk positioned beyond that body, and reject
multi-chunk lists where accumulated read bytes exceed the next
chunk's position. Apply the same position and overlap checks in
the call-chunk interleaving path.
Fixes: d96962e6d0e2 ("svcrdma: Use the new parsed chunk list when pulling Read chunks")
Cc: stable@vger.kernel.org
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260526-rpc-kernel-bugs-v1-1-e251306ccca9@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Oleg Nesterov <oleg@redhat.com>
Date: Mon Jul 20 13:13:43 2026 +0200
sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]
commit 7170ca01623b399c97f2ae9d3e228badc1f25ea3 upstream.
cad_pid is global, and kill_cad_pid() is only used in the root namespace.
However, due to pid_table_root_permissions(), a non-root user can unshare
pid/user namespaces and modify it from the child namespace. This makes no
sense and is simply wrong.
Move it to kern_reboot_table[] where it logically belongs; this ensures
that only GLOBAL_ROOT_UID can read/modify this sysctl.
Note that this patch doesn't preserve "#ifdef CONFIG_PROC_SYSCTL" around
the "cad_pid"; CONFIG_PROC_SYSCTL selects CONFIG_SYSCTL, so it is always
set when kern_reboot_table[] is compiled.
Cc: stable@vger.kernel.org
Fixes: e054bcbe7e7a ("sysctl: move cad_pid into kernel/pid.c")
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Alexey Gladkov <legion@kernel.org>
Reviewed-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Joel Granados <joel.granados@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bradley Morgan <include@grrlz.net>
Date: Thu Jul 23 21:09:22 2026 +0000
taskstats: fix cpumask parsing cutting off the last character
commit 1f58a5335cdd14b3fb5f2a5d3763dee1f5cba1d3 upstream.
parse() hands nla_strscpy() len as dstsize, and nla_strscpy() copies at
most dstsize - 1 bytes. When the attr payload comes in without a trailing
NUL, srclen == len >= dstsize and the last character of the cpumask string
gets cut off. Register "0-15" and you are silently listening on "0-1",
exit data for the rest never shows up.
The bug only bites when the sender doesn't NUL terminate the payload;
senders that include the NUL were always fine (srclen gets decremented for
the trailing NUL, so srclen < dstsize). Thats probably why this survived
20 years. And the policy is NLA_STRING, not NLA_NUL_STRING, so a payload
without the trailing NUL is legit input here.
Skip the kmalloc/nla_strscpy dance entirely and use nla_strdup(), which
already allocates srclen + 1 and terminates. The nla_len() bounds checks
stay as they were.
Link: https://lore.kernel.org/EC49FE41-7F5F-41E0-A07A-ABEB8ECA514D@grrlz.net
Fixes: f9fd8914c1ac ("[PATCH] per-task delay accounting taskstats interface: control exit data through cpumasks")
Signed-off-by: Bradley Morgan <include@grrlz.net>
Reported-by: Oleg Deomi <oleg.deomi@gmail.com>
Closes: https://lore.kernel.org/CAByWkfZ6b1=3H9pwkz-dDQOs9cZaF-HYQ6b9Yb0=Hq2r1Vv_Pw@mail.gmail.com
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thomas Weißschuh (Schneider Electric) <thomas.weissschuh@linutronix.de>
Date: Fri Jul 31 16:17:43 2026 +0200
timekeeping: Check the return value of tk_get_aux_ts64 in __do_adjtimex()
commit 4b61084b11bcecce86d03804ff30f8d7b465593c upstream.
If the auxiliary clock is disabled during tk_get_aux_ts64() but is enabled
before tks->clock_valid is checked, then uninitialized stackdata will be
used in the calculations and indirectly leaked to userspace.
The same race window also exists after this change and also for the core
timekeeper. But in these cases the only effect would be incorrect
adjustments and this is userspace's responsibility to avoid this.
Fixes: 4eca49d0b621 ("timekeeping: Prepare do_adtimex() for auxiliary clocks")
Signed-off-by: Thomas Weißschuh (Schneider Electric) <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260731-timekeeping-aux-adjtimex-return-v1-1-b7fea4692886@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Thomas Gleixner <tglx@kernel.org>
Date: Tue Aug 18 00:14:57 2026 +0200
timer: Keep debugobjects state consistent in migrate_timer_list()
commit c793bbfc4a0a9f5a66978fc91559e9681748dbeb upstream.
When timers are migrated away from an offline CPU the debugobjects state
gets corrupted. The timer is accounted as inactive on deletion, but the
enqueue on the alive CPU lacks the activation call.
That used to work, but got broken when the trace point and the debug
objects call got separated. That change missed to fixup
migrate_timer_list().
Add the missing debug_timer_activate() invocation to fix it.
Fixes: dc1e7dc5ac62 ("timer: Move trace point to get proper index")
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/87bjb0l7ha.ffs@fw13
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Sun Aug 9 19:04:16 2026 +0000
timers/itimer: Zero-init old itimerval before copy to userspace
commit 18c7d85864e554adc8fad1e8d2e9d2cb6c3911c8 upstream.
On native sparc64, struct __kernel_old_timeval contains a four-byte hole
after tv_usec because tv_sec is 64-bit while __kernel_suseconds_t is 32-bit.
put_itimerval() fills only the named fields in a stack-allocated
__kernel_old_itimerval and copies the entire object to userspace, so
getitimer() can expose the two padding holes.
Zero-initialize the aggregate before assigning the fields so implicit
padding is deterministic before it crosses the user/kernel boundary.
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Assisted-by: Codex:gpt-5
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260809190428.1523014-1-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joy H.J. Lee <rkr0k0r@gmail.com>
Date: Thu Jul 2 05:06:35 2026 +0900
tools/compiler: match glibc 2.42 definition of __attribute_const__
commit 8700a4761beb219873956666cf91776a2c61e698 upstream.
glibc 2.42 added __attribute_const__ to sys/cdefs.h:
# define __attribute_const__ __attribute__ ((__const__))
GCC 15 warns when a macro is redefined to a different replacement list
(-Wbuiltin-macro-redefined). Since host tool Makefiles (resolve_btfids,
objtool) pass -Werror, this conflict becomes fatal.
The warning is suppressed on standard native builds because GCC treats
/usr/include as a system header path (-isystem), and macro-redefinition
warnings from system headers are silently suppressed by GCC. It fires
when glibc headers are on a regular include path (-I) instead, which
is the case in cross-compilation setups such as NixOS, where the
sysroot's glibc is passed explicitly via -I rather than -isystem.
Per (C11 6.10.3), identical replacement lists are accepted silently.
Match the glibc definition exactly, including the space before "((", so
the redefinition is accepted without warning regardless of whether
glibc headers are treated as system or non-system includes.
Link: https://lore.kernel.org/20260701200635.3992767-1-rkr0k0r@gmail.com
Signed-off-by: Joy H.J. Lee <rkr0k0r@gmail.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: David Laight <david.laight.linux@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Myeonghun Pak <mhun512@gmail.com>
Date: Fri Jun 26 19:35:52 2026 +0300
tpm: tpm_i2c_nuvoton: disable IRQ on wait timeout
commit 705c4ed0643366963547b2616d53165f2519c81f upstream.
i2c_nuvoton_wait_for_stat() enables the IRQ before waiting for the
interrupt handler to report a status change. If the wait times out, or is
interrupted before the handler runs, the function returns without
balancing the enable_irq() call.
Disable the IRQ before leaving the failed wait path. Also preserve an
interrupted wait's original error code instead of converting it to
-ETIMEDOUT inside the helper.
Cc: stable@vger.kernel.org # v5.10+
Fixes: 4c336e4b1556 ("tpm: Add support for the Nuvoton NPCT501 I2C TPM")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260626091653.54929-1-mhun512@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Date: Thu Aug 27 18:43:22 2026 +0000
tracing/user_events: Clear copied tracing state before fork duplication
commit 390f6bd8583d177029d9df4bea6667509e55a765 upstream.
dup_task_struct() copies user_event_mm from the parent into the child,
without grabbing a reference to it. user_event_mm_dup() should
replace it, but it leaves that copied pointer unmodified if
user_event_mm_alloc() fails.
When the child exits, user_event_mm_remove() decrements a reference
the child never owned, which ultimately frees user_event_mm, while
the parent still as a stale pointer to it. This creates a UAF, which
KASAN reports as:
BUG: KASAN: slab-use-after-free in
current_user_event_mm+0x51/0x1d0 Write of size 4 at addr
ffff888005010d30 by task init/44
Call Trace:
<TASK>
kasan_report+0xce/0x100
kasan_check_range+0x10f/0x1e0
current_user_event_mm+0x51/0x1d0
user_events_ioctl+0x82e/0x15c0
__x64_sys_ioctl+0x139/0x1c0
do_syscall_64+0xce/0x450
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Allocated by task 44:
__kasan_kmalloc+0x8f/0xa0
__kmalloc_cache_noprof+0x180/0x3a0
user_event_mm_alloc+0x3c/0x1f0
current_user_event_mm+0x88/0x1d0
Freed by task 42:
__kasan_slab_free+0x43/0x70
kfree+0x13a/0x390
process_one_work+0x696/0xf90
worker_thread+0x420/0xba0
The fix simply clears the copied pointer before any possible failure.
In case of failure, the child then has nothing to free.
Cc: stable@vger.kernel.org
Fixes: 7235759084a4 ("tracing/user_events: Use remote writes for event enablement")
Link: https://patch.msgid.link/20260827184321.2964601-2-Jeremy.Jean@oss.cyber.gouv.fr
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hui Su <sh_def@163.com>
Date: Mon Aug 17 20:06:44 2026 +0800
tracing: Fix crash passing ERR_PTR to kthread_stop()
commit 649bc7df3e5d7be6f7996a95084037dbf3cad1e5 upstream.
event_test_stuff() calls kthread_run() and unconditionally passes the
returned task_struct pointer to kthread_stop(). kthread_run() returns an
error pointer such as ERR_PTR(-ENOMEM) when kthread creation fails, for
example under memory pressure during the boot-time event self-test.
kthread_stop() then dereferences the invalid pointer, crashing the kernel.
Check the result of kthread_run() before passing it to kthread_stop(). Use
WARN_ON() so that a failure to create the self-test thread does not go
unnoticed, matching the ring-buffer self-test fix in commit
91542863abad ("ring-buffer: Fix crash passing ERR_PTR to kthread_stop()").
Cc: stable@vger.kernel.org
Fixes: e6187007d6c3 ("tracing/events: add startup tests for events")
Link: https://patch.msgid.link/20260817120642.668375-3-sh_def@163.com
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Vincent Donnefort <vdonnefort@google.com>
Date: Fri Aug 7 09:54:23 2026 +0100
tracing: Fix logged instance name on creation failure
commit a9a01be2834a529cbd490ccbab02643f0c1735f2 upstream.
When boot instance creation fails, the kernel incorrectly logs "(null)"
as the instance name because strsep() consumes curr_str entirely during
parsing.
Print the properly parsed name variable instead. And while at it log
the error code.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260807085423.4175161-1-vdonnefort@google.com
Fixes: cb1f98c5e574 ("tracing: Add creation of instances at boot command line")
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Deepanshu Kartikey <kartikey406@gmail.com>
Date: Mon Aug 17 19:36:55 2026 +0530
tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
commit 372f8534244d632ad5118e8a87a11291b01712d3 upstream.
Writing to buffer_subbuf_size_kb calls ring_buffer_subbuf_order_set(),
which frees every sub-buffer of the ring buffer, including the reader
page, and replaces them with newly allocated ones.
Readers of trace_pipe hold pointers into those pages. ring_buffer_peek()
looks up an event under cpu_buffer->reader_lock but returns the event
pointer after dropping the lock, and peek_next_entry() then calls
ring_buffer_event_length() and ring_buffer_event_data() on it. If the
sub-buffer order is changed in that window, the reader dereferences
freed memory:
BUG: KASAN: use-after-free in ring_buffer_peek+0x3e0/0x430
Read of size 1 at addr ffff88802a4cf010 by task syz-executor989/6002
Freed by:
free_buffer_page kernel/trace/ring_buffer.c:398 [inline]
ring_buffer_subbuf_order_set+0x1325/0x18e0 kernel/trace/ring_buffer.c:7444
buffer_subbuf_size_write+0x182/0x280 kernel/trace/trace.c:8221
Take trace_access_lock(RING_BUFFER_ALL_CPUS) around the order change.
This is the lock trace_pipe readers already hold across their entire
peek-and-print loop, so the swap can no longer race with a reader that
is dereferencing a peeked event.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260817140655.5694-1-kartikey406@gmail.com
Fixes: f9b94daa542a ("ring-buffer: Set new size of the ring buffer sub page")
Reported-by: syzbot+685955db58555575fdd2@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=685955db58555575fdd2
Tested-by: syzbot+685955db58555575fdd2@syzkaller.appspotmail.com
Reviewed-by: Bradley Morgan <include@grrlz.net>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Hui Su <sh_def@163.com>
Date: Sun Aug 16 18:04:29 2026 +0800
tracing: Fix use-after-free with same-name named triggers
commit a7318172aa332a161fb9618286e64454c827f8fd upstream.
When two hist triggers on different events are registered with the same
name=, the second one reuses the first as named_data. Both are added to
tr->hist_vars by save_hist_vars() during event_hist_trigger_parse(),
because save_hist_vars() is called before event_trigger_register() while
the named reuse is only detected later, in hist_register_trigger().
In the named-data branch hist_register_trigger() then frees the second
histogram's hist_data via destroy_hist_data(), but never removes its
tr->hist_vars list entry, leaving a dangling pointer and leaking the
trace_array reference it holds.
A later hist trigger that references a variable makes find_var_file()
walk tr->hist_vars and dereference the freed hist_data. The bug is
reproducible from userspace by writing three hist triggers to tracefs:
cd /sys/kernel/tracing
echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_switch/trigger
echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_process_fork/trigger
echo 'hist:keys=common_pid:vals=$x' > events/sched/sched_process_exit/trigger
The third write panics the kernel:
BUG: KASAN: slab-use-after-free in find_var_file.part.0+0x272/0x290
Read of size 8 at addr ffff888001f8a0e0 by task sh/1
CPU: 1 UID: 0 PID: 1 Comm: sh Tainted: G D N
Call Trace:
find_var_file.part.0
find_event_var
parse_atom
parse_expr
__create_val_field
event_hist_trigger_parse
trigger_process_regex
event_trigger_write
vfs_write
ksys_write
do_syscall_64
entry_SYSCALL_64_after_hwframe
Allocated by task 1:
event_hist_trigger_parse
Freed by task 1:
hist_register_trigger+0x618/0xa30
event_hist_trigger_parse
The buggy address belongs to freed 2048-byte region
Oops: general protection fault ... RIP: find_var_file.part.0
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
Fix by removing the hist_data from tr->hist_vars and releasing the
trace_array reference in the named-data branch of hist_register_trigger()
before freeing the hist_data.
Cc: stable@vger.kernel.org
Fixes: 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers list")
Link: https://patch.msgid.link/20260816100427.33642-3-sh_def@163.com
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Ibrahim Hashimov <security@auditcode.ai>
Date: Fri Jul 24 09:43:27 2026 +0200
ubifs: fix out-of-bounds read in signature length check
commit 95d27c1708bb6e8823c8e7c623f9abc2a91bf4bf upstream.
ubifs_sb_verify_signature() bounds the on-disk ubifs_sig_node->len field
before handing the signature payload to verify_pkcs7_signature(), but the
check has the wrong sign:
if (le32_to_cpu(signode->len) > snod->len + sizeof(struct ubifs_sig_node))
The signature bytes start sizeof(struct ubifs_sig_node) (UBIFS_SIG_NODE_SZ,
64 bytes) into the node, so the payload is at most
snod->len - sizeof(struct ubifs_sig_node)
bytes long. Adding the header size instead of subtracting it accepts a
declared length up to 2 * UBIFS_SIG_NODE_SZ larger than the node actually
holds -- past the end of c->sbuf, which is vmalloc(c->leb_size).
verify_pkcs7_signature() -> pkcs7_parse_message() -> asn1_ber_decoder()
is then handed that inflated length and reads beyond the allocation while
walking the DER headers. The node length comes straight from the mounted
image, so a crafted signed UBIFS image reaches this via
ubifs_read_superblock() before the signature is cryptographically checked.
snod->len is guaranteed to be >= UBIFS_SIG_NODE_SZ by the node scanner
(c->ranges[UBIFS_SIG_NODE].min_len == UBIFS_SIG_NODE_SZ), so the corrected
subtraction cannot underflow. Legitimately signed images are unaffected: a
correct superblock never declares a signature longer than the node it is
embedded in.
Fixes: 817aa094842d ("ubifs: support offline signed images")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
Reviewed-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zhan Xusheng <zhanxusheng1024@gmail.com>
Date: Wed Jul 22 16:24:25 2026 +0800
udf: Fix i_lenExtents truncation on 32-bit kernels
commit a5a5ed23b1340ff0f32a14a7ca8585f7c4e9b2e2 upstream.
In udf_do_extend_file() the total extent length is rounded up to a block
boundary with:
iinfo->i_lenExtents = (iinfo->i_lenExtents + sb->s_blocksize - 1) &
~(sb->s_blocksize - 1);
i_lenExtents is a __u64, but sb->s_blocksize is unsigned long. On 32-bit
kernels unsigned long is 32-bit, so ~(sb->s_blocksize - 1) is a 32-bit
value (e.g. 0xfffff800 for a 2 KiB block) that is zero-extended in the AND,
clearing the upper 32 bits of i_lenExtents. For UDF files whose total
extent length exceeds 4 GiB this truncates i_lenExtents when the file is
extended, corrupting the tracked extent length.
Cast the block size to 64-bit before forming the mask. 64-bit kernels are
unaffected.
Fixes: 48d6d8ff7dca ("udf: cache struct udf_inode_info")
Cc: stable@vger.kernel.org
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Link: https://patch.msgid.link/20260722082425.213311-1-zhanxusheng@xiaomi.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: David Lee <david.lee@trailofbits.com>
Date: Wed Jul 8 10:17:09 2026 +0000
udf: reject VAT indexes equal to the entry count
commit cac0cb07f29ccfb373fd4a36c81e908ef3ce608c upstream.
UDF 1.50 virtual partition mapping uses the VAT as an array of physical
block mappings. s_num_entries stores the number of entries in that array,
not the highest valid index. The valid VAT indexes are therefore below
s_num_entries.
udf_get_pblock_virt15() currently rejects only indexes greater than
s_num_entries. A crafted image can request index s_num_entries, pass the
bounds check, and make the kernel read one entry past the allocated VAT table.
Change the check to reject block >= s_num_entries, so the count is handled as
an exclusive upper bound.
A crafted UDF image reproduced this on origin/master commit
0e35b9b6ec0ffcc5e23cbdec09f5c622ad532b53 with a KASAN slab-out-of-bounds
report in udf_get_pblock_virt15().
Trail of Bits has a reproducer that triggers kernel panic demonstrating the bug, and can share it if needed.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: David Lee <david.lee@trailofbits.com>
Assisted-by: Codex:gpt-5.5
Link: https://patch.msgid.link/20260708101712.1706564-1-david.lee@trailofbits.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Francesco Lavra <flavra@baylibre.com>
Date: Tue Jul 28 17:44:20 2026 +0200
usb: dwc2: gadget: Exit partial power down state when changing USB pull-up
commit bf1e90189a98ca4a824fd64b4f3c6043d13c98ea upstream.
When a USB host suspends a connected device, the DWC2 USB device controller
enters a partial power down state where controller registers are not
accessible. If the USB gadget is then disconnected or deactivated
(e.g. when a gadget function is unbound from the controller), the `pullup`
callback in struct usb_gadget_ops is invoked; if the controller is kept in
partial power down, the register write in dwc2_hsotg_core_disconnect() does
not take effect; as a result, the USB host keeps seeing the device as
connected, even though the device is disabled.
Properly exit partial power down state in the pullup callback, so that the
USB host detects a device disconnection as intended.
Fixes: 97861781daff ("usb: dwc2: Allow entering hibernation from USB_SUSPEND interrupt")
Cc: stable@vger.kernel.org
Signed-off-by: Francesco Lavra <flavra@baylibre.com>
Link: https://patch.msgid.link/20260728154420.2021519-1-flavra@baylibre.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Pei Xiao <xiaopei01@kylinos.cn>
Date: Wed Aug 5 09:40:49 2026 +0800
usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition
commit 9c855832790cd488d87de1885974f4c37cfe7358 upstream.
In dwc3_gadget_init_endpoint, &dep->nostream_work is bound with
dwc3_nostream_work, and dwc3_gadget_endpoint_stream_event can queue
this delayed work on system_percpu_wq when a DEPEVT_STREAM_NOSTREAM
event is received.
If we remove the gadget, dwc3_gadget_free_endpoints makes cleanup and
the memory allocated for dep with kzalloc() is released by kfree(dep),
while the delayed work mentioned above may still be pending or
running. The sequence of operations that may lead to a UAF bug is as
follows:
CPU0 CPU1
| dwc3_thread_interrupt
| dwc3_endpoint_interrupt
| dwc3_gadget_endpoint_stream_event
| queue_delayed_work(system_percpu_wq,
| &dep->nostream_work)
dwc3_gadget_free_endpoints |
dwc3_free_trb_pool(dep) |
list_del(&dep->endpoint.ep_list) |
dwc3_debugfs_remove_endpoint_dir(dep) |
kfree(dep) |
// dep is freed |
| dwc3_nostream_work
| // use dep (use-after-free)
Fix it by canceling the delayed work before kfree(dep) in
dwc3_gadget_free_endpoints.
Fixes: dcfe437492e2 ("usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior")
Assisted-by: Codex:deepseek-v4-flash
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: stable@vger.kernel.org
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/331d1d5133496d2b4184e05f8848adb06930a138.1785893865.git.xiaopei01@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sun Jul 19 04:28:39 2026 +0000
usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed
commit c27d13ce4bab80fbdf6523928071b6c24b37606c upstream.
In polled-VBUS mode (board.vbus_pin && board.vbus_polled), probe arms a
self-restarting cycle: at91_vbus_timer() schedules vbus_timer_work, and
at91_vbus_timer_work() calls at91_vbus_update() and re-arms the timer via
mod_timer(). Both recover the same udc through container_of and dereference
it on every iteration.
Neither teardown path cancels this cycle. udc is devm-allocated, so it is
freed after at91udc_remove() returns, and is likewise freed when probe
fails and devres runs. A timer callback or work item that is pending or
running at either point dereferences the freed udc.
Add at91_udc_shutdown_vbus_timer() and call it from at91udc_remove() and
from the usb_add_gadget_udc() failure path in probe; the remaining probe
error paths fail before the timer is armed. timer_shutdown_sync() waits
for a running callback and clears timer->function, which makes the work
handler's mod_timer() a permanent no-op; cancel_work_sync() then drains
any pending or running work whose re-arm attempt now does nothing. The
timer must be shut down first, since cancelling the work alone would let
the timer re-queue it. The guard mirrors probe: in IRQ mode the timer and
work_struct are never initialized.
This does not require a fault; a normal driver unbind can interleave with
an already queued work item.
This issue was found by an in-house static analysis tool.
Fixes: 4037242c4f5f ("ARM: 6209/3: at91_udc: Add vbus polarity and polling mode")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260719042839.3167094-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Neill Kapron <nkapron@google.com>
Date: Fri Jul 24 20:41:16 2026 +0000
usb: gadget: f_fs: Prevent deadlock during ep0 read loop
commit 569dd7e5dcffe1e1c6b26ca2cd3be57eb433e082 upstream.
Currently, ffs_ep0_read() holds ffs->mutex when it prepares to go to
sleep waiting for an event. When no setup events are pending, it calls
wait_event_interruptible_exclusive_locked_irq() with the mutex still
held. The wait macro deliberately drops the waitqueue spinlock before
sleeping but does not drop the mutex.
If a userspace daemon is polling ep0 via read() and the gadget is
asynchronously torn down via configfs (e.g., echo "" > UDC), a
deadlock can occur:
1. The configfs teardown calls functionfs_unbind(), which queues a
FUNCTIONFS_UNBIND event.
2. The daemon wakes up, consumes the event, and drops the mutex.
3. However, if the daemon loops and immediately issues another read()
before exiting, it reacquires ffs->mutex and again goes into an
interruptible sleep.
4. Meanwhile, functionfs_unbind() continues execution and attempts to
acquire ffs->mutex to tear down ep0req.
5. The kernel deadlocks because the configfs thread is stuck in an
uninterruptible sleep waiting for the mutex, while the userspace
daemon is in an interruptible sleep holding the mutex forever
because no more events will arrive.
To fix this, we drop both the waitqueue spinlock and ffs->mutex before
going to sleep, and use wait_event_interruptible_exclusive() instead.
Upon waking up, we jump back to the `retry` label to safely reacquire
the mutex and re-evaluate the state machine. By not sleeping with
ffs->mutex held, we natively decouple gadget teardowns (which require
the mutex) from userspace polling.
Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver")
Cc: stable@vger.kernel.org
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
Link: https://patch.msgid.link/20260724204117.4036015-1-nkapron@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yun Zhou <yun.zhou@windriver.com>
Date: Fri Jul 31 16:11:51 2026 +0800
usb: gadget: f_tcm: fix deadlock in usbg_make_tpg()
commit 9dbf74f4022f80f7669d2b3c22c5deb46c1b5674 upstream.
usbg_make_tpg() held dep_lock while calling
configfs_depend_item_unlocked(), which acquires the configfs root
inode lock when operating across subsystems. This creates a circular
lock dependency with configfs_rmdir():
dep_lock -> configfs root inode lock -> su_mutex -> dep_lock
In usbg_make_tpg(), dep_lock only serialized the read of opts->ready,
which is a monotonic flag that transitions from false to true exactly
once (in tcm_set_name()) and never reverts. Remove dep_lock from
usbg_make_tpg() entirely and use READ_ONCE/WRITE_ONCE to access
opts->ready locklessly instead.
Reported-by: syzbot+c9f9d646b08f3b6032fe@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c9f9d646b08f3b6032fe
Fixes: 4bb8548df632 ("usb: gadget: f_tcm: add configfs support")
Cc: stable@vger.kernel.org
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
Link: https://patch.msgid.link/20260731081151.285599-1-yun.zhou@windriver.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Joshua Crofts <joshua.crofts1@gmail.com>
Date: Thu Jul 30 13:58:11 2026 +0000
usb: gadget: midi2: remove default configfs groups on teardown
commit 0f6bffb5008f0cba9cad5ded2caccc64466a6e54 upstream.
f_midi2_alloc_inst() creates default configfs child groups for the
default endpoint and default block using configfs_add_default_group(),
setting their internal refcount to 1.
However, during function teardown in f_midi2_free_inst() or EP cleanup
in f_midi2_ep_opts_release(), configfs_remove_default_groups() is
never called, therefore never dropping the refcount and leaking struct
f_midi2_ep_opts and f_midi2_block_opts.
Add the missing configfs_remove_default_groups() in the afformentioned
functions to free the structs properly.
Fixes: 8b645922b223 ("usb: gadget: Add support for USB MIDI 2.0 function driver")
Cc: stable@vger.kernel.org
Reported-by: syzbot+eaa106d192c9daf37f95@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=eaa106d192c9daf37f95
Tested-by: syzbot+eaa106d192c9daf37f95@syzkaller.appspotmail.com
Signed-off-by: Joshua Crofts <joshua.crofts1@gmail.com>
Link: https://patch.msgid.link/20260730135811.1498-1-joshua.crofts1@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Myeonghun Pak <mhun512@gmail.com>
Date: Tue Aug 4 23:05:10 2026 +0900
usb: gadget: snps_udc_plat: clean up PHY on probe deferral
commit 886338ea7d40e4ba5123c58204d7f7e53d825825 upstream.
When the referenced extcon device has not registered yet,
extcon_get_edev_by_phandle() returns -EPROBE_DEFER after the driver has
initialized and powered on the PHY. The direct return bypasses the common
cleanup path and leaves both operations unbalanced.
Store the lookup error first and route deferred probing through exit_phy,
while retaining the existing behavior of suppressing the error message for
deferral.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 1b9f35adb0ff ("usb: gadget: udc: Add Synopsys UDC Platform driver")
Cc: stable@vger.kernel.org
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260804140510.37639-1-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Sonali Pradhan <sonalipradhan@google.com>
Date: Mon Aug 10 07:12:37 2026 +0000
usb: gadget: u_audio: Fix use-after-free on sound card disconnect
commit 858965947081d10d41d9a1010a540d3d5eea958b upstream.
g_audio_cleanup() invokes snd_card_free_when_closed() to initiate sound
card teardown and immediately frees the underlying struct snd_uac_chip
context. However, snd_card_free_when_closed() returns asynchronously
while ALSA control elements (kctls) remain open in userspace.
When userspace control applications access or close these open file
descriptors, kctl callbacks attempt to dereference kctl->private_data
pointing to &uac->c_prm or &uac->p_prm within the freed uac structure,
resulting in a use-after-free (UAF) memory corruption.
Fix this issue by deferring the destruction of struct snd_uac_chip until
all references to the ALSA sound card are released. Register a custom
card->private_free callback (u_audio_card_free) during g_audio_setup()
that frees uac and its associated playback/capture request and ring
buffers only when the sound card reference count drops to zero.
Fixes: 6c67ed9ad9b8 ("usb: gadget: u_audio: don't let userspace block driver unbind")
Cc: stable@vger.kernel.org
Signed-off-by: Sonali Pradhan <sonalipradhan@google.com>
Link: https://patch.msgid.link/20260810071237.2207680-1-sonalipradhan@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeffin Philip <jeffinphilip14@gmail.com>
Date: Thu Aug 13 23:13:11 2026 +0530
usb: gadget: uvc: fix dangling pointers in uvc_function_bind() and uvc_function_unbind()
commit bdab5605259ba5d6ff927c1a85cc83eb3ecfdacc upstream.
In uvc_function_bind() error path, we use usb_ep_free_request which
uses uvc->control_req but does not set it to NULL afterwards. Thus,
uvc->control_req is a dangling pointer causing a UAF. Also we do not set
the uvc->control_buf pointer to NULL after freeing it, which is another
dangling pointer. Fix it by setting uvc->control_req to NULL after we run
usb_ep_free_request() and uvc->control_buf to NULL after kfree. Do the
same for uvc_function_unbind().
Reported-by: syzbot+de553c19cb054f174a35@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=de553c19cb054f174a35
Fixes: 0f9df9393855 ("usb: gadget: uvc: fix error path in uvc_function_bind()")
Fixes: 6d11ed76c45d ("usb: gadget: f_uvc: convert f_uvc to new function interface")
Cc: stable@vger.kernel.org
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Link: https://patch.msgid.link/20260813174311.130823-1-jeffinphilip14@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Jeffin Philip <jeffinphilip14@gmail.com>
Date: Tue Aug 4 09:13:38 2026 +0530
usb: gadget: uvc: Fix null pointer dereference in uvcg_video_init()
commit 5b1da38592efdc1a263d4c0353298cba19e9d6fc upstream.
In uvcg_video_init(), if kthread_run_worker() fails,
the error logged uses uvcg_err(), however, the pointer it uses:
video->uvc is not assigned at this point, triggering a null
pointer dereference. Fix this by directly using uvc->func which
is assigned already.
Reported-by: syzbot+8dcac923582c28505fd7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=8dcac923582c28505fd7
Fixes: f0bbfbd16b3b ("usb: gadget: uvc: rework to enqueue in pump worker from encoded queue")
Cc: stable@vger.kernel.org
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Reviewed-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://patch.msgid.link/20260804034338.7976-1-jeffinphilip14@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Johan Hovold <johan@kernel.org>
Date: Fri Jul 17 17:49:57 2026 +0200
USB: phy: fsl-usb: fix missing static keywords
commit 80574c40598aedbc1751c528e414d7e224bc6313 upstream.
A recent change enabling compile testing of a Freescale dual-role
controller indirectly enabled a USB PHY driver to be built. That driver
in turn is missing a bunch of static keywords which results in warnings
like:
drivers/usb/phy/phy-fsl-usb.c:105:5: error: no previous prototype for 'write_ulpi' [-Werror=missing-prototypes]
105 | int write_ulpi(u8 addr, u8 data)
| ^~~~~~~~~~
which consequently breaks -Werror builds.
Add the missing static keywords.
Fixes: 0807c500a1a6 ("USB: add Freescale USB OTG Transceiver driver")
Cc: stable@vger.kernel.org # 3.0
Reported-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/4f9f5ff9-8eaa-4bd5-9331-37119f78e13f@sirena.org.uk
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260717154957.1853976-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xu Yang <xu.yang_2@nxp.com>
Date: Thu Jul 23 18:46:14 2026 +0800
usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()
commit b691a07c5f644080374ddd24de6a0e05f5d28744 upstream.
Previously, tcpci_irq() always passed TCPC_TX_SOP as the receive type
to tcpm_pd_receive(), ignoring the actual frame type reported by the
TCPC_RX_BUF_FRAME_TYPE register.
Cache the TCPC_RX_DETECT register value in rx_type_mask variable. When
a PD messageis received, read TCPC_RX_BUF_FRAME_TYPE register and handle
the message only if its frame type is enabled in mask.
The TCPC_RX_BUF_FRAME_TYPE register records the received message type,
which has a 1:1 mapping to enum tcpm_transmit_type.
Fixes: fb7ff25ae433 ("usb: typec: tcpm: add discover identity support for SOP'")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Link: https://patch.msgid.link/20260723104614.3717623-1-xu.yang_2@oss.nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Sun Aug 2 01:49:59 2026 +0000
usb: typec: thunderbolt: Disable work before freeing tbt on remove
commit 92090f6ff2acc81e9dd99881dcfb4f8c1bdaabd3 upstream.
tbt_altmode_remove() drops the plug and cable references without
draining tbt->work. The work function dereferences those references,
and can also requeue itself in its error path. The VDM callbacks can
queue the same work item.
Disable and drain tbt->work before dropping the references. This waits
for an existing invocation and prevents subsequent schedule_work()
calls from queueing it during teardown.
This issue was found by an in-house static analysis tool and confirmed
by manual code review.
Fixes: 100e25738659 ("usb: typec: Add driver for Thunderbolt 3 Alternate Mode")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260802014959.416687-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Huang Wei <huangwei@kylinos.cn>
Date: Wed Aug 5 16:57:25 2026 +0800
usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command completion
commit eb4573cf2fd860b20adfae050c3f6ec6ddc3abdb upstream.
The synchronous command completion path in ucsi_sync_control_common()
hardcodes a 5 second (5 * HZ) timeout when waiting for the PPM to signal
command completion via ACPI notification. This value matched
UCSI_TIMEOUT_MS when it was still 5000 ms, but it was not updated when
that macro was later raised to 10000 ms to fix PPM reset timeouts.
As a result, the two PPM communication paths are now inconsistent: the
polling path in ucsi_reset_ppm() respects the 10 second timeout, while
the event-driven completion path still uses 5 seconds. On machines where
the firmware is slow to respond during boot (e.g. some Lenovo ThinkPad
models such as the E14 Gen 7), commands sent after the PPM reset, such
as SET_NOTIFICATION_ENABLE and GET_CAPABILITY, can exceed 5 seconds and
cause UCSI initialization to fail with:
ucsi_acpi USBC000:00: error -ETIMEDOUT: PPM init failed
Once UCSI init aborts, USB-C PD negotiation never completes, which in
turn blocks USB-C dock enumeration since the dock depends on a successful
PD contract.
Replace the hardcoded 5 * HZ with msecs_to_jiffies(UCSI_TIMEOUT_MS) so
that both communication paths share a single, consistent timeout value,
and future adjustments to UCSI_TIMEOUT_MS are picked up automatically.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221740
Link: https://bugzilla.kernel.org/show_bug.cgi?id=2183790
Fixes: bf4f9ae1cb08c ("usb: typec: ucsi: increase timeout for PPM reset operations")
Cc: stable@vger.kernel.org
Signed-off-by: Huang Wei <huangwei@kylinos.cn>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Fedor Pchelkin <boddah8794@gmail.com>
Link: https://patch.msgid.link/20260805085725.389761-1-huangwei@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Chengfeng Ye <nicoyip.dev@gmail.com>
Date: Sun Aug 23 00:45:56 2026 +0800
vsock/virtio: flush works in dependency order
commit 728836ebca239810f164262b10211ef59182f811 upstream.
virtio_vsock_remove() stops the virtqueues and then flushes each work
item before freeing the enclosing virtio_vsock. The current order does
not account for dependencies between those items: tx_work may queue
send_pkt_work, and send_pkt_work may queue rx_work.
In particular, send_pkt_work can set restart_rx and release tx_lock.
The remove path can then stop the queues and flush rx_work before
send_pkt_work queues it. Although the later send_pkt_work flush waits
for that producer to finish, nothing waits for the newly queued rx_work,
so kfree(vsock) can race with it.
KASAN reported:
BUG: KASAN: slab-use-after-free in
virtio_transport_rx_work+0x487/0x4b0
Read of size 8 at addr ffff888114c2b008 by task kworker/1:1/47
Workqueue: virtio_vsock virtio_transport_rx_work
Call Trace:
virtio_transport_rx_work+0x487/0x4b0
process_one_work+0x688/0x1120
worker_thread+0x45b/0xd10
Allocated by task 1:
virtio_vsock_probe+0xef/0x6b0
Freed by task 84:
kfree+0x131/0x3c0
virtio_vsock_remove+0xd1/0x100
Flush the works in producer-to-consumer order. virtio_vsock_vqs_del()
has already disabled the queue callbacks and cleared the run flags, so
after tx_work and send_pkt_work are drained, no source remains that can
queue rx_work after its flush.
Fixes: 0ea9e1d3a9e3 ("VSOCK: Introduce virtio_transport.ko")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://patch.msgid.link/20260822164556.3750959-1-nicoyip.dev@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Maoyi Xie <maoyixie.tju@gmail.com>
Date: Mon Jun 29 20:10:43 2026 +0800
w1: ds28e17: reject an oversize length on an I2C block read
commit 169ae5e65e5aaf213b6a578f6478a9fd2e523606 upstream.
w1_f19_i2c_master_transfer() is the master_xfer for the DS28E17 1-Wire
to I2C bridge. On an I2C_M_RECV_LEN read, it takes the length from the
device. The downstream slave puts a length byte in buf[0]. The driver
then reads that many bytes into buf[1] with w1_f19_i2c_read().
buf[0] is controlled by the device and can be 0 to 255.
w1_f19_i2c_read() only rejects a zero count. The caller buffer is
I2C_SMBUS_BLOCK_MAX + 2, so 34 bytes. A length above 32 makes the read
run past it, up to about 222 bytes out of bounds.
The SMBus core does check buf[0] against I2C_SMBUS_BLOCK_MAX. That
check runs after master_xfer returns. By then the write is already
done. i2c-algo-bit rejects an oversize length before it copies, and
returns -EPROTO.
Reject a length above I2C_SMBUS_BLOCK_MAX at both RECV_LEN sites, the
same way i2c-algo-bit does.
Fixes: ebc4768ac497 ("add w1_ds28e17 driver for the DS28E17 Onewire to I2C master bridge")
Cc: stable@vger.kernel.org
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260629121043.199487-1-maoyixie.tju@gmail.com
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zilin Guan <zilin@seu.edu.cn>
Date: Fri Jan 30 08:44:51 2026 +0000
wifi: ath11k: fix memory leaks in beacon template setup
[ Upstream commit ff49eba595df500e4ddccc593088c8a4ab5f2c27 ]
The functions ath11k_mac_setup_bcn_tmpl_ema() and
ath11k_mac_setup_bcn_tmpl_mbssid() allocate memory for beacon templates
but fail to free it when parameter setup returns an error.
Since beacon templates must be released during normal execution, they
must also be released in the error handling paths to prevent memory
leaks.
Fix this by using unified exit paths with proper cleanup in the respective
error paths.
Compile tested only. Issue found using a prototype static analysis tool
and code review.
Fixes: 3a415daa3e8b ("wifi: ath11k: add P2P IE in beacon template")
Fixes: 335a92765d30 ("wifi: ath11k: MBSSID beacon support")
Suggested-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260130084451.110768-1-zilin@seu.edu.cn
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Doruk Tan Ozturk <doruk@0sec.ai>
Date: Mon Jul 13 23:32:51 2026 +0200
wifi: ath6kl: clamp assoc request/response lengths before subtracting IE offsets
commit 3bbd05723d15dd06f0560bcd94fbf9a91b5f5613 upstream.
ath6kl_cfg80211_connect_event() subtracts fixed IE offsets from
assoc_req_len (-= 4) and assoc_resp_len (-= 6), both u8, with no lower
bound. The aggregate check recently added to ath6kl_wmi_connect_event_rx()
bounds the declared lengths from above (their sum must fit the received
event), but an assoc request/response shorter than its fixed offset still
underflows here: the u8 wraps to ~250, and cfg80211_connect_result() /
cfg80211_roamed() then treat that wrapped value as the IE length and copy
that many bytes out of the small assoc_info buffer to user space via
nl80211, disclosing adjacent slab memory.
Clamp both lengths to their offsets before subtracting.
Found by 0sec (https://0sec.ai) using automated source analysis; the
missing lower bound is evident from source. Compile-tested.
Fixes: bdcd81707973 ("Add ath6kl cleaned up driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Link: https://patch.msgid.link/20260713213251.21161-1-doruk@0sec.ai
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Date: Mon Aug 3 11:35:06 2026 +0200
wifi: brcmfmac: Fix memory leak in brcmf_sdio_read_control()
commit 0d10db8e94fcb23a799789aaa696b4d8f937e207 upstream.
The memory allocated for buf is not freed in some of the error paths in
brcmf_sdio_read_control(). Fix that by adding vfree() calls.
Cc: stable@vger.kernel.org
Fixes: dd43a01c5cdb ("brcmfmac: use dynamically allocated control frame buffer")
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
[arend: rework as suggested by Johannes]
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260803093506.1647790-1-arend.vanspriel@broadcom.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Dawei Feng <dawei.feng@seu.edu.cn>
Date: Wed Jun 24 16:44:04 2026 +0800
wifi: iwlwifi: dvm: fix memory leak in iwl_op_mode_dvm_start()
commit 67105abd6195a685a84dcb8a5daf54a1f4bfdb60 upstream.
In iwl_op_mode_dvm_start(), jumping to out_free_eeprom currently bypasses
the out_free_eeprom_blob label. Consequently, error paths triggered after
successfully parsing the EEPROM free priv->nvm_data but leak
priv->eeprom_blob.
Fix this memory leak by reordering the error handling labels so
that out_free_eeprom falls through to out_free_eeprom_blob.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1-rc6.
An x86_64 allyesconfig build showed no new warnings. As we do not have
supported Intel DVM wireless hardware and firmware to test with, no
runtime testing was able to be performed.
Cc: stable@vger.kernel.org
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
Link: https://patch.msgid.link/20260624084404.570703-1-dawei.feng@seu.edu.cn
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zilin Guan <zilin@seu.edu.cn>
Date: Fri Jan 16 14:49:19 2026 +0000
wifi: mt76: Fix memory leak after mt76_connac_mcu_alloc_sta_req()
[ Upstream commit c41075ce8cf05ed8c0e7b7efef000dce548ffc42 ]
mt76_connac_mcu_alloc_sta_req() allocates an skb which is expected to
be freed eventually by mt76_mcu_skb_send_msg(). However, currently if
an intermediate function fails before sending, the allocated skb is
leaked.
Specifically, mt76_connac_mcu_sta_wed_update() and
mt76_connac_mcu_sta_key_tlv() may fail, leading to an immediate memory
leak in the error path.
Fix this by explicitly freeing the skb in these error paths.
Commit 7c0f63fe37a5 ("wifi: mt76: mt7996: fix memory leak on
mt7996_mcu_sta_key_tlv error") made a similar change.
Compile tested only. Issue found using a prototype static analysis tool
and code review.
Fixes: d1369e515efe ("wifi: mt76: connac: introduce mt76_connac_mcu_sta_wed_update utility routine")
Fixes: 6683d988089c ("mt76: connac: move mt76_connac_mcu_add_key in connac module")
Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support")
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Link: https://patch.msgid.link/20260116144919.1482558-1-zilin@seu.edu.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Fri Jun 12 12:13:31 2026 +0800
wifi: mt76: mt7615: avoid waiting for mac work under the mt76 mutex
commit bda8324270b1ac91bfba1df8928e0570e29759e8 upstream.
mt7615_suspend() acquired the mt76 mutex and then called
cancel_delayed_work_sync() on mac_work. mt7615_mac_work() acquires the
same mutex via mt7615_mutex_acquire() at the top of the worker, so if
mac_work is already running and blocked on the mutex, the suspend path
deadlocks waiting for the work it holds the mutex against.
Flush scan_work and mac_work before taking the mutex, matching the
suspend paths in mt7921 and mt7925. scan_work only takes the mt76
spinlock, but moving it keeps the sequence consistent. This also keeps
mac_work from running over an already suspended HIF, which the previous
split (async cancel under the lock, sync cancel after release) would
have allowed.
Fixes: c6bf20109a3f ("mt76: mt7615: add WoW support")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260612041331.2596331-1-runyu.xiao@seu.edu.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Bryam Vargas <hexlabsecurity@proton.me>
Date: Thu Jun 25 07:10:26 2026 -0500
wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy
commit 44b5adfe49499f53002737f5fe81d608c08122fc upstream.
mt7915_mcu_get_eeprom() copies a fixed EFUSE block into the driver's
dev->mt76.eeprom.data buffer at the offset reported by the MCU response
(res->addr, a device-controlled __le32) without checking it against the
buffer size. A malicious or malfunctioning device can report an arbitrary
address and drive a 16-byte out-of-bounds write past eeprom.data.
Reject a response whose address would place the copy outside eeprom.data
before deriving the destination pointer. Devices that echo the requested
in-bounds offset are unaffected.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260625-b4-disp-16f99062-v1-1-aee52ecf61b9@proton.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Devin Wittmayer <lucid_duck@justthetip.ca>
Date: Sat Jun 27 13:29:46 2026 -0700
wifi: mt76: mt7925: cancel mlo_pm_work on stop
commit 81faf578320df2dfc682a96baa6e85851dd68b6f upstream.
mt7925 queues mlo_pm_work with a 5 second delay during multi-link
power-save setup and never cancels it on the stop path. If the device is
torn down inside that window, the work outlives the teardown and its timer
fires afterwards, trying to queue onto the workqueue that is already gone:
workqueue: cannot queue mt7925_mlo_pm_work [mt7925_common] on wq phy0
WARNING: kernel/workqueue.c:2283 at __queue_work+0x59/0xa0, CPU#1: swapper/1/0
call_timer_fn+0x2a/0x140
__run_timers+0x203/0x330
run_timer_softirq+0x86/0xf0
mt7921 already has its own stop callback, so add one for mt7925 that
cancels the work before calling mt792x_stop(). mt7925_ops backs both the
PCIe and USB drivers, so this covers both.
Fixes: 276a56883257 ("wifi: mt76: mt7925: update the power-saving flow")
Cc: stable@vger.kernel.org
Tested-by: Traockl <281473483+Traockl@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260627202946.25598-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Wentao Guan <guanwentao@uniontech.com>
Date: Tue Jun 30 17:02:18 2026 +0800
wifi: mt76: mt7925: cancel pending mlo_pm_work
commit 2889e84282dda147f10b10d94cf0efd90a349c53 upstream.
If the device is reset, suspended or unregistered within that window,
the pending work can still run and access vif/bss data that may already
be freed, or send MCU commands while the firmware is not available.
Add cancel_delayed_work_sync(&dev->mlo_pm_work) in all relevant teardown
and suspend paths:
- mt7925_mac_reset_work() (chip reset recovery)
- mt7925e_unregister_device() (PCIe unbind)
- mt7925_pci_suspend() (PCIe bus suspend)
- mt7925_suspend() (mac80211 suspend)
- mt7925u_suspend() (USB bus / runtime suspend)
This ensures the work is stopped before the device state becomes
invalid.
Assisted-by: kimi-cli:kimi-k2.7 code
Assisted-by: atomcode:glm-5.2 #Reported-by
Fixes: 276a568832577 ("wifi: mt76: mt7925: update the power-saving flow")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Link: https://patch.msgid.link/20260630090218.3202029-1-guanwentao@uniontech.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Felix Fietkau <nbd@nbd.name>
Date: Wed Jul 22 08:26:05 2026 +0000
wifi: mt76: mt7996: fix TX DMA mapping leak for AddBA req frames
commit deaa2e3656937fbbe312f0ee2616c756c6e2511f upstream.
mt7996/mt7992 hand the firmware a HW MAC-TXP for AddBA req action frames
(MT_TXD7_MAC_TXD, set in mt7996_mac_write_txwi_80211()), but are otherwise
FW-TXP devices. On tx free mt76_connac_txp_skb_unmap() therefore decodes
the per-frame txp as a struct mt76_connac_fw_txp. For a MAC-TXP the
fw_txp.nbuf byte aliases the AddBA TID word (MT_TXP1_TID_ADDBA), which is
always zero, so the unmap loop runs zero times and the skb DMA mapping in
buf[1] is never unmapped. buf[1].skip_unmap is set unconditionally, so the
generic DMA-ring cleanup skips it as well.
Each AddBA req therefore leaks one TX DMA mapping, roughly one per
(re)association. With WED enabled these mappings are bounced through the
WED swiotlb pool, so under continuous client reconnect churn the pool is
exhausted after ~1-2 days, after which DMA mapping fails for WED, the WiFi
MCU and other on-SoC consumers.
Keep the deferred (token release) unmap that the design relies on, and add
an mt7996-specific txp unmap that inspects MT_TXD7_MAC_TXD and unmaps
buf[1] from the MAC-TXP layout for those frames, delegating to
mt76_connac_txp_skb_unmap() otherwise.
Cc: stable@vger.kernel.org
Fixes: cb6ebbdffef2 ("wifi: mt76: mt7996: support writing MAC TXD for AddBA Request")
Link: https://patch.msgid.link/20260722082610.2699628-13-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Date: Mon Jul 13 17:39:12 2026 +0545
wifi: mt76: mt7996: validate default EEPROM firmware size
commit 653c6e289b13cc6942f3e8f8e3c568e70fa42d1f upstream.
The default EEPROM firmware is parsed and copied as a full EEPROM
without checking its length. A truncated file can make the driver
read beyond the firmware buffer during variant validation or the
fallback copy.
Reject files shorter than MT7996_EEPROM_SIZE before parsing or
copying the firmware.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Link: https://patch.msgid.link/20260713115412.67095-1-acharyalaxman8848@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fabio Estevam <festevam@nabladev.com>
Date: Fri Jul 24 17:33:19 2026 -0300
wifi: mwifiex: Detach sync cmd buffer on interrupted wait
commit ef06882c7d8a7400b67d0d003b1008093dd589ed upstream.
mwifiex synchronous commands keep the caller-provided data buffer in
cmd_node->data_buf. Several callers pass stack-allocated objects there.
If wait_event_interruptible_timeout() is interrupted, the caller can
return and release that stack object while the firmware command is still
the current command. A late firmware response then reaches the normal
response handler, which can copy data through cmd_node->data_buf into the
stale stack address.
This fixes a stack corruption observed during repeated association and
disassociation cycles. The panic trace showed the command wait being
interrupted immediately before a bad pointer dereference:
cmd_wait_q terminated: -512
Unable to handle kernel paging request at virtual address 002c583837384662
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted
...
Tainted: [M]=MACHINE_CHECK
The fault address decodes as little-endian ASCII:
0x002c583837384662 -> "bF878X,\0"
which is a fragment of the VERSION_EXT firmware string exposed as
debugfs "verext":
w8997o-V4, RF878X, FP92, 16.92.21.p153.7
The same runs also showed corrupted control data containing:
0x2400372e333531 -> "153.7\0$"
which is the tail of the same VERSION_EXT string. This points at a late
VERSION_EXT response writing through a stale stack-backed data_buf after
the interrupted wait returned.
After cancelling pending commands on an interrupted or timed-out wait,
detach the caller-owned data buffer from the still-current command. This
preserves the existing command cancellation behaviour while preventing a
late response from writing through a pointer whose lifetime ended with the
waiting caller.
Tested on an i.MX8MP board using an 88W8997.
Cc: stable@vger.kernel.org
Fixes: 3d026d09b28d ("mwifiex: cancel pending commands for signal")
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Link: https://patch.msgid.link/20260724203320.78793-1-festevam@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Stanislaw Gruszka <stf_xl@wp.pl>
Date: Thu Jul 23 13:06:40 2026 +0200
wifi: rtl818x: initialize eeprom_93cx6 struct to zero
commit 799b5f45cb8194ebd06c9c89e0afdad5bedd2cc5 upstream.
Commit 7738a7ab9d12 ("misc: eeprom: eeprom_93cx6: Add quirk for extra
read clock cycle") added extra 'quirk' field to struct eeprom_93cx6.
Many existing users of eeprom_93cx6, including rtl818x drivers, allocate
the structure on the stack without initializing all fields. As a result,
the added quirk field has an undefined value and can randomly cause
reading wrong data from the EEPROM.
Fix by initializing the structures with {}.
Fixes: 7738a7ab9d12 ("misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle")
Cc: stable@kernel.org # v6.13+
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260723110640.8588-1-stf_xl@wp.pl
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Fan Wu <fanwu01@zju.edu.cn>
Date: Tue Jun 30 03:31:17 2026 +0000
wifi: rtl8xxxu: fix use-after-free from rx_urb_wq on stop
commit 6c080026ecc17eecb103f8927c64ea73a74bb818 upstream.
rtl8xxxu arms rx_urb_wq from the RX completion path:
rtl8xxxu_rx_complete() hands the URB to rtl8xxxu_queue_rx_urb(), which
queues it on rx_urb_pending_list and, once the list grows past
RTL8XXXU_RX_URB_PENDING_WATER, schedules rx_urb_wq. The worker
rtl8xxxu_rx_urb_work() drains rx_urb_pending_list, recovers priv through
container_of, and resubmits each URB through rtl8xxxu_submit_rx_urb(),
which anchors it on rx_anchor and dereferences priv->udev.
rtl8xxxu_stop() cancels the sibling work items (c2hcmd_work, ra_watchdog,
update_beacon_work) but never cancels rx_urb_wq, so a worker armed during
the last burst of RX traffic can run rtl8xxxu_rx_urb_work() after
rtl8xxxu_disconnect() has called ieee80211_free_hw(), which frees priv,
producing a use-after-free. The window opens under active RX traffic
(pending count above the watermark) followed by a disconnect.
There are two teardown races to close:
* rtl8xxxu_queue_rx_urb() decided whether to enqueue under rx_urb_lock
but called schedule_work() after dropping the lock. A completion
that observed shutdown == false and released the lock could then call
schedule_work() after rtl8xxxu_stop() had set shutdown and
cancel_work_sync() had already returned, arming the worker to run
after the teardown. Move schedule_work() under the same !shutdown
branch so the arming decision is atomic with the shutdown check.
* rtl8xxxu_rx_urb_work() anchors every URB it drained back onto
rx_anchor through rtl8xxxu_submit_rx_urb(). A worker still running
when usb_kill_anchored_urbs(&priv->rx_anchor) returned would submit a
URB that escaped the kill. In rtl8xxxu_stop(), call
cancel_work_sync(&priv->rx_urb_wq) before the kill so the worker is
drained first.
After priv->shutdown is set under rx_urb_lock, completions can no longer
queue rx_urb_wq. cancel_work_sync() then drains the last queued or running
worker, and the following usb_kill_anchored_urbs() kills the URBs it may
have submitted.
rtl8xxxu_disconnect() is covered because ieee80211_unregister_hw()
guarantees .stop() runs for a live interface before ieee80211_free_hw()
frees priv. The probe error path needs no cancel: rx_urb_wq is
INIT_WORK()'d there but cannot have been scheduled, since no URB is
submitted before ieee80211_register_hw() succeeds.
This bug was found by static analysis.
Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)")
Cc: stable@vger.kernel.org
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260630033117.3377-1-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Runyu Xiao <runyu.xiao@seu.edu.cn>
Date: Sat Jun 20 10:56:32 2026 +0800
wifi: rtlwifi: rtl8192du: check QoS TID before indexing tids
commit ed4f05d9f2f42fd866f55108db8123eefcc5fb33 upstream.
rtl92du_tx_fill_desc() uses ieee80211_get_tid() to read the QoS TID
from the 802.11 header and then uses it as an index into
sta_entry->tids[]. ieee80211_get_tid() returns the low 4-bit QoS TID
value, so the result can be in the range 0..15.
rtlwifi only allocates MAX_TID_COUNT entries for sta_entry->tids[], and
MAX_TID_COUNT is 9. A QoS TID greater than 8 therefore indexes past the
aggregation state array. Keep the default RTL_AGG_STOP state for
out-of-range TIDs, matching rtl92cu_tx_fill_desc().
This issue was detected by our static analysis tool and confirmed by
manual audit. UBSAN validation for the same bug pattern reports an
array-index-out-of-bounds access with index 10 for type
'rtl_tid_data [9]'.
Fixes: 8321424134a4 ("wifi: rtlwifi: Add rtl8192du/trx.{c,h}")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260620025632.46206-1-runyu.xiao@seu.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Date: Thu Jul 23 17:15:37 2026 +0530
wifi: rtlwifi: rtl8192du: Fix possible memory leak in rtl92du_init_sw_vars()
commit 6496ce90845df2d22fb8e8ed235cd2936fad41c8 upstream.
The memory allocated inside rtl92du_init_shared_data() is not freed in
any of the subsequent error paths in rtl92du_init_sw_vars().
Fix that by adding a call to rtl92du_deinit_shared_data() in the error
path.
Fixes: b5dc8873b6ff ("wifi: rtlwifi: Add rtl8192du/sw.c")
Cc: stable@vger.kernel.org
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260723114539.136986-1-nihaal@cse.iitm.ac.in
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Date: Mon Jul 27 12:12:22 2026 +0530
wifi: rtw88: Fix potential memory leak in rtw_txq_push_skb()
commit 9f2948010764d708bda27369d09ce6f194abe8e3 upstream.
The skb passed to the rtw_hci_tx_write() is expected to be freed when
the function fails, but the error path in rtw_txq_push_skb() does not
free the skb before returning. This can lead to a memory leak in
rtw_txq_push() where a dequeued skb is passed to rtw_txq_push_skb().
Fixes: aaab5d0e6737 ("rtw88: kick off TX packets once for higher efficiency")
Cc: stable@vger.kernel.org
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260727064223.61836-1-nihaal@cse.iitm.ac.in
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Dawei Feng <dawei.feng@seu.edu.cn>
Date: Wed Jun 17 09:35:02 2026 +0800
wifi: rtw88: pci: fix resource leak on failed NAPI setup
commit e779df4806cd29cbcca5c9dc0a1073662c76b889 upstream.
rtw_pci_probe() allocates PCI resources through
rtw_pci_setup_resource() before it sets up NAPI. If
rtw_pci_napi_init() fails, the error path jumps straight to
err_pci_declaim and skips rtw_pci_destroy(), leaving the PCI
resources allocated by rtw_pci_setup_resource() behind.
Add a dedicated cleanup label for the NAPI setup failure path so probe
destroys the PCI resources.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing current
mainline kernels. The tool is still under development and is not yet
publicly available. Manual inspection confirms that the bug is still
present in v7.1-rc7.
An x86_64 allyesconfig build showed no new warnings. As we do not have a
suitable rtw88 PCI board to test with, no runtime testing was able to be
performed.
Fixes: d0bcb10e7b94 ("wifi: rtw88: Un-embed dummy device")
Cc: stable@vger.kernel.org
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260617013502.114057-1-dawei.feng@seu.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kiryl Shutsemau (Meta) <kas@kernel.org>
Date: Mon Jul 13 14:37:52 2026 +0100
x86/insn-eval: Move assign_register() out of KVM as insn_assign_reg()
commit 1fe104b048d77d6cb25bd938e6a67450fb50e61d upstream.
KVM's instruction emulator has a small helper, assign_register(), that
writes a value into a register following the x86 rules for writes to
general-purpose registers: an 8- or 16-bit write leaves the rest of the
register untouched, a 32-bit write zero-extends the result to 64 bits,
and a 64-bit write replaces the whole register.
The TDX guest #VE handler needs the same logic for port I/O emulation
to get 32-bit zero-extension right. Rather than add a third copy of
the same switch, move the helper verbatim to <asm/insn-eval.h>, rename
it to insn_assign_reg(), and route KVM's callers through it.
Add <asm/insn.h> to the header's includes so it builds standalone in
callers that have not pulled it in transitively.
No functional change.
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Sean Christopherson <seanjc@google.com>
Cc:stable@vger.kernel.org
Link: https://patch.msgid.link/20260713133753.223947-3-kirill@shutemov.name
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Yao Zi <me@ziyao.cc>
Date: Sat Aug 1 18:29:53 2026 +0000
x86/locking: Use sfence for wmb() if SSE is available
commit d824ed1307680dd482f607b0e707c575f70668c4 upstream.
When adding cc clobber to wmb()'s definition, the alternative()
condition to use sfence was incorrectly raised from X86_FEATURE_XMM to
X86_FEATURE_XMM2.
Restore the correct constraint for potential better performance on
machines without SSE2.
Fixes: bd922477d935 ("locking/x86: Add cc clobber for ADDL")
Signed-off-by: Yao Zi <me@ziyao.cc>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260801182953.15069-1-me@ziyao.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kiryl Shutsemau (Meta) <kas@kernel.org>
Date: Mon Jul 13 14:37:51 2026 +0100
x86/tdx: Fix off-by-one in port I/O handling
commit 0f63e656b1c679d32ac595de29d10c03efca6a25 upstream.
handle_in() and handle_out() in arch/x86/coco/tdx/tdx.c use:
u64 mask = GENMASK(BITS_PER_BYTE * size, 0);
GENMASK(h, l) includes bit h. For size=1 (INB), this produces
GENMASK(8, 0) = 0x1FF (9 bits) instead of GENMASK(7, 0) = 0xFF (8
bits). The mask is one bit too wide for all I/O sizes.
Fix the mask calculation.
Fixes: 03149948832a ("x86/tdx: Port I/O: Add runtime hypercalls")
Reported-by: Borys Tsyrulnikov <tsyrulnikov.borys@gmail.com>
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Link: https://lore.kernel.org/all/CAKw_Dz96rfSQc6Rn+9QBcUFHhmkK+9zu+P=bxowfZwxrATCBRg@mail.gmail.com/
Cc:stable@vger.kernel.org
Link: https://patch.msgid.link/20260713133753.223947-2-kirill@shutemov.name
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Kiryl Shutsemau (Meta) <kas@kernel.org>
Date: Mon Jul 13 14:37:53 2026 +0100
x86/tdx: Fix zero-extension for 32-bit port I/O
commit 941370fc93cc3474e26811f4d3b062903eefe2cf upstream.
According to x86 architecture rules, 32-bit operations zero-extend the
result to 64 bits. The current implementation of handle_in() only masks
the lower 32 bits, which preserves the upper 32 bits of RAX when a
32-bit port IN instruction is emulated.
Use insn_assign_reg() to write the result back into RAX with proper
partial-register-write semantics: 1- and 2-byte forms leave the upper
bits untouched, the 4-byte form zero-extends to the full register.
Fixes: 03149948832a ("x86/tdx: Port I/O: Add runtime hypercalls")
Reported-by: Borys Tsyrulnikov <tsyrulnikov.borys@gmail.com>
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Link: https://lore.kernel.org/all/CAKw_Dz96rfSQc6Rn+9QBcUFHhmkK+9zu+P=bxowfZwxrATCBRg@mail.gmail.com/
Cc:stable@vger.kernel.org
Link: https://patch.msgid.link/20260713133753.223947-4-kirill@shutemov.name
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Zi Yan <ziy@nvidia.com>
Date: Tue Aug 4 17:04:28 2026 -0400
xarray: honor XA_FLAGS_ACCOUNT in xas_split_alloc()
commit 789763523fb43cdc328de5cb5dcd19240ccf90d8 upstream.
XArray operations that allocate xa_nodes, such as xas_nomem() and
xas_alloc(), add __GFP_ACCOUNT when the array has XA_FLAGS_ACCOUNT set.
This charges the allocated memory and avoids the workingset convergence
issue described by commit 7b785645e8f13 ("mm: fix page cache convergence
regression").
xas_split_alloc() does not add _GFP_ACCOUNT when XA_FLAGS_ACCOUNT is
present. Fix it.
Link: https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-2-38cb3ff325c5@nvidia.com
Fixes: 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache")
Signed-off-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Weiming Shi <bestswngs@gmail.com>
Date: Tue Aug 18 23:45:15 2026 +0800
xdp: fix zero-copy frame layout
commit 71283aaa6c65b3cec84caf1dc78560985737641f upstream.
xdp_convert_zc_to_xdp_frame() clones an XSK packet into an order-0 page
and advertises PAGE_SIZE as its frame size. It allows the copied frame
to occupy the page tail needed by skb_shared_info and records zero
headroom even when metadata separates the frame header from packet data.
An AF_XDP zero-copy packet redirected through cpumap can therefore make
the skb overlap skb_shared_info or place it beyond the allocated page.
Limit the copied layout to SKB_WITH_OVERHEAD(PAGE_SIZE) and include the
metadata length in frame headroom. Redirect callers already handle a
NULL conversion result.
BUG: KASAN: slab-out-of-bounds in skb_gro_receive
Write of size 4 at addr ffff88800cf37004 by task cpumap/1/map:1/146
Call Trace:
skb_gro_receive (net/core/gro.c:174)
udp_gro_receive (net/ipv4/udp_offload.c:812)
inet_gro_receive (net/ipv4/af_inet.c:1539)
dev_gro_receive (net/core/gro.c:515)
gro_receive_skb (net/core/gro.c:633)
cpu_map_kthread_run (kernel/bpf/cpumap.c:395)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:164)
ret_from_fork_asm (arch/x86/entry/entry_64.S:255)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Fixes: b0d1beeff2a9 ("xdp: implement convert_to_xdp_frame for MEM_TYPE_ZERO_COPY")
Cc: stable@vger.kernel.org
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20260818154516.793517-1-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Xu Rao <raoxu@uniontech.com>
Date: Tue Aug 4 10:34:03 2026 +0800
zloop: truncate finished zones to zone capacity
commit 72e67c118642634c25465db0c8bcfa54c4ce086c upstream.
The size of a sequential zone backing file records the amount of data
written and is used to restore the zone state. A backing file whose size
is equal to the zone capacity is restored as a full zone, while a file
larger than the zone capacity is rejected as invalid.
However, zloop_finish_zone() currently truncates the backing file to the
zone size. For devices with a reduced zone capacity, finishing a zone
therefore creates a backing file larger than the zone capacity. After the
device is removed and later re-added, that zone file is rejected instead
of being restored as a full zone.
Truncate finished sequential zones to the zone capacity, matching the
persistent representation accepted by zloop_update_seq_zone() for a full
zone.
Suggested-by: Damien Le Moal <dlemoal@kernel.org>
Fixes: eb0570c7df23 ("block: new zoned loop block device driver")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://patch.msgid.link/B39E5FD81D1A07F4+20260804023403.939767-1-raoxu@uniontech.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Sergey Senozhatsky <senozhatsky@chromium.org>
Date: Wed Jul 29 13:57:36 2026 +0900
zram: validate deflate params
commit ec7607ac4717ff521c9c1e9d8271c26293345513 upstream.
We must validate user-supplied deflate winbits before we pass it to
zlib_deflate_workspacesize(), which triggers BUG_ON() if winbits value is
outside of valid ranges.
Link: https://lore.kernel.org/20260729045745.775973-3-senozhatsky@chromium.org
Fixes: dc75a0d93bd5 ("zram: support deflate-specific params")
Link: https://sashiko.dev/#/patchset/20260728092935.31139-1-haoqinhuang7@gmail.com
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Haoqin Huang <haoqinhuang7@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Author: Longlong Xia <xialonglong@kylinos.cn>
Date: Sun Aug 9 19:55:18 2026 +0800
zsmalloc: account for handle size in class lookup
commit f7bf5cd5b5f2b13fe2361860880c4e214c08b440 upstream.
zs_lookup_class_index() lets zram recompression decide whether a newly
compressed object would use a smaller size class. It currently classifies
the payload size directly, while zs_malloc() adds ZS_HANDLE_SIZE before
selecting the class.
This makes lookup disagree with allocation near size-class boundaries.
With 4 KiB pages, CONFIG_ZSMALLOC_CHAIN_SIZE=8, and 64-bit handles, a
1025-to-1024-byte recompression appears to move from class 64 to class 62
although both allocations use class 64. Conversely, a 1049-to-1025-byte
recompression appears to stay in class 64 although the allocations move
from class 65 to class 64.
As a result, zram can accept replacements with no allocation benefit or
reject ones that would save memory, potentially marking the object
incompressible.
Factor size-class selection into lookup_size_class(), account for the
handle there, and use the helper for both lookup and allocation.
Link: https://lore.kernel.org/20260809115518.3791787-1-xialonglong2025@163.com
Fixes: 7c2af309abd2 ("zram: add size class equals check into recompression")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>