In the Linux kernel, the following vulnerability has been resolved:
tcp/dccp: Don't use timerpending() in reqskqueue_unlink().
Martin KaFai Lau reported use-after-free [0] in reqsktimerhandler().
""" We are seeing a use-after-free from a bpf prog attached to tracetcpretransmitsynack. The program passes the req->sk to the bpfskstorageget_tracing kernel helper which does check for null before using it. """
The commit 83fccfc3940c ("inet: fix potential deadlock in reqskqueueunlink()") added timerpending() in reqskqueueunlink() not to call deltimersync() from reqsktimer_handler(), but it introduced a small race window.
Before the timer is called, expiretimers() calls detachtimer(timer, true) to clear timer->entry.pprev and marks it as not pending.
If reqskqueueunlink() checks timerpending() just after expiretimers() calls detachtimer(), TCP will miss deltimer_sync(); the reqsk timer will continue running and send multiple SYN+ACKs until it expires.
The reported UAF could happen if req->sk is close()d earlier than the timer expiration, which is 63s by default.
The scenario would be
inetcskcompletehashdance() calls inetcskreqskqueuedrop(), but deltimer_sync() is missed
reqsk timer is executed and scheduled again
req->sk is accept()ed and reqskput() decrements rskrefcnt, but reqsk timer still has another one, and inetcskaccept() does not clear req->sk for non-TFO sockets
sk is close()d
reqsk timer is executed again, and BPF touches req->sk
Let's not use timerpending() by passing the caller context to _inetcskreqskqueuedrop().
Note that reqsk timer is pinned, so the issue does not happen in most use cases. [1]
[0] BUG: KFENCE: use-after-free read in bpfskstoragegettracing+0x2e/0x1b0
Use-after-free read at 0x00000000a891fb3a (in kfence-#1): bpfskstoragegettracing+0x2e/0x1b0 bpfprog5ea3e95db6da0438tcpretransmitsynack+0x1d20/0x1dda bpftracerun2+0x4c/0xc0 tcprtxsynack+0xf9/0x100 reqsktimerhandler+0xda/0x3d0 runtimersoftirq+0x292/0x8a0 irqexitrcu+0xf5/0x320 sysvecapictimerinterrupt+0x6d/0x80 asmsysvecapictimerinterrupt+0x16/0x20 intelidleirq+0x5a/0xa0 cpuidleenterstate+0x94/0x273 cpustartupentry+0x15e/0x260 startsecondary+0x8a/0x90 secondarystartup64no_verify+0xfa/0xfb
kfence-#1: 0x00000000a72cc7b6-0x00000000d97616d9, size=2376, cache=TCPv6
allocated by task 0 on cpu 9 at 260507.901592s: skprotalloc+0x35/0x140 skclonelock+0x1f/0x3f0 inetcskclonelock+0x15/0x160 tcpcreateopenreqchild+0x1f/0x410 tcpv6synrecvsock+0x1da/0x700 tcpcheckreq+0x1fb/0x510 tcpv6rcv+0x98b/0x1420 ipv6listrcv+0x2258/0x26e0 napicompletedone+0x5b1/0x2990 mlx5enapipoll+0x2ae/0x8d0 netrxaction+0x13e/0x590 irqexitrcu+0xf5/0x320 commoninterrupt+0x80/0x90 asmcommoninterrupt+0x22/0x40 cpuidleenterstate+0xfb/0x273 cpustartupentry+0x15e/0x260 startsecondary+0x8a/0x90 secondarystartup64noverify+0xfa/0xfb
freed by task 0 on cpu 9 at 260507.927527s: rcucoresi+0x4ff/0xf10 irqexitrcu+0xf5/0x320 sysvecapictimerinterrupt+0x6d/0x80 asmsysvecapictimerinterrupt+0x16/0x20 cpuidleenterstate+0xfb/0x273 cpustartupentry+0x15e/0x260 startsecondary+0x8a/0x90 secondarystartup64noverify+0xfa/0xfb
[ { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "64704740596726658714337321968995990757", "length": 1897.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@51e34db64f4e43c7b055ccf881b7f3e0c31bb26d", "id": "CVE-2024-50154-00c25fb0", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "124689568586661251303657627098227544479", "length": 406.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8459d61fbf24967839a70235165673148c7c7f17", "id": "CVE-2024-50154-0be60cc1", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "64704740596726658714337321968995990757", "length": 1897.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5071beb59ee416e8ab456ac8647a4dabcda823b1", "id": "CVE-2024-50154-1670e99c", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8459d61fbf24967839a70235165673148c7c7f17", "id": "CVE-2024-50154-3f065648", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "48556197400282954584174378905549765682", "length": 387.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@997ae8da14f1639ce6fb66a063dab54031cd61b3", "id": "CVE-2024-50154-3fc0e953", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "48556197400282954584174378905549765682", "length": 387.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@51e34db64f4e43c7b055ccf881b7f3e0c31bb26d", "id": "CVE-2024-50154-4c236771", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "170996444804039754499179149408679603822", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "36896008633916616306865272513646448332", "58703656449459996816183146181533197630", "262013112363793562674923512893641132138", "300645766492400889246574906072924075697", "111892480733136349664874038011740563316", "201786555154536837112391120412698105861", "101364267078000962071712677851623074076", "196630416804819657667941523509133357078" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8459d61fbf24967839a70235165673148c7c7f17", "id": "CVE-2024-50154-52aa28fa", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5071beb59ee416e8ab456ac8647a4dabcda823b1", "id": "CVE-2024-50154-5fb1a546", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "128313556592618298349658413336607944058", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "36896008633916616306865272513646448332", "58703656449459996816183146181533197630", "262013112363793562674923512893641132138", "300645766492400889246574906072924075697", "111892480733136349664874038011740563316", "201786555154536837112391120412698105861", "101364267078000962071712677851623074076", "196630416804819657667941523509133357078" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@997ae8da14f1639ce6fb66a063dab54031cd61b3", "id": "CVE-2024-50154-732d575c", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "124689568586661251303657627098227544479", "length": 406.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@106e457953315e476b3642ef24be25ed862aaba3", "id": "CVE-2024-50154-79870956", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@51e34db64f4e43c7b055ccf881b7f3e0c31bb26d", "id": "CVE-2024-50154-7e1496ca", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e8c526f2bdf1845bedaf6a478816a3d06fa78b8f", "id": "CVE-2024-50154-7e86d290", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "48556197400282954584174378905549765682", "length": 387.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5071beb59ee416e8ab456ac8647a4dabcda823b1", "id": "CVE-2024-50154-8bdcf97a", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "64704740596726658714337321968995990757", "length": 1897.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e8c526f2bdf1845bedaf6a478816a3d06fa78b8f", "id": "CVE-2024-50154-91cff78b", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "64704740596726658714337321968995990757", "length": 1897.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@8459d61fbf24967839a70235165673148c7c7f17", "id": "CVE-2024-50154-9c1e3737", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "170996444804039754499179149408679603822", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "46659330718087596692142233802574958054", "108222141527307633496964138856963763694", "279038978215635746268451942835714781081", "142625150202285898554689134915412740774" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@106e457953315e476b3642ef24be25ed862aaba3", "id": "CVE-2024-50154-9c317c4c", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "170996444804039754499179149408679603822", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "46659330718087596692142233802574958054", "108222141527307633496964138856963763694", "279038978215635746268451942835714781081", "142625150202285898554689134915412740774" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@c964bf65f80a14288d767023a1b300b30f5b9cd0", "id": "CVE-2024-50154-9f8d7b6a", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "48556197400282954584174378905549765682", "length": 387.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e8c526f2bdf1845bedaf6a478816a3d06fa78b8f", "id": "CVE-2024-50154-a98ebf27", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "128313556592618298349658413336607944058", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "36896008633916616306865272513646448332", "58703656449459996816183146181533197630", "262013112363793562674923512893641132138", "300645766492400889246574906072924075697", "111892480733136349664874038011740563316", "201786555154536837112391120412698105861", "101364267078000962071712677851623074076", "196630416804819657667941523509133357078" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@5071beb59ee416e8ab456ac8647a4dabcda823b1", "id": "CVE-2024-50154-ab758b11", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@106e457953315e476b3642ef24be25ed862aaba3", "id": "CVE-2024-50154-b6591797", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "128313556592618298349658413336607944058", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "36896008633916616306865272513646448332", "58703656449459996816183146181533197630", "262013112363793562674923512893641132138", "300645766492400889246574906072924075697", "111892480733136349664874038011740563316", "201786555154536837112391120412698105861", "101364267078000962071712677851623074076", "196630416804819657667941523509133357078" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@51e34db64f4e43c7b055ccf881b7f3e0c31bb26d", "id": "CVE-2024-50154-bb37ddef", "signature_version": "v1" }, { "signature_type": "Line", "target": { "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "threshold": 0.9, "line_hashes": [ "128313556592618298349658413336607944058", "210157165349096110274611437896720687911", "171781158412444750965850304670983865516", "186608874152332948017356444316901016368", "35637255808054568185922388577776229202", "293450542033064579584097379474374369822", "297422862884201848021288415433064895394", "263732465170256860361538683089324907905", "120302066335605760584942706714101100019", "100173222790130767398601716739540294816", "331015096628798863234592905793237861864", "10644977216423451168257140793409712424", "40581575732233074060616389512085429888", "20954404232672819522401843267515272455", "82684254511611362081420013322396737882", "324100523845985646762200342907633932631", "36896008633916616306865272513646448332", "58703656449459996816183146181533197630", "262013112363793562674923512893641132138", "300645766492400889246574906072924075697", "111892480733136349664874038011740563316", "201786555154536837112391120412698105861", "101364267078000962071712677851623074076", "196630416804819657667941523509133357078" ] }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@e8c526f2bdf1845bedaf6a478816a3d06fa78b8f", "id": "CVE-2024-50154-beedf230", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "304036792542030668237133201730089335469", "length": 1103.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@c964bf65f80a14288d767023a1b300b30f5b9cd0", "id": "CVE-2024-50154-c654ad97", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "64704740596726658714337321968995990757", "length": 1897.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@997ae8da14f1639ce6fb66a063dab54031cd61b3", "id": "CVE-2024-50154-ce57a06a", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@c964bf65f80a14288d767023a1b300b30f5b9cd0", "id": "CVE-2024-50154-d40abdce", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_timer_handler", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "99409000672171603694504076083424477953", "length": 1154.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@106e457953315e476b3642ef24be25ed862aaba3", "id": "CVE-2024-50154-e3301ce4", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "inet_csk_reqsk_queue_drop", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "159081251697448771999131281460528694119", "length": 199.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@997ae8da14f1639ce6fb66a063dab54031cd61b3", "id": "CVE-2024-50154-f45a4965", "signature_version": "v1" }, { "signature_type": "Function", "target": { "function": "reqsk_queue_unlink", "file": "net/ipv4/inet_connection_sock.c" }, "deprecated": false, "digest": { "function_hash": "124689568586661251303657627098227544479", "length": 406.0 }, "source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@c964bf65f80a14288d767023a1b300b30f5b9cd0", "id": "CVE-2024-50154-fe16a0c0", "signature_version": "v1" } ]