CVE-2025-21825

Source
https://nvd.nist.gov/vuln/detail/CVE-2025-21825
Import Source
https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2025-21825.json
JSON Data
https://api.test.osv.dev/v1/vulns/CVE-2025-21825
Related
Published
2025-03-06T16:15:54Z
Modified
2025-03-10T05:49:31.878783Z
Summary
[none]
Details

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

bpf: Cancel the running bpftimer through kworker for PREEMPTRT

During the update procedure, when overwrite element in a pre-allocated htab, the freeing of oldelement is protected by the bucket lock. The reason why the bucket lock is necessary is that the oldelement has already been stashed in htab->extraelems after allochtabelem() returns. If freeing the oldelement after the bucket lock is unlocked, the stashed element may be reused by concurrent update procedure and the freeing of oldelement will run concurrently with the reuse of the oldelement. However, the invocation of checkandfree_fields() may acquire a spin-lock which violates the lockdep rule because its caller has already held a raw-spin-lock (bucket lock). The following warning will be reported when such race happens:

BUG: scheduling while atomic: testprogs/676/0x00000003 3 locks held by testprogs/676: #0: ffffffff864b0240 (rcureadlocktrace){....}-{0:0}, at: bpfprogtestrunsyscall+0x2c0/0x830 #1: ffff88810e961188 (&htab->lockdepkey){....}-{2:2}, at: htabmapupdateelem+0x306/0x1500 #2: ffff8881f4eac1b8 (&base->softirqexpirylock){....}-{2:2}, at: hrtimercancelwaitrunning+0xe9/0x1b0 Modules linked in: bpftestmod(O) Preemption disabled at: [<ffffffff817837a3>] htabmapupdateelem+0x293/0x1500 CPU: 0 UID: 0 PID: 676 Comm: testprogs Tainted: G ... 6.12.0+ #11 Tainted: [W]=WARN, [O]=OOTMODULE Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)... Call Trace: <TASK> dumpstacklvl+0x57/0x70 dumpstack+0x10/0x20 _schedulebug+0x120/0x170 _schedule+0x300c/0x4800 schedulertlock+0x37/0x60 rtlockslowlocklocked+0x6d9/0x54c0 rtspinlock+0x168/0x230 hrtimercancelwaitrunning+0xe9/0x1b0 hrtimercancel+0x24/0x30 bpftimerdeletework+0x1d/0x40 bpftimercancelandfree+0x5e/0x80 bpfobjfreefields+0x262/0x4a0 checkandfreefields+0x1d0/0x280 htabmapupdateelem+0x7fc/0x1500 bpfprog9f90bc20768e0cb9overwritecb+0x3f/0x43 bpfprogea601c4649694dbdoverwritetimer+0x5d/0x7e bpfprogtestrunsyscall+0x322/0x830 _sysbpf+0x135d/0x3ca0 _x64sysbpf+0x75/0xb0 x64syscall+0x1b5/0xa10 dosyscall64+0x3b/0xc0 entrySYSCALL64afterhwframe+0x4b/0x53 ... </TASK>

It seems feasible to break the reuse and refill of per-cpu extraelems into two independent parts: reuse the per-cpu extraelems with bucket lock being held and refill the oldelement as per-cpu extraelems after the bucket lock is unlocked. However, it will make the concurrent overwrite procedures on the same CPU return unexpected -E2BIG error when the map is full.

Therefore, the patch fixes the lock problem by breaking the cancelling of bpftimer into two steps for PREEMPTRT: 1) use hrtimertrytocancel() and check its return value 2) if the timer is running, use hrtimercancel() through a kworker to cancel it again Considering that the current implementation of hrtimercancel() will try to acquire a being held softirqexpiry_lock when the current timer is running, these steps above are reasonable. However, it also has downside. When the timer is running, the cancelling of the timer is delayed when releasing the last map uref. The delay is also fixable (e.g., break the cancelling of bpf timer into two parts: one part in locked scope, another one in unlocked scope), it can be revised later if necessary.

