// For flags

CVE-2021-46925

net/smc: fix kernel panic caused by race of smc_sock

Severity Score

4.7
*CVSS v3.1

Exploit Likelihood

*EPSS

Affected Versions

*CPE

Public Exploits

0
*Multiple Sources

Exploited in Wild

-
*KEV

Decision

Track
*SSVC
Descriptions

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

net/smc: fix kernel panic caused by race of smc_sock

A crash occurs when smc_cdc_tx_handler() tries to access smc_sock
but smc_release() has already freed it.

[ 4570.695099] BUG: unable to handle page fault for address: 000000002eae9e88
[ 4570.696048] #PF: supervisor write access in kernel mode
[ 4570.696728] #PF: error_code(0x0002) - not-present page
[ 4570.697401] PGD 0 P4D 0
[ 4570.697716] Oops: 0002 [#1] PREEMPT SMP NOPTI
[ 4570.698228] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-rc4+ #111
[ 4570.699013] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8c24b4c 04/0
[ 4570.699933] RIP: 0010:_raw_spin_lock+0x1a/0x30
<...>
[ 4570.711446] Call Trace:
[ 4570.711746] <IRQ>
[ 4570.711992] smc_cdc_tx_handler+0x41/0xc0
[ 4570.712470] smc_wr_tx_tasklet_fn+0x213/0x560
[ 4570.712981] ? smc_cdc_tx_dismisser+0x10/0x10
[ 4570.713489] tasklet_action_common.isra.17+0x66/0x140
[ 4570.714083] __do_softirq+0x123/0x2f4
[ 4570.714521] irq_exit_rcu+0xc4/0xf0
[ 4570.714934] common_interrupt+0xba/0xe0

Though smc_cdc_tx_handler() checked the existence of smc connection,
smc_release() may have already dismissed and released the smc socket
before smc_cdc_tx_handler() further visits it.

smc_cdc_tx_handler() |smc_release()
if (!conn) |
|
|smc_cdc_tx_dismiss_slots()
| smc_cdc_tx_dismisser()
|
|sock_put(&smc->sk) <- last sock_put,
| smc_sock freed
bh_lock_sock(&smc->sk) (panic) |

To make sure we won't receive any CDC messages after we free the
smc_sock, add a refcount on the smc_connection for inflight CDC
message(posted to the QP but haven't received related CQE), and
don't release the smc_connection until all the inflight CDC messages
haven been done, for both success or failed ones.

Using refcount on CDC messages brings another problem: when the link
is going to be destroyed, smcr_link_clear() will reset the QP, which
then remove all the pending CQEs related to the QP in the CQ. To make
sure all the CQEs will always come back so the refcount on the
smc_connection can always reach 0, smc_ib_modify_qp_reset() was replaced
by smc_ib_modify_qp_error().
And remove the timeout in smc_wr_tx_wait_no_pending_sends() since we
need to wait for all pending WQEs done, or we may encounter use-after-
free when handling CQEs.

For IB device removal routine, we need to wait for all the QPs on that
device been destroyed before we can destroy CQs on the device, or
the refcount on smc_connection won't reach 0 and smc_sock cannot be
released.

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: net/smc: soluciona el pánico del kernel causado por la carrera de smc_sock. Se produce un bloqueo cuando smc_cdc_tx_handler() intenta acceder a smc_sock pero smc_release() ya lo ha liberado. [ 4570.695099] ERROR: no se puede manejar el error de página para la dirección: 000000002eae9e88 [ 4570.696048] #PF: acceso de escritura del supervisor en modo kernel [ 4570.696728] #PF: error_code(0x0002) - página no presente [ 4570.697401] PGD 0 P4D 0 [ 4 570.697716 ] Ups: 0002 [#1] PREEMPT SMP NOPTI [ 4570.698228] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-rc4+ #111 [ 4570.699013] Nombre de hardware: Alibaba Cloud Alibaba Cloud ECS, BIOS 8c24b4c 04/ 0 [ 4570.699933] RIP: 0010:_raw_spin_lock+0x1a/0x30 &lt;...&gt; [ 4570.711446] Seguimiento de llamadas: [ 4570.711746] [ 4570.711992] smc_cdc_tx_handler+0x41/0xc0 [ 4570.7 12470] smc_wr_tx_tasklet_fn+0x213/0x560 [ 4570.712981] ? smc_cdc_tx_dismisser+0x10/0x10 [ 4570.713489] tasklet_action_common.isra.17+0x66/0x140 [ 4570.714083] __do_softirq+0x123/0x2f4 [ 4570.714521] irq_exit_rcu+0xc4/0x f0 [4570.714934] common_interrupt+0xba/0xe0 Aunque smc_cdc_tx_handler() comprobó la existencia de smc conexión, es posible que smc_release() ya haya descartado y liberado el socket smc antes de que smc_cdc_tx_handler() lo visite más. smc_cdc_tx_handler() |smc_release() si (!conn) | | |smc_cdc_tx_dismiss_slots() | smc_cdc_tx_dismisser() | |sock_put(&amp;smc-&gt;sk) &lt;- último sock_put, | smc_sock liberó bh_lock_sock(&amp;smc-&gt;sk) (pánico) | Para asegurarnos de que no recibiremos ningún mensaje CDC después de liberar el smc_sock, agregue un recuento en smc_connection para el mensaje CDC en vuelo (publicado en el QP pero no haya recibido el CQE relacionado) y no libere el smc_connection hasta que todo Los mensajes CDC a bordo se han realizado, tanto para los exitosos como para los fallidos. El uso de refcount en mensajes CDC trae otro problema: cuando el enlace se va a destruir, smcr_link_clear() restablecerá el QP, lo que luego eliminará todos los CQE pendientes relacionados con el QP en el CQ. Para asegurarse de que todos los CQE siempre regresen para que el recuento en smc_connection siempre pueda llegar a 0, smc_ib_modify_qp_reset() fue reemplazado por smc_ib_modify_qp_error(). Y elimine el tiempo de espera en smc_wr_tx_wait_no_pending_sends() ya que debemos esperar a que se completen todos los WQE pendientes, o podemos encontrarnos con use-after- free al manejar CQE. Para la rutina de eliminación del dispositivo IB, debemos esperar a que se destruyan todos los QP de ese dispositivo antes de poder destruir los CQ del dispositivo, o el recuento de referencia en smc_connection no llegará a 0 y smc_sock no podrá liberarse.

*Credits: N/A
CVSS Scores
Attack Vector
Local
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
* Common Vulnerability Scoring System
SSVC
  • Decision:Track
Exploitation
None
Automatable
No
Tech. Impact
Partial
* Organization's Worst-case Scenario
Timeline
  • 2024-02-25 CVE Reserved
  • 2024-02-27 CVE Published
  • 2024-04-21 EPSS Updated
  • 2024-08-04 CVE Updated
  • ---------- Exploited in Wild
  • ---------- KEV Due Date
  • ---------- First Exploit
CWE
  • CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
CAPEC
Affected Vendors, Products, and Versions
Vendor Product Version Other Status
Vendor Product Version Other Status <-- --> Vendor Product Version Other Status
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 4.11 < 5.10.90
Search vendor "Linux" for product "Linux Kernel" and version " >= 4.11 < 5.10.90"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 4.11 < 5.15.13
Search vendor "Linux" for product "Linux Kernel" and version " >= 4.11 < 5.15.13"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 4.11 < 5.16
Search vendor "Linux" for product "Linux Kernel" and version " >= 4.11 < 5.16"
en
Affected