In the Linux kernel, the following vulnerability has been resolved:
nvdimm: pmem: keep PREFLUSH before data writes
pmemsubmitbio() records a REQPREFLUSH error, but continues to copy the bio data and can later overwrite the error with a successful REQFUA flush. That lets data writes run after a failed preflush and can complete the bio successfully despite the failed ordering barrier.
Run the REQPREFLUSH flush synchronously before touching the bio data and complete the bio with the flush error if it fails. Keep asynchronous flush chaining for REQFUA. At that point, data copy has completed and the parent bio can wait for the chained flush bio.
In the Linux kernel, the following vulnerability has been resolved:
usb: typec: ucsi: unregister debugfs entries on teardown
ucsiregister() creates per-instance debugfs entries, but ucsiunregister() keeps them around until ucsidestroy().
Drivers like ucsiglink that unregister/register the same UCSI instance across remoteproc restart then try to create an already existing debugfs directory and log:
debugfs: 'pmicglink.ucsi.0' already exists in 'ucsi'
Unregister debugfs entries as part of ucsiunregister(), and clear ucsi->debugfs after freeing it so repeated unregister paths remain safe.
drm/msm: Recover HW before retire hung submit
In the Linux kernel, the following vulnerability has been resolved:
staging: rtl8723bs: fix xmitframe/xmitbuf leaks on mgnt-frame error paths
issuebeacon(), issueprobersp() and issueasocrsp() obtain a management xmitframe together with its xmitbuf from the driver's fixed-size management-TX pools via allocmgtxmitframe(). On the normal path the frame is handed to dumpmgntframe(), which transfers ownership and eventually returns both objects to their pools (the frame and, for beacons, the buf in rtl8723bsmgntxmit(); other bufs via the pending-xmitbuf/TX-completion path).
Several error/edge paths return early after a successful allocmgtxmitframe() but before dumpmgntframe(), so ownership is never transferred and neither object is freed:
- issuebeacon(): beacon larger than 512 bytes - issueprobersp(): curnetwork->ielength > MAXIESZ - issueprobersp(): kzalloc() of the SSID scratch buffer fails - issueasocrsp(): pkttype is neither ASSOCRSP nor REASSOCRSP
Because allocmgtxmitframe() removes the frame and buf from their free lists (listdelinit) without placing them on any pending list, an orphaned pair is on no list and referenced by nobody, so it is only reclaimed at driver teardown. Repeated hits progressively exhaust the management-TX pools until allocmgtxmitframe() returns NULL and the interface can no longer send beacons or probe/assoc responses.
Free the frame and buffer on these paths, matching the existing correct error handling in issueassocreq().
bpf: Mark bpfrefcount field as unique
Bluetooth: hcicore: Fix race condition during device registration
btrfs: fix the possible bioclist memory leak during error
btrfs: do not force reloc root creation during qgroupaccountsnapshot()
In the Linux kernel, the following vulnerability has been resolved:
ipvs: fix reversed sequence option serialization
htonseq() expects the host-order source first and the unaligned network-order destination second. The version 1 sync sender passes these arguments in reverse for both sequence blocks. This leaves 24 bytes of the kmalloc-backed message unwritten. It may disclose stale heap data and replace the live connection sequence state with values read from the buffer.
Pass the connection sequence state as the source and the message payload as the destination for both blocks.
In the Linux kernel, the following vulnerability has been resolved:
bpf: Mark signal tracepoint siginfo arguments as scalar
The signalgenerate and signaldeliver tracepoints declare their info argument as a struct kernelsiginfo pointer. btfctxaccess() therefore treats it as a trusted pointer for tpbtf programs.
Signal delivery also uses SENDSIGNOINFO and SENDSIGPRIV as special values for this argument. Those values are zero and one respectively, and are not pointers. A tpbtf program can currently dereference either value and fault the kernel. In particular, signalgenerate can run from timer interrupt context, turning the fault into a kernel panic.
Record both tracepoints in rawtpnullargs[] and mark argument one as a non-pointer. This preserves scalar access to the cookie while rejecting direct and helper-mediated pointer use. Merely marking it nullable would not suffice because SENDSIGPRIV is nonzero.
In the Linux kernel, the following vulnerability has been resolved:
ASoC: Intel: avs: Fix unbalanced module reference count
straceopen() invokes trymoduleget() which on success takes the module reference. If any follow up operation causes straceopen() to fail, the refcount shall be put down.
In the Linux kernel, the following vulnerability has been resolved:
ASoC: Intel: avs: Refactor and fix initconfig access
Existing code accesses enties found in ->initconfigs array through indexes that are part of ->configids array. Those two are limited by: ->numinitconfigs and ->numconfigids respectively. Using ID larger or equal to ->numinitconfigs leads to out-of-bounds access:
avspathmodulesendinitconfigs() loop: (...) &acomp->tplg->initconfigs[ids[i]] ^ out-of-bounds candidate
Rather than adding another if-statement, refactor the code. There is no need to store the IDs, have a list of pointers to actual config-entries instead. As the verification of ->initconfig entries does not differ from verification of other types that are part of the topology.c file, simply reuse the code.
In the Linux kernel, the following vulnerability has been resolved:
net: bcmasp: fix txspbringfull() checking same slot cnt times
The loop initialised nextindex from intf->txspbindex on every iteration, so incrring() always produced the same result and only one slot was ever tested. Move the initialisation before the loop so each iteration advances nextindex and the function correctly checks that cnt consecutive descriptor slots are available before allowing a new transmission.
In the Linux kernel, the following vulnerability has been resolved:
tracing: Fix NULL pointer dereference in funcsetflag()
funcsetflag() dereferences tr->currenttraceflags before verifying that the current tracer is actually the function tracer. When the active tracer has been switched away from "function" (e.g., to "wakeuprt"), tr->currenttraceflags can be NULL, leading to a NULL pointer dereference and kernel crash.
The call chain that triggers this is:
traceoptionswrite() -> settraceroption() -> trace->setflag() / funcsetflag /
In funcsetflag(), the first operation is:
if (!!set == !!(tr->currenttraceflags->val & bit))
This dereferences tr->currenttraceflags unconditionally. The safety check that guards against a non-function tracer:
if (tr->currenttrace != &functiontrace) return 0;
is placed after the dereference, which is too late.
This was observed with the following crash dump:
BUG: unable to handle page fault at 0000000000000000 RIP: funcsetflag+0xd
Call Trace: settraceroption+0x27 traceoptionswrite+0x75 vfswrite+0x12a ksyswrite+0x66 dosyscall64+0x5b
RIP: ffffffff914c973d RSP: ff67ec88b01dfdf0 RFLAGS: 00010202 RAX: 0000000000000000 RBX: ff3a826e80354580 RCX: 0000000000000001 RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffffff93918080
The disassembly confirms the fault:
funcsetflag+0: mov 0x1f08(%rdi), %rax ; RAX = tr->currenttraceflags = NULL funcsetflag+13: mov (%rax), %eax ; page fault: dereference NULL
At the time of the crash: tr->currenttraceflags = 0x0 (NULL) tr->currenttrace = wakeuprttracer (not functiontrace)
The scenario is that a process opens a function tracer option file (such as "funcstacktrace"), then the current tracer is switched to another tracer (e.g., "wakeuprt"), which sets currenttraceflags to NULL. When the process subsequently writes to the option file, funcsetflag() is invoked and crashes on the NULL dereference.
Fix this by moving the currenttrace check before the currenttraceflags dereference, so that funcsetflag() returns early when the function tracer is not active.
gpio: eic-sprd: use rawspinlockt in the irq startup path
In the Linux kernel, the following vulnerability has been resolved:
iouring/nop: fix file reference leak with IOSQEFIXEDFILE
NOP file-acquisition support choses between a fixed (registered) file and a normal fget()'d file based on its own IORINGNOPFIXEDFILE flag in sqe->nopflags. However, a request's REQFFIXEDFILE is set independently from the generic IOSQEFIXEDFILE sqe flag during request init, before the issue handler runs.
If a NOP is submitted with IOSQEFIXEDFILE set (so REQFFIXEDFILE is set) but without IORINGNOPFIXEDFILE, ionop() takes the normal path and grabs a real reference via iofilegetnormal(). On completion, ioputfile() only drops the reference when REQFFIXEDFILE is clear, so the fget()'d file is never released and leaks:
BUG: memory leak unreferenced object 0xffff88800f42c240 (size 176): kmemcacheallocnoprof+0x358/0x440 allocemptyfile+0x57/0x180 pathopenat+0x44/0x1e50 dofileopen+0x121/0x200 dosysopenat2+0xa7/0x150 x64sysopenat+0x82/0xf0
Decide between fixed and normal file acquisition from REQFFIXEDFILE, the same way ioassignfile() does for every other opcode, and fold IORINGNOPFIXEDFILE into REQFFIXEDFILE at prep time.
In the Linux kernel, the following vulnerability has been resolved:
iouring/io-wq: re-check IOWQBITEXIT for each linked work item
commit 10dc95939817 ("iouring/io-wq: check IOWQBITEXIT inside work run loop") fixed the obvious case where ioworkerhandlework() took one exit-bit snapshot before draining pending work, but the fix stops one level too early.
ioworkerhandlework() now re-checks IOWQBITEXIT in its outer work run loop, yet it still snapshots that bit once before processing a whole dependent linked-work chain. If iowqexitstart() sets IOWQBITEXIT after the first linked item has started, the remaining linked items can still reuse stale dokill = false, skip IOWQWORKCANCEL, and continue running after exit has begun.
Move the check further inside, so it covers linked items too. Note: this is a syzbot special as it loves setting up tons of slow linked work on weird devices like msr that take forever to read, and immediately close the ring. Exit then takes a long time.
In the Linux kernel, the following vulnerability has been resolved:
mm/shrinker: do not hold RCU lock in shrinkerdebugfscountshow()
Reading the debugfs "count" file of a memcg-aware shrinker can sleep inside an RCU read-side critical section:
BUG: sleeping function called from invalid context at kernel/cgroup/rstat.c:421 RCU nest depth: 1, expected: 0 cssrstatflush memcgroupflushstats zswapshrinkercount shrinkerdebugfscountshow
shrinkerdebugfscountshow() invokes the ->countobjects() callback under rcureadlock(). The zswap callback flushes memcg stats via cssrstatflush(), which may sleep, so it must not run under RCU.
The RCU lock is not needed here. memcgroupiter() takes RCU internally and returns a memcg holding a css reference (dropped on the next iteration or by memcgroupiterbreak()), so the memcg stays alive without it. The shrinker is kept alive by the open debugfs file: shrinkerfree() removes the debugfs entries via debugfsremoverecursive(), which waits for in-flight readers to drain, before callrcu(..., shrinkerfreercucb). The sibling "scan" handler already invokes the sleeping ->scanobjects() callback with no RCU section.
Drop the rcureadlock()/rcureadunlock().
In the Linux kernel, the following vulnerability has been resolved:
mm: shrinker: fix NULL pointer dereference in debugfs
shrinkerdebugfsadd() creates both "count" and "scan" debugfs files unconditionally.
That assumes every shrinker implements both countobjects() and scanobjects(), which is not guaranteed. For example, the xen-backend shrinker sets countobjects() but leaves scanobjects() NULL, so writing to its scan file calls through a NULL function pointer and panics the kernel:
BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. Call Trace: <TASK> shrinkerdebugfsscanwrite+0x12e/0x270 fullproxywrite+0x5f/0x90 vfswrite+0xde/0x420 ? filpflush+0x75/0x90 ? filpclose+0x1d/0x30 ? dodup2+0xb8/0x120 ksyswrite+0x68/0xf0 ? filpflush+0x75/0x90 dosyscall64+0xb3/0x5b0 entrySYSCALL64afterhwframe+0x76/0x7e
The count path has the same issue in principle if a shrinker omits countobjects().
To fix it, only create "count" and "scan" debugfs files when the corresponding callbacks are present.
In the Linux kernel, the following vulnerability has been resolved:
mm/swap: add condresched() in swapreclaimfullclusters to prevent softlockup
We hit a real softlockup in an internal stress test environment. The workload was LTP memory/swap stress on a large arm64 machine, with 320 CPUs, about 1TB memory and an 8.6GB swap device. The system was under heavy load and the swap device had a large number of full clusters. The softlockup was triggered during a stress test after about 3 days.
So, add periodic condresched() calls during large fullclusters reclaim operations to prevent softlockup issues.
Detailed call trace as follow:
PID: 3817773 TASK: ffff0883bb28b780 CPU: 48 COMMAND: "kworker/48:7" #0 [ffff800080183d10] crashkexec at ffffa4c1361e5de4 #1 [ffff800080183d90] panic at ffffa4c1360d5e9c #2 [ffff800080183e20] watchdogtimerfn at ffffa4c136231fa8 ... #16 [ffff8000c4ad3cb0] swapcachedelfolio at ffffa4c1363e1614 #17 [ffff8000c4ad3ce0] trytoreclaimswap at ffffa4c1363e4bfc #18 [ffff8000c4ad3d40] swapreclaimfullclusters at ffffa4c1363e5474 #19 [ffff8000c4ad3da0] swapreclaimwork at ffffa4c1363e550c #20 [ffff8000c4ad3dc0] processonework at ffffa4c136102edc #21 [ffff8000c4ad3e10] workerthread at ffffa4c136103398 #22 [ffff8000c4ad3e70] kthread at ffffa4c13610d95c
In the Linux kernel, the following vulnerability has been resolved:
mm: swapcgroup: fix NULL deref in lookupswapcgroupid on swapless host
lookupswapcgroupid() passes swapcgroupctrl[type].map to swapcgroupidlookup() without checking that the type was ever registered via swapcgroupswapon(). On a swapless host every ctrl->map is NULL, so swapcgroupidlookup() dereferences NULL + a scaled swpoffset().
Since commit bea67dcc5eea ("mm: attempt to batch free swap entries for zappterange()"), zappterange() -> swapptebatch() calls lookupswapcgroupid() on any non-present, non-none PTE that decodes as a real swap entry, without first validating it against swapinfo[]. A single PTE corrupted into a type-0 swap entry takes the host down at process exit.
We hit this in production on a swapless 6.12.58 host: ~1s of "getswapdevice: Bad swap file entry 3f800204222bb" (doswappage() being correctly defensive about the same entry) followed by
BUG: unable to handle page fault for address: 000003f800204220 RIP: 0010:lookupswapcgroupid+0x2b/0x60 Call Trace: swapptebatch+0xbf/0x230 zappterange+0x4c8/0x780 unmappagerange+0x190/0x3e0 exitmmap+0xd9/0x3c0 doexit+0x20c/0x4b0
syzbot has reported the identical stack.
The source of the PTE corruption is a separate bug; this change makes the teardown path as robust as the fault path already is. Every other caller of lookupswapcgroupid() is downstream of a getswapdevice() that has already validated the entry, so the new branch is cold.
Bluetooth: btmtksdio: fix infinite loop in btmtksdiotxrxwork()
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: ISO: avoid NULL deref of conn in isoconnbigsync()
isoconnbigsync() drops the socket lock to call hcigetroute() and then re-acquires it, but dereferences isopi(sk)->conn->hcon afterwards without re-checking that conn is still valid.
While the lock is dropped, the connection can be torn down under the same socket lock: isodisconncfm() -> isoconndel() -> isochandel() sets isopi(sk)->conn to NULL (and the broadcast teardown path can also clear conn->hcon on its own). When isoconnbigsync() re-acquires the lock and reads conn->hcon, conn may be NULL, causing a NULL pointer dereference (hcon is the first member of struct isoconn).
This path is reached from isosockrecvmsg() for a PA-sync broadcast sink socket (BTSKDEFERSETUP | BTSKPASYNC), so the dropped-lock window can race with connection teardown driven by controller events.
Re-validate isopi(sk)->conn and its hcon after re-acquiring the socket lock and bail out if the connection went away, as already done in the sibling isosockrebindbc().
In the Linux kernel, the following vulnerability has been resolved:
firmwareloader: fix device reference leak in firmwareuploadregister()
firmwareuploadregister() -> fwcreateinstance() -> deviceinitialize()
After fwcreateinstance() succeeds, the lifetime of the embedded struct device is expected to be managed through the device core reference counting, since fwcreateinstance() has already called deviceinitialize().
In firmwareuploadregister(), if alloclookupfwpriv() fails after fwcreateinstance() succeeds, the code reaches freefwsysfs and frees fwsysfs directly instead of releasing the device reference with putdevice(). This may leave the reference count of the embedded struct device unbalanced, resulting in a refcount leak.
The issue was identified by a static analysis tool I developed and confirmed by manual review. Fix this by using putdevice(fwdev) in the failure path and letting fwdevrelease() handle the final cleanup, instead of freeing the instance directly from the error path.
cpufreq: Fix hotplug-suspend race during reboot
In the Linux kernel, the following vulnerability has been resolved:
proc: protect ptracemayaccess() with execupdatelock (part 1)
Fix the easy cases where procfs currently calls ptracemayaccess() without execupdatelock protection, where the fix is to simply add the extra lock or use mmaccess():
- dotaskstat(): grab execupdatelock - procpidwchan(): grab execupdatelock - procmapfileslookup(): use mmaccess() instead of gettaskmm() - procmapfilesreaddir(): use mmaccess() instead of gettaskmm() - procnsgetlink(): grab execupdatelock - procnsreadlink(): grab execupdatelock
In the Linux kernel, the following vulnerability has been resolved:
posix-cpu-timers: Fix pid refcount leak in docpunanosleep() error path
In docpunanosleep(), posixcputimercreate() takes a pid reference via getpid() and stores it in timer.it.cpu.pid. If the subsequent posixcputimerset() call fails, the function returns immediately without calling posixcputimerdel() to release the pid reference, causing a leak.
Fix it by calling posixcputimerdel() before the unlock-and-return on the error path, consistent with the other exit paths in the same function.
In the Linux kernel, the following vulnerability has been resolved:
s390: Revert support for DCACHEWORDACCESS
loadunalignedzeropad() reads eight bytes from unaligned addresses and may cross page boundaries. It handles exceptions which may happen if reading from the second page results in an exception.
For pages which are donated to the Ultravisor for secure execution purposes the dosecurestorageaccess() exception handler however does not handle such exceptions correctly. Such an exception may result in an endless exception loop which will never be resolved.
An attempt to fix this [1] turned out to be not sufficient. For now revert loadunalignedzeropad() until this problem has been resolved in a proper way.
Note that the implementation of loadunalignedzeropad() itself is correct. The revert is just a temporary workaround until there is complete fix for secure storage access exceptions.
[1] commit b00be77302d7 ("s390/mm: Add missing secure storage access fixups for donated memory")
In the Linux kernel, the following vulnerability has been resolved:
hfs/hfsplus: zero-initialize buffer in hfsbnoderead
hfsbnoderead() can return early without writing to the output buffer when isbnodeoffsetvalid() fails or when checkandcorrectrequested length() corrects the length to zero. Callers such as hfsbnoderead u16() and hfsbnodereadu8() pass stack-allocated buffers and use the result unconditionally, leading to KMSAN uninit-value reports.
Rather than initializing at each individual call site, zero the buffer at the start of hfsbnoderead() before any validation checks. This ensures all callers in both hfs and hfsplus get a deterministic zero value regardless of which early-return path is taken.
In the Linux kernel, the following vulnerability has been resolved:
nilfs2: reject CLEANSEGMENTS ioctl with out-of-range segment numbers
Syzbot reported a hung task in nilfstransactionbegin() where multiple tasks performing chmod() on a nilfs2 mount blocked for over 143 seconds waiting to acquire nssegctorsem for read:
INFO: task syz.0.17:5918 blocked for more than 143 seconds. Call Trace: schedule+0x164/0x360 rwsemdownreadslowpath+0x6d9/0x940 downread+0x99/0x2e0 nilfstransactionbegin+0x364/0x710 fs/nilfs2/segment.c:221 nilfssetattr+0x124/0x2c0 fs/nilfs2/inode.c:921 notifychange+0xc1a/0xf40 chmodcommon+0x273/0x4a0 dofchmodat+0x12d/0x230
The writer holding nssegctorsem was a concurrent NILFSIOCTLCLEANSEGMENTS caller, stuck inside printk while emitting per-element warnings from nilfssufileupdatev():
nilfsmsg+0x373/0x450 fs/nilfs2/super.c:78 nilfssufileupdatev+0x21c/0x6d0 fs/nilfs2/sufile.c:186 nilfssufilefreev fs/nilfs2/sufile.h:93 [inline] nilfsfreesegments fs/nilfs2/segment.c:1140 [inline] nilfssegctorcollectblocks fs/nilfs2/segment.c:1261 [inline] nilfssegctordoconstruct+0x1f55/0x76c0 nilfscleansegments+0x3bd/0xa50 nilfsioctlcleansegments fs/nilfs2/ioctl.c:922 [inline] nilfsioctl+0x261f/0x2780
The root cause is that user-supplied segment numbers are not validated before nilfscleansegments() begins doing work; the range check on each segnum is performed deep inside the call chain by nilfssufileupdatev(), which emits a nilfswarn() per invalid entry while still holding the segctor lock and the sufile misem. Under load (repeated invocations across multiple mounts saturating the global printk path), the cumulative printk latency keeps nssegctorsem held long enough to trip the hungtask watchdog, blocking concurrent operations such as chmod() that need nssegctorsem for read.
Fix by validating the contents of kbufs[4] in nilfscleansegments() immediately after acquiring nssegctorsem via nilfstransactionlock(). Holding nssegctorsem serializes the check against nilfsioctlresize(), which can modify nsnsegments, so the validation uses a consistent value. Out-of-range segment numbers are rejected with -EINVAL before any segment-cleaning work begins, so the bad entries never reach the per-element diagnostic path inside nilfssufileupdatev().