In the Linux kernel, the following vulnerability has been resolved:
USB: serial: ioti: fix heap overflow in getmanufinfo()
getmanufinfo() reads le16tocpu(romdesc->Size) bytes from the device I2C EEPROM into a buffer allocated with kmallocobj(), which is sizeof(struct edgetimanufdescriptor) = 10 bytes.
The Size field comes from the device and is only validated (in checki2cimage()) to make sure the descriptor fits within TIMAXI2CSIZE (16384 bytes), not against the destination buffer size. A malicious USB device can therefore set Size to any value up to 16377, causing a heap overflow of up to 16367 bytes when plugged into a host running this driver.
validcsum() is called after readrom() and also iterates buffer[0..Size-1], compounding the out-of-bounds access.
Fix by rejecting descriptors with unexpected length before calling readrom().
[ johan: amend commit message; also check for short descriptors ]
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ebtables: zero chainstack array
sashiko reports: looking at ebtables table translation, could a sparse cpupossiblemask lead to an uninitialized pointer free?
If cpupossiblemask is sparse (for example, CPU 0 and CPU 2 are possible, but CPU 1 is not), the allocation loop skips CPU 1. If vmallocnode() fails at CPU 2, the cleanup loop will blindly decrement and call vfree() on newinfo->chainstack[1].
Not a real-world bug, such allocation isn't expected to fail in the first place.
In the Linux kernel, the following vulnerability has been resolved:
isofs: bound Rock Ridge symlink components to the SL record
getsymlinkchunk() and the SL handling in parserockridgeinodeinternal() walk the variable-length components of a Rock Ridge "SL" (symbolic link) record. Each component is a two-byte header (flags, len) followed by len bytes of text, so it occupies slp->len + 2 bytes. Both loops read slp->len and advance to the next component, and getsymlinkchunk() additionally does memcpy(rpnt, slp->text, slp->len), but neither checks that the component lies within the SL record before dereferencing it.
A crafted SL record whose component declares a len that runs past the record (rr->len) therefore triggers an out-of-bounds read of up to 255 bytes. When the record sits at the tail of its backing buffer - for example a small kmalloc()ed continuation block reached through a CE record - the read crosses the allocation; getsymlinkchunk() then copies the out-of-bounds bytes into the symlink body returned to user space by readlink(), disclosing adjacent kernel memory.
ISO 9660 images are routinely mounted from untrusted removable media - desktop environments auto-mount them (e.g. via udisks2) without CAPSYSADMIN - so the record contents are attacker-controlled.
Reject any component that does not fit in the remaining record bytes before using it. In getsymlinkchunk() return NULL, like the existing output-buffer (plimit) checks, so a malformed record makes readlink() fail with -EIO rather than silently returning a truncated target; in parserockridgeinodeinternal() stop the inode-size walk.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ebtables: terminate table name before findtablelock()
updatecounters() and compatupdatecounters() forward a user-supplied 32-byte table name to findtablelock() without NUL-terminating it. On a lookup miss, findinlistlock() calls trythenrequestmodule(..., "%s%s", "ebtable", name), and vsnprintf() reads past the name field and the stack object until it hits a zero byte.
BUG: KASAN: stack-out-of-bounds in string (lib/vsprintf.c:648 lib/vsprintf.c:730) Read of size 1 at addr ffff8880119dfb20 by task exploit/147 Call Trace: ... string (lib/vsprintf.c:648 lib/vsprintf.c:730) vsnprintf (lib/vsprintf.c:2945) requestmodule (kernel/module/kmod.c:150) doupdatecounters.isra.0 (net/bridge/netfilter/ebtables.c:371 net/bridge/netfilter/ebtables.c:380) updatecounters (net/bridge/netfilter/ebtables.c:1440) doebtsetctl (net/bridge/netfilter/ebtables.c:2573) nfsetsockopt (net/netfilter/nfsockopt.c:101) ipsetsockopt (net/ipv4/ipsockglue.c:1424) rawsetsockopt (net/ipv4/raw.c:847) syssetsockopt (net/socket.c:2393) ...
compatdoreplace() shares the same unterminated name via compatcopyebtreplacefromuser(); terminate it there too so all findtablelock() callers behave alike. The other callers already terminate the name after the copy.
In the Linux kernel, the following vulnerability has been resolved:
ipv4: restrict IPOPTSSRR and IPOPTLSRR options
This patch restricts setting Loose Source and Record Route (LSRR) and Strict Source and Record Route (SSRR) IP options to users with CAPNETRAW capability.
This prevents unprivileged applications from forcing packets to route through attacker-controlled nodes to leak TCP ISN and possibly other protocol information.
While LSRR and SSRR are commonly filtered in many network environments, they may still be supported and forwarded along some network paths.
RFC 7126 (Recommendations on Filtering of IPv4 Packets Containing IPv4 Options) recommend to drop these options in 4.3 and 4.4.
In the Linux kernel, the following vulnerability has been resolved:
tcp: restrict SOATTACHFILTER to priv users
This patch restricts the use of SOATTACHFILTER (cBPF) on TCP sockets to users with CAPNETADMIN capability.
This blocks potential side-channel attack where an unprivileged application attaches a filter to leak TCP sequence/acknowledgment numbers.
In the Linux kernel, the following vulnerability has been resolved:
fs/fcntl: fix SOFTIRQ-unsafe lock order in fasync signaling
A SOFTIRQ-safe to SOFTIRQ-unsafe lock order deadlock can occur in sendsigio() and sendsigurg() when a process group receives a signal.
When FASYNC is configured for a process group (PIDTYPEPGID), both functions use readlock(&tasklistlock) to traverse the task list. However, they are frequently called from softirq context: - sendsigio() via inputinjectevent -> killfasync - sendsigurg() via tcpcheckurg -> sksendsigurg (NETRXSOFTIRQ)
The deadlock is caused by the rwlock writer fairness mechanism: 1. CPU 0 (process context) holds readlock(&tasklistlock) in dowait(). 2. CPU 1 (process context) attempts writelock(&tasklistlock) in fork() or exit() and spins, which blocks all new readers. 3. CPU 0 is interrupted by a softirq (e.g., TCP URG packet reception). 4. The softirq calls sendsigurg() and attempts to acquire readlock(&tasklistlock), deadlocking because CPU 1 is waiting.
Since PID hashing and doeachpidtask() traversals are already RCU-protected, the readlock on tasklistlock is no longer strictly required for safe traversal. Fix this by replacing tasklistlock with rcureadlock(), aligning the process group signaling path with the single-PID path. This also mitigates a potential remote denial of service vector via TCP URG packets.
Lockdep splat: ===================================================== WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected [...] Chain exists of: &dev->eventlock --> &fowner->lock --> tasklistlock
Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(tasklistlock); localirqdisable(); lock(&dev->eventlock); lock(&fowner->lock); <Interrupt> lock(&dev->eventlock);
DEADLOCK
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ip6trt: reject oversized addrnr in rtmt6check()
Reject rt match rules whose addrnr exceeds IP6TRTHOPS.
rtmt6() expects addrnr to stay within the bounds of rtinfo->addrs[]. Validate addrnr during rule installation so malformed rules are rejected before the match logic can use an out-of-range value.
In the Linux kernel, the following vulnerability has been resolved:
module: Fix kernel panic when a symbol stshndx is out of bounds
The module loader doesn't check for bounds of the ELF section index in simplifysymbols():
for (i = 1; i < symsec->shsize / sizeof(ElfSym); i++) { const char name = info->strtab + sym[i].stname;
switch (sym[i].stshndx) { case SHNCOMMON:
[...]
default: / Divert to percpu allocation if a percpu var. / if (sym[i].stshndx == info->index.pcpu) secbase = (unsigned long)modpercpu(mod); else / HERE --> / secbase = info->sechdrs[sym[i].stshndx].shaddr; sym[i].stvalue += secbase; break; } }
A symbol with an out-of-bounds stshndx value, for example 0xffff (known as SHNXINDEX or SHNHIRESERVE), may cause a kernel panic:
BUG: unable to handle page fault for address: ... RIP: 0010:simplifysymbols+0x2b2/0x480 ... Kernel panic - not syncing: Fatal exception
This can happen when module ELF is legitimately using SHNXINDEX or when it is corrupted.
Add a bounds check in simplifysymbols() to validate that stshndx is within the valid range before using it.
This issue was discovered due to a bug in llvm-objcopy, see relevant discussion for details [1].
[1] https://lore.kernel.org/linux-modules/20251224005752.201911-1-ihor.solodrai@linux.dev/
In the Linux kernel, the following vulnerability has been resolved:
net/x25: Fix overflow when accumulating packets
Add a check to ensure that x25sock.fraglen does not overflow.
The fraglen also needs to be resetted when purging fragmentqueue in x25clearqueues().
In the Linux kernel, the following vulnerability has been resolved:
net: rose: include node references in roseneigh refcount
Current implementation maintains two separate reference counting mechanisms: the 'count' field in struct roseneigh tracks references from rosenode structures, while the 'use' field (now refcountt) tracks references from rosesock.
This patch merges these two reference counting systems using 'use' field for proper reference management. Specifically, this patch adds incrementing and decrementing of roseneigh->use when roseneigh->count is incremented or decremented.
This patch also modifies rosertfree(), rosertdevicedown() and roseclearroute() to properly release references to roseneigh objects before freeing a rosenode through roseremovenode().
These changes ensure roseneigh structures are properly freed only when all references, including those from rosenode structures, are released. As a result, this resolves a slab-use-after-free issue reported by Syzbot.
In the Linux kernel, the following vulnerability has been resolved:
net: rose: convert 'use' field to refcountt
The 'use' field in struct roseneigh is used as a reference counter but lacks atomicity. This can lead to race conditions where a roseneigh structure is freed while still being referenced by other code paths.
For example, when roseneigh->use becomes zero during an ioctl operation via rosertioctl(), the structure may be removed while its timer is still active, potentially causing use-after-free issues.
This patch changes the type of 'use' from unsigned short to refcountt and updates all code paths to use roseneighhold() and roseneighput() which operate reference counts atomically.
fs/buffer: fix use-after-free when call bhread() helper
In the Linux kernel, the following vulnerability has been resolved:
net: rose: fix timer races against user threads
Rose timers only acquire the socket spinlock, without checking if the socket is owned by one user thread.
Add a check and rearm the timers if needed.
BUG: KASAN: slab-use-after-free in rosetimerexpiry+0x31d/0x360 net/rose/rosetimer.c:174 Read of size 2 at addr ffff88802f09b82a by task swapper/0/0
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc5-syzkaller-00172-gd1bf27c4e176 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Call Trace: <IRQ> dumpstack lib/dumpstack.c:94 [inline] dumpstacklvl+0x241/0x360 lib/dumpstack.c:120 printaddressdescription mm/kasan/report.c:378 [inline] printreport+0x169/0x550 mm/kasan/report.c:489 kasanreport+0x143/0x180 mm/kasan/report.c:602 rosetimerexpiry+0x31d/0x360 net/rose/rosetimer.c:174 calltimerfn+0x187/0x650 kernel/time/timer.c:1793 expiretimers kernel/time/timer.c:1844 [inline] runtimers kernel/time/timer.c:2418 [inline] runtimerbase+0x66a/0x8e0 kernel/time/timer.c:2430 runtimerbase kernel/time/timer.c:2439 [inline] runtimersoftirq+0xb7/0x170 kernel/time/timer.c:2449 handlesoftirqs+0x2d4/0x9b0 kernel/softirq.c:561 dosoftirq kernel/softirq.c:595 [inline] invokesoftirq kernel/softirq.c:435 [inline] irqexitrcu+0xf7/0x220 kernel/softirq.c:662 irqexitrcu+0x9/0x30 kernel/softirq.c:678 instrsysvecapictimerinterrupt arch/x86/kernel/apic/apic.c:1049 [inline] sysvecapictimerinterrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1049 </IRQ>
ax25: fix use-after-free bugs caused by ax25dsdeltimer
dm log: fix out-of-bounds write due to regioncount overflow
In the Linux kernel, the following vulnerability has been resolved:
USB: serial: digiacceleport: fix write buffer corruption
The digiwriteinbcommand() is supposed to wait for the write urb to become available or return an error, but instead it updates the transfer buffer and tries to resubmit the urb on timeout.
To make things worse, for commands like break control where no timeout is used, the driver would corrupt the urb immediately due to a broken jiffies comparison (on 32-bit machines this takes five minutes of uptime to trigger due to INITIALJIFFIES).
Fix this by adding the missing return on timeout and waiting indefinitely when no timeout has been specified as intended.
This issue was (sort of) flagged by Sashiko when reviewing an unrelated change to the driver.
In the Linux kernel, the following vulnerability has been resolved:
jfs: add check read-only before truncation in jfstruncatenolock()
Added a check for "read-only" mode in the jfstruncatenolock function to avoid errors related to writing to a read-only filesystem.
Call stack:
blockwritebegin() { jfswritefailed() { jfstruncate() { jfstruncatenolock() { txEnd() { ... log = JFSSBI(tblk->sb)->log; // (log == NULL)
If the isReadOnly(ip) condition is triggered in jfstruncatenolock, the function execution will stop, and no further data modification will occur. Instead, the xtTruncate function will be called with the "COMMITWMAP" flag, preventing modifications in "read-only" mode.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox devices
A bogus device can provide a bNumConfigurations value that exceeds the initial value used in usbgetconfiguration for allocating dev->config.
This can lead to out-of-bounds accesses later, e.g. in usbdestroyconfiguration.
atm: clip: Fix infinite recursive call of clippush().
Bluetooth: SCO: Fix use-after-free in scorecvframe() due to missing sockhold
In the Linux kernel, the following vulnerability has been resolved:
Input: iforce - bound the device-reported force-feedback effect index
iforceprocesspacket() handles a status report (packet id 0x02) by taking a force-feedback effect index straight from the device wire and using it to address the per-effect state array:
i = data[1] & 0x7f; if (data[1] & 0x80) { if (!testandsetbit(FFCOREISPLAYED, iforce->coreeffects[i].flags)) ... } else if (testandclearbit(FFCOREISPLAYED, iforce->coreeffects[i].flags)) { ... }
The index is masked only with 0x7f, so it ranges 0..127, but coreeffects[] holds only IFORCEEFFECTSMAX (32) entries. For an index of 32..127 the testandsetbit()/testandclearbit() is an out-of-bounds single-bit read-modify-write past the array. coreeffects[] is the second-to-last member of struct iforce, so the write lands in the trailing members and beyond the embedding kzalloc()'d iforceserio / iforceusb object.
data[1] is unvalidated device payload on both transports (the USB interrupt endpoint and serio), and the status path is not gated on force feedback being present, so a malicious or counterfeit device can set or clear a bit at an attacker-chosen offset past the object.
Reject an out-of-range index instead of indexing with it. Bound against the array dimension IFORCEEFFECTSMAX rather than dev->ff->maxeffects so the check guarantees memory safety regardless of how many effects the device registered. A legitimate "effect started/stopped" status always carries an index below IFORCEEFFECTSMAX, so well-formed devices are unaffected; the neighbouring markcoreasready() loop is already bounded and is left untouched.
hdlcppp: sync per-proto timers before freeing hdlc state
In the Linux kernel, the following vulnerability has been resolved:
sctp: properly validate chunk size in sctpsfootb()
A size validation fix similar to that in Commit 50619dbf8db7 ("sctp: add size validation when walking chunks") is also required in sctpsfootb() to address a crash reported by syzbot:
BUG: KMSAN: uninit-value in sctpsfootb+0x7f5/0xce0 net/sctp/smstatefuns.c:3712 sctpsfootb+0x7f5/0xce0 net/sctp/smstatefuns.c:3712 sctpdosm+0x181/0x93d0 net/sctp/smsideeffect.c:1166 sctpendpointbhrcv+0xc38/0xf90 net/sctp/endpointola.c:407 sctpinqpush+0x2ef/0x380 net/sctp/inqueue.c:88 sctprcv+0x3831/0x3b20 net/sctp/input.c:243 sctp4rcv+0x42/0x50 net/sctp/protocol.c:1159 ipprotocoldeliverrcu+0xb51/0x13d0 net/ipv4/ipinput.c:205 iplocaldeliverfinish+0x336/0x500 net/ipv4/ipinput.c:233
In the Linux kernel, the following vulnerability has been resolved:
netsched: schsfq: don't allow 1 packet limit
The current implementation does not work correctly with a limit of 1. iproute2 actually checks for this and this patch adds the check in kernel as well.
This fixes the following syzkaller reported crash:
UBSAN: array-index-out-of-bounds in net/sched/schsfq.c:210:6 index 65535 is out of range for type 'struct sfqhead[128]' CPU: 0 PID: 2569 Comm: syz-executor101 Not tainted 5.10.0-smp-DEV #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Call Trace: dumpstack lib/dumpstack.c:79 [inline] dumpstack+0x125/0x19f lib/dumpstack.c:120 ubsanepilogue lib/ubsan.c:148 [inline] ubsanhandleoutofbounds+0xed/0x120 lib/ubsan.c:347 sfqlink net/sched/schsfq.c:210 [inline] sfqdec+0x528/0x600 net/sched/schsfq.c:238 sfqdequeue+0x39b/0x9d0 net/sched/schsfq.c:500 sfqreset+0x13/0x50 net/sched/schsfq.c:525 qdiscreset+0xfe/0x510 net/sched/schgeneric.c:1026 tbfreset+0x3d/0x100 net/sched/schtbf.c:319 qdiscreset+0xfe/0x510 net/sched/schgeneric.c:1026 devresetqueue+0x8c/0x140 net/sched/schgeneric.c:1296 netdevforeachtxqueue include/linux/netdevice.h:2350 [inline] devdeactivatemany+0x6dc/0xc20 net/sched/schgeneric.c:1362 devclosemany+0x214/0x350 net/core/dev.c:1468 devclosemany+0x207/0x510 net/core/dev.c:1506 unregisternetdevicemany+0x40f/0x16b0 net/core/dev.c:10738 unregisternetdevicequeue+0x2be/0x310 net/core/dev.c:10695 unregisternetdevice include/linux/netdevice.h:2893 [inline] tundetach+0x6b6/0x1600 drivers/net/tun.c:689 tundetach drivers/net/tun.c:705 [inline] tunchrclose+0x104/0x1b0 drivers/net/tun.c:3640 fput+0x203/0x840 fs/filetable.c:280 taskworkrun+0x129/0x1b0 kernel/taskwork.c:185 exittaskwork include/linux/taskwork.h:33 [inline] doexit+0x5ce/0x2200 kernel/exit.c:931 dogroupexit+0x144/0x310 kernel/exit.c:1046 dosysexitgroup kernel/exit.c:1057 [inline] sesysexitgroup kernel/exit.c:1055 [inline] x64sysexitgroup+0x3b/0x40 kernel/exit.c:1055 dosyscall64+0x6c/0xd0 entrySYSCALL64afterhwframe+0x61/0xcb RIP: 0033:0x7fe5e7b52479 Code: Unable to access opcode bytes at RIP 0x7fe5e7b5244f. RSP: 002b:00007ffd3c800398 EFLAGS: 00000246 ORIGRAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fe5e7b52479 RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000 RBP: 00007fe5e7bcd2d0 R08: ffffffffffffffb8 R09: 0000000000000014 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fe5e7bcd2d0 R13: 0000000000000000 R14: 00007fe5e7bcdd20 R15: 00007fe5e7b24270
The crash can be also be reproduced with the following (with a tc recompiled to allow for sfq limits of 1):
tc qdisc add dev dummy0 handle 1: root tbf rate 1Kbit burst 100b lat 1s ../iproute2-6.9.0/tc/tc qdisc add dev dummy0 handle 2: parent 1:10 sfq limit 1 ifconfig dummy0 up ping -I dummy0 -f -c2 -W0.1 8.8.8.8 sleep 1
Scenario that triggers the crash:
the first packet is sent and queued in TBF and SFQ; qdisc qlen is 1
TBF dequeues: it peeks from SFQ which moves the packet to the gsoskb list and keeps qdisc qlen set to 1. TBF is out of tokens so it schedules itself for later.
the second packet is sent and TBF tries to queues it to SFQ. qdisc qlen is now 2 and because the SFQ limit is 1 the packet is dropped by SFQ. At this point qlen is 1, and all of the SFQ slots are empty, however q->tail is not NULL.
At this point, assuming no more packets are queued, when schdequeue runs again it will decrement the qlen for the current empty slot causing an underflow and the subsequent out of bounds access.
In the Linux kernel, the following vulnerability has been resolved:
ipv4: raw: reject IPHDRINCL packets with ihl < 5
rawsendhdrinc() validates that the caller-supplied IPv4 header fits within the message length:
iphlen = iph->ihl 4; err = -EINVAL; if (iphlen > length) goto errorfree;
if (iphlen >= sizeof(iph)) { / fix up saddr, totlen, id, csum, transportheader / }
It does not, however, reject ihl < 5. For such a packet the "if (iphlen >= sizeof(iph))" branch is skipped, leaving the crafted iphdr untouched, but the packet is still handed to iplocalout() and onward. Downstream consumers that read iph->ihl assume a sane value: net/ipv4/ah4.c:ahoutput() in particular subtracts sizeof(struct iphdr) from topiph->ihl 4 and passes the (signed-int-negative, then cast to sizet) result to memcpy(), producing an OOB access of length close to SIZEMAX and a host kernel panic.
An IPv4 header with ihl < 5 is malformed by definition (RFC 791: "Internet Header Length is the length of the internet header in 32 bit words ... Note that the minimum value for a correct header is 5."). The kernel should not be willing to inject such a packet into its own output path.
Reject "iphlen < sizeof(iph)" alongside the existing "iphlen > length" check. This matches the principle that locally constructed packets that re-enter the IP stack must pass the same basic sanity tests that a foreign packet would be subjected to.
Once this lands, the "if (iphlen >= sizeof(iph))" wrapper around the fixup branch becomes redundant; left in place to keep the patch minimal and backport-friendly. A follow-up can unwrap it.
Note that commit 86f4c90a1c5c ("ipv4, ipv6: ensure raw socket message is big enough to hold an IP header") ensures the message buffer is large enough to hold an iphdr, but does not constrain the self-reported iph->ihl.
Reachability: the malformed packet source is any caller with CAPNETRAW, including an unprivileged process in a user+net namespace on a kernel with CONFIGUSERNS=y. The reproduced AH crash also requires a matching xfrm AH policy on the outgoing route; a container granted CAPNETADMIN can install that state and policy in its netns. Loopback bypasses xfrmoutput, so the trigger uses a real netdev.
Reproduced on UML + KASAN: kernel-mode fault at addr 0x0 with memcpyorig at the crash site. Same shape reproduces inside a rootless Docker container with --cap-add NETADMIN on a stock distro kernel.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: bnep: Fix UAF read of dev->name
bnepaddconnection() needs to keep holding the bnepsessionsem while reading dev->name (just like bnepgetconnlist() does); otherwise the bnepsession() thread can concurrently free the netdevice, which can for example be triggered by a concurrent bnepdelconnection().
(This UAF is fairly uninteresting from a security perspective; calling bnepaddconnection() requires passing a capable(CAPNETADMIN) check. It also requires completely tearing down a netdev during a fairly tight race window.)
In the Linux kernel, the following vulnerability has been resolved:
udf: reject descriptors with oversized CRC length
udfreadtagged() skips CRC verification when descCRCLength + sizeof(struct tag) exceeds the block size. A crafted UDF image can set descCRCLength to an oversized value to bypass CRC validation entirely; the descriptor is then accepted based solely on the 8-bit tag checksum, which is trivially recomputable.
Reject such descriptors instead of silently accepting them. A legitimate single-block descriptor should never have a CRC length that exceeds the block.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: RFCOMM: hold listener socket in rfcommconnectind()
rfcommgetsockbychannel() scans rfcommsklist under the list lock, but returns the selected listener after dropping that lock without taking a reference. rfcommconnectind() then locks the listener, queues a child socket on it, and may notify it after unlocking it.
The buggy scenario involves two paths, with each column showing the order within that path:
rfcommconnectind(): listener close: 1. Find parent in 1. close() enters rfcommgetsockbychannel() rfcommsockrelease(). 2. Drop rfcommsklist.lock 2. rfcommsockshutdown() without pinning parent. closes the listener. 3. Call locksock(parent) and 3. rfcommsockkill() btacceptenqueue(parent, unlinks and puts parent. sk, true). 4. Read parent flags and may 4. parent can be freed. call skstatechange().
If close wins the race, parent can be freed before rfcommconnectind() reaches locksock(), btacceptenqueue(), or the deferred-setup callback.
Take a reference on the listener before leaving rfcommsklist.lock. After locksock() succeeds, recheck that it is still in BTLISTEN before queueing a child, cache the deferred-setup bit while the parent is locked, and drop the reference after the last parent use.
KASAN reported a slab-use-after-free in locksocknested() from rfcommconnectind(), with the freeing stack going through rfcommsockkill() and rfcommsockrelease().
Bluetooth: RFCOMM: validate skb length in MCC handlers