CVE-2025-22059

Source
https://nvd.nist.gov/vuln/detail/CVE-2025-22059
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2025-22059.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2025-22059
Downstream
Published
2025-04-16T14:12:15Z
Modified
2025-10-15T23:35:36.614469Z
Severity
  • 5.5 (Medium) CVSS_V3 - CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H CVSS Calculator
Summary
udp: Fix multiple wraparounds of sk->sk_rmem_alloc.
Details

In the Linux kernel, the following vulnerability has been resolved:

udp: Fix multiple wraparounds of sk->skrmemalloc.

_udpenqueuescheduleskb() has the following condition:

if (atomicread(&sk->skrmemalloc) > sk->skrcvbuf) goto drop;

sk->skrcvbuf is initialised by net.core.rmemdefault and later can be configured by SORCVBUF, which is limited by net.core.rmemmax, or SO_RCVBUFFORCE.

If we set INTMAX to sk->skrcvbuf, the condition is always false as sk->skrmemalloc is also signed int.

Then, the size of the incoming skb is added to sk->skrmemalloc unconditionally.

This results in integer overflow (possibly multiple times) on sk->skrmemalloc and allows a single socket to have skb up to net.core.udp_mem[1].

For example, if we set a large value to udpmem[1] and INTMAX to sk->sk_rcvbuf and flood packets to the socket, we can see multiple overflows:

# cat /proc/net/sockstat | grep UDP: UDP: inuse 3 mem 7956736 <-- (7956736 << 12) bytes > INTMAX * 15 ^- PAGESHIFT # ss -uam State Recv-Q ... UNCONN -1757018048 ... <-- flipping the sign repeatedly skmem:(r2537949248,rb2147483646,t0,tb212992,f1984,w0,o0,bl0,d0)

Previously, we had a boundary check for INTMAX, which was removed by commit 6a1f12dd85a8 ("udp: relax atomic operation on sk->skrmem_alloc").

A complete fix would be to revert it and cap the right operand by INT_MAX:

rmem = atomicaddreturn(size, &sk->skrmemalloc); if (rmem > min(size + (unsigned int)sk->skrcvbuf, INTMAX)) goto uncharge_drop;

but we do not want to add the expensive atomicaddreturn() back just for the corner case.

Casting rmem to unsigned int prevents multiple wraparounds, but we still allow a single wraparound.

# cat /proc/net/sockstat | grep UDP: UDP: inuse 3 mem 524288 <-- (INT_MAX + 1) >> 12

# ss -uam State Recv-Q ... UNCONN -2147482816 ... <-- INT_MAX + 831 bytes skmem:(r2147484480,rb2147483646,t0,tb212992,f3264,w0,o0,bl0,d14468947)

So, let's define rmem and rcvbuf as unsigned int and check skb->truesize only when rcvbuf is large enough to lower the overflow possibility.

Note that we still have a small chance to see overflow if multiple skbs to the same socket are processed on different core at the same time and each size does not exceed the limit but the total size does.

Note also that we must ignore skb->truesize for a small buffer as explained in commit 363dc73acacb ("udp: be less conservative with sock rmem accounting").

References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
6a1f12dd85a8b24f871dfcf467378660af9c064d
Fixed
94d5ad7b41122be33ebc2a6830fe710cba1ecd75
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
6a1f12dd85a8b24f871dfcf467378660af9c064d
Fixed
1f529988efe9870db802cb79d01d8f473099b4d7
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
6a1f12dd85a8b24f871dfcf467378660af9c064d
Fixed
7571aadd20289e9ea10ebfed0986f39ed8b3c16b
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
6a1f12dd85a8b24f871dfcf467378660af9c064d
Fixed
5a465a0da13ee9fbd7d3cd0b2893309b0fe4b7e3

Affected versions

v6.*

v6.10
v6.10-rc1
v6.10-rc2
v6.10-rc3
v6.10-rc4
v6.10-rc5
v6.10-rc6
v6.10-rc7
v6.11
v6.11-rc1
v6.11-rc2
v6.11-rc3
v6.11-rc4
v6.11-rc5
v6.11-rc6
v6.11-rc7
v6.12
v6.12-rc1
v6.12-rc2
v6.12-rc3
v6.12-rc4
v6.12-rc5
v6.12-rc6
v6.12-rc7
v6.12.1
v6.12.10
v6.12.11
v6.12.12
v6.12.13
v6.12.14
v6.12.15
v6.12.16
v6.12.17
v6.12.18
v6.12.19
v6.12.2
v6.12.20
v6.12.21
v6.12.22
v6.12.3
v6.12.4
v6.12.5
v6.12.6
v6.12.7
v6.12.8
v6.12.9
v6.13
v6.13-rc1
v6.13-rc2
v6.13-rc3
v6.13-rc4
v6.13-rc5
v6.13-rc6
v6.13-rc7
v6.13.1
v6.13.10
v6.13.2
v6.13.3
v6.13.4
v6.13.5
v6.13.6
v6.13.7
v6.13.8
v6.13.9
v6.14
v6.14-rc1
v6.14-rc2
v6.14-rc3
v6.14-rc4
v6.14-rc5
v6.14-rc6
v6.14-rc7
v6.14.1
v6.9
v6.9-rc2
v6.9-rc3
v6.9-rc4
v6.9-rc5
v6.9-rc6
v6.9-rc7

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.10.0
Fixed
6.12.23
Type
ECOSYSTEM
Events
Introduced
6.13.0
Fixed
6.13.11
Type
ECOSYSTEM
Events
Introduced
6.14.0
Fixed
6.14.2