CVE-2025-21861
Severity CVSS v4.0:
Pending analysis
Type:
CWE-416
Use After Free
Publication date:
12/03/2025
Last modified:
02/10/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
mm/migrate_device: don&#39;t add folio to be freed to LRU in migrate_device_finalize()<br />
<br />
If migration succeeded, we called<br />
folio_migrate_flags()->mem_cgroup_migrate() to migrate the memcg from the<br />
old to the new folio. This will set memcg_data of the old folio to 0.<br />
<br />
Similarly, if migration failed, memcg_data of the dst folio is left unset.<br />
<br />
If we call folio_putback_lru() on such folios (memcg_data == 0), we will<br />
add the folio to be freed to the LRU, making memcg code unhappy. Running<br />
the hmm selftests:<br />
<br />
# ./hmm-tests<br />
...<br />
# RUN hmm.hmm_device_private.migrate ...<br />
[ 102.078007][T14893] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7ff27d200 pfn:0x13cc00<br />
[ 102.079974][T14893] anon flags: 0x17ff00000020018(uptodate|dirty|swapbacked|node=0|zone=2|lastcpupid=0x7ff)<br />
[ 102.082037][T14893] raw: 017ff00000020018 dead000000000100 dead000000000122 ffff8881353896c9<br />
[ 102.083687][T14893] raw: 00000007ff27d200 0000000000000000 00000001ffffffff 0000000000000000<br />
[ 102.085331][T14893] page dumped because: VM_WARN_ON_ONCE_FOLIO(!memcg && !mem_cgroup_disabled())<br />
[ 102.087230][T14893] ------------[ cut here ]------------<br />
[ 102.088279][T14893] WARNING: CPU: 0 PID: 14893 at ./include/linux/memcontrol.h:726 folio_lruvec_lock_irqsave+0x10e/0x170<br />
[ 102.090478][T14893] Modules linked in:<br />
[ 102.091244][T14893] CPU: 0 UID: 0 PID: 14893 Comm: hmm-tests Not tainted 6.13.0-09623-g6c216bc522fd #151<br />
[ 102.093089][T14893] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014<br />
[ 102.094848][T14893] RIP: 0010:folio_lruvec_lock_irqsave+0x10e/0x170<br />
[ 102.096104][T14893] Code: ...<br />
[ 102.099908][T14893] RSP: 0018:ffffc900236c37b0 EFLAGS: 00010293<br />
[ 102.101152][T14893] RAX: 0000000000000000 RBX: ffffea0004f30000 RCX: ffffffff8183f426<br />
[ 102.102684][T14893] RDX: ffff8881063cb880 RSI: ffffffff81b8117f RDI: ffff8881063cb880<br />
[ 102.104227][T14893] RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000<br />
[ 102.105757][T14893] R10: 0000000000000001 R11: 0000000000000002 R12: ffffc900236c37d8<br />
[ 102.107296][T14893] R13: ffff888277a2bcb0 R14: 000000000000001f R15: 0000000000000000<br />
[ 102.108830][T14893] FS: 00007ff27dbdd740(0000) GS:ffff888277a00000(0000) knlGS:0000000000000000<br />
[ 102.110643][T14893] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
[ 102.111924][T14893] CR2: 00007ff27d400000 CR3: 000000010866e000 CR4: 0000000000750ef0<br />
[ 102.113478][T14893] PKRU: 55555554<br />
[ 102.114172][T14893] Call Trace:<br />
[ 102.114805][T14893] <br />
[ 102.115397][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170<br />
[ 102.116547][T14893] ? __warn.cold+0x110/0x210<br />
[ 102.117461][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170<br />
[ 102.118667][T14893] ? report_bug+0x1b9/0x320<br />
[ 102.119571][T14893] ? handle_bug+0x54/0x90<br />
[ 102.120494][T14893] ? exc_invalid_op+0x17/0x50<br />
[ 102.121433][T14893] ? asm_exc_invalid_op+0x1a/0x20<br />
[ 102.122435][T14893] ? __wake_up_klogd.part.0+0x76/0xd0<br />
[ 102.123506][T14893] ? dump_page+0x4f/0x60<br />
[ 102.124352][T14893] ? folio_lruvec_lock_irqsave+0x10e/0x170<br />
[ 102.125500][T14893] folio_batch_move_lru+0xd4/0x200<br />
[ 102.126577][T14893] ? __pfx_lru_add+0x10/0x10<br />
[ 102.127505][T14893] __folio_batch_add_and_move+0x391/0x720<br />
[ 102.128633][T14893] ? __pfx_lru_add+0x10/0x10<br />
[ 102.129550][T14893] folio_putback_lru+0x16/0x80<br />
[ 102.130564][T14893] migrate_device_finalize+0x9b/0x530<br />
[ 102.131640][T14893] dmirror_migrate_to_device.constprop.0+0x7c5/0xad0<br />
[ 102.133047][T14893] dmirror_fops_unlocked_ioctl+0x89b/0xc80<br />
<br />
Likely, nothing else goes wrong: putting the last folio reference will<br />
remove the folio from the LRU again. So besides memcg complaining, adding<br />
the folio to be freed to the LRU is just an unnecessary step.<br />
<br />
The new flow resembles what we have in migrate_folio_move(): add the dst<br />
to the lru, rem<br />
---truncated---
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
Vulnerable products and versions
| CPE | From | Up to |
|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 4.14 (including) | 6.12.17 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.13 (including) | 6.13.5 (excluding) |
| cpe:2.3:o:linux:linux_kernel:6.14:rc1:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.14:rc2:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.14:rc3:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/069dd21ea8262204f94737878389c2815a054a9e
- https://git.kernel.org/stable/c/20fb6fc51863fbff7868de8b5f6d249d2094df1f
- https://git.kernel.org/stable/c/3f9240d59e9a95d19f06120bfd1d0e681c6c0ac7
- https://git.kernel.org/stable/c/41cddf83d8b00f29fd105e7a0777366edc69a5cf
- https://git.kernel.org/stable/c/4f52f7c50f5b6f5eeb06823e21fe546d90f9c595
- https://git.kernel.org/stable/c/61fa824e304ed162fe965f64999068e6fcff2059
- https://git.kernel.org/stable/c/64397b0cb7c09e3ef3f9f5c7c17299c4eebd3875
- https://git.kernel.org/stable/c/78f579cb7d825134e071a1714d8d0c4fd0ffe459



