Description of problem: When readbuf is called to move over to the next page in the pagelist of an NFSv4 request, it sets argp->end to essentially a random number, certainly not an address within the page which argp->p now points to. So subsequent calls to READBUF will think there is much more than a page of spare space (the cast to u32 ensures an unsigned comparison) so we can expect to fall off the end of the second page. We never encountered this in testing because typically the only operations which use more than two pages are write-like operations, which have their own decoding logic. Something like a getattr after a write may cross a page boundary, but it would be very unusual for it to cross another boundary after that.
Upstream commit: http://git.kernel.org/linus/2bc3c1179c781b359d4f2f3439cb3df72afc17fc
The asn1 implementation in (a) the Linux kernel 2.4 before 2.4.36.6 and 2.6 before 2.6.25.5, as used in the cifs and ipnatsnmpbasic modules; and (b) the gxsnmp package; does not properly validate length values during decoding of ASN.1 BER data, which allows remote attackers to cause a denial of service (crash) or execute arbitrary code via (1) a length greater than the working buffer, which can lead to an unspecified overflow; (2) an oid length of zero, which can lead to an off-by-one error; or (3) an indefinite length for a primitive encoding.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: bridge: confirm multicast packets before passing them up the stack
conntrack nfconfirm logic cannot handle cloned skbs referencing the same nfconn entry, which will happen for multicast (broadcast) frames on bridges.
Example: macvlan0 | br0 / \ ethX ethY
ethX (or Y) receives a L2 multicast or broadcast packet containing an IP packet, flow is not yet in conntrack table.
1. skb passes through bridge and fake-ip (brnetfilter)Prerouting. -> skb->nfct now references a unconfirmed entry 2. skb is broad/mcast packet. bridge now passes clones out on each bridge interface. 3. skb gets passed up the stack. 4. In macvlan case, macvlan driver retains clone(s) of the mcast skb and schedules a work queue to send them out on the lower devices.
The clone skb->nfct is not a copy, it is the same entry as the original skb. The macvlan rx handler then returns RXHANDLERPASS. 5. Normal conntrack hooks (in NFINETLOCALIN) confirm the orig skb.
The Macvlan broadcast worker and normal confirm path will race.
This race will not happen if step 2 already confirmed a clone. In that case later steps perform skbclone() with skb->nfct already confirmed (in hash table). This works fine.
But such confirmation won't happen when eb/ip/nftables rules dropped the packets before they reached the nfconfirm step in postrouting.
Pablo points out that nfconntrackbridge doesn't allow use of stateful nat, so we can safely discard the nfconn entry and let inet call conntrack again.
This doesn't work for bridge netfilter: skb could have a nat transformation. Also bridge nf prevents re-invocation of inet prerouting via 'sabotagein' hook.
Work around this problem by explicit confirmation of the entry at LOCALIN time, before upper layer has a chance to clone the unconfirmed entry.
The downside is that this disables NAT and conntrack helpers.
Alternative fix would be to add locking to all code parts that deal with unconfirmed packets, but even if that could be done in a sane way this opens up other problems, for example:
-m physdev --physdev-out eth0 -j SNAT --snat-to 1.2.3.4 -m physdev --physdev-out eth1 -j SNAT --snat-to 1.2.3.5
For multicast case, only one of such conflicting mappings will be created, conntrack only handles 1:1 NAT mappings.
Users should set create a setup that explicitly marks such traffic NOTRACK (conntrack bypass) to avoid this, but we cannot auto-bypass them, ruleset might have accept rules for untracked traffic already, so user-visible behaviour would change.
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix heap overflow in NFSv4.0 LOCK replay cache
The NFSv4.0 replay cache uses a fixed 112-byte inline buffer (rpibuf[NFSD4REPLAYISIZE]) to store encoded operation responses. This size was calculated based on OPEN responses and does not account for LOCK denied responses, which include the conflicting lock owner as a variable-length field up to 1024 bytes (NFS4OPAQUELIMIT).
When a LOCK operation is denied due to a conflict with an existing lock that has a large owner, nfsd4encodeoperation() copies the full encoded response into the undersized replay buffer via readbytesfromxdrbuf() with no bounds check. This results in a slab-out-of-bounds write of up to 944 bytes past the end of the buffer, corrupting adjacent heap memory.
This can be triggered remotely by an unauthenticated attacker with two cooperating NFSv4.0 clients: one sets a lock with a large owner string, then the other requests a conflicting lock to provoke the denial.
We could fix this by increasing NFSD4REPLAYISIZE to allow for a full opaque, but that would increase the size of every stateowner, when most lockowners are not that large.
Instead, fix this by checking the encoded response length against NFSD4REPLAYISIZE before copying into the replay buffer. If the response is too large, set rpbuflen to 0 to skip caching the replay payload. The status is still cached, and the client already received the correct response on the original request.
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/x25: Fix potential double free of skb
When allocskb fails in x25queuerxframe it calls kfreeskb(skb) at line 48 and returns 1 (error). This error propagates back through the call chain:
x25queuerxframe returns 1 | v x25state3machine receives the return value 1 and takes the else branch at line 278, setting queued=0 and returning 0 | v x25processrxframe returns queued=0 | v x25backlogrcv at line 452 sees queued=0 and calls kfreeskb(skb) again
This would free the same skb twice. Looking at x25backlogrcv:
net/x25/x25in.c:x25backlogrcv() { ... queued = x25processrxframe(sk, skb); ... if (!queued) kfreeskb(skb); }
ax25: fix use-after-free bugs caused by ax25dsdeltimer
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.
ax25: properly unshare skbs in ax25kissrcv()
In the Linux kernel, the following vulnerability has been resolved:
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.)
Last updated 25 April 2025
In the Linux kernel, the following vulnerability has been resolved:
net: atm: fix use after free in lecsend()
The ->send() operation frees skb so save the length before calling ->send() to avoid a use after free.
In the Linux kernel, the following vulnerability has been resolved:
net: sched: Disallow replacing of child qdisc from one parent to another
Lion Ackermann was able to create a UAF which can be abused for privilege escalation with the following script
Step 1. create root qdisc tc qdisc add dev lo root handle 1:0 drr
step2. a class for packet aggregation do demonstrate uaf tc class add dev lo classid 1:1 drr
step3. a class for nesting tc class add dev lo classid 1:2 drr
step4. a class to graft qdisc to tc class add dev lo classid 1:3 drr
step5. tc qdisc add dev lo parent 1:1 handle 2:0 plug limit 1024
step6. tc qdisc add dev lo parent 1:2 handle 3:0 drr
step7. tc class add dev lo classid 3:1 drr
step 8. tc qdisc add dev lo parent 3:1 handle 4:0 pfifo
step 9. Display the class/qdisc layout
tc class ls dev lo class drr 1:1 root leaf 2: quantum 64Kb class drr 1:2 root leaf 3: quantum 64Kb class drr 3:1 root leaf 4: quantum 64Kb
tc qdisc ls qdisc drr 1: dev lo root refcnt 2 qdisc plug 2: dev lo parent 1:1 qdisc pfifo 4: dev lo parent 3:1 limit 1000p qdisc drr 3: dev lo parent 1:2
step10. trigger the bug <=== prevented by this patch tc qdisc replace dev lo parent 1:3 handle 4:0
step 11. Redisplay again the qdiscs/classes
tc class ls dev lo class drr 1:1 root leaf 2: quantum 64Kb class drr 1:2 root leaf 3: quantum 64Kb class drr 1:3 root leaf 4: quantum 64Kb class drr 3:1 root leaf 4: quantum 64Kb
tc qdisc ls qdisc drr 1: dev lo root refcnt 2 qdisc plug 2: dev lo parent 1:1 qdisc pfifo 4: dev lo parent 3:1 refcnt 2 limit 1000p qdisc drr 3: dev lo parent 1:2
Observe that a) parent for 4:0 does not change despite the replace request. There can only be one parent. b) refcount has gone up by two for 4:0 and c) both class 1:3 and 3:1 are pointing to it.
Step 12. send one packet to plug echo "" | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888,priority=$((0x10001)) step13. send one packet to the grafted fifo echo "" | socat -u STDIN UDP4-DATAGRAM:127.0.0.1:8888,priority=$((0x10003))
step14. lets trigger the uaf tc class delete dev lo classid 1:3 tc class delete dev lo classid 1:1
The semantics of "replace" is for a del/add on the same node and not a delete from one node(3:1) and add to another node (1:3) as in step10. While we could "fix" with a more complex approach there could be consequences to expectations so the patch takes the preventive approach of "disallow such config".
Joint work with Lion Ackermann <nnamrec@gmail.com>
In the Linux kernel, the following vulnerability has been resolved:
net: atm: fix /proc/net/atm/lec handling
/proc/net/atm/lec must ensure safety against devlec[] changes.
It appears it had devput() calls without prior devhold(), leading to imbalance and UAF.
In the Linux kernel, the following vulnerability has been resolved:
net/sched: Enforce that teql can only be used as root qdisc
Design intent of teql is that it is only supposed to be used as root qdisc. We need to check for that constraint.
Although not important, I will describe the scenario that unearthed this issue for the curious.
GangMin Kim <km.kim1503@gmail.com> managed to concot a scenario as follows:
ROOT qdisc 1:0 (QFQ) ├── class 1:1 (weight=15, lmax=16384) netem with delay 6.4s └── class 1:2 (weight=1, lmax=1514) teql
GangMin sends a packet which is enqueued to 1:1 (netem). Any invocation of dequeue by QFQ from this class will not return a packet until after 6.4s. In the meantime, a second packet is sent and it lands on 1:2. teql's enqueue will return success and this will activate class 1:2. Main issue is that teql only updates the parent visible qlen (sch->q.qlen) at dequeue. Since QFQ will only call dequeue if peek succeeds (and teql's peek always returns NULL), dequeue will never be called and thus the qlen will remain as 0. With that in mind, when GangMin updates 1:2's lmax value, the qfqchangeclass calls qfqdeactrmfromagg. Since the child qdisc's qlen was not incremented, qfq fails to deactivate the class, but still frees its pointers from the aggregate. So when the first packet is rescheduled after 6.4 seconds (netem's delay), a dangling pointer is accessed causing GangMin's causing a UAF.
A denial of service flaw was found in atmtcenqueue in net/sched/schatm.c in the Linux kernel. In this flaw a local attacker may cause a denial of service because of type confusion (non-negative numbers can sometimes indicate a TCACTSHOT condition rather than valid classification results).
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a2965c7be0522eaa18808684b7b82b248515511b
In the Linux kernel, the following vulnerability has been resolved:
rose: fix dangling neighbour pointers in rosertdevicedown()
There are two bugs in rosertdevicedown() that can cause use-after-free:
1. The loop bound t->count is modified within the loop, which can cause the loop to terminate early and miss some entries.
2. When removing an entry from the neighbour array, the subsequent entries are moved up to fill the gap, but the loop index i is still incremented, causing the next entry to be skipped.
For example, if a node has three neighbours (A, A, B) with count=3 and A is being removed, the second A is not checked.
i=0: (A, A, B) -> (A, B) with count=2 ^ checked i=1: (A, B) -> (A, B) with count=2 ^ checked (B, not A!) i=2: (doesn't occur because i < count is false)
This leaves the second A in the array with count=2, but the roseneigh structure has been freed. Code that accesses these entries assumes that the first count entries are valid pointers, causing a use-after-free when it accesses the dangling pointer.
Fix both issues by iterating over the array in reverse order with a fixed loop bound. This ensures that all entries are examined and that the removal of an entry doesn't affect subsequent iterations.
atm: atmtcp: Prevent arbitrary write in atmtcprecvcontrol().
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:
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:
In the Linux kernel, the following vulnerability has been resolved:
media: ttpci: fix two memleaks in budgetavattach
When saa7146registerdevice and saa7146vvinit fails, budgetavattach should free the resources it allocates, like the error-handling of ttpcibudgetinit does. Besides, there are two fixme comment refers to such deallocations.
Integer overflow in the fbmmap function in drivers/video/fbmem.c in the Linux kernel before 3.8.9, as used in a certain Motorola build of Android 4.1.2 and other products, allows local users to create a read-write memory mapping for the entirety of kernel memory, and consequently gain privileges, via crafted /dev/graphics/fb0 mmap2 system calls, as demonstrated by the Motochopper pwn program.
In the Linux kernel, the following vulnerability has been resolved:
initramfs: avoid filename buffer overrun
The initramfs filename field is defined in Documentation/driver-api/early-userspace/buffer-format.rst as:
37 cpiofile := ALGN(4) + cpioheader + filename + "\0" + ALGN(4) + data ... 55 ============= ================== ========================= 56 Field name Field size Meaning 57 ============= ================== ========================= ... 70 cnamesize 8 bytes Length of filename, including final \0
When extracting an initramfs cpio archive, the kernel's doname() path handler assumes a zero-terminated path at @collected, passing it directly to filpopen() / initmkdir() / initmknod().
If a specially crafted cpio entry carries a non-zero-terminated filename and is followed by uninitialized memory, then a file may be created with trailing characters that represent the uninitialized memory. The ability to create an initramfs entry would imply already having full control of the system, so the buffer overrun shouldn't be considered a security vulnerability.
Append the output of the following bash script to an existing initramfs and observe any created /initramfstestfnameoverrunAA path. E.g. ./reproducer.sh | gzip >> /myinitramfs
It's easiest to observe non-zero uninitialized memory when the output is gzipped, as it'll overflow the heap allocated @outbuf in gunzip(), rather than the initrdstart+initrdsize block.
---- reproducer.sh ---- nilchar="A" # change to "\0" to properly zero terminate / pad magic="070701" ino=1 mode=$(( 0100777 )) uid=0 gid=0 nlink=1 mtime=1 filesize=0 devmajor=0 devminor=1 rdevmajor=0 rdevminor=0 csum=0 fname="initramfstestfnameoverrun" namelen=$(( ${#fname} + 1 )) # plus one to account for terminator
printf "%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s" \ $magic $ino $mode $uid $gid $nlink $mtime $filesize \ $devmajor $devminor $rdevmajor $rdevminor $namelen $csum $fname
termpadlen=$(( 1 + ((4 - ((110 + $namelen) & 3)) % 4) )) printf "%.s${nilchar}" $(seq 1 $termpadlen) ---- reproducer.sh ----
Symlink filename fields handled in dosymlink() won't overrun past the data segment, due to the explicit zero-termination of the symlink target.
Fix filename buffer overrun by aborting the initramfs FSM if any cpio entry doesn't carry a zero-terminator at the expected (namelen - 1) offset.
In multiple functions of quirks.c, there is a possible way to free arbitrary memory due to improper input validation. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.
In the Linux kernel, the following vulnerability has been resolved: