CVE-2023-52587

Source
https://nvd.nist.gov/vuln/detail/CVE-2023-52587
Import Source
https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2023-52587.json
JSON Data
https://api.test.osv.dev/v1/vulns/CVE-2023-52587
Downstream
Related
Published
2024-03-06T06:45:21.418Z
Modified
2025-11-28T02:34:02.512882Z
Summary
IB/ipoib: Fix mcast list locking
Details

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

IB/ipoib: Fix mcast list locking

Releasing the priv->lock while iterating the priv->multicast_list in ipoib_mcast_join_task() opens a window for ipoib_mcast_dev_flush() to remove the items while in the middle of iteration. If the mcast is removed while the lock was dropped, the for loop spins forever resulting in a hard lockup (as was reported on RHEL 4.18.0-372.75.1.el8_6 kernel):

Task A (kworker/u72:2 below)       | Task B (kworker/u72:0 below)
-----------------------------------+-----------------------------------
ipoib_mcast_join_task(work)        | ipoib_ib_dev_flush_light(work)
  spin_lock_irq(&priv->lock)       | __ipoib_ib_dev_flush(priv, ...)
  list_for_each_entry(mcast,       | ipoib_mcast_dev_flush(dev = priv->dev)
      &priv->multicast_list, list) |
    ipoib_mcast_join(dev, mcast)   |
      spin_unlock_irq(&priv->lock) |
                                   |   spin_lock_irqsave(&priv->lock, flags)
                                   |   list_for_each_entry_safe(mcast, tmcast,
                                   |                  &priv->multicast_list, list)
                                   |     list_del(&mcast->list);
                                   |     list_add_tail(&mcast->list, &remove_list)
                                   |   spin_unlock_irqrestore(&priv->lock, flags)
      spin_lock_irq(&priv->lock)   |
                                   |   ipoib_mcast_remove_list(&remove_list)

(Here, mcast is no longer on the | listforeachentrysafe(mcast, tmcast, priv->multicast_list and we keep | removelist, list) spinning on the remove_list of | >>> waitfor_completion(&mcast->done) the other thread which is blocked | and the list is still valid on | it's stack.)

Fix this by keeping the lock held and changing to GFP_ATOMIC to prevent eventual sleeps. Unfortunately we could not reproduce the lockup and confirm this fix but based on the code review I think this fix should address such lockups.

crash> bc 31

PID: 747 TASK: ff1c6a1a007e8000 CPU: 31 COMMAND: "kworker/u72:2"

[exception RIP: ipoib_mcast_join_task+0x1b1]
RIP: ffffffffc0944ac1  RSP: ff646f199a8c7e00  RFLAGS: 00000002
RAX: 0000000000000000  RBX: ff1c6a1a04dc82f8  RCX: 0000000000000000
                              work (&priv->mcast_task{,.work})
RDX: ff1c6a192d60ac68  RSI: 0000000000000286  RDI: ff1c6a1a04dc8000
       &mcast->list
RBP: ff646f199a8c7e90   R8: ff1c699980019420   R9: ff1c6a1920c9a000
R10: ff646f199a8c7e00  R11: ff1c6a191a7d9800  R12: ff1c6a192d60ac00
                                                     mcast
R13: ff1c6a1d82200000  R14: ff1c6a1a04dc8000  R15: ff1c6a1a04dc82d8
       dev                    priv (&priv->lock)     &priv->multicast_list (aka head)
ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018

--- <NMI exception stack> --- #5 [ff646f199a8c7e00] ipoibmcastjointask+0x1b1 at ffffffffc0944ac1 [ibipoib] #6 [ff646f199a8c7e98] processonework+0x1a7 at ffffffff9bf10967

crash> rx ff646f199a8c7e68 ff646f199a8c7e68: ff1c6a1a04dc82f8 <<< work = &priv->mcast_task.work

crash> list -hO ipoibdevpriv.multicast_list ff1c6a1a04dc8000 (empty)

crash> ipoibdevpriv.mcasttask.work.func,mcastmutex.owner.counter ff1c6a1a04dc8000 mcasttask.work.func = 0xffffffffc0944910 <ipoib_mcast_join_task>, mcastmutex.owner.counter = 0xff1c69998efec000

crash> b 8

PID: 8 TASK: ff1c69998efec000 CPU: 33 COMMAND: "kworker/u72:0"

#3 [ff646f1980153d50] waitforcompletion+0x96 at ffffffff9c7d7646 #4 [ff646f1980153d90] ipoibmcastremovelist+0x56 at ffffffffc0944dc6 [ibipoib] #5 [ff646f1980153de8] ipoibmcastdevflush+0x1a7 at ffffffffc09455a7 [ibipoib] #6 [ff646f1980153e58] _ipoibibdevflush+0x1a4 at ffffffffc09431a4 [ib_ipoib] #7 [ff ---truncated---

Database specific
{
    "cna_assigner": "Linux",
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2023/52xxx/CVE-2023-52587.json"
}
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
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
Fixed
4c8922ae8eb8dcc1e4b7d1059d97a8334288d825
Fixed
615e3adc2042b7be4ad122a043fc9135e6342c90
Fixed
ac2630fd3c90ffec34a0bfc4d413668538b0e8f2
Fixed
ed790bd0903ed3352ebf7f650d910f49b7319b34
Fixed
5108a2dc2db5630fb6cd58b8be80a0c134bc310a
Fixed
342258fb46d66c1b4c7e2c3717ac01e10c03cf18
Fixed
7c7bd4d561e9dc6f5b7df9e184974915f6701a89
Fixed
4f973e211b3b1c6d36f7c6a19239d258856749f9

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
4.19.307
Type
ECOSYSTEM
Events
Introduced
4.20.0
Fixed
5.4.269
Type
ECOSYSTEM
Events
Introduced
5.5.0
Fixed
5.10.210
Type
ECOSYSTEM
Events
Introduced
5.11.0
Fixed
5.15.149
Type
ECOSYSTEM
Events
Introduced
5.16.0
Fixed
6.1.77
Type
ECOSYSTEM
Events
Introduced
6.2.0
Fixed
6.6.16
Type
ECOSYSTEM
Events
Introduced
6.7.0
Fixed
6.7.4