It is a bit hard to decide the right fix tag. One reason is that the problem depends on PREEMPTRT which is enabled in v6.12. Considering the softirqexpirylock lock exists since v5.4 and bpftimer is introduced in v5.15, the bpftimer commit is used in the fixes tag and an extra depends-on tag is added to state the dependency on PREEMPTRT.

Depends-on: v6.12+ with PREEMPT_RT enabled

References

Affected packages

Debian:12 / linux

Package

Name
linux
Purl
pkg:deb/debian/linux?arch=source

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected

Affected versions

6.*

6.1.27-1
6.1.37-1
6.1.38-1
6.1.38-2~bpo11+1
6.1.38-2
6.1.38-3
6.1.38-4~bpo11+1
6.1.38-4
6.1.52-1
6.1.55-1~bpo11+1
6.1.55-1
6.1.64-1
6.1.66-1
6.1.67-1
6.1.69-1~bpo11+1
6.1.69-1
6.1.76-1~bpo11+1
6.1.76-1
6.1.82-1
6.1.85-1
6.1.90-1~bpo11+1
6.1.90-1
6.1.94-1~bpo11+1
6.1.94-1
6.1.98-1
6.1.99-1
6.1.106-1
6.1.106-2
6.1.106-3
6.1.112-1
6.1.115-1
6.1.119-1
6.1.123-1
6.1.124-1
6.1.128-1
6.1.129-1
6.3.1-1~exp1
6.3.2-1~exp1
6.3.4-1~exp1
6.3.5-1~exp1
6.3.7-1~bpo12+1
6.3.7-1
6.3.11-1
6.4~rc6-1~exp1
6.4~rc7-1~exp1
6.4.1-1~exp1
6.4.4-1~bpo12+1
6.4.4-1
6.4.4-2
6.4.4-3~bpo12+1
6.4.4-3
6.4.11-1
6.4.13-1
6.5~rc4-1~exp1
6.5~rc6-1~exp1
6.5~rc7-1~exp1
6.5.1-1~exp1
6.5.3-1~bpo12+1
6.5.3-1
6.5.6-1
6.5.8-1
6.5.10-1~bpo12+1
6.5.10-1
6.5.13-1
6.6.3-1~exp1
6.6.4-1~exp1
6.6.7-1~exp1
6.6.8-1
6.6.9-1
6.6.11-1
6.6.13-1~bpo12+1
6.6.13-1
6.6.15-1
6.6.15-2
6.7-1~exp1
6.7.1-1~exp1
6.7.4-1~exp1
6.7.7-1
6.7.9-1
6.7.9-2
6.7.12-1~bpo12+1
6.7.12-1
6.8.9-1
6.8.11-1
6.8.12-1~bpo12+1
6.8.12-1
6.9.2-1~exp1
6.9.7-1~bpo12+1
6.9.7-1
6.9.8-1
6.9.9-1
6.9.10-1~bpo12+1
6.9.10-1
6.9.11-1
6.9.12-1
6.10-1~exp1
6.10.1-1~exp1
6.10.3-1
6.10.4-1
6.10.6-1~bpo12+1
6.10.6-1
6.10.7-1
6.10.9-1
6.10.11-1~bpo12+1
6.10.11-1
6.10.12-1
6.11~rc4-1~exp1
6.11~rc5-1~exp1
6.11-1~exp1
6.11.2-1
6.11.4-1
6.11.5-1~bpo12+1
6.11.5-1
6.11.6-1
6.11.7-1
6.11.9-1
6.11.10-1~bpo12+1
6.11.10-1
6.12~rc6-1~exp1
6.12.3-1
6.12.5-1
6.12.6-1
6.12.8-1
6.12.9-1~bpo12+1
6.12.9-1
6.12.9-1+alpha
6.12.10-1
6.12.11-1
6.12.11-1+alpha
6.12.11-1+alpha.1
6.12.12-1~bpo12+1
6.12.12-1
6.12.13-1
6.12.15-1
6.12.16-1
6.12.17-1
6.13~rc6-1~exp1
6.13~rc7-1~exp1
6.13.2-1~exp1
6.13.3-1~exp1
6.13.4-1~exp1
6.13.5-1~exp1
6.13.6-1~exp1

