See how linux kernel compares to other vendors in security performance
In the Linux kernel, the following vulnerability has been resolved:
crypto: marvell/octeontx - fix DMA cleanup using wrong loop index
The sgcleanup path used list[i] instead of list[j] when unmapping DMA buffers, leaking successfully mapped entries and repeatedly unmapping the failed one.
A system does not present an appropriate legal message or warning to a user who is accessing it.
In the Linux kernel, the following vulnerability has been resolved:
net: serialize netifrunning() check in enqueuetobacklog()
Syzbot reported a KASAN slab-use-after-free in fibruleslookup().
The root cause is a race condition where packets can escape the backlog flushing during device unregistration (e.g., during netns exit).
Commit e9e4dd3267d0 ("net: do not process device backlog during unregistration") introduced a lockless netifrunning() check in enqueuetobacklog() to prevent queuing packets to an unregistering device.
However, this creates a TOCTOU race window.
A lockless transmitter (like vethxmit) can pass the check before devclose() clears IFFUP. If the transmitter is then delayed, flushallbacklogs() can run and finish before the transmitter grabs the backlog lock and queues the packet. The packet then escapes the flush and triggers UAF later when processed.
Fix this by moving the netifrunning() check inside the backlog lock. This serializes the check with the flush work (which also grabs the lock). We then either queue the packet before the flush runs (so it gets flushed), or check netifrunning() after the flush/close completes (so it gets dropped).
batman-adv: v: stop OGMv2 on disabled interface
In the Linux kernel, the following vulnerability has been resolved:
batman-adv: tpmeter: avoid use of uninit sender vars
apparmor: fix use-after-free in rawdata dedup loop
In the Linux kernel, the following vulnerability has been resolved:
block: recompute nrintegritysegments in blkinsertclonedrequest
blkinsertclonedrequest() already recomputes nrphyssegments against the bottom queue, because "the queue settings related to segment counting may differ from the original queue." The exact same reasoning applies to integrity segments: a stacked driver's underlying queue can have tighter virtboundarymask, segboundarymask, or maxsegmentsize than the top queue, in which case blkrqcountintegritysg() against the bottom queue produces a different count than the cached rq->nrintegritysegments inherited from the source request by blkrqprepclone().
When the cached count is lower than the bottom queue's actual count, blkrqmapintegritysg() trips
BUGON(segments > rq->nrintegritysegments);
on dispatch. The same families of stacked setups that motivated the existing nrphyssegments recompute -- dm-multipath fanning out to nvme-rdma in particular -- can produce this.
Mirror the nrphyssegments handling: when the request carries integrity, recompute nrintegritysegments against the bottom queue and reject the request if it exceeds the bottom queue's maxintegritysegments. blkrqcountintegritysg() and queuemaxintegritysegments() are both already available via <linux/blk-integrity.h>, which blk-mq.c includes.
This closes a latent gap in the stacking contract and brings the integrity-segment accounting in line with the existing phys-segment accounting.
In the Linux kernel, the following vulnerability has been resolved:
net: gro: properly validate BIG TCP aggregation criteria
When GRO attempts to aggregate packets beyond GROLEGACYMAXSIZE (64KB), BIG TCP should only be permitted for plain IPv4 TCP and plain IPv6 TCP (with sufficient MAC header room to insert the temporary HBH jumbo header).
However, commit b1a78b9b9886 ("net: add support for ipv4 big tcp") loosened the check in skbgroreceive(), leading to several issues:
1. skbgroreceive() checked skbheadroom(p) instead of the actual space before the MAC header (p->macheader). Because skbheadroom(p) includes maclen, crafted frames (e.g. injected via AFPACKET) can pass the check with p->macheader < 8 bytes. When ipv6grocomplete() inserts the temporary HBH jumbo header, the memmove() starts before skb->head, causing an out-of-bounds write and wrapping skb->macheader. 2. It allowed non-IP protocols such as software VLAN (ETHP8021Q / ETHP8021AD) to aggregate beyond 64KB because p->protocol != ETHPIPV6 was true. 3. It checked p->encapsulation instead of NAPIGROCB(skb)->encapmark, allowing encapsulated flows (e.g. SIT / IPv6-in-IPv4) to aggregate beyond 64KB.
Fix skbgroreceive() to strictly enforce: - NAPIGROCB(skb)->proto == IPPROTOTCP - Not encapsulated (!NAPIGROCB(skb)->encapmark && !p->encapsulation) - Protocol must be either ETHPIP or ETHPIPV6 - If ETHPIPV6, p->macheader must be at least sizeof(struct hopjumbohdr)
Returning -E2BIG from skbgroreceive() ensures that packets which cannot become BIG TCP are cleanly flushed at <= 64KB and delivered intact without dropping.
This issue does not exist in mainline (7.0+) because the subsystem was rewritten in commit 81be30c1f5f2 ("net/ipv6: Drop HBH for BIG TCP on RX side"), making this fix relevant only for older stable branches like 6.18.y.
In the Linux kernel, the following vulnerability has been resolved:
seg6: reset IP6CB after IPv6 decapsulation
decapandvalidate() 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, ip6protocoldeliverrcu() uses that stale offset on the inner packet and reads beyond the skb head. KASAN reports:
BUG: KASAN: slab-out-of-bounds in ip6protocoldeliverrcu ip6protocoldeliverrcu+0x1118/0x1450 ip6inputfinish+0x11b/0x240 seg6localinputcore+0xed/0x2e0 lwtunnelinput+0x1e9/0x4e0 ipv6rthdrrcv+0x525f/0x6c50 ip6protocoldeliverrcu+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->skbiif because VRF processing can replace skbiif with the L3 master while IP6CB keeps the receiving interface. Preserve IP6SKBL3SLAVE for the same reason.
In the Linux kernel, the following vulnerability has been resolved:
smb: smbdirect: free completion queues with ibfreecq()
smbdirectconnectiondestroyqp() creates the send and receive completion queues with iballoccqany(), which for IBPOLLWORKQUEUE arms an internal completion handler that runs ibcqpollwork() on a workqueue. Tearing those CQs down with ibdestroycq() frees them without first cancelling that poll work.
If the provider posts a completion late -- for example Soft-RoCE (rxe) posting an RNR error from rxereceiver() after rdmadestroyqp() -- the handler re-queues ibcqpollwork() on the already-freed CQ, and a follow-on access faults in rxereqnotifycq().
Use ibfreecq(), which cancelworksync()es the poll work before freeing the CQ, so no completion handler can run against a freed queue.
[ 1236.599526] ================================================================== [ 1236.602142] BUG: KASAN: slab-use-after-free in ibcqpollwork+0xd0/0x1a0 [ 1236.605524] Read of size 8 at addr ffff888111865800 by task kworker/4:1H/82 [ 1236.609017] [ 1236.609270] CPU: 4 UID: 0 PID: 82 Comm: kworker/4:1H Not tainted 7.2.0-rc3-next-20260717-virtme #110 PREEMPT(lazy) [ 1236.609287] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 [ 1236.609498] Workqueue: ib-comp-wq ibcqpollwork [ 1236.609525] Call Trace: [ 1236.609536] <TASK> [ 1236.609545] dumpstack+0x21/0x60 [ 1236.609562] dumpstacklvl+0xc2/0x100 [ 1236.609573] printaddressdescription+0x77/0x200 [ 1236.609587] ? ibcqpollwork+0xd0/0x1a0 [ 1236.609597] printreport+0x58/0x70 [ 1236.609607] kasanreport+0x117/0x150 [ 1236.609623] ? ibcqpollwork+0xd0/0x1a0 [ 1236.609636] ? processscheduledworks+0x954/0x1600 [ 1236.609650] ibcqpollwork+0xd0/0x1a0 [ 1236.609662] ? processscheduledworks+0x954/0x1600 [ 1236.609674] processscheduledworks+0xc22/0x1600 [ 1236.609698] ? pfxprocessscheduledworks+0x10/0x10 [ 1236.609713] ? pfxassignwork+0x10/0x10 [ 1236.609726] ? lockisheldtype+0x7b/0x110 [ 1236.609741] workerthread+0x975/0xee0 [ 1236.609757] ? pfxdorawspinlock+0x10/0x10 [ 1236.609775] ? kthreadparkme+0x21e/0x260 [ 1236.609789] kthread+0x3a6/0x490 [ 1236.609800] ? pfxworkerthread+0x10/0x10 [ 1236.609809] ? pfxkthread+0x10/0x10 [ 1236.609820] retfromfork+0x55a/0xa20 [ 1236.609835] ? pfxretfromfork+0x10/0x10 [ 1236.609850] ? pfxkthread+0x10/0x10 [ 1236.609861] retfromforkasm+0x1a/0x30 [ 1236.609880] </TASK> [ 1236.609886] [ 1236.661292] Allocated by task 5076: [ 1236.662640] kasansavetrack+0x3e/0x80 [ 1236.663842] kasankmalloc+0x72/0x90 [ 1236.664763] kmallocnoprof+0x2b0/0x5d0 [ 1236.665356] iballoccq+0x284/0x1000 [ 1236.666573] iballoccqany+0x23e/0x340 [ 1236.668654] smbdirectconnectioncreateqp+0x6f7/0x1070 [ 1236.669757] smbdirectacceptconnectrequest+0x500/0x1ca0 [ 1236.672625] smbdirectlistenrdmaeventhandler+0x1655/0x1c50 [ 1236.673930] cmalistenhandler+0x1bf/0x260 [ 1236.674923] cmacmeventhandler+0x128/0x380 [ 1236.676926] cmaibreqhandler+0x2d3d/0x4de0 [ 1236.678368] cmprocesswork+0xb0/0x530 [ 1236.680454] cmqueueworkunlock+0xb1/0x230 [ 1236.681673] cmworkhandler+0x969f/0xdca0 [ 1236.682704] processscheduledworks+0xc22/0x1600 [ 1236.683447] workerthread+0x975/0xee0 [ 1236.685901] kthread+0x3a6/0x490 [ 1236.688164] retfromfork+0x55a/0xa20 [ 1236.689522] retfromforkasm+0x1a/0x30 [ 1236.690073] [ 1236.690378] Freed by task 5137: [ 1236.692242] kasansavetrack+0x3e/0x80 [ 1236.694272] kasansavefreeinfo+0x40/0x50 [ 1236.695514] kasanslabfree+0x3a/0x60 [ 1236.696773] kfree+0x14e/0x4e0 [ 1236.697216] ibdestroycquser+0x18d/0x250 [ 1236.699817] smbdirectconnectiondestroyqp+0xf2/0x280 [ 1236.702115] smbdirectsocketdestroysync+0x1607/0x2720 [ 1236.704062] smbdirectsocketrelease+0x140/0x280 [ 1236.705286] smbdirectfreetranspor ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: vgic-its: Drop the translation cache reference only for the erased entry
vgicitsinvalidatecache() walks the per-ITS translation cache with xaforeach() and drops the cache's reference on each entry with vgicputirq(). It puts the iterated pointer, though, rather than the value returned by xaerase().
The function is called from contexts that do not exclude one another: the ITS command handlers hold itslock, the GITSCTLR write path holds cmdlock, and the path that clears EnableLPIs in a redistributor's GICRCTLR holds neither. Two or more of them can drain the same cache concurrently, and if each one observes the same entry, erases it and then puts it, the single reference the cache holds on that entry is dropped more than once. The entry can then be freed while an ITE still maps it.
xaerase() is atomic and returns the previous entry, so put only the entry that this context actually removed. The cache reference is then dropped exactly once per entry even when the invalidations run concurrently, and the behavior is unchanged when only one context runs.
IB/isert: reject login PDUs declaring more data than was received
In the Linux kernel, the following vulnerability has been resolved:
IB/isert: reject PDUs declaring more data than was received
isertrecvdone() hands each received PDU to the opcode handlers without ever looking at wc->bytelen, the number of bytes the HCA actually placed in the receive descriptor. The handlers then copy that many bytes - the data-segment length the initiator declared in the BHS (ntoh24(hdr->dlength), via the derived unsoldatalen / immdatalen) - out of the fixed-size descriptor:
iserthandleiscsidataout(): sgcopyfrombuffer(sgstart, sgnents, isertgetdata(rxdesc), unsoldatalen); iserthandlescsicmd(): sgcopyfrombuffer(cmd->secmd.tdatasg, sgnents, isertgetdata(rxdesc), immdatalen);
Because the declared length is never checked against wc->bytelen, an initiator can declare a data segment larger than the bytes it actually sent (and larger than the descriptor) and cause an out-of-bounds read of the receive buffer.
Nothing upstream of isert closes this door:
- iscsitcheckdataouthdr() bounds the inbound payload against connops->MaxXmitDataSegmentLength (MXDSL) - a transmit parameter, used here for the inbound check. - iscsisetconnectionparameters() sets ops->MaxXmitDataSegmentLength = ops->TargetRecvDataSegmentLength; and TARGETRECVDATASEGMENTLENGTH is absent from the min()-clamp list in iscsicheckacceptorstate(), so the value the initiator declares is adopted verbatim (type range 512..16777215). The initiator effectively raises its own ceiling. - isert never clamps the negotiated value to its own fixed receive descriptor (ISERRXSIZE, 9216 bytes), so the target core's bound and the descriptor size are unrelated.
The immdatalen == datalen path is more than an over-read: it aliases the receive descriptor via sgsetbuf() and passes it to the backend as the data source for the SCSI WRITE, so an over-declared length causes heap contents past the descriptor to be written through the backend to the backing store. The backend is the victim of the oversized scatterlist isert hands it, not the cause; no read-back of the written bytes was demonstrated.
Trigger: after login completes (full feature phase), an initiator that has declared a large TargetRecvDataSegmentLength and a FirstBurstLength that permits unsolicited/immediate data sends a PDU whose declared data-segment length exceeds what was received. With KASAN:
BUG: KASAN: slab-out-of-bounds in sgcopybuffer+0x150/0x1c0 Read of size 4096 at addr ffff888109720800 by task kworker/1:0H/25 Workqueue: ib-comp-wq ibcqpollwork Call Trace: sgcopybuffer+0x150/0x1c0 isertrecvdone+0xba6/0x2390 ibprocesscq+0xe1/0x390 ibcqpollwork+0x46/0x150
isertrecvdone+0xba6 resolves to iserthandleiscsidataout() (ibisert.c:1160), inlined through isertrxopcode().
Validate wc->bytelen against the framing in isertrecvdone() before the PDU reaches any handler, and reinstate the connection if it is short. Because the test compares without subtracting the header length, it also rejects PDUs shorter than the iSER and iSCSI headers, which would otherwise be parsed out of stale descriptor contents. The login handler rejects PDUs shorter than ISERHEADERSLEN (commit 29e7b925ae6d ("IB/isert: Reject login PDUs shorter than ISERHEADERSLEN")) but does not bound the declared length either; that is fixed in the next patch. The data handlers had no length check at all.
isert reads the data segment from a fixed offset: isertgetdata() returns the iSER header plus ISERHEADERSLEN and makes no adjustment for an AHS. The bytes the handlers touch are therefore exactly [ISERHEADERSLEN, ISERHEADERSLEN + dlength), and comparing that sum against wc->bytelen bounds precisely the region that is read. An AHS term would only make the test stricter without bounding anything furth ---truncated---
In the Linux kernel, the following vulnerability has been resolved:
powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW
Power Hypervisor can possibily allocate MMIO window intersecting with Dynamic DMA Window (DDW) range, which is over 32-bit addressing.
These MMIO pages needs to be marked as reserved so that IOMMU doesn't map DMA buffers in this range.
The current code is not marking these pages correctly which is resulting in LPAR to OOPS while booting. The stack is at below
BUG: Unable to handle kernel data access on read at 0xc00800005cd40000 Faulting instruction address: 0xc00000000005cdac Oops: Kernel access of bad area, sig: 11 [#1] LE PAGESIZE=64K MMU=Hash SMP NRCPUS=2048 NUMA pSeries Modules linked in: afpacket rfkill ibmveth(X) lpfc(+) nvmetfc nvmet nvmekeyring crct10difvpmsum nvmefc nvmefabrics nvmecore be2net(+) nvmeauth rtcgeneric nfsd authrpcgss nfsacl lockd grace sunrpc fuse configfs iptables xtables xfs libcrc32c dmservicetime ibmvfc(X) scsitransportfc vmxcrypto gf128mul crc32cvpmsum dmmirror dmregionhash dmlog dmmultipath dmmod sdmod scsidhemc scsidhrdac scsidhalua t10pi crc64rocksoftgeneric crc64rocksoft sg crc64 scsimod Supported: Yes, External CPU: 8 PID: 241 Comm: kworker/8:1 Kdump: loaded Not tainted 6.4.0-150600.23.14-default #1 SLE15-SP6 b44ee71c81261b9e4bab5e0cde1f2ed891d5359b Hardware name: IBM,9080-M9S POWER9 (raw) 0x4e2103 0xf000005 of:IBM,FW950.B0 (VH950149) hv:phyp pSeries Workqueue: events workforcpufn NIP: c00000000005cdac LR: c00000000005e830 CTR: 0000000000000000 REGS: c00001400c9ff770 TRAP: 0300 Not tainted (6.4.0-150600.23.14-default) MSR: 800000000280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24228448 XER: 00000001 CFAR: c00000000005cdd4 DAR: c00800005cd40000 DSISR: 40000000 IRQMASK: 0 GPR00: c00000000005e830 c00001400c9ffa10 c000000001987d00 c00001400c4fe800 GPR04: 0000080000000000 0000000000000001 0000000004000000 0000000000800000 GPR08: 0000000004000000 0000000000000001 c00800005cd40000 ffffffffffffffff GPR12: 0000000084228882 c00000000a4c4f00 0000000000000010 0000080000000000 GPR16: c00001400c4fe800 0000000004000000 0800000000000000 c00000006088b800 GPR20: c00001401a7be980 c00001400eff3800 c000000002a2da68 000000000000002b GPR24: c0000000026793a8 c000000002679368 000000000000002a c0000000026793c8 GPR28: 000008007effffff 0000080000000000 0000000000800000 c00001400c4fe800 NIP [c00000000005cdac] iommutablereservepages+0xac/0x100 LR [c00000000005e830] iommuinittable+0x80/0x1e0 Call Trace: [c00001400c9ffa10] [c00000000005e810] iommuinittable+0x60/0x1e0 (unreliable) [c00001400c9ffa90] [c00000000010356c] iommubypasssupportedpSeriesLP+0x9cc/0xe40 [c00001400c9ffc30] [c00000000005c300] dmaiommudmasupported+0xf0/0x230 [c00001400c9ffcb0] [c00000000024b0c4] dmasupported+0x44/0x90 [c00001400c9ffcd0] [c00000000024b14c] dmasetmask+0x3c/0x80 [c00001400c9ffd00] [c0080000555b715c] beprobe+0xc4/0xb90 [be2net] [c00001400c9ffdc0] [c000000000986f3c] localpciprobe+0x6c/0x110 [c00001400c9ffe40] [c000000000188f28] workforcpufn+0x38/0x60 [c00001400c9ffe70] [c00000000018e454] processonework+0x314/0x620 [c00001400c9fff10] [c00000000018f280] workerthread+0x2b0/0x620 [c00001400c9fff90] [c00000000019bb18] kthread+0x148/0x150 [c00001400c9fffe0] [c00000000000ded8] startkernelthread+0x14/0x18
There are 2 issues in the code
1. The index is "int" while the address is "unsigned long". This results in negative value when setting the bitmap.
2. The DMA offset is page shifted but the MMIO range is used as-is (64-bit address). MMIO address needs to be page shifted as well.
In the Linux kernel, the following vulnerability has been resolved:
wifi: brcmfmac: validate bsscfg indices in IF events
brcmffwehhandleifevent() validates the firmware-provided interface index before it touches drvr->iflist[], but it still uses the raw bsscfgidx field as an array index without a matching range check.
Reject IF events whose bsscfg index does not fit in drvr->iflist[] before indexing the interface array.
[add missing wifi prefix]
In the Linux kernel, the following vulnerability has been resolved:
KVM: SEV: Require in-GHCB scratch area if GHCB v2+ is in use
As per the GHCB spec, when using GHCB v2+ require the software scratch area to reside in the GHCB's shared buffer. Note, things like Page State Change (PSC) requests rely on this behavior, as the guest can't provide a length when making the request, i.e. the size of the guest payload is bounded by the size of the shared buffer.
Failure to force usage of the GHCB, and a slew of other flaws, lets a malicious SNP guest corrupt host kernel heap memory, and leak host heap layout information.
setupvmgexitscratch() allocates a buffer via kvzalloc(exitinfo2), where exitinfo2 is guest-controlled. With exitinfo2=24, this yields a 24-byte allocation in kmalloc-cg-32 (32-byte slab objects). The buffer holds an 8-byte pschdr followed by 8-byte pscentry structs, so only entries[0] and entries[1] are in-bounds.
snpbeginpsc() validates endentry against VMGEXITPSCMAXCOUNT (253) but NOT against the actual buffer size:
idxend = hdr->endentry;
if (idxend >= VMGEXITPSCMAXCOUNT) { // checks 253, not buffer snpcompletepsc(svm, ...); return 1; }
for (idx = idxstart; idx <= idxend; idx++) { entrystart = entries[idx]; // OOB when idx >= 2
The guest sets endentry=10+, causing the host to iterate entries[2+] which are OOB into adjacent slab objects. For each OOB entry:
- The host reads 8 bytes (OOB READ / info leak oracle) - If the data passes PSC validation, snpcompleteonepsc() writes curpage = 1 or 512 into the entry (OOB WRITE, sev.c:3806) - If validation fails, the error response reveals whether adjacent memory is zero vs non-zero (information disclosure to guest)
The guest controls allocation size (exitinfo2), entry range (curentry/endentry), and can fire unlimited VMGEXITs to repeatedly hit different slab positions.
By exploiting the variety of bugs, a malicious SEV-SNP guest can: - OOB read adjacent kmalloc-cg-32 objects (heap layout disclosure) - OOB write curpage bits into adjacent objects (heap corruption) - Trigger use-after-free conditions across VMGEXITs
E.g. with KASAN enabled, a single insmod of the PoC guest module produces 73 KASAN reports:
BUG: KASAN: slab-out-of-bounds in snpbeginpsc+0x126/0x890 Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199
BUG: KASAN: slab-out-of-bounds in snpbeginpsc+0x468/0x890 Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199
The buggy address belongs to the object at ffff888XXXXXXXXX which belongs to the cache kmalloc-cg-32 of size 32 The buggy address is located N bytes to the right of allocated 32-byte region [ffff888XXXXXXXXX, ffff888XXXXXXXXX)
Breakdown: 62 slab-out-of-bounds (reads + writes past allocation) 7 slab-use-after-free 4 use-after-free
All credit to Stan for the wonderful description and reproducer!
[sean: write changelog]
In the Linux kernel, the following vulnerability has been resolved:
tipc: fix slab-use-after-free Read in tipcaeaddecryptdone
tipcaeaddecrypt() goes straight from tipcbearerhold(b) to cryptoaeaddecrypt(req) without taking a reference on the netns, unlike the encrypt path. When cryptoaeaddecrypt() is offloaded asynchronously (e.g. the SIMD aead wrapper queuing to cryptd), the cryptd worker runs tipcaeaddecryptdone() later. If the bearer's netns is torn down in the meantime, cleanupnet() -> tipcexitnet() -> tipccryptostop() frees the per-netns tipccrypto, and the completion then reads it: tipcaeaddecryptdone() dereferences aead->crypto->stats and aead->crypto->net, and tipccryptorcvcomplete() dereferences aead->crypto->aead[] and the node table -- reading freed memory.
Decoded KASAN splat (v7.1-rc7, CONFIGKASANINLINE + TIPC + TIPCCRYPTO):
BUG: KASAN: slab-use-after-free in tipcaeaddecryptdone (net/tipc/crypto.c:999) Read of size 8 at addr ffff8881056258a8 by task kworker/u16:2/51 Workqueue: eventsunbound Call Trace: tipcaeaddecryptdone (net/tipc/crypto.c:999) processonework (kernel/workqueue.c:3314) workerthread (kernel/workqueue.c:3397 kernel/workqueue.c:3478) kthread (kernel/kthread.c:436) retfromfork (arch/x86/kernel/process.c:158) retfromforkasm (arch/x86/entry/entry64.S:245)
Allocated by task 169: kasankmalloc (mm/kasan/common.c:398 mm/kasan/common.c:415) tipccryptostart (net/tipc/crypto.c:1502) tipcinitnet (net/tipc/core.c:72) opsinit (net/core/netnamespace.c:137) setupnet (net/core/netnamespace.c:446) copynetns (net/core/netnamespace.c:579) createnewnamespaces (kernel/nsproxy.c:132) x64sysunshare (kernel/fork.c:3316) dosyscall64 (arch/x86/entry/syscall64.c:63) entrySYSCALL64afterhwframe (arch/x86/entry/entry64.S:121)
Freed by task 8: kfree (mm/slub.c:6566) tipcexitnet (net/tipc/core.c:119) cleanupnet (net/core/netnamespace.c:704) processonework (kernel/workqueue.c:3314) kthread (kernel/kthread.c:436)
This is the same class of bug that commit e279024617134 ("net/tipc: fix slab-use-after-free Read in tipcaeadencryptdone") fixed for the encrypt side. The encrypt path takes maybegetnet(aead->crypto->net) before cryptoaeadencrypt() and drops it with putnet() on the synchronous return paths and in tipcaeadencryptdone(); the -EINPROGRESS/-EBUSY return keeps the reference for the async callback to release. The decrypt path was left without the equivalent guard.
Mirror the encrypt-side fix on the decrypt path: take a net reference before cryptoaeaddecrypt() (failing with -ENODEV and the matching bearer put if it cannot be acquired), keep it across the -EINPROGRESS/-EBUSY async return, and drop it with putnet() on the synchronous success/error return and at the end of tipcaeaddecryptdone().
Reproduced under KASAN on v7.1-rc7: a UDP bearer with a cluster key is flooded with crafted encrypted frames from an unknown peer (driving the cluster-key decrypt path) while the bearer's netns is repeatedly torn down. The completion must run asynchronously to outlive tipccryptostop(); on x86 the stock aesni gcm(aes) now decrypts synchronously, so the async path was exercised via cryptd offload. The unguarded aead->crypto dereference in tipcaeaddecryptdone() is the unpatched upstream path; tipcaeaddecrypt() still lacks maybegetnet(aead->crypto->net), so the completion can outlive the free on any config where cryptoaeaddecrypt() goes async.
Found by 0sec automated security-research tooling (https://0sec.ai).
In the Linux kernel, the following vulnerability has been resolved:
HID: wacom: Fix OOB write in wacomhidsetdevicemode()
wacomhidsetdevicemode() currently assumes that the HIDDGINPUTMODE usage is always located in the first field (field[0]) of the feature report. However, a device can specify HIDDGINPUTMODE in a different field.
If HIDDGINPUTMODE is in a field other than the first one and the first field has a reportcount smaller than the usageindex of HIDDGINPUTMODE, this leads to an out-of-bounds write to r->field[0]->value.
Fix this by storing the field index of HIDDGINPUTMODE in 'struct hiddata' during feature mapping. In wacomhidsetdevicemode(), use this stored field index to access the correct field and add bounds checks to ensure both the field index and the value index are within valid ranges before writing.
In the Linux kernel, the following vulnerability has been resolved:
batman-adv: tpmeter: directly shut down timer on cleanup
batadvtpsendercleanup() was calling timerdeletesync() followed by timerdelete() to guard against the timer handler re-arming itself between the two calls. This double-deletion hack relied on the sending status being set to 0 to suppress re-arming.
Replace both calls with a single timershutdownsync(). This function both waits for any running timer callback to complete (like timerdeletesync()) and permanently disarms the timer so it cannot be re-armed afterwards, making re-arming prevention unconditional and self-documenting.
The re-arming property is also required because otherwise:
1. context 0 (batadvtprecvack()) checks in batadvtpresetsendertimer() if sending is still 1 -> it is 2. context 1 changes in batadvtpsendershutdown() sending to 0 and in this process forces the kthread to stop timer in batadvtpsendercleanup() 3. context 0 continues in batadvtpresetsendertimer() and rearms the timer -> but the reference for it is already gone
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hcisync: Fix advertising data UAFs
hcifindadvinstance() returns an advinfo pointer that is valid only while hdev->lock is held. The advertising command-sync paths perform instance lookups without that lock and, in some cases, retain the pointer while waiting for a controller response.
An advertising termination event can therefore interleave as follows:
hcicmdsyncwork hcirxwork hcifindadvinstance() hcicmdsyncstatus() wait for controller reply hcidevlock() hciremoveadvinstance() kfree(adv) adv->scanrspchanged = false
KASAN reported:
BUG: KASAN: slab-use-after-free in hcisetextscanrspdatasync+0x2e1/0x300 Write of size 1 at addr ffff88810a45d21d by task kworker/u17:0/88 Workqueue: hci0 hcicmdsyncwork Call Trace: hcisetextscanrspdatasync+0x2e1/0x300 hcischeduleadvinstancesync+0x390/0x4c0 hcicmdsyncwork+0x173/0x300 Allocated by task 87: hciaddadvinstance+0x538/0xac0 addadvertising+0x885/0x1160 Freed by task 89: kfree+0x131/0x3c0 hciremoveadvinstance+0x1d8/0x3b0 hcileextadvtermevt+0x17b/0x730
Protect the instance lookup and payload construction in the extended advertising, scan response, and periodic advertising data paths. Snapshot the advertising parameters under hdev->lock, but release the lock before waiting for the controller.
Clear advertising-data dirty bits before issuing their commands and restore them after a failure using a fresh lookup. Likewise, update the reported transmit power through a fresh lookup after the parameter command completes. No advinfo pointer then survives an HCI command wait.
HID: rmi: fix OOB access with undersized RMI reports
In the Linux kernel, the following vulnerability has been resolved:
wifi: mt76: mt7915: unlink TWT flow if the MCU rejects the agreement
The flow is added to dev->twtlist before sending the agreement to the firmware, but the error path leaves it linked while flowidmask is never set. The flow slot can then be reused and memset while still on the list, corrupting twtlist, and station removal leaves a dangling entry behind that mt7915mactwtschedlistadd() later walks.
In the Linux kernel, the following vulnerability has been resolved:
wifi: mt76: mt7921: Add PCIe AER handler support to prevent system crash
When an AER error occurs and the bus is hung, the register reads return 0xFFFFFFFF, causing the DMA queue state to be corrupted and resulting in an invalid memory access when accessing q->desc[] or q->entry[].
Unable to handle kernel paging request at virtual address ffffffc01099eac0 pc : mt76dmaaddbuf+0x124/0x188 [mt76] lr : mt76dmarxfill+0x11c/0x1d8 [mt76] sp : ffffffc016d9bbf0 x29: ffffffc016d9bc10 x28: 0000000000000000 x27: 0000000000000000 x26: ffffffb7855e50b8 x25: ffffffb80d04f000 x24: 0000000000000000 x23: 0000000000000ec0 x22: ffffffb796803648 x21: ffffffb796801f80 x20: ffffffb7968035f8 x19: 0000000000000ec0 x18: 0000000000000000 x17: 000000004ec00000 x16: 000000000ec00000 x15: ffffffc01099eac0 x14: 000000004ec00000 x13: 00000000ffc5a000 x12: ffffffc016d9bc32 x11: 00000000ffffffff x10: 0000000000000002 x9 : 0000000000000000 x8 : 000000000000b4ac x7 : 0000000000000a20 x6 : ffffffb6c1806400 x5 : 0000000000000000 x4 : ffffffb80d04f000 x3 : 0000000000000000 x2 : 0000000000000001 x1 : 000000000ec04000 x0 : ffffffb7968035f8 Call trace: mt76dmaaddbuf+0x124/0x188 [mt76 (HASH:1029 4)] mt76dmarxreset+0xe8/0xfc [mt76 (HASH:1029 4)] mt7921wpdmareset+0x188/0x1b0 [mt7921e (HASH:ee48 5)] mt7921emacreset+0x128/0x418 [mt7921e (HASH:ee48 5)] mt7921macresetwork+0xac/0x1a8 [mt7921common (HASH:f721 6)] processonework+0x188/0x514 workerthread+0x12c/0x300 kthread+0x140/0x1fc retfromfork+0x10/0x30
Fix the invalid memory access by validating the DMA index read from the hardware before it is used as a queue index. An out-of-range value, such as the 0xFFFFFFFF returned while the bus is hung, is now clamped so it can no longer corrupt q->head or q->tail. In addition, check the bushung flag in mt7921macresetwork() before attempting the reset sequence, reject MCU messages while the bus is hung, and install no-op bus operations when an unrecoverable AER error is detected, preventing further invalid hardware accesses.
Due to hardware limitations - such as the lack of a connected hardware reset pin or the absence of host re-probe functionality - affected Wi-Fi devices may not fully recover to a normal operational state after certain errors, even with AER enabled.
In the Linux kernel, the following vulnerability has been resolved:
iouring/zcrx: fix overshooting recv limit
It's reported that sometimes a zcrx request can receive more than was requested. It's caused by iozcrxrecvskb() adjusting desc->count for all received buffers including frag lists, but then doing recursive calls to process frag list skbs, which leads to desc->count double accounting and underflow.
hwrng: virtio: clamp device-reported used.len at copydata()
In the Linux kernel, the following vulnerability has been resolved:
nvme-pci: fix out-of-bounds access in nvmesetupdescriptorpools
nvmesetupdescriptorpools() indexes dev->descriptorpools[] using the numanode forwarded from hctx->numanode by its single caller, nvmeinithctxcommon(). On a non-NUMA kernel hctx->numanode is NUMANONODE (-1). Because the parameter was declared 'unsigned', the value becomes UINTMAX and the index walks off the array (sized to nrnodeids), faulting during nvmeallocns() and leaving the namespace without a /dev node.
Reproduces on any NVMe controller probed by a CONFIGNUMA=n kernel:
BUG: unable to handle page fault for address: ffff889101603d38 RIP: 0010:nvmeinithctxcommon+0x5a/0x190 [nvme] Call Trace: nvmeinithctx+0x10/0x20 [nvme] nvmeallocns+0x9e/0xa10 [nvmecore] nvmescanns+0x301/0x3b0 [nvmecore] nvmescannsasync+0x23/0x30 [nvmecore]
Switch the parameter to int and fall back to node 0 when it is NUMANONODE; node 0 is always present.
i2c: imx: Fix slave registration race and error handling
In the Linux kernel, the following vulnerability has been resolved:
ipv4: icmp: validate reply type before using icmppointers
Extended echo replies use ICMPEXTECHOREPLY as the outbound reply type. That value is outside the range covered by icmppointers[], which only describes the traditional ICMP types up to NRICMPTYPES.
Avoid consulting icmppointers[] for reply types outside that range, and use arrayindexnospec() for the remaining in-range lookup. Normal ICMP replies keep their existing behavior unchanged.
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: validate NTLMv2 response before updating session key
ksmbdauthntlmv2() derives the NTLMv2 session key into sess->sesskey before it verifies the NTLMv2 response. ksmbddecodentlmsspauthblob() then continues into KEYXCH even when ksmbdauthntlmv2() failed.
With SMB3 multichannel binding, the failed authentication operates on an existing session and the session setup error path does not expire binding sessions. A client can send a binding session setup with a bad NT proof and KEYXCH and still modify sess->sesskey before STATUSLOGONFAILURE is returned.
Relevant path:
smb2sesssetup() -> conn->binding = true -> ntlmauthenticate() -> sessionuser() -> ksmbddecodentlmsspauthblob() -> ksmbdauthntlmv2() -> calcntlmv2hash() -> hmacmd5usingrawkey(..., sess->sesskey) -> cryptomemneq() returns mismatch -> KEYXCH arc4crypt(..., sess->sesskey, ...) -> outerr without expiring the binding session
Derive the base session key into a local buffer and copy it to sess->sesskey only after the proof matches. Return immediately on authentication failure so KEYXCH is only processed after successful authentication.