CVE-2024-56788CWE-362

CVE-2024-56788

High · published January 11, 2025

CVSS v3.1
7.5
EPSS
0%
Percentile
14.8
In the wild
Unconfirmed
What it is

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

net: ethernet: oa_tc6: fix tx skb race condition between reference pointers

There are two skb pointers to manage tx skb's enqueued from n/w stack.

waiting_tx_skb pointer points to the tx skb which needs to be processed

and ongoing_tx_skb pointer points to the tx skb which is being processed.

SPI thread prepares the tx data chunks from the tx skb pointed by the

ongoing_tx_skb pointer. When the tx skb pointed by the ongoing_tx_skb is

processed, the tx skb pointed by the waiting_tx_skb is assigned to

ongoing_tx_skb and the waiting_tx_skb pointer is assigned with NULL.

Whenever there is a new tx skb from n/w stack, it will be assigned to

waiting_tx_skb pointer if it is NULL. Enqueuing and processing of a tx skb

handled in two different threads.

Consider a scenario where the SPI thread processed an ongoing_tx_skb and

it moves next tx skb from waiting_tx_skb pointer to ongoing_tx_skb pointer

without doing any NULL check. At this time, if the waiting_tx_skb pointer

is NULL then ongoing_tx_skb pointer is also assigned with NULL. After

that, if a new tx skb is assigned to waiting_tx_skb pointer by the n/w

stack and there is a chance to overwrite the tx skb pointer with NULL in

the SPI thread. Finally one of the tx skb will be left as unhandled,

resulting packet missing and memory leak.

- Consider the below scenario where the TXC reported from the previous

transfer is 10 and ongoing_tx_skb holds an tx ethernet frame which can be

transported in 20 TXCs and waiting_tx_skb is still NULL.

tx_credits = 10; /* 21 are filled in the previous transfer */

ongoing_tx_skb = 20;

waiting_tx_skb = NULL; /* Still NULL */

- So, (tc6->ongoing_tx_skb || tc6->waiting_tx_skb) becomes true.

- After oa_tc6_prepare_spi_tx_buf_for_tx_skbs()

ongoing_tx_skb = 10;

waiting_tx_skb = NULL; /* Still NULL */

- Perform SPI transfer.

- Process SPI rx buffer to get the TXC from footers.

- Now let's assume previously filled 21 TXCs are freed so we are good to

transport the next remaining 10 tx chunks from ongoing_tx_skb.

tx_credits = 21;

ongoing_tx_skb = 10;

waiting_tx_skb = NULL;

- So, (tc6->ongoing_tx_skb || tc6->waiting_tx_skb) becomes true again.

- In the oa_tc6_prepare_spi_tx_buf_for_tx_skbs()

ongoing_tx_skb = NULL;

waiting_tx_skb = NULL;

- Now the below bad case might happen,

Thread1 (oa_tc6_start_xmit) Thread2 (oa_tc6_spi_thread_handler)

--------------------------- -----------------------------------

- if waiting_tx_skb is NULL

- if ongoing_tx_skb is NULL

- ongoing_tx_skb = waiting_tx_skb

- waiting_tx_skb = skb

- waiting_tx_skb = NULL

...

- ongoing_tx_skb = NULL

- if waiting_tx_skb is NULL

- waiting_tx_skb = skb

To overcome the above issue, protect the moving of tx skb reference from

waiting_tx_skb pointer to ongoing_tx_skb pointer and assigning new tx skb

to waiting_tx_skb pointer, so that the other thread can't access the

waiting_tx_skb pointer until the current thread completes moving the tx

skb reference safely.

The record
Technical detail
CVSS v3.1
7.5 · HIGH
Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CVSS v4.0
Not supplied
EPSS
0.00245 · 14.8th percentile
Weakness
CWE-362 · Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Published
2025-01-11T18:15Z
Affected products (4)
ProductVersionsFixed in
linux/linux_kernel≥ 6.12, < 6.12.76.12.7
linux/linux_kernelall versions—
linux/linux_kernelall versions—
linux/linux_kernelall versions—
References (2)
EPSS history
Timeline
  • 11 JAN 12:35Z
    net: ethernet: oa_tc6: fix tx skb race condition between reference pointers
    cvelistv5