← Back to CVE Explorer

CVE-2025-40002

Full vulnerability record from the local CVENow database.

Description

In the Linux kernel, the following vulnerability has been resolved: thunderbolt: Fix use-after-free in tb_dp_dprx_work The original code relies on cancel_delayed_work() in tb_dp_dprx_stop(), which does not ensure that the delayed work item tunnel->dprx_work has fully completed if it was already running. This leads to use-after-free scenarios where tb_tunnel is deallocated by tb_tunnel_put(), while tunnel->dprx_work remains active and attempts to dereference tb_tunnel in tb_dp_dprx_work(). A typical race condition is illustrated below: CPU 0 | CPU 1 tb_dp_tunnel_active() | tb_deactivate_and_free_tunnel()| tb_dp_dprx_start() tb_tunnel_deactivate() | queue_delayed_work() tb_dp_activate() | tb_dp_dprx_stop() | tb_dp_dprx_work() //delayed worker cancel_delayed_work() | tb_tunnel_put(tunnel); | | tunnel = container_of(...); //UAF | tunnel-> //UAF Replacing cancel_delayed_work() with cancel_delayed_work_sync() is not feasible as it would introduce a deadlock: both tb_dp_dprx_work() and the cleanup path acquire tb->lock, and cancel_delayed_work_sync() would wait indefinitely for the work item that cannot proceed. Instead, implement proper reference counting: - If cancel_delayed_work() returns true (work is pending), we release the reference in the stop function. - If it returns false (work is executing or already completed), the reference is released in delayed work function itself. This ensures the tb_tunnel remains valid during work item execution while preventing memory leaks. This bug was found by static analysis.

Severity
Not scored
CVSS score
Not available
Vulnerability status
Deferred
Source identifier
416baaa9-dc9f-4396-8d5f-8c081fb06d67
Published
2025-10-18 08:15:34.243000
Last modified
2026-10-19 21:10:00.160000
View original CVE JSON
{
  "id": "CVE-2025-40002",
  "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
  "published": "2025-10-18T08:15:34.243",
  "lastModified": "2026-10-19T21:10:00.160",
  "vulnStatus": "Deferred",
  "cveTags": [],
  "descriptions": [
    {
      "lang": "en",
      "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nthunderbolt: Fix use-after-free in tb_dp_dprx_work\n\nThe original code relies on cancel_delayed_work() in tb_dp_dprx_stop(),\nwhich does not ensure that the delayed work item tunnel->dprx_work has\nfully completed if it was already running. This leads to use-after-free\nscenarios where tb_tunnel is deallocated by tb_tunnel_put(), while\ntunnel->dprx_work remains active and attempts to dereference tb_tunnel\nin tb_dp_dprx_work().\n\nA typical race condition is illustrated below:\n\nCPU 0                            | CPU 1\ntb_dp_tunnel_active()            |\n  tb_deactivate_and_free_tunnel()| tb_dp_dprx_start()\n    tb_tunnel_deactivate()       |   queue_delayed_work()\n      tb_dp_activate()           |\n        tb_dp_dprx_stop()        | tb_dp_dprx_work() //delayed worker\n          cancel_delayed_work()  |\n    tb_tunnel_put(tunnel);       |\n                                 |   tunnel = container_of(...); //UAF\n                                 |   tunnel-> //UAF\n\nReplacing cancel_delayed_work() with cancel_delayed_work_sync() is\nnot feasible as it would introduce a deadlock: both tb_dp_dprx_work()\nand the cleanup path acquire tb->lock, and cancel_delayed_work_sync()\nwould wait indefinitely for the work item that cannot proceed.\n\nInstead, implement proper reference counting:\n- If cancel_delayed_work() returns true (work is pending), we release\n  the reference in the stop function.\n- If it returns false (work is executing or already completed), the\n  reference is released in delayed work function itself.\n\nThis ensures the tb_tunnel remains valid during work item execution\nwhile preventing memory leaks.\n\nThis bug was found by static analysis."
    },
    {
      "lang": "es",
      "value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\nthunderbolt: Soluciona uso después de liberación en tb_dp_dprx_work\n\nEl código original se basa en cancel_delayed_work() en tb_dp_dprx_stop(), lo que no asegura que el elemento de trabajo retrasado tunnel->dprx_work haya completado completamente si ya estaba en ejecución. Esto lleva a escenarios de uso después de liberación donde tb_tunnel es desasignado por tb_tunnel_put(), mientras que tunnel->dprx_work permanece activo e intenta desreferenciar tb_tunnel en tb_dp_dprx_work().\n\nUna condición de carrera típica se ilustra a continuación:\n\nCPU 0                            | CPU 1\ntb_dp_tunnel_active()            |\n  tb_deactivate_and_free_tunnel()| tb_dp_dprx_start()\n    tb_tunnel_deactivate()       |   queue_delayed_work()\n      tb_dp_activate()           |\n        tb_dp_dprx_stop()        | tb_dp_dprx_work() //trabajador retrasado\n          cancel_delayed_work()  |\n    tb_tunnel_put(tunnel);       |\n                                 |   tunnel = container_of(...); //UAF\n                                 |   tunnel-> //UAF\n\nReemplazar cancel_delayed_work() con cancel_delayed_work_sync() no es factible ya que introduciría un interbloqueo: tanto tb_dp_dprx_work() como la ruta de limpieza adquieren tb->lock, y cancel_delayed_work_sync() esperaría indefinidamente por el elemento de trabajo que no puede continuar.\n\nEn su lugar, implementa un conteo de referencias adecuado:\n- Si cancel_delayed_work() devuelve verdadero (el trabajo está pendiente), liberamos la referencia en la función de parada.\n- Si devuelve falso (el trabajo se está ejecutando o ya ha completado), la referencia se libera en la propia función de trabajo retrasado.\n\nEsto asegura que el tb_tunnel permanezca válido durante la ejecución del elemento de trabajo mientras previene fugas de memoria.\n\nEste error fue encontrado mediante análisis estático."
    }
  ],
  "affected": [
    {
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
      "affectedData": [
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "unaffected",
          "programFiles": [
            "drivers/thunderbolt/tunnel.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "versions": [
            {
              "version": "d6d458d42e1e1544a18f37f1d5c840e00d5261b9",
              "lessThan": "c07923f6a8729fc27ee652221a51702ff6654097",
              "versionType": "git",
              "status": "affected"
            },
            {
              "version": "d6d458d42e1e1544a18f37f1d5c840e00d5261b9",
              "lessThan": "67600ccfc4f38ebd331b9332ac94717bfbc87ea7",
              "versionType": "git",
              "status": "affected"
            }
          ]
        },
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "affected",
          "programFiles": [
            "drivers/thunderbolt/tunnel.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "versions": [
            {
              "version": "6.14",
              "status": "affected"
            },
            {
              "version": "0",
              "lessThan": "6.14",
              "versionType": "semver",
              "status": "unaffected"
            },
            {
              "version": "6.17.3",
              "lessThanOrEqual": "6.17.*",
              "versionType": "semver",
              "status": "unaffected"
            },
            {
              "version": "6.18",
              "lessThanOrEqual": "*",
              "versionType": "original_commit_for_fix",
              "status": "unaffected"
            }
          ]
        }
      ]
    }
  ],
  "metrics": {},
  "references": [
    {
      "url": "https://git.kernel.org/stable/c/67600ccfc4f38ebd331b9332ac94717bfbc87ea7",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/c07923f6a8729fc27ee652221a51702ff6654097",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    }
  ]
}