data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2024-53079 in the interactive tracker

CVE-2024-53079

mm/thp: fix deferred split unqueue naming and locking

7.8 EPSS 0.2% AV:L

Published 2024-11-19 (23 months ago) by the Linux kernel CNA. Subsystem mm. Debian urgency: not yet assigned.

What to do, per Debian release

Debian's own status for CVE-2024-53079 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormvulnerable6.1.190-1No fix published anywhere yet, neither in Debian nor upstream for the series bookworm tracks. Watch the Debian tracker page for this CVE. Advisories for bookworm have historically landed a median of 23 days after publication.
Debian 13trixiefixed6.11.9-1Update the kernel and reboot. Fixed in 6.11.9-1. A running kernel keeps the old code until the machine restarts.
Debian 14forkyfixed6.11.9-1Update the kernel and reboot. Fixed in 6.11.9-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed6.11.9-1Update the kernel and reboot. Fixed in 6.11.9-1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

Recent changes are putting more pressure on THP deferred split queues: under load revealing long-standing races, causing list_del corruptions, "Bad page state"s and worse (I keep BUGs in both of those, so usually don't get to see how badly they end up without). The relevant recent changes being 6.8's mTHP, 6.10's mTHP swapout, and 6.12's mTHP swapin, improved swap allocation, and underused THP splitting. Before fixing locking: rename misleading folio_undo_large_rmappable(), which does not undo large_rmappable, to folio_unqueue_deferred_split(), which is what it does. But that and its out-of-line __callee are mm internals of very limited usability: add comment and WARN_ON_ONCEs to check usage; and return a bool to say if a deferred split was unqueued, which can then be used in WARN_ON_ONCEs around safety checks (sparing callers the arcane conditionals in __folio_unqueue_deferred_split()). Just omit the folio_unqueue_deferred_split() from free_unref_folios(), all of whose callers now call it beforehand (and if any forget then bad_page() will tell) - except for its caller put_pages_list(), which itself no longer has any callers (and will be deleted separately). Swapout: mem_cgroup_swapout() has been resetting folio->memcg_data 0 without checking and unqueueing a THP folio from deferred split list; which is unfortunate, since the split_queue_lock depends on the memcg (when memcg is enabled); so swapout has been unqueueing such THPs later, when freeing the folio, using the pgdat's lock instead: potentially corrupting the memcg's list. __remove_mapping() has frozen refcount to 0 here, so no problem with calling folio_unqueue_deferred_split() before resetting memcg_data. That goes back to 5.4 commit 87eaceb3faa5 ("mm: thp: make deferred split shrinker memcg aware"): which included a check on swapcache before adding to deferred queue, but no check on deferred queue before adding THP to swapcache. That worked fine with the usual sequence of events in reclaim (though there were a couple of rare ways in which a THP on deferred queue could have been swapped out), but 6.12 commit dafff3f4c850 ("mm: split underused THPs") avoids splitting underused THPs in reclaim, which makes swapcache THPs on deferred queue commonplace. Keep the check on swapcache before adding to deferred queue? Yes: it is no longer essential, but preserves the existing behaviour, and is likely to be a worthwhile optimization (vmstat showed much more traffic on the queue under swapping load if the check was removed); update its comment. Memcg-v1 move (deprecated): mem_cgroup_move_account() has been changing folio->memcg_data without checking and unqueueing a THP folio from the deferred list, sometimes corrupting "from" memcg's list, like swapout. Refcount is non-zero here, so folio_unqueue_deferred_split() can only be used in a WARN_ON_ONCE to validate the fix, which must be done earlier: mem_cgroup_move_charge_pte_range() first try to split the THP (splitting of course unqueues), or skip it if that fails. Not ideal, but moving charge has been requested, and khugepaged should repair the THP later: nobody wants new custom unqueueing code just for this deprecated case. The 87eaceb3faa5 commit did have the code to move from one deferred list to another (but was not conscious of its unsafety while refcount non-0); but that was removed by 5.6 commit fac0516b5534 ("mm: thp: don't need care deferred split queue in memcg charge move path"), which argued that the existence of a PMD mapping guarantees that the THP cannot be on a deferred list. As above, false in rare cases, and now commonly false. Backport to 6.11 should be straightforward. Earlier backports must take care that other _deferred_list fixes and dependencies are included. There is not a strong case for backports, but they can fix cornercases.

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

mm/huge_memory.c
mm/internal.h
mm/memcontrol-v1.c
mm/memcontrol.c
mm/migrate.c
mm/page_alloc.c
mm/swap.c
mm/vmscan.c

What this is
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)MAINTAINERS section matched on mm/huge_memory.c · linux-mm@kvack.org · Maintained

Check it on the machine

grep -w CONFIG_TRANSPARENT_HUGEPAGE /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

Show whether Debian builds this, per release

Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.

  • bookwormYnot built on amd64/rt/amd64, arm64/rt/arm64, armhf/armmp, armhf/rt/armmp, i386/rt/686-pae
  • trixieYnot built on amd64/rt/amd64, arm64/rt/arm64, armel/rpi, armhf/armmp, armhf/rt/armmp
  • forky, sidYnot built on amd64/rt-amd64, arm64/rt-arm64, armhf/armmp
Y
built in where it is built at all; some flavours do not build it
Build switch
CONFIG_TRANSPARENT_HUGEPAGE

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2024-11-19 (23 months ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.18%, higher than 6.9% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
not yet assignedsource
Subsystem
mm

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
5.46.6.62fc4951c3e335
5.46.11.8afb1352d06b1
5.46.12f8f931bba0f9

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
The bug lives in the THP deferred-split/memcg reclaim machinery and is driven entirely by local memory operations (THP allocation, partial unmap via munmap/MADV_DONTNEED, and induced memory pressure/swapout). There is no network-facing input path.
AC:LAttack complexity, low
The attacker controls both sides of the race — one set of threads queues partially-mapped THPs onto the memcg split queue while another forces reclaim/swapout that unqueues them under the wrong (pgdat) lock — and the maintainer reports the corruption firing routinely "under load" on ordinary systems since underused-THP splitting made swapcache THPs on the deferred queue commonplace.
PR:LPrivileges required, low
Any unprivileged local process can queue folios on the deferred split list simply by partially unmapping an anonymous THP, and with CONFIG_MEMCG every folio (even in the root cgroup) is charged to a memcg queue, so no capabilities or cgroup write access are required.
UI:NUser interaction, none
The attacker performs every step himself — allocating THPs, partially unmapping them, and generating the memory pressure that forces swapout; no victim action is involved.
S:UScope, unchanged
The corruption is confined to kernel memory-management structures within the same security authority; there is no VM, IOMMU, or sandbox boundary crossed.
C:HConfidentiality impact, high
The unlocked list_del corrupts struct page fields (_deferred_list overlaps the second tail page's ->mapping) and can leave freed folios reachable on the memcg queue, so deferred_split_scan() operates on pages already reallocated to other processes or the kernel — a use-after-free giving read access to memory outside the attacker's ownership.
I:HIntegrity impact, high
The same racing list_del writes attacker-influenced pointer values into page structures, and the resulting use-after-free lets the shrinker take references on and split folios that now belong to another context, providing the heap-grooming and write primitives typical of exploitable memory corruption.
A:HAvailability impact, high
Observed effects include list_del corruption, bad_page("on deferred list") reports and BUGs, split_queue_len underflow, and a self-referencing list that makes the queue walk loop forever while holding split_queue_lock with interrupts disabled — a hard lockup or panic.