CVE-2024-56547

Source
https://nvd.nist.gov/vuln/detail/CVE-2024-56547
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2024-56547.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2024-56547
Downstream
Published
2024-12-27T14:11:28.548Z
Modified
2025-11-20T07:14:03.038881Z
Summary
rcu/nocb: Fix missed RCU barrier on deoffloading
Details

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

rcu/nocb: Fix missed RCU barrier on deoffloading

Currently, running rcutorture test with torturetype=rcu fwdprogress=8 nbarriercbs=8 nocbsnthreads=8 nocbstoggle=100 onoffinterval=60 testboost=2, will trigger the following warning:

WARNING: CPU: 19 PID: 100 at kernel/rcu/tree_nocb.h:1061 rcu_nocb_rdp_deoffload+0x292/0x2a0
RIP: 0010:rcu_nocb_rdp_deoffload+0x292/0x2a0
 Call Trace:
  <TASK>
  ? __warn+0x7e/0x120
  ? rcu_nocb_rdp_deoffload+0x292/0x2a0
  ? report_bug+0x18e/0x1a0
  ? handle_bug+0x3d/0x70
  ? exc_invalid_op+0x18/0x70
  ? asm_exc_invalid_op+0x1a/0x20
  ? rcu_nocb_rdp_deoffload+0x292/0x2a0
  rcu_nocb_cpu_deoffload+0x70/0xa0
  rcu_nocb_toggle+0x136/0x1c0
  ? __pfx_rcu_nocb_toggle+0x10/0x10
  kthread+0xd1/0x100
  ? __pfx_kthread+0x10/0x10
  ret_from_fork+0x2f/0x50
  ? __pfx_kthread+0x10/0x10
  ret_from_fork_asm+0x1a/0x30
  </TASK>

CPU0 CPU2 CPU3 //rcunocbtoggle //nocbcbwait //rcutorture

// deoffload CPU1 // process CPU1's rdp rcubarrier() rcusegcblistentrain() rcusegcblistaddlen(1); // len == 2 // enqueue barrier // callback to CPU1's // rdp->cblist rcudobatch() // invoke CPU1's rdp->cblist // callback rcubarriercallback() rcubarrier() mutexlock(&rcustate.barriermutex); // still see len == 2 // enqueue barrier callback // to CPU1's rdp->cblist rcusegcblistentrain() rcusegcblistaddlen(1); // len == 3 // decrement len rcusegcblistaddlen(-2); kthread_parkme()

// CPU1's rdp->cblist len == 1 // Warn because there is // still a pending barrier // trigger warning WARNONONCE(rcusegcblistncbs(&rdp->cblist)); cpusread_unlock();

                                                            // wait CPU1 to comes online and
                                                            // invoke barrier callback on
                                                            // CPU1 rdp's->cblist
                                                            wait_for_completion(&rcu_state.barrier_completion);

// deoffload CPU4 cpusreadlock() rcubarrier() mutexlock(&rcustate.barriermutex); // block on barriermutex // wait rcubarrier() on // CPU3 to unlock barriermutex // but CPU3 unlock barriermutex // need to wait CPU1 comes online // when CPU1 going online will block on cpuswritelock

The above scenario will not only trigger a WARNONONCE(), but also trigger a deadlock.

Thanks to nocb locking, a second racing rcubarrier() on an offline CPU will either observe the decremented callback counter down to 0 and spare the callback enqueue, or rcuo will observe the new callback and keep rdp->nocbcb_sleep to false.

Therefore check rdp->nocbcbsleep before parking to make sure no further rcu_barrier() is waiting on the rdp.

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
1fcb932c8b5ce86219d7dedcd63659351a43291c
Fixed
224b62028959858294789772d372dcb36cf5f820
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
1fcb932c8b5ce86219d7dedcd63659351a43291c
Fixed
2996980e20b7a54a1869df15b3445374b850b155

Affected versions

v6.*

v6.11
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

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.12.0
Fixed
6.12.2