In the Linux kernel, the following vulnerability has been resolved:
nfc: nci: add flush_workqueue to prevent uaf
Our detector found a concurrent use-after-free bug when detaching an NCI device. The main reason for this bug is the unexpected scheduling between the used delayed mechanism (timer and workqueue).
The race can be demonstrated below:
Thread-1 Thread-2 | ncidevup() | nciopendevice() | _ncirequest(nciresetreq) | ncisendcmd | queuework(cmdwork) nciunregisterdevice() | nciclosedevice() | ... deltimersync(cmdtimer)[1] | ... | Worker ncifreedevice() | ncicmdwork() kfree(ndev)[3] | modtimer(cmd_timer)[2]
In short, the cleanup routine thought that the cmdtimer has already been detached by [1] but the modtimer can re-attach the timer [2], even it is already released [3], resulting in UAF.
This UAF is easy to trigger, crash trace by POC is like below
[ 66.703713] ================================================================== [ 66.703974] BUG: KASAN: use-after-free in enqueuetimer+0x448/0x490 [ 66.703974] Write of size 8 at addr ffff888009fb7058 by task kworker/u4:1/33 [ 66.703974] [ 66.703974] CPU: 1 PID: 33 Comm: kworker/u4:1 Not tainted 5.18.0-rc2 #5 [ 66.703974] Workqueue: nfc2ncicmdwq ncicmdwork [ 66.703974] Call Trace: [ 66.703974] <TASK> [ 66.703974] dumpstacklvl+0x57/0x7d [ 66.703974] printreport.cold+0x5e/0x5db [ 66.703974] ? enqueuetimer+0x448/0x490 [ 66.703974] kasanreport+0xbe/0x1c0 [ 66.703974] ? enqueuetimer+0x448/0x490 [ 66.703974] enqueuetimer+0x448/0x490 [ 66.703974] _modtimer+0x5e6/0xb80 [ 66.703974] ? markheldlocks+0x9e/0xe0 [ 66.703974] ? trytodeltimersync+0xf0/0xf0 [ 66.703974] ? lockdephardirqsonprepare+0x17b/0x410 [ 66.703974] ? queueworkon+0x61/0x80 [ 66.703974] ? lockdephardirqson+0xbf/0x130 [ 66.703974] processonework+0x8bb/0x1510 [ 66.703974] ? lockdephardirqsonprepare+0x410/0x410 [ 66.703974] ? pwqdecnrinflight+0x230/0x230 [ 66.703974] ? rwlockbug.part.0+0x90/0x90 [ 66.703974] ? rawspinlockirq+0x41/0x50 [ 66.703974] workerthread+0x575/0x1190 [ 66.703974] ? processonework+0x1510/0x1510 [ 66.703974] kthread+0x2a0/0x340 [ 66.703974] ? kthreadcompleteandexit+0x20/0x20 [ 66.703974] retfromfork+0x22/0x30 [ 66.703974] </TASK> [ 66.703974] [ 66.703974] Allocated by task 267: [ 66.703974] kasansavestack+0x1e/0x40 [ 66.703974] _kasankmalloc+0x81/0xa0 [ 66.703974] nciallocatedevice+0xd3/0x390 [ 66.703974] nfcmrvlnciregisterdev+0x183/0x2c0 [ 66.703974] nfcmrvlnciuartopen+0xf2/0x1dd [ 66.703974] nciuartttyioctl+0x2c3/0x4a0 [ 66.703974] ttyioctl+0x764/0x1310 [ 66.703974] _x64sysioctl+0x122/0x190 [ 66.703974] dosyscall64+0x3b/0x90 [ 66.703974] entrySYSCALL64afterhwframe+0x44/0xae [ 66.703974] [ 66.703974] Freed by task 406: [ 66.703974] kasansavestack+0x1e/0x40 [ 66.703974] kasansettrack+0x21/0x30 [ 66.703974] kasansetfreeinfo+0x20/0x30 [ 66.703974] _kasanslabfree+0x108/0x170 [ 66.703974] kfree+0xb0/0x330 [ 66.703974] nfcmrvlnciunregisterdev+0x90/0xd0 [ 66.703974] nciuartttyclose+0xdf/0x180 [ 66.703974] ttyldisckill+0x73/0x110 [ 66.703974] ttyldischangup+0x281/0x5b0 [ 66.703974] _ttyhangup.part.0+0x431/0x890 [ 66.703974] ttyrelease+0x3a8/0xc80 [ 66.703974] _fput+0x1f0/0x8c0 [ 66.703974] taskworkrun+0xc9/0x170 [ 66.703974] exittousermodeprepare+0x194/0x1a0 [ 66.703974] syscallexittousermode+0x19/0x50 [ 66.703974] dosyscall64+0x48/0x90 [ 66.703974] entrySYSCALL64after_hwframe+0x44/0x ---truncated---
{ "vanir_signatures": [ { "id": "CVE-2022-49059-2111fa1f", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5c63ad2b0a267a524c12c88acb1ba9c2d109a801" }, { "id": "CVE-2022-49059-32cba824", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 833.0, "function_hash": "218393462140329062506187290232190607081" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@ef27324e2cb7bb24542d6cb2571740eefe6b00dc" }, { "id": "CVE-2022-49059-33ff0b09", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 833.0, "function_hash": "218393462140329062506187290232190607081" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@edd4600120641e1714e30112e69a548cfb68e067" }, { "id": "CVE-2022-49059-431f5489", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@1a1748d0dd0f0a98535c6baeef671c8722107639" }, { "id": "CVE-2022-49059-67b16225", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9ded5ae40f4fe37fcc28f36d76bf45df20be5432" }, { "id": "CVE-2022-49059-7ea4d385", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 821.0, "function_hash": "221363571853476975912309897623010049484" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@7d3232214ca4ea8f7d18df264c3b254aa8089d7f" }, { "id": "CVE-2022-49059-8994f0e8", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 833.0, "function_hash": "218393462140329062506187290232190607081" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9ded5ae40f4fe37fcc28f36d76bf45df20be5432" }, { "id": "CVE-2022-49059-91757943", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@7d3232214ca4ea8f7d18df264c3b254aa8089d7f" }, { "id": "CVE-2022-49059-96fc66ea", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@edd4600120641e1714e30112e69a548cfb68e067" }, { "id": "CVE-2022-49059-aa6a491b", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 821.0, "function_hash": "236895061116955220461311893158298649459" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@67677050cecbe0edfdd81cd508415e9636ba7c65" }, { "id": "CVE-2022-49059-cc7c842c", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@ef27324e2cb7bb24542d6cb2571740eefe6b00dc" }, { "id": "CVE-2022-49059-ce1eaac9", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 821.0, "function_hash": "221363571853476975912309897623010049484" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5c63ad2b0a267a524c12c88acb1ba9c2d109a801" }, { "id": "CVE-2022-49059-db4545c4", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9d243aff5f7e6b04e907c617426bbdf26e996ac8" }, { "id": "CVE-2022-49059-f13be71a", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 821.0, "function_hash": "221363571853476975912309897623010049484" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9d243aff5f7e6b04e907c617426bbdf26e996ac8" }, { "id": "CVE-2022-49059-f7e53501", "signature_type": "Function", "target": { "file": "net/nfc/nci/core.c", "function": "nci_close_device" }, "deprecated": false, "digest": { "length": 821.0, "function_hash": "221363571853476975912309897623010049484" }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@1a1748d0dd0f0a98535c6baeef671c8722107639" }, { "id": "CVE-2022-49059-ffcd025e", "signature_type": "Line", "target": { "file": "net/nfc/nci/core.c" }, "deprecated": false, "digest": { "line_hashes": [ "35149437234782704116987049837847963007", "80517307482413553861375218651644460352", "70770786728960080766248770755876804676", "1992539026138648105923749074459036243" ], "threshold": 0.9 }, "signature_version": "v1", "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@67677050cecbe0edfdd81cd508415e9636ba7c65" } ] }