In the Linux kernel, the following vulnerability has been resolved:
mm/migratedevice: don't add folio to be freed to LRU in migratedevice_finalize()
If migration succeeded, we called foliomigrateflags()->memcgroupmigrate() to migrate the memcg from the old to the new folio. This will set memcg_data of the old folio to 0.
Similarly, if migration failed, memcg_data of the dst folio is left unset.
If we call folioputbacklru() on such folios (memcg_data == 0), we will add the folio to be freed to the LRU, making memcg code unhappy. Running the hmm selftests:
# ./hmm-tests ... # RUN hmm.hmmdeviceprivate.migrate ... [ 102.078007][T14893] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7ff27d200 pfn:0x13cc00 [ 102.079974][T14893] anon flags: 0x17ff00000020018(uptodate|dirty|swapbacked|node=0|zone=2|lastcpupid=0x7ff) [ 102.082037][T14893] raw: 017ff00000020018 dead000000000100 dead000000000122 ffff8881353896c9 [ 102.083687][T14893] raw: 00000007ff27d200 0000000000000000 00000001ffffffff 0000000000000000 [ 102.085331][T14893] page dumped because: VMWARNONONCEFOLIO(!memcg && !memcgroupdisabled()) [ 102.087230][T14893] ------------[ cut here ]------------ [ 102.088279][T14893] WARNING: CPU: 0 PID: 14893 at ./include/linux/memcontrol.h:726 foliolruveclockirqsave+0x10e/0x170 [ 102.090478][T14893] Modules linked in: [ 102.091244][T14893] CPU: 0 UID: 0 PID: 14893 Comm: hmm-tests Not tainted 6.13.0-09623-g6c216bc522fd #151 [ 102.093089][T14893] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014 [ 102.094848][T14893] RIP: 0010:foliolruveclockirqsave+0x10e/0x170 [ 102.096104][T14893] Code: ... [ 102.099908][T14893] RSP: 0018:ffffc900236c37b0 EFLAGS: 00010293 [ 102.101152][T14893] RAX: 0000000000000000 RBX: ffffea0004f30000 RCX: ffffffff8183f426 [ 102.102684][T14893] RDX: ffff8881063cb880 RSI: ffffffff81b8117f RDI: ffff8881063cb880 [ 102.104227][T14893] RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000 [ 102.105757][T14893] R10: 0000000000000001 R11: 0000000000000002 R12: ffffc900236c37d8 [ 102.107296][T14893] R13: ffff888277a2bcb0 R14: 000000000000001f R15: 0000000000000000 [ 102.108830][T14893] FS: 00007ff27dbdd740(0000) GS:ffff888277a00000(0000) knlGS:0000000000000000 [ 102.110643][T14893] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 102.111924][T14893] CR2: 00007ff27d400000 CR3: 000000010866e000 CR4: 0000000000750ef0 [ 102.113478][T14893] PKRU: 55555554 [ 102.114172][T14893] Call Trace: [ 102.114805][T14893] <TASK> [ 102.115397][T14893] ? foliolruveclockirqsave+0x10e/0x170 [ 102.116547][T14893] ? _warn.cold+0x110/0x210 [ 102.117461][T14893] ? foliolruveclockirqsave+0x10e/0x170 [ 102.118667][T14893] ? reportbug+0x1b9/0x320 [ 102.119571][T14893] ? handlebug+0x54/0x90 [ 102.120494][T14893] ? excinvalidop+0x17/0x50 [ 102.121433][T14893] ? asmexcinvalidop+0x1a/0x20 [ 102.122435][T14893] ? _wakeupklogd.part.0+0x76/0xd0 [ 102.123506][T14893] ? dumppage+0x4f/0x60 [ 102.124352][T14893] ? foliolruveclockirqsave+0x10e/0x170 [ 102.125500][T14893] foliobatchmovelru+0xd4/0x200 [ 102.126577][T14893] ? _pfxlruadd+0x10/0x10 [ 102.127505][T14893] _foliobatchaddandmove+0x391/0x720 [ 102.128633][T14893] ? _pfxlruadd+0x10/0x10 [ 102.129550][T14893] folioputbacklru+0x16/0x80 [ 102.130564][T14893] migratedevicefinalize+0x9b/0x530 [ 102.131640][T14893] dmirrormigratetodevice.constprop.0+0x7c5/0xad0 [ 102.133047][T14893] dmirrorfopsunlocked_ioctl+0x89b/0xc80
Likely, nothing else goes wrong: putting the last folio reference will remove the folio from the LRU again. So besides memcg complaining, adding the folio to be freed to the LRU is just an unnecessary step.
The new flow resembles what we have in migratefoliomove(): add the dst to the lru, rem ---truncated---
[
    {
        "id": "CVE-2025-21861-1bedaacf",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate_device.c"
        },
        "digest": {
            "line_hashes": [
                "50451431563651054342396805333462659817",
                "45417123760283016389188344900856320873",
                "164526268033590125823897933001894104519",
                "55606194174916190799684255709070083836",
                "166139238708551268942002936961021062504",
                "241399277823257902567588962624992933772",
                "5766907307032254202654924818213143639",
                "63980039093077641409462909043359675052",
                "115187732542730729154413024974557019606",
                "252920848398489606761800208168516151178",
                "297952959881627432995914578524242340259",
                "106994705626039566600925175062977629771",
                "35603007503449834722768948824211480056",
                "162318457171142476312314548060174372815",
                "327141462017825610467511091722980112307"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@069dd21ea8262204f94737878389c2815a054a9e"
    },
    {
        "id": "CVE-2025-21861-4528acd4",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate_device.c",
            "function": "migrate_device_finalize"
        },
        "digest": {
            "function_hash": "110561897819324288977381700448562559288",
            "length": 775.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@78f579cb7d825134e071a1714d8d0c4fd0ffe459"
    },
    {
        "id": "CVE-2025-21861-6990d3e0",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate_device.c",
            "function": "migrate_device_finalize"
        },
        "digest": {
            "function_hash": "110561897819324288977381700448562559288",
            "length": 775.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@20fb6fc51863fbff7868de8b5f6d249d2094df1f"
    },
    {
        "id": "CVE-2025-21861-6ffeff8e",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate_device.c"
        },
        "digest": {
            "line_hashes": [
                "50451431563651054342396805333462659817",
                "45417123760283016389188344900856320873",
                "164526268033590125823897933001894104519",
                "55606194174916190799684255709070083836",
                "166139238708551268942002936961021062504",
                "241399277823257902567588962624992933772",
                "5766907307032254202654924818213143639",
                "63980039093077641409462909043359675052",
                "115187732542730729154413024974557019606",
                "252920848398489606761800208168516151178",
                "297952959881627432995914578524242340259",
                "106994705626039566600925175062977629771",
                "35603007503449834722768948824211480056",
                "162318457171142476312314548060174372815",
                "327141462017825610467511091722980112307"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3f9240d59e9a95d19f06120bfd1d0e681c6c0ac7"
    },
    {
        "id": "CVE-2025-21861-7fb5cc58",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate_device.c"
        },
        "digest": {
            "line_hashes": [
                "50451431563651054342396805333462659817",
                "45417123760283016389188344900856320873",
                "164526268033590125823897933001894104519",
                "55606194174916190799684255709070083836",
                "166139238708551268942002936961021062504",
                "241399277823257902567588962624992933772",
                "5766907307032254202654924818213143639",
                "63980039093077641409462909043359675052",
                "115187732542730729154413024974557019606",
                "252920848398489606761800208168516151178",
                "297952959881627432995914578524242340259",
                "106994705626039566600925175062977629771",
                "35603007503449834722768948824211480056",
                "162318457171142476312314548060174372815",
                "327141462017825610467511091722980112307"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@41cddf83d8b00f29fd105e7a0777366edc69a5cf"
    },
    {
        "id": "CVE-2025-21861-898d0e5c",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate_device.c"
        },
        "digest": {
            "line_hashes": [
                "95081400305623064504442301560561373514",
                "267001854012252705387873490658055535685",
                "90218986845191387028371929772971187932",
                "122952881745370570334815733836059140550",
                "166139238708551268942002936961021062504",
                "241399277823257902567588962624992933772",
                "5766907307032254202654924818213143639",
                "63980039093077641409462909043359675052",
                "115187732542730729154413024974557019606",
                "252920848398489606761800208168516151178",
                "297952959881627432995914578524242340259",
                "106994705626039566600925175062977629771",
                "35603007503449834722768948824211480056",
                "162318457171142476312314548060174372815",
                "327141462017825610467511091722980112307"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@20fb6fc51863fbff7868de8b5f6d249d2094df1f"
    },
    {
        "id": "CVE-2025-21861-a7f7f96f",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate.c",
            "function": "migrate_vma_finalize"
        },
        "digest": {
            "function_hash": "158939861227049062814020147015961050127",
            "length": 682.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@4f52f7c50f5b6f5eeb06823e21fe546d90f9c595"
    },
    {
        "id": "CVE-2025-21861-a85dce0e",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate.c"
        },
        "digest": {
            "line_hashes": [
                "162605109764143541471798083658704240258",
                "311407412323837557115359578135293996649",
                "318138337085754220010083099793881531318",
                "131587959791526802822365849364710727940",
                "338167486480027834641309862698243076790",
                "191981573389963997962602865622396739139",
                "139455266649186474520298324714471874804",
                "234301332670341386891503796277104953790",
                "131088642640299758920996605463889388265",
                "284871613412000740509388477149172192051",
                "77902254137998325910646365415983847845",
                "303824399024687240319853680271493722525",
                "160224447413036110096666689746026604385",
                "205463623827653703154318676842800212416",
                "271698165766033687045206743495976829972"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@64397b0cb7c09e3ef3f9f5c7c17299c4eebd3875"
    },
    {
        "id": "CVE-2025-21861-b1a737bc",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate_device.c",
            "function": "migrate_device_finalize"
        },
        "digest": {
            "function_hash": "316480964250252203969599179909792456112",
            "length": 771.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@3f9240d59e9a95d19f06120bfd1d0e681c6c0ac7"
    },
    {
        "id": "CVE-2025-21861-b625e430",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate_device.c",
            "function": "migrate_device_finalize"
        },
        "digest": {
            "function_hash": "316480964250252203969599179909792456112",
            "length": 771.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@41cddf83d8b00f29fd105e7a0777366edc69a5cf"
    },
    {
        "id": "CVE-2025-21861-cf555cb3",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate.c"
        },
        "digest": {
            "line_hashes": [
                "162605109764143541471798083658704240258",
                "311407412323837557115359578135293996649",
                "136400979658196492544334420867269170238",
                "176846488489844844577336205620900602011",
                "288836299725925214016833131301833953939",
                "49350670150289252265849754054918870877",
                "191981573389963997962602865622396739139",
                "139455266649186474520298324714471874804",
                "234301332670341386891503796277104953790",
                "131088642640299758920996605463889388265",
                "284871613412000740509388477149172192051",
                "77902254137998325910646365415983847845",
                "303824399024687240319853680271493722525",
                "160224447413036110096666689746026604385",
                "205463623827653703154318676842800212416",
                "271698165766033687045206743495976829972"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@61fa824e304ed162fe965f64999068e6fcff2059"
    },
    {
        "id": "CVE-2025-21861-dbfa42cd",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate.c"
        },
        "digest": {
            "line_hashes": [
                "162605109764143541471798083658704240258",
                "311407412323837557115359578135293996649",
                "318138337085754220010083099793881531318",
                "131587959791526802822365849364710727940",
                "338167486480027834641309862698243076790",
                "191981573389963997962602865622396739139",
                "139455266649186474520298324714471874804",
                "234301332670341386891503796277104953790",
                "131088642640299758920996605463889388265",
                "284871613412000740509388477149172192051",
                "77902254137998325910646365415983847845",
                "303824399024687240319853680271493722525",
                "160224447413036110096666689746026604385",
                "205463623827653703154318676842800212416",
                "271698165766033687045206743495976829972"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@4f52f7c50f5b6f5eeb06823e21fe546d90f9c595"
    },
    {
        "id": "CVE-2025-21861-e2f130c1",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Line",
        "target": {
            "file": "mm/migrate_device.c"
        },
        "digest": {
            "line_hashes": [
                "95081400305623064504442301560561373514",
                "267001854012252705387873490658055535685",
                "90218986845191387028371929772971187932",
                "122952881745370570334815733836059140550",
                "166139238708551268942002936961021062504",
                "241399277823257902567588962624992933772",
                "5766907307032254202654924818213143639",
                "63980039093077641409462909043359675052",
                "115187732542730729154413024974557019606",
                "252920848398489606761800208168516151178",
                "297952959881627432995914578524242340259",
                "106994705626039566600925175062977629771",
                "35603007503449834722768948824211480056",
                "162318457171142476312314548060174372815",
                "327141462017825610467511091722980112307"
            ],
            "threshold": 0.9
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@78f579cb7d825134e071a1714d8d0c4fd0ffe459"
    },
    {
        "id": "CVE-2025-21861-e966ee34",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate.c",
            "function": "migrate_vma_finalize"
        },
        "digest": {
            "function_hash": "158939861227049062814020147015961050127",
            "length": 682.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@64397b0cb7c09e3ef3f9f5c7c17299c4eebd3875"
    },
    {
        "id": "CVE-2025-21861-ed7c02aa",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate_device.c",
            "function": "migrate_device_finalize"
        },
        "digest": {
            "function_hash": "316480964250252203969599179909792456112",
            "length": 771.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@069dd21ea8262204f94737878389c2815a054a9e"
    },
    {
        "id": "CVE-2025-21861-f4289608",
        "deprecated": false,
        "signature_version": "v1",
        "signature_type": "Function",
        "target": {
            "file": "mm/migrate.c",
            "function": "migrate_vma_finalize"
        },
        "digest": {
            "function_hash": "140394309719238548451910901422664540027",
            "length": 703.0
        },
        "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@61fa824e304ed162fe965f64999068e6fcff2059"
    }
]