Ecosystem specific

{
    "urgency": "not yet assigned"
}

Debian:13 / linux

Package

Name
linux
Purl
pkg:deb/debian/linux?arch=source

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
6.12.13-1

Affected versions

6.*

6.1.27-1
6.1.37-1
6.1.38-1
6.1.38-2~bpo11+1
6.1.38-2
6.1.38-3
6.1.38-4~bpo11+1
6.1.38-4
6.1.52-1
6.1.55-1~bpo11+1
6.1.55-1
6.1.64-1
6.1.66-1
6.1.67-1
6.1.69-1~bpo11+1
6.1.69-1
6.1.76-1~bpo11+1
6.1.76-1
6.1.82-1
6.1.85-1
6.1.90-1~bpo11+1
6.1.90-1
6.1.94-1~bpo11+1
6.1.94-1
6.1.98-1
6.1.99-1
6.1.106-1
6.1.106-2
6.1.106-3
6.1.112-1
6.1.115-1
6.1.119-1
6.1.123-1
6.1.124-1
6.1.128-1
6.1.129-1
6.3.1-1~exp1
6.3.2-1~exp1
6.3.4-1~exp1
6.3.5-1~exp1
6.3.7-1~bpo12+1
6.3.7-1
6.3.11-1
6.4~rc6-1~exp1
6.4~rc7-1~exp1
6.4.1-1~exp1
6.4.4-1~bpo12+1
6.4.4-1
6.4.4-2
6.4.4-3~bpo12+1
6.4.4-3
6.4.11-1
6.4.13-1
6.5~rc4-1~exp1
6.5~rc6-1~exp1
6.5~rc7-1~exp1
6.5.1-1~exp1
6.5.3-1~bpo12+1
6.5.3-1
6.5.6-1
6.5.8-1
6.5.10-1~bpo12+1
6.5.10-1
6.5.13-1
6.6.3-1~exp1
6.6.4-1~exp1
6.6.7-1~exp1
6.6.8-1
6.6.9-1
6.6.11-1
6.6.13-1~bpo12+1
6.6.13-1
6.6.15-1
6.6.15-2
6.7-1~exp1
6.7.1-1~exp1
6.7.4-1~exp1
6.7.7-1
6.7.9-1
6.7.9-2
6.7.12-1~bpo12+1
6.7.12-1
6.8.9-1
6.8.11-1
6.8.12-1~bpo12+1
6.8.12-1
6.9.2-1~exp1
6.9.7-1~bpo12+1
6.9.7-1
6.9.8-1
6.9.9-1
6.9.10-1~bpo12+1
6.9.10-1
6.9.11-1
6.9.12-1
6.10-1~exp1
6.10.1-1~exp1
6.10.3-1
6.10.4-1
6.10.6-1~bpo12+1
6.10.6-1
6.10.7-1
6.10.9-1
6.10.11-1~bpo12+1
6.10.11-1
6.10.12-1
6.11~rc4-1~exp1
6.11~rc5-1~exp1
6.11-1~exp1
6.11.2-1
6.11.4-1
6.11.5-1~bpo12+1
6.11.5-1
6.11.6-1
6.11.7-1
6.11.9-1
6.11.10-1~bpo12+1
6.11.10-1
6.12~rc6-1~exp1
6.12.3-1
6.12.5-1
6.12.6-1
6.12.8-1
6.12.9-1~bpo12+1
6.12.9-1
6.12.9-1+alpha
6.12.10-1
6.12.11-1
6.12.11-1+alpha
6.12.11-1+alpha.1
6.12.12-1~bpo12+1
6.12.12-1

Ecosystem specific

{
    "urgency": "not yet assigned"
}