In the Linux kernel, the following vulnerability has been resolved:
btrfs: fix deadlock with fiemap and extent locking
While working on the patchset to remove extent locking I got a lockdep splat with fiemap and pagefaulting with my new extent lock replacement lock.
This deadlock exists with our normal code, we just don't have lockdep annotations with the extent locking so we've never noticed it.
Since we're copying the fiemap extent to user space on every iteration we have the chance of pagefaulting. Because we hold the extent lock for the entire range we could mkwrite into a range in the file that we have mmap'ed. This would deadlock with the following stack trace
[<0>] lockextent+0x28d/0x2f0 [<0>] btrfspagemkwrite+0x273/0x8a0 [<0>] dopagemkwrite+0x50/0xb0 [<0>] dofault+0xc1/0x7b0 [<0>] _handlemmfault+0x2fa/0x460 [<0>] handlemmfault+0xa4/0x330 [<0>] douseraddrfault+0x1f4/0x800 [<0>] excpagefault+0x7c/0x1e0 [<0>] asmexcpagefault+0x26/0x30 [<0>] repmovsalternative+0x33/0x70 [<0>] _copytouser+0x49/0x70 [<0>] fiemapfillnextextent+0xc8/0x120 [<0>] emitfiemapextent+0x4d/0xa0 [<0>] extentfiemap+0x7f8/0xad0 [<0>] btrfsfiemap+0x49/0x80 [<0>] _x64sysioctl+0x3e1/0xb50 [<0>] dosyscall64+0x94/0x1a0 [<0>] entrySYSCALL64after_hwframe+0x6e/0x76
I wrote an fstest to reproduce this deadlock without my replacement lock and verified that the deadlock exists with our existing locking.
To fix this simply don't take the extent lock for the entire duration of the fiemap. This is safe in general because we keep track of where we are when we're searching the tree, so if an ordered extent updates in the middle of our fiemap call we'll still emit the correct extents because we know what offset we were on before.
The only place we maintain the lock is searching delalloc. Since the delalloc stuff can change during writeback we want to lock the extent range so we have a consistent view of delalloc at the time we're checking to see if we need to set the delalloc flag.
With this patch applied we no longer deadlock with my testcase.
{ "vanir_signatures": [ { "signature_version": "v1", "target": { "function": "fiemap_process_hole", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@89bca7fe6382d61e88c67a0b0e7bce315986fb8b", "deprecated": false, "digest": { "length": 1605.0, "function_hash": "13456519971076773626880548209013156782" }, "id": "CVE-2024-35784-4c8d3c22" }, { "signature_version": "v1", "target": { "function": "fiemap_process_hole", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@ded566b4637f1b6b4c9ba74e7d0b8493e93f19cf", "deprecated": false, "digest": { "length": 1605.0, "function_hash": "13456519971076773626880548209013156782" }, "id": "CVE-2024-35784-5675f09d" }, { "signature_version": "v1", "target": { "file": "fs/btrfs/extent_io.c" }, "signature_type": "Line", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@ded566b4637f1b6b4c9ba74e7d0b8493e93f19cf", "deprecated": false, "digest": { "line_hashes": [ "146792862488252680835610567239249907663", "33797247576468341629789235444313135779", "291147640871542169756898728513409939566", "45508331146939523503015418260374178680", "226432510845592878467832734690532532656", "325527186985141489082322475089932203087", "155054955505449670005589626632563523451", "139384323298777156085656414872333930722", "11806383483542041679909246954382705188", "71419502785103307588297845811782383840", "250722455649262744337376544844313267330", "143745438007153368015143751308760369715", "179066994469569548448458258005235392334", "294076598759250832337018569375229167106", "217502098578490565938755398426078858054", "66489695774215632052769320686307848395", "146973977401085102485873756711499184937", "143317999797627153493941730151209350072", "275737793797802809884010822838008160856", "184731682844664436921604289729264712107", "95093201916024820806101891962049391694", "230120153805798590161648498777152241489", "182274794638895821229280654055490158248", "277744677368292359333570209790663630459", "190479365873981817156911989616720917699", "266657679246512794473565203573922869629", "98397288784173239248822931946373404066", "270605371202678201730675731748032444881", "159879006897460348194209439997234876419", "6612827124253772747955503695814724260", "175004440347943332275097146659998887641", "302571972079056355139229105418931707141", "241304398620543880449238858454725049023", "2791158605269883674356885694000394251", "68652443277058464250489036324074474602", "96010720737726370080353327771271807388", "196121874020048341413760470867744056612", "159919729393765735245206548859215425181", "323871090979754544630536996762701965366", "334673057638755419998034496654689394714", "16201337704714875727882711686653623518", "261233643218254830983214695567852728683", "38486494414674153128366606233876329817", "790947437694412215004471927548735734", "291609365384175757096480396450781885713", "54740206976234492667256227181330564213", "37798115861433900129291068606103817184", "84016450268507608838899988751189877724", "321393531952956209215131299766623832196", "2626605045853012135859483677558781042", "190786181767328007386907554201306856003", "116230597048650035450677671515401614208", "3039400901989881821478668038727959532", "135480008663860552977886220377934024543", "246443721714649926564700292475948611660", "320131640025250551987879797268384311934", "317476046494578369515166533044033703315", "173112287774158319865980541943505447442", "238248591405742349396422591829562860616", "169940336775911079049955764327578316761", "136695287564232285825115361466665604694", "202460258029327615405982689574778773534", "217930785174202894188171125304746396899", "157588669055197448040416248337899194819", "240872630025076375904400201909830512720", "186553449458648620146415587285665361213", "155589391564419960725720942839696077576", "318265520148491969502646848963471480429", "264810713777918197459239095038964636927", "267285539899129011382354591000780425940", "117735646457640524860698445756795383322", "286991295249004576357556326636146131263", "3681831003910004508906572682694310682", "205742696701710572589298260815303053706", "199460167557207036614312017509237903877", "68690249838141248364548890907087821477", "135152286490362895872935743265880820810", "141292100446853698110676177180883484255", "177333965337638884709685395622460119446", "141030460637988554161710635757477585072", "141211811701230245259060801420985295503", "207060147483863685899790198973995492973", "109713666578716208413043344003402394444", "99753015118443794361276205946906068169" ], "threshold": 0.9 }, "id": "CVE-2024-35784-75cfa321" }, { "signature_version": "v1", "target": { "function": "fiemap_process_hole", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b0ad381fa7690244802aed119b478b4bdafc31dd", "deprecated": false, "digest": { "length": 1605.0, "function_hash": "13456519971076773626880548209013156782" }, "id": "CVE-2024-35784-766bd6b9" }, { "signature_version": "v1", "target": { "function": "extent_fiemap", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b0ad381fa7690244802aed119b478b4bdafc31dd", "deprecated": false, "digest": { "length": 3745.0, "function_hash": "119085328900539336230136411070438857293" }, "id": "CVE-2024-35784-7c5c441c" }, { "signature_version": "v1", "target": { "file": "fs/btrfs/extent_io.c" }, "signature_type": "Line", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@b0ad381fa7690244802aed119b478b4bdafc31dd", "deprecated": false, "digest": { "line_hashes": [ "146792862488252680835610567239249907663", "33797247576468341629789235444313135779", "291147640871542169756898728513409939566", "45508331146939523503015418260374178680", "226432510845592878467832734690532532656", "325527186985141489082322475089932203087", "155054955505449670005589626632563523451", "139384323298777156085656414872333930722", "11806383483542041679909246954382705188", "71419502785103307588297845811782383840", "250722455649262744337376544844313267330", "143745438007153368015143751308760369715", "179066994469569548448458258005235392334", "294076598759250832337018569375229167106", "217502098578490565938755398426078858054", "66489695774215632052769320686307848395", "146973977401085102485873756711499184937", "143317999797627153493941730151209350072", "275737793797802809884010822838008160856", "184731682844664436921604289729264712107", "95093201916024820806101891962049391694", "230120153805798590161648498777152241489", "182274794638895821229280654055490158248", "277744677368292359333570209790663630459", "190479365873981817156911989616720917699", "266657679246512794473565203573922869629", "98397288784173239248822931946373404066", "270605371202678201730675731748032444881", "159879006897460348194209439997234876419", "6612827124253772747955503695814724260", "175004440347943332275097146659998887641", "302571972079056355139229105418931707141", "241304398620543880449238858454725049023", "2791158605269883674356885694000394251", "68652443277058464250489036324074474602", "96010720737726370080353327771271807388", "196121874020048341413760470867744056612", "159919729393765735245206548859215425181", "323871090979754544630536996762701965366", "334673057638755419998034496654689394714", "16201337704714875727882711686653623518", "261233643218254830983214695567852728683", "38486494414674153128366606233876329817", "790947437694412215004471927548735734", "291609365384175757096480396450781885713", "54740206976234492667256227181330564213", "37798115861433900129291068606103817184", "84016450268507608838899988751189877724", "321393531952956209215131299766623832196", "2626605045853012135859483677558781042", "190786181767328007386907554201306856003", "116230597048650035450677671515401614208", "3039400901989881821478668038727959532", "135480008663860552977886220377934024543", "246443721714649926564700292475948611660", "320131640025250551987879797268384311934", "317476046494578369515166533044033703315", "173112287774158319865980541943505447442", "238248591405742349396422591829562860616", "169940336775911079049955764327578316761", "136695287564232285825115361466665604694", "202460258029327615405982689574778773534", "217930785174202894188171125304746396899", "157588669055197448040416248337899194819", "240872630025076375904400201909830512720", "186553449458648620146415587285665361213", "155589391564419960725720942839696077576", "318265520148491969502646848963471480429", "264810713777918197459239095038964636927", "267285539899129011382354591000780425940", "117735646457640524860698445756795383322", "286991295249004576357556326636146131263", "3681831003910004508906572682694310682", "205742696701710572589298260815303053706", "199460167557207036614312017509237903877", "68690249838141248364548890907087821477", "135152286490362895872935743265880820810", "141292100446853698110676177180883484255", "177333965337638884709685395622460119446", "141030460637988554161710635757477585072", "141211811701230245259060801420985295503", "207060147483863685899790198973995492973", "109713666578716208413043344003402394444", "99753015118443794361276205946906068169" ], "threshold": 0.9 }, "id": "CVE-2024-35784-85e27a9c" }, { "signature_version": "v1", "target": { "file": "fs/btrfs/extent_io.c" }, "signature_type": "Line", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@89bca7fe6382d61e88c67a0b0e7bce315986fb8b", "deprecated": false, "digest": { "line_hashes": [ "146792862488252680835610567239249907663", "33797247576468341629789235444313135779", "291147640871542169756898728513409939566", "45508331146939523503015418260374178680", "226432510845592878467832734690532532656", "325527186985141489082322475089932203087", "155054955505449670005589626632563523451", "139384323298777156085656414872333930722", "11806383483542041679909246954382705188", "71419502785103307588297845811782383840", "250722455649262744337376544844313267330", "143745438007153368015143751308760369715", "179066994469569548448458258005235392334", "294076598759250832337018569375229167106", "217502098578490565938755398426078858054", "66489695774215632052769320686307848395", "146973977401085102485873756711499184937", "143317999797627153493941730151209350072", "275737793797802809884010822838008160856", "184731682844664436921604289729264712107", "95093201916024820806101891962049391694", "230120153805798590161648498777152241489", "182274794638895821229280654055490158248", "277744677368292359333570209790663630459", "190479365873981817156911989616720917699", "266657679246512794473565203573922869629", "98397288784173239248822931946373404066", "270605371202678201730675731748032444881", "159879006897460348194209439997234876419", "6612827124253772747955503695814724260", "175004440347943332275097146659998887641", "302571972079056355139229105418931707141", "241304398620543880449238858454725049023", "2791158605269883674356885694000394251", "68652443277058464250489036324074474602", "96010720737726370080353327771271807388", "196121874020048341413760470867744056612", "159919729393765735245206548859215425181", "323871090979754544630536996762701965366", "334673057638755419998034496654689394714", "16201337704714875727882711686653623518", "261233643218254830983214695567852728683", "38486494414674153128366606233876329817", "790947437694412215004471927548735734", "291609365384175757096480396450781885713", "54740206976234492667256227181330564213", "37798115861433900129291068606103817184", "84016450268507608838899988751189877724", "321393531952956209215131299766623832196", "2626605045853012135859483677558781042", "190786181767328007386907554201306856003", "116230597048650035450677671515401614208", "3039400901989881821478668038727959532", "135480008663860552977886220377934024543", "246443721714649926564700292475948611660", "320131640025250551987879797268384311934", "317476046494578369515166533044033703315", "173112287774158319865980541943505447442", "238248591405742349396422591829562860616", "169940336775911079049955764327578316761", "136695287564232285825115361466665604694", "202460258029327615405982689574778773534", "217930785174202894188171125304746396899", "157588669055197448040416248337899194819", "240872630025076375904400201909830512720", "186553449458648620146415587285665361213", "155589391564419960725720942839696077576", "318265520148491969502646848963471480429", "264810713777918197459239095038964636927", "267285539899129011382354591000780425940", "117735646457640524860698445756795383322", "286991295249004576357556326636146131263", "3681831003910004508906572682694310682", "205742696701710572589298260815303053706", "199460167557207036614312017509237903877", "68690249838141248364548890907087821477", "135152286490362895872935743265880820810", "141292100446853698110676177180883484255", "177333965337638884709685395622460119446", "141030460637988554161710635757477585072", "141211811701230245259060801420985295503", "207060147483863685899790198973995492973", "109713666578716208413043344003402394444", "99753015118443794361276205946906068169" ], "threshold": 0.9 }, "id": "CVE-2024-35784-b1d43f31" }, { "signature_version": "v1", "target": { "function": "extent_fiemap", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@ded566b4637f1b6b4c9ba74e7d0b8493e93f19cf", "deprecated": false, "digest": { "length": 3745.0, "function_hash": "119085328900539336230136411070438857293" }, "id": "CVE-2024-35784-b3fdbf88" }, { "signature_version": "v1", "target": { "function": "extent_fiemap", "file": "fs/btrfs/extent_io.c" }, "signature_type": "Function", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@89bca7fe6382d61e88c67a0b0e7bce315986fb8b", "deprecated": false, "digest": { "length": 3745.0, "function_hash": "119085328900539336230136411070438857293" }, "id": "CVE-2024-35784-fa2b9864" } ] }