CVE-2024-40979CWE-401CWE-763

CVE-2024-40979

High · published July 12, 2024

CVSS v3.1
7.8
EPSS
0%
Percentile
21.8
In the wild
Unconfirmed
What it is

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

wifi: ath12k: fix kernel crash during resume

Currently during resume, QMI target memory is not properly handled, resulting

in kernel crash in case DMA remap is not supported:

BUG: Bad page state in process kworker/u16:54 pfn:36e80

page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80

page dumped because: nonzero _refcount

Call Trace:

bad_page

free_page_is_bad_report

__free_pages_ok

__free_pages

dma_direct_free

dma_free_attrs

ath12k_qmi_free_target_mem_chunk

ath12k_qmi_msg_mem_request_cb

The reason is:

Once ath12k module is loaded, firmware sends memory request to host. In case

DMA remap not supported, ath12k refuses the first request due to failure in

allocating with large segment size:

ath12k_pci 0000:04:00.0: qmi firmware request memory request

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 7077888

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 8454144

ath12k_pci 0000:04:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size

ath12k_pci 0000:04:00.0: qmi delays mem_request 2

ath12k_pci 0000:04:00.0: qmi firmware request memory request

Later firmware comes back with more but small segments and allocation

succeeds:

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 262144

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288

ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 65536

ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288

Now ath12k is working. If suspend is triggered, firmware will be reloaded

during resume. As same as before, firmware requests two large segments at

first. In ath12k_qmi_msg_mem_request_cb() segment count and size are

assigned:

ab->qmi.mem_seg_count == 2

ab->qmi.target_mem[0].size == 7077888

ab->qmi.target_mem[1].size == 8454144

Then allocation failed like before and ath12k_qmi_free_target_mem_chunk()

is called to free all allocated segments. Note the first segment is skipped

because its v.addr is cleared due to allocation failure:

chunk->v.addr = dma_alloc_coherent()

Also note that this leaks that segment because it has not been freed.

While freeing the second segment, a size of 8454144 is passed to

dma_free_coherent(). However remember that this segment is allocated at

the first time firmware is loaded, before suspend. So its real size is

524288, much smaller than 8454144. As a result kernel found we are freeing

some memory which is in use and thus cras

---truncated---

The record
Technical detail
CVSS v3.1
7.8 · HIGH
Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0
Not supplied
EPSS
0.00302 · 21.8th percentile
Weaknesses
CWE-401 · Missing Release of Memory after Effective Lifetime; CWE-763 · Release of Invalid Pointer or Reference
Published
2024-07-12T17:15Z
Affected products (1)
ProductVersionsFixed in
linux/linux_kernel≥ 6.3, < 6.9.76.9.7
References (5)
EPSS history
Timeline
  • 12 JUL 12:32Z
    wifi: ath12k: fix kernel crash during resume
    cvelistv5