CVE-2025-22077 (GCVE-0-2025-22077)
Vulnerability from cvelistv5
Published
2025-04-16 14:12
Modified
2025-05-26 05:17
Severity ?
VLAI Severity ?
EPSS score ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
Revert "smb: client: fix TCP timers deadlock after rmmod"
This reverts commit e9f2517a3e18a54a3943c098d2226b245d488801.
Commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock after
rmmod") is intended to fix a null-ptr-deref in LOCKDEP, which is
mentioned as CVE-2024-54680, but is actually did not fix anything;
The issue can be reproduced on top of it. [0]
Also, it reverted the change by commit ef7134c7fc48 ("smb: client:
Fix use-after-free of network namespace.") and introduced a real
issue by reviving the kernel TCP socket.
When a reconnect happens for a CIFS connection, the socket state
transitions to FIN_WAIT_1. Then, inet_csk_clear_xmit_timers_sync()
in tcp_close() stops all timers for the socket.
If an incoming FIN packet is lost, the socket will stay at FIN_WAIT_1
forever, and such sockets could be leaked up to net.ipv4.tcp_max_orphans.
Usually, FIN can be retransmitted by the peer, but if the peer aborts
the connection, the issue comes into reality.
I warned about this privately by pointing out the exact report [1],
but the bogus fix was finally merged.
So, we should not stop the timers to finally kill the connection on
our side in that case, meaning we must not use a kernel socket for
TCP whose sk->sk_net_refcnt is 0.
The kernel socket does not have a reference to its netns to make it
possible to tear down netns without cleaning up every resource in it.
For example, tunnel devices use a UDP socket internally, but we can
destroy netns without removing such devices and let it complete
during exit. Otherwise, netns would be leaked when the last application
died.
However, this is problematic for TCP sockets because TCP has timers to
close the connection gracefully even after the socket is close()d. The
lifetime of the socket and its netns is different from the lifetime of
the underlying connection.
If the socket user does not maintain the netns lifetime, the timer could
be fired after the socket is close()d and its netns is freed up, resulting
in use-after-free.
Actually, we have seen so many similar issues and converted such sockets
to have a reference to netns.
That's why I converted the CIFS client socket to have a reference to
netns (sk->sk_net_refcnt == 1), which is somehow mentioned as out-of-scope
of CIFS and technically wrong in e9f2517a3e18, but **is in-scope and right
fix**.
Regarding the LOCKDEP issue, we can prevent the module unload by
bumping the module refcount when switching the LOCKDDEP key in
sock_lock_init_class_and_name(). [2]
For a while, let's revert the bogus fix.
Note that now we can use sk_net_refcnt_upgrade() for the socket
conversion, but I'll do so later separately to make backport easy.
References
Impacted products
{ "containers": { "cna": { "affected": [ { "defaultStatus": "unaffected", "product": "Linux", "programFiles": [ "fs/smb/client/connect.c" ], "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "vendor": "Linux", "versions": [ { "lessThan": "8dbf060480236877703bff0106fc984576184d11", "status": "affected", "version": "906807c734ed219dcb2e7bbfde5c4168ed72a3d0", "versionType": "git" }, { "lessThan": "f761eeefd531e6550cd3a5c047835b4892acb00d", "status": "affected", "version": "127e907e11ccd54b59bb78fc22c43ccb76c71079", "versionType": "git" }, { "lessThan": "4b6f6bf1bde8d6045c389fda8d21c304dfe49384", "status": "affected", "version": "e9f2517a3e18a54a3943c098d2226b245d488801", "versionType": "git" }, { "lessThan": "95d2b9f693ff2a1180a23d7d59acc0c4e72f4c41", "status": "affected", "version": "e9f2517a3e18a54a3943c098d2226b245d488801", "versionType": "git" } ] }, { "defaultStatus": "affected", "product": "Linux", "programFiles": [ "fs/smb/client/connect.c" ], "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "vendor": "Linux", "versions": [ { "status": "affected", "version": "6.13" }, { "lessThan": "6.13", "status": "unaffected", "version": "0", "versionType": "semver" }, { "lessThanOrEqual": "6.6.*", "status": "unaffected", "version": "6.6.88", "versionType": "semver" }, { "lessThanOrEqual": "6.12.*", "status": "unaffected", "version": "6.12.25", "versionType": "semver" }, { "lessThanOrEqual": "6.14.*", "status": "unaffected", "version": "6.14.4", "versionType": "semver" }, { "lessThanOrEqual": "*", "status": "unaffected", "version": "6.15", "versionType": "original_commit_for_fix" } ] } ], "cpeApplicability": [ { "nodes": [ { "cpeMatch": [ { "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionEndExcluding": "6.6.88", "versionStartIncluding": "6.6.68", "vulnerable": true }, { "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionEndExcluding": "6.12.25", "versionStartIncluding": "6.12.7", "vulnerable": true }, { "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionEndExcluding": "6.14.4", "versionStartIncluding": "6.13", "vulnerable": true }, { "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionEndExcluding": "6.15", "versionStartIncluding": "6.13", "vulnerable": true } ], "negate": false, "operator": "OR" } ] } ], "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nRevert \"smb: client: fix TCP timers deadlock after rmmod\"\n\nThis reverts commit e9f2517a3e18a54a3943c098d2226b245d488801.\n\nCommit e9f2517a3e18 (\"smb: client: fix TCP timers deadlock after\nrmmod\") is intended to fix a null-ptr-deref in LOCKDEP, which is\nmentioned as CVE-2024-54680, but is actually did not fix anything;\nThe issue can be reproduced on top of it. [0]\n\nAlso, it reverted the change by commit ef7134c7fc48 (\"smb: client:\nFix use-after-free of network namespace.\") and introduced a real\nissue by reviving the kernel TCP socket.\n\nWhen a reconnect happens for a CIFS connection, the socket state\ntransitions to FIN_WAIT_1. Then, inet_csk_clear_xmit_timers_sync()\nin tcp_close() stops all timers for the socket.\n\nIf an incoming FIN packet is lost, the socket will stay at FIN_WAIT_1\nforever, and such sockets could be leaked up to net.ipv4.tcp_max_orphans.\n\nUsually, FIN can be retransmitted by the peer, but if the peer aborts\nthe connection, the issue comes into reality.\n\nI warned about this privately by pointing out the exact report [1],\nbut the bogus fix was finally merged.\n\nSo, we should not stop the timers to finally kill the connection on\nour side in that case, meaning we must not use a kernel socket for\nTCP whose sk-\u003esk_net_refcnt is 0.\n\nThe kernel socket does not have a reference to its netns to make it\npossible to tear down netns without cleaning up every resource in it.\n\nFor example, tunnel devices use a UDP socket internally, but we can\ndestroy netns without removing such devices and let it complete\nduring exit. Otherwise, netns would be leaked when the last application\ndied.\n\nHowever, this is problematic for TCP sockets because TCP has timers to\nclose the connection gracefully even after the socket is close()d. The\nlifetime of the socket and its netns is different from the lifetime of\nthe underlying connection.\n\nIf the socket user does not maintain the netns lifetime, the timer could\nbe fired after the socket is close()d and its netns is freed up, resulting\nin use-after-free.\n\nActually, we have seen so many similar issues and converted such sockets\nto have a reference to netns.\n\nThat\u0027s why I converted the CIFS client socket to have a reference to\nnetns (sk-\u003esk_net_refcnt == 1), which is somehow mentioned as out-of-scope\nof CIFS and technically wrong in e9f2517a3e18, but **is in-scope and right\nfix**.\n\nRegarding the LOCKDEP issue, we can prevent the module unload by\nbumping the module refcount when switching the LOCKDDEP key in\nsock_lock_init_class_and_name(). [2]\n\nFor a while, let\u0027s revert the bogus fix.\n\nNote that now we can use sk_net_refcnt_upgrade() for the socket\nconversion, but I\u0027ll do so later separately to make backport easy." } ], "providerMetadata": { "dateUpdated": "2025-05-26T05:17:58.451Z", "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux" }, "references": [ { "url": "https://git.kernel.org/stable/c/8dbf060480236877703bff0106fc984576184d11" }, { "url": "https://git.kernel.org/stable/c/f761eeefd531e6550cd3a5c047835b4892acb00d" }, { "url": "https://git.kernel.org/stable/c/4b6f6bf1bde8d6045c389fda8d21c304dfe49384" }, { "url": "https://git.kernel.org/stable/c/95d2b9f693ff2a1180a23d7d59acc0c4e72f4c41" } ], "title": "Revert \"smb: client: fix TCP timers deadlock after rmmod\"", "x_generator": { "engine": "bippy-1.2.0" } } }, "cveMetadata": { "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "assignerShortName": "Linux", "cveId": "CVE-2025-22077", "datePublished": "2025-04-16T14:12:27.882Z", "dateReserved": "2024-12-29T08:45:45.815Z", "dateUpdated": "2025-05-26T05:17:58.451Z", "state": "PUBLISHED" }, "dataType": "CVE_RECORD", "dataVersion": "5.1", "vulnerability-lookup:meta": { "nvd": "{\"cve\":{\"id\":\"CVE-2025-22077\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2025-04-16T15:16:01.907\",\"lastModified\":\"2025-04-25T11:15:45.767\",\"vulnStatus\":\"Awaiting Analysis\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nRevert \\\"smb: client: fix TCP timers deadlock after rmmod\\\"\\n\\nThis reverts commit e9f2517a3e18a54a3943c098d2226b245d488801.\\n\\nCommit e9f2517a3e18 (\\\"smb: client: fix TCP timers deadlock after\\nrmmod\\\") is intended to fix a null-ptr-deref in LOCKDEP, which is\\nmentioned as CVE-2024-54680, but is actually did not fix anything;\\nThe issue can be reproduced on top of it. [0]\\n\\nAlso, it reverted the change by commit ef7134c7fc48 (\\\"smb: client:\\nFix use-after-free of network namespace.\\\") and introduced a real\\nissue by reviving the kernel TCP socket.\\n\\nWhen a reconnect happens for a CIFS connection, the socket state\\ntransitions to FIN_WAIT_1. Then, inet_csk_clear_xmit_timers_sync()\\nin tcp_close() stops all timers for the socket.\\n\\nIf an incoming FIN packet is lost, the socket will stay at FIN_WAIT_1\\nforever, and such sockets could be leaked up to net.ipv4.tcp_max_orphans.\\n\\nUsually, FIN can be retransmitted by the peer, but if the peer aborts\\nthe connection, the issue comes into reality.\\n\\nI warned about this privately by pointing out the exact report [1],\\nbut the bogus fix was finally merged.\\n\\nSo, we should not stop the timers to finally kill the connection on\\nour side in that case, meaning we must not use a kernel socket for\\nTCP whose sk-\u003esk_net_refcnt is 0.\\n\\nThe kernel socket does not have a reference to its netns to make it\\npossible to tear down netns without cleaning up every resource in it.\\n\\nFor example, tunnel devices use a UDP socket internally, but we can\\ndestroy netns without removing such devices and let it complete\\nduring exit. Otherwise, netns would be leaked when the last application\\ndied.\\n\\nHowever, this is problematic for TCP sockets because TCP has timers to\\nclose the connection gracefully even after the socket is close()d. The\\nlifetime of the socket and its netns is different from the lifetime of\\nthe underlying connection.\\n\\nIf the socket user does not maintain the netns lifetime, the timer could\\nbe fired after the socket is close()d and its netns is freed up, resulting\\nin use-after-free.\\n\\nActually, we have seen so many similar issues and converted such sockets\\nto have a reference to netns.\\n\\nThat\u0027s why I converted the CIFS client socket to have a reference to\\nnetns (sk-\u003esk_net_refcnt == 1), which is somehow mentioned as out-of-scope\\nof CIFS and technically wrong in e9f2517a3e18, but **is in-scope and right\\nfix**.\\n\\nRegarding the LOCKDEP issue, we can prevent the module unload by\\nbumping the module refcount when switching the LOCKDDEP key in\\nsock_lock_init_class_and_name(). [2]\\n\\nFor a while, let\u0027s revert the bogus fix.\\n\\nNote that now we can use sk_net_refcnt_upgrade() for the socket\\nconversion, but I\u0027ll do so later separately to make backport easy.\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: smb: cliente: Corregir el desequilibrio en el recuento de referencias de netns que causa fugas y use-after-free. el commit ef7134c7fc48 (\\\"smb: cliente: Corregir el use-after-free del espacio de nombres de red\\\") intent\u00f3 corregir un problema de use-after-free de netns ajustando manualmente los recuentos de referencias mediante sk-\u0026gt;sk_net_refcnt y sock_inuse_add(). Sin embargo, una confirmaci\u00f3n posterior e9f2517a3e18 (\\\"smb: cliente: Corregir el bloqueo de los temporizadores TCP despu\u00e9s de rmmod\\\") indic\u00f3 que la configuraci\u00f3n manual de sk-\u0026gt;sk_net_refcnt en la primera confirmaci\u00f3n era t\u00e9cnicamente incorrecta, ya que sk-\u0026gt;sk_net_refcnt solo debe configurarse para sockets de usuario. Esto provoc\u00f3 problemas como que los temporizadores TCP no se borraran correctamente al cerrar. La segunda confirmaci\u00f3n se adapt\u00f3 a un modelo que simplemente almacena una referencia netns adicional para server-\u0026gt;ssocket mediante get_net() y la elimina al desmantelar el servidor. Sin embargo, persisten algunas deficiencias en el equilibrio entre get_net() y put_net(), a\u00f1adidas por estas confirmaciones. El manejo incompleto de las referencias en estas correcciones genera dos problemas: 1. Fugas de recuento de referencias de netns[1]. El proceso del problema es el siguiente: ``` mount.cifs cifsd cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* Primero, obtener net. */ ip_connect generic_ip_connect /* Intentar el puerto 445 */ get_net() -\u0026gt;connect() /* Error */ put_net() generic_ip_connect /* Intentar el puerto 139 */ get_net() /* Falta put_net() coincidente para este get_net().*/ cifs_get_smb_ses cifs_negotiate_protocol smb2_negotiate SMB2_negotiate cifs_send_recv wait_for_response cifs_demultiplex_thread cifs_read_from_socket cifs_readv_from_socket cifs_reconnect cifs_abort_connection sock_release(); server-\u0026gt;ssocket = NULL; /* Falta put_net() aqu\u00ed. */ generic_ip_connect get_net() -\u0026gt;connect() /* Error */ put_net() sock_release(); server-\u0026gt;ssocket = NULL; free_rsp_buf ... clean_demultiplex_info /* Solo se llama una vez aqu\u00ed. */ put_net() ``` Cuando se activa cifs_reconnect(), el servidor-\u0026gt;ssocket se libera sin un put_net() correspondiente para la referencia obtenida previamente en generic_ip_connect(). Termina llamando a generic_ip_connect() de nuevo para reintentar get_net(). Despu\u00e9s, el servidor-\u0026gt;ssocket se establece en NULL en la ruta de error de generic_ip_connect(), y el recuento neto no se puede liberar en la funci\u00f3n clean_demultiplex_info() final. 2. Posible use-after-free. El esquema actual de recuento de referencias puede generar un posible problema de use-after-free en el siguiente escenario: ``` cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* First get net */ ip_connect generic_ip_connect get_net() bind_socket kernel_bind /* failed */ put_net() /* after out_err_crypto_release label */ put_net() /* after out_err label */ put_net() ``` En el proceso de gesti\u00f3n de excepciones donde falla la vinculaci\u00f3n del socket, las llamadas get_net() y put_net() est\u00e1n desequilibradas, lo que puede provocar que el recuento de referencias server-\u0026gt;net baje a cero y se libere prematuramente. Para solucionar ambos problemas, este parche vincula el recuento de referencias netns ---truncated---\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/4b6f6bf1bde8d6045c389fda8d21c304dfe49384\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/8dbf060480236877703bff0106fc984576184d11\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/95d2b9f693ff2a1180a23d7d59acc0c4e72f4c41\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/f761eeefd531e6550cd3a5c047835b4892acb00d\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}" } }
Loading…
Loading…
Sightings
Author | Source | Type | Date |
---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.
Loading…
Loading…