In the Linux kernel, the following vulnerability has been resolved:
net: extend IPv6 exthdr detection of tunneled packets
Commit c4336a07eb6b ("net: correctly handle tunneled traffic on IPV6CSUM GSO fallback") split skbgsohasextensionhdr() into mutually exclusive branches on skb->encapsulation. This did not yet address all paths:
1. With skb->encapsulation set, the outer header is not checked. IPv6 tunnels such as ip6gre and ip6tunnel add an outer Destination Options header by default (encaplimit). Their GSO packets skip software GSO, then skbcsumhwoffloadhelp() sees the outer extension header and calls skbchecksumhelp() on the GSO skb, which warns and drops it.
2. Tunnels over IPv6 without an outer transport header, such as ip6tunnel, leave skb->transportheader at the inner transport header. skbnetworkheaderlen() then spans the outer IPv6, tunnel and inner IP headers, a false positive.
3. UDP tunnels without an inner network header, such as SCTP-in-UDP or PSP, have no inner IPv6 header to check. Decide on the outer header alone.
4. Directly dereferencing inneriphdr(skb)->version without skbheaderpointer() is unsafe.
Instead, check ipv6exthdr(nexthdr) on the outer IPv6 header and, if set, on the inner IPv6 header. Read the headers with skbheaderpointer(). Keep the skbnetworkheaderlen() check when !skb->encapsulation to also catch encapsulated packets without skb->encapsulation (e.g., virtio).
Use the same helper in skbcsumhwoffloadhelp(). Its open coded test has the false positive of (2) and ignores the inner header.
Background: checksum offload of tunneled packets invariants:
Non-GSO skb: - If the inner packet is CHECKSUMPARTIAL, Local Checksum Offload computes the outer checksum in software and the device offloads only the inner L4 checksum. - If the inner packet is CHECKSUMNONE (e.g., SCTP-in-UDP, ESP-in-UDP, Remote Checksum Offload), the device offloads the outer UDP or GRE checksum instead.
GSO skb: - A device with NETIFFGSOUDPTUNNELCSUM or NETIFFGSOGRECSUM computes both inner and outer checksums per segment. The outer checksum is seeded with only the pseudo-header checksum.
A NETIFFIPV6CSUM device must parse through the outer headers to reach the inner ones.
In the Linux kernel, the following vulnerability has been resolved:
vcscreen: reload vc pointer before if (ret) in vcswrite() to avoid UAF
The reload of 'vc' added by commit 8fb9ea65c9d1 ("vcscreen: reload load of struct vcdata pointer in vcswrite() to avoid UAF") sits after the 'if (ret)' block, so the copy-failure break path exits the loop without reloading vc. If the vc was kfree()'d via vcportdestruct during the unlocked copyfromuser() window, the post-loop 'if (written && vc) vcsscrupdated(vc)' is reached with a stale non-NULL vc. The '&& vc' guard from commit a287620312dc ("vcscreen: fix null-ptr-deref in vcsnotifier() during concurrent vcswrite") only handles the NULL case, not this stale-non-NULL case; vcsnotifier() then reads param->vc->vcnum from freed memory:
BUG: KASAN: slab-use-after-free in vcsnotifier+0x7c/0xd0 Read of size 2 at addr ffff888007149190 Call Trace: vcsnotifier+0x7c/0xd0 atomicnotifiercallchain+0x70/0xa0 vcsscrupdated+0x77/0xa0 vcswrite+0x71b/0x7e0 Allocated by task: vcallocate -> coninstall -> ttyopen Freed by task: kfree <- vtioctl (VTDISALLOCATE -> vcportdestruct)
Move the reload to immediately after consolelock(), before 'if (ret)', so every break path below passes a fresh vc to the post-loop vcsscrupdated().
ALSA: caiaq: unregister the input device when probe fails
drm/amd/display: check dcstatecreatecopy() for NULL in dmsuspend
In the Linux kernel, the following vulnerability has been resolved:
USB: cdc-acm: skip URB restart in portshutdown if disconnected
acmportshutdown() is called from the tty-port machinery whenever the last user closes the port. acmdisconnect() sets acm->disconnected and calls ttyportttyvhangup(), which eventually triggers portshutdown(). At that point acmdisconnect() has already called acmpoisonurbs() and is about to free the control and read URBs.
However, acmportshutdown() unconditionally calls acmunpoisonurbs() and, when the ALWAYSPOLLCTRL quirk is set, immediately re-submits the ctrlurb and all read URBs. If the concurrent acmdisconnect() then frees those URBs and their DMA buffers while they are in-flight, the result is a use-after-free in acmctrlirq() or acmreadbulkcallback() accessing the freed DMA memory.
Fix by checking acm->disconnected after draining the delayed anchor and returning early: if we are in a disconnect path the URBs must remain poisoned and must not be resubmitted.
The early return is placed after the delayed-anchor drain loop because that loop only cancels write-side accounting (wb->use = false and autopm counter) and does not touch the hardware path.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: discard post-EOF pagecache when extending a file via clone range
cifsremapfilerange() discarded the pagecache only for the folios overlapping the destination region, so when a clone extends the file the folio straddling the old EOF - which may hold data dirtied past EOF through an mmap - was never dropped and became visible as file content once the file was extended.
Start the discard at the smaller of fstart and the old EOF. isize is still old here, so nothing past the old EOF is flushed to the server.
In the Linux kernel, the following vulnerability has been resolved:
tcp: Skip condresched() in inetcsklistenstop() under BPF context
bpfsockdestroy() runs from the tcp iterator, under rcureadlock(). If the sock is a listener that still has children in its accept queue, tcpabort() ends up in inetcsklistenstop() and the condresched() there trips the debug check:
BUG: sleeping function called from invalid context at net/ipv4/inetconnectionsock.c:1523 inatomic(): 0, irqsdisabled(): 0, nonblock: 0, pid: 628, name: testprogs preemptcount: 0, expected: 0 RCU nest depth: 1, expected: 0 locks held by testprogs/628: 3, last CPU#3: #0: ffff8881158cee18 (&p->lock){+.+.}-{4:4}, at: bpfseqread+0x56/0x1210 #1: ffff8881106bb858 (sklock-AFINET6){+.+.}-{0:0}, at: bpfitertcpseqshow+0x32b/0x4b0 #2: ffffffffb435af20 (rcureadlock){....}-{1:3}, at: bpfiterrunprog+0x46b/0xde0 CPU: 3 UID: 0 PID: 628 Comm: testprogs Tainted: G W 7.2.0+ #65 PREEMPT Tainted: [W]=WARN Call Trace: <TASK> dumpstacklvl+0xc1/0xf0 dumpstack+0x10/0x20 mightresched+0x3d2/0x610 inetcsklistenstop+0x7b/0xbf0 tcpabort+0x23b/0x3b0 bpfsockdestroy+0xfc/0x140 bpfprog448133d24601754fitertcp6server+0x81/0x8a bpfiterrunprog+0x538/0xde0 bpfitertcpseqshow+0x26b/0x4b0 bpfseqread+0x424/0x1210 vfsread+0x197/0xe40 ksysread+0x119/0x240 x64sysread+0x72/0xc0 x64syscall+0x647/0x27e0 dosyscall64+0xe5/0x610 entrySYSCALL64afterhwframe+0x76/0x7e RIP: 0033:0x7fad39b28aca RSP: 002b:00007ffc381c61c0 EFLAGS: 00000246 ORIGRAX: 0000000000000000 RAX: ffffffffffffffda RBX: 00007ffc381c6a88 RCX: 00007fad39b28aca RDX: 0000000000000032 RSI: 00007ffc381c6250 RDI: 0000000000000014 RBP: 00007ffc381c61e0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003 R13: 0000000000000000 R14: 000055f077c1bbb0 R15: 00007fad3a0f3000 </TASK>
The commit that added the kfunc already guards locksock() in tcpabort() and udpabort() with hascurrentbpfctx(), but missed the listener path. Do the same for the condresched(). The loop runs inside the iterator's rcureadlock(), it must not reschedule or report a quiescent state there.
bpf: Avoid soft lockup in htabmaplookupanddeletebatch()
bpf: Fix out-of-bounds read of rttmin in sockops
HID: amdsfh: Validate PCI BAR size before mapping
In the Linux kernel, the following vulnerability has been resolved:
squashfs: Add dictionary size range check to prevent shift-out-of-bounds
When an abnormal SquashFS image (COMPOPTS flag is 1 but dictionary size is 0) is mounted, and performs shift operations using dictionarysize, the shift exponent is -1, causing a shift-out-of-bounds.
Detail as below: squashfscompopts(msblk, buffer, length) squashfsxzcompopts() if (compopts) n = ffs(opts->dictsize) - 1;<----opts->dictsize=0, n=-1 if (opts->dictsize != (1 << n) && opts->dictsize != (1 << n) + (1 << (n + 1))) <----shift-out-of-bounds
Fix it by adding a dictionary size range check before the shift operation.
In the Linux kernel, the following vulnerability has been resolved:
xsk: Use a 32-bit compare in xskmapgenlookup
xskmapgenlookup() loads a u32 key and compares it with maxentries using BPFJMPIMM. BPF immediates are sign-extended to 64 bits, so a maxentries value of 0x80000000 or higher becomes a threshold larger than every zero-extended 32-bit key. An out-of-range index then skips the bounds check and the generated lookup reads past xskmap[].
Compare with BPFJMP32IMM so the check stays in 32-bit unsigned range.
In the Linux kernel, the following vulnerability has been resolved:
net/sched: clsu32: fix manual hash table handle IDR aliasing
A u32 hash table created with an explicit handle ('tc filter add ... handle 801: u32 divisor N') keys its IDR entry on the raw handle, while the destroy paths free it under handle2id(handle). The two key domains disagree for handles in the 0x800..0xFFF htid range: handle2id() folds them back into the auto-allocated id space (1..0x7FF).
A manual table therefore leaves its raw-keyed IDR entry unreachable on delete (a permanent leak), and its delete can drop the idr entry of an unrelated live auto table. A later auto allocation can then hand out a handle that aliases the live manual table; u32lookupht() first-match routes lookups and TCAU32LINK for that htid to the wrong table.
Key the divisor-path alloc on handle2id(handle) so allocation and removal share one key domain. A manual handle that maps onto an id already in use is rejected with -ENOSPC, and auto allocation skips ids held by live manual tables.
Conditions to recreate: ip link add test0 type dummy tc qdisc add dev test0 clsact tc filter add dev test0 ingress protocol ip pref 1 \ handle 801: u32 divisor 16 tc filter add dev test0 ingress protocol ip pref 2 u32 divisor 16 tc -d filter show dev test0 ingress | grep 'fh 801:' # unpatched: two live tables with handle 0x80100000 (the pref 2 root # hnode is auto-allocated id 1); patched: the auto hnode takes id 2.
Also tested with a poc with a live u32 table on the block, add/delete a manual table 'handle 901: u32 divisor 1' twice; unpatched, the re-add fails with -ENOSPC because the raw key leaked on the first delete.
bpf: Restrict CO-RE poisoning to relocatable instructions
In the Linux kernel, the following vulnerability has been resolved:
netfilter: flowtable: publish HWDEAD after worker is done
flowoffloadworkdel() sets NFFLOWHWDEAD before the work handler clears NFFLOWHWPENDING. Once a flow is both HWDYING and HWDEAD, a concurrent garbage collection pass can remove it and schedule it for RCU freeing.
The offload worker holds neither an RCU read lock nor a reference to the flow. If it is preempted after publishing HWDEAD, the RCU callback can free the flow before the worker resumes and clears HWPENDING, resulting in a use-after-free.
Move HWDEAD publication to the common worker epilogue after the pending bit is cleared, making it the final flow access by destroy work. Order all preceding flow accesses before publishing the bit that allows garbage collection to free the object.
In the Linux kernel, the following vulnerability has been resolved:
net/sched: actct: don't WARN on benign flowoffloadalloc() failure
flowoffloadalloc() returns NULL when the conntrack entry is dying (e.g. raced with a conntrack flush) or when the GFPATOMIC allocation fails; both are expected under load and neither is a kernel bug. This path runs from softirq on every committed packet, so with paniconwarn=1 an unprivileged user can panic the box just by racing a conntrack flush against a tc ... action ct commit classifier.
Reproduced with a custom repro under QEMU: a small, fixed set of UDP flows through tc filter ... action ct commit on lo, raced against threads flooding bare ctnetlink CTDELETE (flush) requests. Hits WARNING: net/sched/actct.c:437 (tcfctflowtableadd(), inlined into tcfctact() in this build) within ~15s on the unpatched kernel; same setup is clean on the patched kernel. The fix itself is behavior-preserving: both branches already did goto erralloc before and after, only the WARN is removed.
In the Linux kernel, the following vulnerability has been resolved:
net: gue: reject invalid REMCSUM offsets
The REMCSUM option carries an absolute checksum start and checksum field offset. gueremcsum() passes them to skbremcsumprocess(), whose partial path stores offset - start in the u16 skb->csumoffset variable. If offset is less than start, this underflows.
A forwarded packet can retain CHECKSUMPARTIAL and reach a NETIFFHWCSUM driver which trusts the metadata, leading skbcopyandcsumdev() to write two bytes about 64 KiB beyond the destination buffer.
Reject reversed tuples in validategueflags(), after the existing length validation, so all GUE parsers enforce the ordering in one place.
In the Linux kernel, the following vulnerability has been resolved:
net: ethernet: mtkethsoc: unregister netdevices in case of probe failure
If registernetdev() fails for one of the MTKMAXDEVS devices in mtkprobe(), the error path jumps to errdeinitppe, skipping mtkunregdev(). The previously registered netdevices are then freed by mtkfreedev() while still in NETREGREGISTERED state, hitting the BUGON(dev->regstate != NETREGUNREGISTERED).
Route the registernetdev() failure to errunregnetdev so the netdevices registered so far are properly unregistered before being freed.
In the Linux kernel, the following vulnerability has been resolved:
net: usb: catc: bound the RX packet length in catcrxdone()
catcrxdone() walks a multi-packet URB, reading a two-byte length from each packet header. Its bound, pktlen > urb->actuallength, ignores the header offset and compares against the whole transfer rather than the bytes left from pktstart, so a crafted packet header makes skbcopytolineardata() read past the buffer.
A length below ETHHLEN is also accepted, including zero, and ethtypetrans() then reads a MAC header from the uninitialised tailroom of a shorter skb. The isf5u011 branch takes its length straight from the transfer, so a zero-length URB reaches the same path.
Track the bytes remaining from the current packet, and reject a header that does not fit, a length past what is left, and a length below an Ethernet header.
A transfer shorter than an Ethernet header, including a zero-length one, previously became a runt skb passed to netifrx() and counted as received; it is now counted in rxlengtherrors and ends the walk.
In the Linux kernel, the following vulnerability has been resolved:
net/sched: schhfsc: bound the classify inner-filter walk with a drift budget
hfscclassify() applies the "filter may only point downwards" level check only when the filter result carries no bound class. A filter created with a flowid gets res.class set once at bind time, so the check never runs for it during classification. hfscadjustlevels() can later raise a class's level without revalidating existing bindings, leaving two binds that were each legal at bind time pointing at each other; the classify walk then bounces between two interior classes forever with the qdisc lock held and BH disabled — a soft lockup from a single packet. The stuck walk trips the watchdog:
watchdog: BUG: soft lockup - CPU#3 stuck for 13s! [ping:444] RIP: 0010:u32classify+0x542/0x17f0 ... tcfclassify+0x66/0xa0 hfscenqueue+0x166/0xdf0
Bound the traversal with a budget of non-descending hops, the only way a configured walk can move without descending the class tree once levels drift after bind time. The budget is cumulative over the whole walk and is deliberately not reset on a descending hop: a chain that alternates a descent with a lateral hop would return the budget every lap and never trip. Descending hops never decrement it, so legitimately deep trees are unaffected and a terminating lateral chain still classifies normally. Drop the packet with a rate-limited warning once the budget is exhausted, mirroring the merged HTB fix.
This is a follow-up to commit 729c4896ab82 ("net/sched: schhtb: limit htbclassify inner-class filter hops"), which bounded the same classify loop on the HTB side but left the HFSC walk unbounded.
Conditions to recreate the bug: - CONFIGNETSCHED, CONFIGNETSCHHFSC, CONFIGNETCLSU32, CONFIGLOCKUPDETECTOR. - Build a cycle with two legal-at-bind-time flowid binds and a level drift: class X 1:1 (child of root) with leaf child 1:10; class Y 1:2 (sibling of X) with children 1:20 and 1:200; root u32 filter flowid 1:1; filter on X flowid 1:2 (legal when Y is a leaf); after Y's level rises to 2, filter on Y flowid 1:1 (legal then). Send one packet (ping on the device). Unfixed kernel: classify spins with the qdisc lock held; with softlockuppanic=1 it panics. - Reachable from unprivileged user via unshare -Urn (CAPNETADMIN).
drm/virtio: fix object leak when drmgemhandlecreate() fails
drm/virtio: fix object leak in virtiogpuresourcecreateioctl()
drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach
Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough
In the Linux kernel, the following vulnerability has been resolved:
net: usb: sr9700: include receive overhead in the length check
The receive fixup subtracts the Ethernet CRC from the reported packet length, but compares that payload length against the whole remaining receive buffer. The following copy starts after the three-byte header, and the cursor advance consumes both that header and the four-byte CRC.
Require the payload to fit after SRRXOVERHEAD before copying it or advancing to the next packet. The loop already ensures that the remaining buffer is larger than the overhead, so the subtraction is safe.
The issue was found by our static-analysis tool.
In the Linux kernel, the following vulnerability has been resolved:
s390/debug: Fix NULL pointer dereference in debuginfocopy()
When debugregisterstatic() fails, it clears areas, activepages and activeentries but leaves the area bounds unchanged. Copying such an area, either by opening its view file or via debugdump(), makes debuginfocopy() dereference the NULL pointers.
Skip the copy loop when the source has no areas.
bpf: Fix bounds check for skb-backed dynptrs
bpf: Fix bpfsock context code generation
bpf, sockmap: Reject maxentries > INTMAX in sockmapalloc
In the Linux kernel, the following vulnerability has been resolved:
sctp: hold asoc or transport before modtimer() in timer handlers
Take the association or transport reference before rearming a timer in the timer handlers.
The existing code calls modtimer() before taking the reference needed by the rearmed timer without holding the sock lock. This creates a race with timer cleanup: if the timer is deleted after modtimer() returns but before the reference is taken, the cleanup path can drop the timer's reference and destroy the transport or association. The timer handler then takes a reference on the already freed object and eventually drops it, causing a refcount underflow.
Hold the object before modtimer() and drop the reference if modtimer() reports that the timer was already pending in timer handlers. Apply the same ordering to the proto-unreachable path, which can rearm a transport timer outside the timer handlers without holding the sock lock.