In the Linux kernel, the following vulnerability has been resolved:
fs/proc: task_mmu.c: don't read mapcount for migration entry
The syzbot reported the below BUG:
kernel BUG at include/linux/page-flags.h:785! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 4392 Comm: syz-executor560 Not tainted 5.16.0-rc6-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:PageDoubleMap include/linux/page-flags.h:785 [inline] RIP: 0010:_pagemapcount+0x2d2/0x350 mm/util.c:744 Call Trace: pagemapcount include/linux/mm.h:837 [inline] smapsaccount+0x470/0xb10 fs/proc/taskmmu.c:466 smapspteentry fs/proc/taskmmu.c:538 [inline] smapspterange+0x611/0x1250 fs/proc/taskmmu.c:601 walkpmdrange mm/pagewalk.c:128 [inline] walkpudrange mm/pagewalk.c:205 [inline] walkp4drange mm/pagewalk.c:240 [inline] walkpgdrange mm/pagewalk.c:277 [inline] _walkpagerange+0xe23/0x1ea0 mm/pagewalk.c:379 walkpagevma+0x277/0x350 mm/pagewalk.c:530 smapgatherstats.part.0+0x148/0x260 fs/proc/taskmmu.c:768 smapgatherstats fs/proc/taskmmu.c:741 [inline] showsmap+0xc6/0x440 fs/proc/taskmmu.c:822 seqreaditer+0xbb0/0x1240 fs/seqfile.c:272 seqread+0x3e0/0x5b0 fs/seqfile.c:162 vfsread+0x1b5/0x600 fs/readwrite.c:479 ksysread+0x12d/0x250 fs/readwrite.c:619 dosyscallx64 arch/x86/entry/common.c:50 [inline] dosyscall64+0x35/0xb0 arch/x86/entry/common.c:80 entrySYSCALL64after_hwframe+0x44/0xae
The reproducer was trying to read /proc/$PID/smaps when calling MADVFREE at the mean time. MADVFREE may split THPs if it is called for partial THP. It may trigger the below race:
CPU A CPU B
----- -----
smaps walk: MADVFREE: pagemapcount() PageCompound() splithugepage() page = compound_head(page) PageDoubleMap(page)
When calling PageDoubleMap() this page is not a tail page of THP anymore so the BUG is triggered.
This could be fixed by elevated refcount of the page before calling mapcount, but that would prevent it from counting migration entries, and it seems overkilling because the race just could happen when PMD is split so all PTE entries of tail pages are actually migration entries, and smaps_account() does treat migration entries as mapcount == 1 as Kirill pointed out.
Add a new parameter for smapsaccount() to tell this entry is migration entry then skip calling pagemapcount(). Don't skip getting mapcount for device private entries since they do track references with mapcount.
Pagemap also has the similar issue although it was not reported. Fixed it as well.
[shy828301@gmail.com: v4] [nathan@kernel.org: avoid unused variable warning in pagemappmdrange()]
{ "vanir_signatures": [ { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 770.0, "function_hash": "62427042284755426042725394383711569468" }, "id": "CVE-2022-48802-03b9b87d", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pmd_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1052.0, "function_hash": "316162174337176749685726469197229421941" }, "id": "CVE-2022-48802-0bf83501", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pte_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1878.0, "function_hash": "333243760891370598381416715558981215767" }, "id": "CVE-2022-48802-0fa62fe2", "target": { "file": "fs/proc/task_mmu.c", "function": "pagemap_pmd_range" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 844.0, "function_hash": "272592022158839664611973651023729222366" }, "id": "CVE-2022-48802-2cfeeca4", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pte_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 820.0, "function_hash": "288751946382798520233095005367779876383" }, "id": "CVE-2022-48802-2d8abd03", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_account" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1106.0, "function_hash": "224224072060897757042428484215891395360" }, "id": "CVE-2022-48802-2e59ff80", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pte_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 922.0, "function_hash": "88295611806332854336671038735255127159" }, "id": "CVE-2022-48802-33a177f1", "target": { "file": "fs/proc/task_mmu.c", "function": "pte_to_pagemap_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Line", "digest": { "line_hashes": [ "65444879951885382086952889093890898913", "282784328110842977796198122876765874201", "299583513358648395686008129615009052933", "325086340720705983699649684872515797563", "219865561945611532150138112687402649088", "126000321309443345267808034081353659917", "336821557424098579500542193961328988070", "18509273195148022185093835630297621968", "73735212753739208731559857431466319080", "266333670304261764518832707544718514106", "252808654856284833785090154169194593950", "166228293557834944372790480309626286513", "18837629337346759390200563592292871546", "82835729093376021647630681054125774594", "263377573955386910555788206265837005081", "101942214975643348039175904042764419290", "150277727847130655017828901662551728763", "95569357170831969992523206484425509143", "135186660037997760689772355153231866206", "156865944696522295630086780632932597079", "66282481534367975436155598331687696022", "282579355721825557049570035168876989420", "73735212753739208731559857431466319080", "242207096518405667496761093739109753348", "281261494574482244946558084785852635289", "194880234008304810629304332727844509447", "266973074800615803031485045998503276826", "186340213248617810376104108605263009319", "315516661202967422328498853650282486024", "78112067665964730657212687151217755164", "45358705822730142058104196835458970051", "184822513959317497790620227105996134093", "312198640495119479165707893255785663537", "250849014162742520595012713682270698533", "265472525604177284959421637086601207836", "88860819120499770913535196527266182168", "100394747920448770286459741303936527554", "206575831333422001754680081528291609031", "136764547451062384260893048703079425324", "253410217073476573902520640688447447439", "138453235100387472700265885493024455712", "193508710514878674264409853550533841709", "125448939535218123555161971388389727843", "104877805207461521769900965185532120147", "82067055634541001569875849635378410334", "33014430284913339829292846976201440366", "258239592503280809976901986356857901854", "264147586950274830846562385208807359550", "90503881347179359050135205407441679010", "184473535766760603037540590318558475697", "176203052869844382362108050478673290452", "12795231337329694547912849216316310794", "106638707310557439600224940758125305927", "84757007975258831440867385753598977974", "65760763026753045564243599192393799793", "259002145755753485071499144352940088731", "304029960073255742228570446226090275736", "16765472576379768684804373145249727243", "292017597660822615123011535310131801657", "313961899435000576822994605914287374870" ], "threshold": 0.9 }, "id": "CVE-2022-48802-4d69ed49", "target": { "file": "fs/proc/task_mmu.c" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 820.0, "function_hash": "288751946382798520233095005367779876383" }, "id": "CVE-2022-48802-5d644f53", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_account" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1878.0, "function_hash": "333243760891370598381416715558981215767" }, "id": "CVE-2022-48802-63341ba8", "target": { "file": "fs/proc/task_mmu.c", "function": "pagemap_pmd_range" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Line", "digest": { "line_hashes": [ "65444879951885382086952889093890898913", "282784328110842977796198122876765874201", "299583513358648395686008129615009052933", "325086340720705983699649684872515797563", "219865561945611532150138112687402649088", "126000321309443345267808034081353659917", "336821557424098579500542193961328988070", "18509273195148022185093835630297621968", "73735212753739208731559857431466319080", "266333670304261764518832707544718514106", "252808654856284833785090154169194593950", "166228293557834944372790480309626286513", "89482880901447068680625165334439079963", "294781199575534931924806324596301382786", "50197721460550999930790966190184601501", "175149798130477836265668290337254487953", "134029049299469627703434267840166119380", "135186660037997760689772355153231866206", "156865944696522295630086780632932597079", "66282481534367975436155598331687696022", "282579355721825557049570035168876989420", "73735212753739208731559857431466319080", "242207096518405667496761093739109753348", "281261494574482244946558084785852635289", "194880234008304810629304332727844509447", "266973074800615803031485045998503276826", "52047227798790247636778567025837637670", "323384049926061369943680906593547934050", "116188121922695649175168252854996848721", "230704082084535111381117073746360440879", "184822513959317497790620227105996134093", "312198640495119479165707893255785663537", "250849014162742520595012713682270698533", "265472525604177284959421637086601207836", "88860819120499770913535196527266182168", "100394747920448770286459741303936527554", "206575831333422001754680081528291609031", "136764547451062384260893048703079425324", "209645020059981029115984566367068850058", "204243306463233500209873001757978571265", "338360021378141001055917281044845523284", "325257559402220687225942321884288285100", "81511666318832079668065212777633547067", "281603448525828385243487384025038998848", "82067055634541001569875849635378410334", "33014430284913339829292846976201440366", "258239592503280809976901986356857901854", "264147586950274830846562385208807359550", "90503881347179359050135205407441679010", "184473535766760603037540590318558475697", "176203052869844382362108050478673290452", "12795231337329694547912849216316310794", "208180434689823505380100906771948293903", "283780200195924326128768012418869594237", "184941926129116856019397720988361732782", "71971191442103224792309439538685970115", "39393805862863005544170975608668993054", "16765472576379768684804373145249727243", "292017597660822615123011535310131801657", "313961899435000576822994605914287374870" ], "threshold": 0.9 }, "id": "CVE-2022-48802-6687cb6b", "target": { "file": "fs/proc/task_mmu.c" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 879.0, "function_hash": "135756879088985054759961056606299339789" }, "id": "CVE-2022-48802-66fede4f", "target": { "file": "fs/proc/task_mmu.c", "function": "pte_to_pagemap_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 770.0, "function_hash": "62427042284755426042725394383711569468" }, "id": "CVE-2022-48802-6e62690c", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pmd_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1878.0, "function_hash": "333243760891370598381416715558981215767" }, "id": "CVE-2022-48802-74da800e", "target": { "file": "fs/proc/task_mmu.c", "function": "pagemap_pmd_range" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 1790.0, "function_hash": "317751070325062619544151886450334829089" }, "id": "CVE-2022-48802-8bcee93e", "target": { "file": "fs/proc/task_mmu.c", "function": "pagemap_pmd_range" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 770.0, "function_hash": "62427042284755426042725394383711569468" }, "id": "CVE-2022-48802-9138487a", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pmd_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Line", "digest": { "line_hashes": [ "65444879951885382086952889093890898913", "282784328110842977796198122876765874201", "299583513358648395686008129615009052933", "325086340720705983699649684872515797563", "219865561945611532150138112687402649088", "126000321309443345267808034081353659917", "336821557424098579500542193961328988070", "18509273195148022185093835630297621968", "73735212753739208731559857431466319080", "266333670304261764518832707544718514106", "252808654856284833785090154169194593950", "166228293557834944372790480309626286513", "89482880901447068680625165334439079963", "294781199575534931924806324596301382786", "260670541398429021373520640824974068718", "22525088291611493849619259220248744093", "241628515796164696740586663482116487132", "135186660037997760689772355153231866206", "156865944696522295630086780632932597079", "66282481534367975436155598331687696022", "282579355721825557049570035168876989420", "73735212753739208731559857431466319080", "242207096518405667496761093739109753348", "281261494574482244946558084785852635289", "194880234008304810629304332727844509447", "266973074800615803031485045998503276826", "52047227798790247636778567025837637670", "323384049926061369943680906593547934050", "116188121922695649175168252854996848721", "230704082084535111381117073746360440879", "184822513959317497790620227105996134093", "312198640495119479165707893255785663537", "250849014162742520595012713682270698533", "265472525604177284959421637086601207836", "88860819120499770913535196527266182168", "100394747920448770286459741303936527554", "206575831333422001754680081528291609031", "136764547451062384260893048703079425324", "209645020059981029115984566367068850058", "204243306463233500209873001757978571265", "338360021378141001055917281044845523284", "325257559402220687225942321884288285100", "81511666318832079668065212777633547067", "281603448525828385243487384025038998848", "82067055634541001569875849635378410334", "33014430284913339829292846976201440366", "258239592503280809976901986356857901854", "264147586950274830846562385208807359550", "90503881347179359050135205407441679010", "184473535766760603037540590318558475697", "176203052869844382362108050478673290452", "12795231337329694547912849216316310794", "208180434689823505380100906771948293903", "283780200195924326128768012418869594237", "184941926129116856019397720988361732782", "71971191442103224792309439538685970115", "39393805862863005544170975608668993054", "16765472576379768684804373145249727243", "292017597660822615123011535310131801657", "313961899435000576822994605914287374870" ], "threshold": 0.9 }, "id": "CVE-2022-48802-a00ce35e", "target": { "file": "fs/proc/task_mmu.c" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@a8dd0cfa37792863b6c4bf9542975212a6715d49" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 770.0, "function_hash": "62427042284755426042725394383711569468" }, "id": "CVE-2022-48802-bb5bd74e", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pmd_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 922.0, "function_hash": "88295611806332854336671038735255127159" }, "id": "CVE-2022-48802-bb7fd75c", "target": { "file": "fs/proc/task_mmu.c", "function": "pte_to_pagemap_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 844.0, "function_hash": "272592022158839664611973651023729222366" }, "id": "CVE-2022-48802-c7361981", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_pte_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 820.0, "function_hash": "288751946382798520233095005367779876383" }, "id": "CVE-2022-48802-ca5de538", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_account" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@db3f3636e4aed2cba3e4e7897a053323f7a62249" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 922.0, "function_hash": "88295611806332854336671038735255127159" }, "id": "CVE-2022-48802-caf8b5ba", "target": { "file": "fs/proc/task_mmu.c", "function": "pte_to_pagemap_entry" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@05d3f8045efa59457b323caf00bdb9273b7962fa" }, { "signature_version": "v1", "signature_type": "Function", "digest": { "length": 820.0, "function_hash": "288751946382798520233095005367779876383" }, "id": "CVE-2022-48802-d5ce585e", "target": { "file": "fs/proc/task_mmu.c", "function": "smaps_account" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" }, { "signature_version": "v1", "signature_type": "Line", "digest": { "line_hashes": [ "65444879951885382086952889093890898913", "282784328110842977796198122876765874201", "299583513358648395686008129615009052933", "325086340720705983699649684872515797563", "219865561945611532150138112687402649088", "126000321309443345267808034081353659917", "336821557424098579500542193961328988070", "18509273195148022185093835630297621968", "73735212753739208731559857431466319080", "266333670304261764518832707544718514106", "252808654856284833785090154169194593950", "166228293557834944372790480309626286513", "89482880901447068680625165334439079963", "294781199575534931924806324596301382786", "50197721460550999930790966190184601501", "175149798130477836265668290337254487953", "134029049299469627703434267840166119380", "135186660037997760689772355153231866206", "156865944696522295630086780632932597079", "66282481534367975436155598331687696022", "282579355721825557049570035168876989420", "73735212753739208731559857431466319080", "242207096518405667496761093739109753348", "281261494574482244946558084785852635289", "194880234008304810629304332727844509447", "266973074800615803031485045998503276826", "52047227798790247636778567025837637670", "323384049926061369943680906593547934050", "116188121922695649175168252854996848721", "230704082084535111381117073746360440879", "184822513959317497790620227105996134093", "312198640495119479165707893255785663537", "250849014162742520595012713682270698533", "265472525604177284959421637086601207836", "88860819120499770913535196527266182168", "100394747920448770286459741303936527554", "206575831333422001754680081528291609031", "136764547451062384260893048703079425324", "209645020059981029115984566367068850058", "204243306463233500209873001757978571265", "338360021378141001055917281044845523284", "325257559402220687225942321884288285100", "81511666318832079668065212777633547067", "281603448525828385243487384025038998848", "82067055634541001569875849635378410334", "33014430284913339829292846976201440366", "258239592503280809976901986356857901854", "264147586950274830846562385208807359550", "90503881347179359050135205407441679010", "184473535766760603037540590318558475697", "176203052869844382362108050478673290452", "12795231337329694547912849216316310794", "208180434689823505380100906771948293903", "283780200195924326128768012418869594237", "184941926129116856019397720988361732782", "71971191442103224792309439538685970115", "39393805862863005544170975608668993054", "16765472576379768684804373145249727243", "292017597660822615123011535310131801657", "313961899435000576822994605914287374870" ], "threshold": 0.9 }, "id": "CVE-2022-48802-f8be9ec2", "target": { "file": "fs/proc/task_mmu.c" }, "deprecated": false, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@24d7275ce2791829953ed4e72f68277ceb2571c6" } ] }