af_unix: Give up GC if MSG_PEEK intervened.
In the Linux kernel, the following vulnerability has been resolved: af_unix: Give up GC if MSG_PEEK intervened. Igor Ushakov reported that GC purged the receive queue of an alive socket due to a race with MSG_PEEK with a nice repro. This is the exact same issue previously fixed by commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK"). After GC was replaced with the current algorithm, the cited commit removed the locking dance in unix_peek_fds() and reintroduced the same issue. The problem is that MSG_PEEK bumps a file refcount without interacting with GC. Consider an SCC containing sk-A and sk-B, where sk-A is close()d but can be recv()ed via sk-B. The bad thing happens if sk-A is recv()ed with MSG_PEEK from sk-B and sk-B is close()d while GC is checking unix_vertex_dead() for sk-A and sk-B. GC thread User thread --------- ----------- unix_vertex_dead(sk-A) -> true <------. \ `------ recv(sk-B, MSG_PEEK) invalidate !! -> sk-A's file refcount : 1 -> 2 close(sk-B) -> sk-B's file refcount : 2 -> 1 unix_vertex_dead(sk-B) -> true Initially, sk-A's file refcount is 1 by the inflight fd in sk-B recvq. GC thinks sk-A is dead because the file refcount is the same as the number of its inflight fds. However, sk-A's file refcount is bumped silently by MSG_PEEK, which invalidates the previous evaluation. At this moment, sk-B's file refcount is 2; one by the open fd, and one by the inflight fd in sk-A. The subsequent close() releases one refcount by the former. Finally, GC incor
- Products
- Kernel
- Affected versions
- Not specified
- Fixed versions
- 6.1.183, 6.12.92, 6.18.23, 6.19.10, 6.6.142
- CVEs
- CVE-2026-23394
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 4 Nov 2026, 13:27 UTC · Revision 1
Source evidence
af_unix: Give up GC if MSG_PEEK intervened.
core-osv · Original sourcePublished 25 Mar 2026, 10:33 UTC
In the Linux kernel, the following vulnerability has been resolved: af_unix: Give up GC if MSG_PEEK intervened. Igor Ushakov reported that GC purged the receive queue of an alive socket due to a race with MSG_PEEK with a nice repro. This is the exact same issue previously fixed by commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK"). After GC was replaced with the current algorithm, the cited commit removed the locking dance in unix_peek_fds() and reintroduced the same issue. The problem is that MSG_PEEK bumps a file refcount without interacting with GC. Consider an SCC containing sk-A and sk-B, where sk-A is close()d but can be recv()ed via sk-B. The bad thing happens if sk-A is recv()ed with MSG_PEEK from sk-B and sk-B is close()d while GC is checking unix_vertex_dead() for sk-A and sk-B. GC thread User thread --------- ----------- unix_vertex_dead(sk-A) -> true <------. \ `------ recv(sk-B, MSG_PEEK) invalidate !! -> sk-A's file refcount : 1 -> 2 close(sk-B) -> sk-B's file refcount : 2 -> 1 unix_vertex_dead(sk-B) -> true Initially, sk-A's file refcount is 1 by the inflight fd in sk-B recvq. GC thinks sk-A is dead because the file refcount is the same as the number of its inflight fds. However, sk-A's file refcount is bumped silently by MSG_PEEK, which invalidates the previous evaluation. At this moment, sk-B's file refcount is 2; one by the open fd, and one by the inflight fd in sk-A. The subsequent close() releases one refcount by the former. Finally, GC incor
osv:CVE-2026-23394
Kernel
Fixed versions: 6.1.183, 6.6.142, 6.12.92, 6.18.23, 6.19.10
Complete source record
{
"id": "b72cf1ceddf4c51762a99b65784b0114f2a9becb0534774209b5131d3ab1ba8f",
"url": "https://osv.dev/vulnerability/CVE-2026-23394",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "af_unix: Give up GC if MSG_PEEK intervened.",
"summary": "In the Linux kernel, the following vulnerability has been resolved: af_unix: Give up GC if MSG_PEEK intervened. Igor Ushakov reported that GC purged the receive queue of an alive socket due to a race with MSG_PEEK with a nice repro. This is the exact same issue previously fixed by commit cbcf01128d0a (\"af_unix: fix garbage collect vs MSG_PEEK\"). After GC was replaced with the current algorithm, the cited commit removed the locking dance in unix_peek_fds() and reintroduced the same issue. The problem is that MSG_PEEK bumps a file refcount without interacting with GC. Consider an SCC containing sk-A and sk-B, where sk-A is close()d but can be recv()ed via sk-B. The bad thing happens if sk-A is recv()ed with MSG_PEEK from sk-B and sk-B is close()d while GC is checking unix_vertex_dead() for sk-A and sk-B. GC thread User thread --------- ----------- unix_vertex_dead(sk-A) -> true <------. \\ `------ recv(sk-B, MSG_PEEK) invalidate !! -> sk-A's file refcount : 1 -> 2 close(sk-B) -> sk-B's file refcount : 2 -> 1 unix_vertex_dead(sk-B) -> true Initially, sk-A's file refcount is 1 by the inflight fd in sk-B recvq. GC thinks sk-A is dead because the file refcount is the same as the number of its inflight fds. However, sk-A's file refcount is bumped silently by MSG_PEEK, which invalidates the previous evaluation. At this moment, sk-B's file refcount is 2; one by the open fd, and one by the inflight fd in sk-A. The subsequent close() releases one refcount by the former. Finally, GC incor",
"evidence": "osv:CVE-2026-23394",
"products": [
{
"name": {
"value": "Kernel",
"evidence": "/affected/1/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "6.1.183",
"evidence": "/affected/1/ranges"
},
{
"value": "6.6.142",
"evidence": "/affected/1/ranges"
},
{
"value": "6.12.92",
"evidence": "/affected/1/ranges"
},
{
"value": "6.18.23",
"evidence": "/affected/1/ranges"
},
{
"value": "6.19.10",
"evidence": "/affected/1/ranges"
}
],
"affected_versions": []
}
],
"severity": "unknown",
"structured": {
"id": "CVE-2026-23394",
"aliases": [
"CVE-2026-23394"
],
"affected": [
{
"ranges": [
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "61a75360dca93c945ef6bd757f8b8a96f39b77cb"
},
{
"fixed": "980999a96e1ad043f1197606e5d637219cb102b9"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "7b1ffbd3b22e755d481d49647dcb7c5cfbde5844"
},
{
"fixed": "3106f326f67c03dd9da4ca64663d11e40138cf40"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "118f457da9ed58a79e24b73c2ef0aa1987241f0e"
},
{
"fixed": "e3dd56fb5683ba80bf8d7a2f9aa21cfa53f05202"
},
{
"fixed": "72cf49ad50c16270b52bc512d9c2df5743922968"
},
{
"fixed": "37dd7ab332396eb8dd80b2dc7ea4b61abf767436"
},
{
"fixed": "e5b31d988a41549037b8d8721a3c3cae893d8670"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "6.1.141"
},
{
"fixed": "6.1.183"
}
]
},
{
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"type": "GIT",
"events": [
{
"introduced": "6.6.93"
},
{
"fixed": "6.6.142"
}
]
}
],
"versions": [
"v6.1.182",
"v6.1.181",
"v6.1.180",
"v6.1.179",
"v6.1.178",
"v6.1.177",
"v6.1.176",
"v6.1.175",
"v6.1.174",
"v6.1.173",
"v6.1.172",
"v6.1.171",
"v6.1.170",
"v6.1.169",
"v6.1.168",
"v6.1.167",
"v6.1.166",
"v6.1.165",
"v6.1.164",
"v6.1.163",
"v6.1.162",
"v6.1.161",
"v6.1.160",
"v6.1.159",
"v6.1.158",
"v6.1.157",
"v6.1.156",
"v6.1.155",
"v6.1.154",
"v6.1.153",
"v6.1.152",
"v6.1.151",
"v6.1.150",
"v6.1.149",
"v6.1.148",
"v6.1.147",
"v6.1.146",
"v6.1.145",
"v6.1.144",
"v6.1.143",
"v6.1.142",
"v6.1.141",
"v6.6.141",
"v6.6.140",
"v6.6.139",
"v6.6.138",
"v6.6.137",
"v6.6.136",
"v6.6.135",
"v6.6.134",
"v6.6.133",
"v6.6.132",
"v6.6.131",
"v6.6.130",
"v6.6.129",
"v6.6.128",
"v6.6.127",
"v6.6.126",
"v6.6.125",
"v6.6.124",
"v6.6.123",
"v6.6.122",
"v6.6.121",
"v6.6.120",
"v6.6.119",
"v6.6.118",
"v6.6.117",
"v6.6.116",
"v6.6.115",
"v6.6.114",
"v6.6.113",
"v6.6.112",
"v6.6.111",
"v6.6.110",
"v6.6.109",
"v6.6.108",
"v6.6.107",
"v6.6.106",
"v6.6.105",
"v6.6.104",
"v6.6.103",
"v6.6.102",
"v6.6.101",
"v6.6.100",
"v6.6.99",
"v6.6.98",
"v6.6.97",
"v6.6.96",
"v6.6.95",
"v6.6.94",
"v6.6.93"
],
"database_specific": {
"source": "https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-23394.json"
}
},
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
},
{
"fixed": "6.1.183"
}
]
},
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "6.2.0"
},
{
"fixed": "6.6.142"
}
]
},
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "6.7.0"
},
{
"fixed": "6.12.92"
}
]
},
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "6.10.0"
},
{
"fixed": "6.18.23"
}
]
},
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "6.13.0"
},
{
"fixed": "6.19.10"
}
]
}
],
"package": {
"name": "Kernel",
"ecosystem": "Linux"
},
"database_specific": {
"source": "https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-23394.json"
}
}
],
"modified": "2026-10-28T02:30:35.984019789Z",
"provider": "osv",
"references": [
"https://git.kernel.org/stable/c/3106f326f67c03dd9da4ca64663d11e40138cf40",
"https://git.kernel.org/stable/c/37dd7ab332396eb8dd80b2dc7ea4b61abf767436",
"https://git.kernel.org/stable/c/72cf49ad50c16270b52bc512d9c2df5743922968",
"https://git.kernel.org/stable/c/980999a96e1ad043f1197606e5d637219cb102b9",
"https://git.kernel.org/stable/c/e3dd56fb5683ba80bf8d7a2f9aa21cfa53f05202",
"https://git.kernel.org/stable/c/e5b31d988a41549037b8d8721a3c3cae893d8670",
"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/23xxx/CVE-2026-23394.json",
"https://nvd.nist.gov/vuln/detail/CVE-2026-23394",
"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"
],
"provider_metadata": {
"cna_assigner": "Linux",
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/23xxx/CVE-2026-23394.json"
}
},
"related_cves": [
{
"value": "CVE-2026-23394",
"evidence": "/id"
}
],
"security_relevant": true,
"severity_evidence": null
},
"source_id": "core-osv",
"document_id": 503099,
"published_at": "2026-03-25T10:33:18.18+00:00"
}