CVE-2022-49201: ibmvnic: fix race between xmit and reset

Published Feb 26, 2025
·
Updated

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

ibmvnic: fix race between xmit and reset

There is a race between reset and the transmit paths that can lead to ibmvnicxmit() accessing an scrq after it has been freed in the reset path. It can result in a crash like:

Kernel attempted to read user page (0) - exploit attempt? (uid: 0) BUG: Kernel NULL pointer dereference on read at 0x00000000 Faulting instruction address: 0xc0080000016189f8 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c0080000016189f8] ibmvnicxmit+0x60/0xb60 [ibmvnic] LR [c000000000c0046c] devhardstartxmit+0x11c/0x280 Call Trace: [c008000001618f08] ibmvnicxmit+0x570/0xb60 [ibmvnic] (unreliable) [c000000000c0046c] devhardstartxmit+0x11c/0x280 [c000000000c9cfcc] schdirectxmit+0xec/0x330 [c000000000bfe640] devxmitskb+0x3a0/0x9d0 [c000000000c00ad4] devqueuexmit+0x394/0x730 [c008000002db813c] bondstartxmit+0x254/0x450 [bonding] [c008000002db8378] bondstartxmit+0x40/0xc0 [bonding] [c000000000c0046c] devhardstartxmit+0x11c/0x280 [c000000000c00ca4] devqueuexmit+0x564/0x730 [c000000000cf97e0] neighhhoutput+0xd0/0x180 [c000000000cfa69c] ipfinishoutput2+0x31c/0x5c0 [c000000000cfd244] ipqueuexmit+0x194/0x4f0 [c000000000d2a3c4] tcptransmitskb+0x434/0x9b0 [c000000000d2d1e0] tcpretransmitskb+0x1d0/0x6a0 [c000000000d2d984] tcpretransmitskb+0x34/0x130 [c000000000d310e8] tcpretransmittimer+0x388/0x6d0 [c000000000d315ec] tcpwritetimerhandler+0x1bc/0x330 [c000000000d317bc] tcpwritetimer+0x5c/0x200 [c000000000243270] calltimerfn+0x50/0x1c0 [c000000000243704] runtimers.part.0+0x324/0x460 [c000000000243894] runtimersoftirq+0x54/0xa0 [c000000000ea713c] dosoftirq+0x15c/0x3e0 [c000000000166258] irqexitrcu+0x158/0x190 [c000000000166420] irqexit+0x20/0x40 [c00000000002853c] timerinterrupt+0x14c/0x2b0 [c000000000009a00] decrementercommonvirt+0x210/0x220 --- interrupt: 900 at plparhcallnoretsnotrace+0x18/0x2c

The immediate cause of the crash is the access of txscrq in the following snippet during a reset, where the txscrq can be either NULL or an address that will soon be invalid:

ibmvnicxmit() { ... txscrq = adapter->txscrq[queuenum]; txq = netdevgettxqueue(netdev, queuenum); indbufp = &txscrq->indbuf;

if (testbit(0, &adapter->resetting)) { ... }

But beyond that, the call to ibmvnicxmit() itself is not safe during a reset and the reset path attempts to avoid this by stopping the queue in ibmvniccleanup(). However just after the queue was stopped, an in-flight ibmvniccompletetx() could have restarted the queue even as the reset is progressing.

Since the queue was restarted we could get a call to ibmvnicxmit() which can then access the bad txscrq (or other fields).

We cannot however simply have ibmvniccompletetx() check the ->resetting bit and skip starting the queue. This can race at the "back-end" of a good reset which just restarted the queue but has not cleared the ->resetting bit yet. If we skip restarting the queue due to ->resetting being true, the queue would remain stopped indefinitely potentially leading to transmit timeouts.

IOW ->resetting is too broad for this purpose. Instead use a new flag that indicates whether or not the queues are active. Only the open/ reset paths control when the queues are active. ibmvniccompletetx() and others wake up the queue only if the queue is marked active.

So we will have: A. reset/open thread in ibmvniccleanup() and ibmvnicopen()

->resetting = true ->txqueuesactive = false disable tx queues ... ->txqueuesactive = true start tx queues

B. Tx interrupt in ibmvniccompletetx():

if (->txqueuesactive) netifwakesubqueue();

To ensure that ->txqueuesactive and state of the queues are consistent, we need a lock which:

- must also be taken in the interrupt path (ibmvniccompletetx()) - shared across the multiple ---truncated---

Affected Software

4 affected components
Linux Linux kernel
Linux Linux kernel>=5.4<5.15.33
Linux Linux kernel>=5.16<5.16.19
Linux Linux kernel>=5.17<5.17.2

Event History

Feb 26, 2025
CVE Published
via MITRE·01:55 AM
Data Sourced
via MITRE·01:55 AM
DescriptionSeverity
Data Sourced
via NVD·07:00 AM
RemedyDescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2022-49201?

CVE-2022-49201 has a high severity due to its potential to cause system crashes.

2

How do I fix CVE-2022-49201?

To fix CVE-2022-49201, upgrade the Linux kernel to a version that includes the patch for this vulnerability.

3

Which versions of the Linux kernel are affected by CVE-2022-49201?

CVE-2022-49201 affects Linux kernel versions from 5.4 up to but not including 5.15.33, and between 5.16 and 5.16.19, as well as 5.17 and 5.17.2.

4

What systems are vulnerable to CVE-2022-49201?

Systems running affected versions of the Linux kernel, particularly those using the ibmvnic driver, are vulnerable to CVE-2022-49201.

5

Is CVE-2022-49201 a remote or local vulnerability?

CVE-2022-49201 is primarily a local vulnerability, requiring local access to the vulnerable Linux kernel.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203