---
id: CVE-2026-98694
title: 'thunderbolt: Fix KASAN reported use-after-free when request is canceled'
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  thunderbolt: Fix KASAN reported use-after-free when request is canceled

  Alan reported that when doing stress testing sometimes KASAN notices
  use-after-free during cont…
severity: none
vendor: Linux
product: Linux
affected:
  - >-
    Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 <
    71b3c517e02af2c46ad58d4b3706b7c3cb24936d
  - >-
    Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 <
    f18faa3d3b810d60a3005ae1b1d1866faa67d343
  - >-
    Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 <
    08287212b622039212c972806f896f078dfd28e2
  - >-
    Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 <
    a02188ddc24b7872f0c5e0c5873f827318717803
  - Linux 4.13
published: '2026-10-18'
updated: '2026-10-18'
sourceUpdated: '2026-10-18T15:46:18.654Z'
source: CVEORG
sourceUrl: 'https://www.cve.org/CVERecord?id=CVE-2026-98694'
references:
  - url: 'https://git.kernel.org/stable/c/71b3c517e02af2c46ad58d4b3706b7c3cb24936d'
  - url: 'https://git.kernel.org/stable/c/f18faa3d3b810d60a3005ae1b1d1866faa67d343'
  - url: 'https://git.kernel.org/stable/c/08287212b622039212c972806f896f078dfd28e2'
  - url: 'https://git.kernel.org/stable/c/a02188ddc24b7872f0c5e0c5873f827318717803'
tags:
  - cve.org
ingestedAt: '2026-10-18T16:47:32.518Z'
---

## Overview

In the Linux kernel, the following vulnerability has been resolved:

thunderbolt: Fix KASAN reported use-after-free when request is canceled

Alan reported that when doing stress testing sometimes KASAN notices
use-after-free during control channel operation (stripped down keeping
the relevant parts):

 BUG: KASAN: slab-use-after-free in tb_cfg_request_sync+0x240/0x250 [thunderbolt]
 Read of size 24 at addr ffff88811067f290 by task kworker/u40:2/1760
  <TASK>
  tb_cfg_request_sync+0x240/0x250 [thunderbolt]
  tb_cfg_read_raw+0x367/0x510 [thunderbolt]
  tb_cfg_read+0xec/0x240 [thunderbolt]
  tb_port_get_link_generation+0x258/0x420 [thunderbolt]
  tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
  tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
  tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
  tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
  tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
  process_one_work+0x675/0x1230
  worker_thread+0x5e6/0xf70
  kthread+0x365/0x470
  ret_from_fork+0x54d/0x710
  ret_from_fork_asm+0x1a/0x30
  </TASK>

 Allocated by task 1760:
  __kmalloc_cache_noprof+0x1ee/0x550
  tb_cfg_read_raw+0x1d3/0x510 [thunderbolt]
  tb_cfg_read+0xec/0x240 [thunderbolt]
  tb_port_get_link_generation+0x258/0x420 [thunderbolt]
  tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
  tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
  tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
  tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
  tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
  process_one_work+0x675/0x1230
  worker_thread+0x5e6/0xf70
  kthread+0x365/0x470
  ret_from_fork+0x54d/0x710
  ret_from_fork_asm+0x1a/0x30

 Freed by task 926:
  kfree+0x18f/0x4a0
  tb_cfg_request_put+0xb7/0xe0 [thunderbolt]
  tb_cfg_request_work+0x82/0x120 [thunderbolt]
  process_one_work+0x675/0x1230
  worker_thread+0x5e6/0xf70
  kthread+0x365/0x470
  ret_from_fork+0x54d/0x710
  ret_from_fork_asm+0x1a/0x30

 Second to last potentially related work creation:
  __queue_work+0x575/0xd00
  queue_work_on+0x77/0x80
  tb_cfg_request_cancel+0xc7/0x260 [thunderbolt]
  tb_cfg_request_sync+0x1f6/0x250 [thunderbolt]
  tb_cfg_read_raw+0x367/0x510 [thunderbolt]
  tb_cfg_read+0xec/0x240 [thunderbolt]
  tb_port_get_link_generation+0x258/0x420 [thunderbolt]
  tb_usb3_consumed_bandwidth+0x1c1/0x2c0 [thunderbolt]
  tb_tunnel_consumed_bandwidth+0xfd/0x910 [thunderbolt]
  tb_available_bandwidth+0x5f2/0xeb0 [thunderbolt]
  tb_recalc_estimated_bandwidth+0x2a0/0x1bc0 [thunderbolt]
  tb_handle_dp_bandwidth_request+0x1897/0x5e20 [thunderbolt]
  process_one_work+0x675/0x1230
  worker_thread+0x5e6/0xf70
  kthread+0x365/0x470
  ret_from_fork+0x54d/0x710
  ret_from_fork_asm+0x1a/0x30

The last stack trace is helpful because it shows that we are cancelling
a request and looking at tb_cfg_request_cancel() what might happen is
that tb_cfg_request_work() completes right before tb_cfg_request_cancel()
starts and because of this it will call schedule_work() queueing the
same work to run again. However, it is already removed from the
request_queue and reference count is dropped so when
tb_cfg_request_work() triggers again it will access memory that is
already released.

Fix this so that we first make sure a cancelled request is not handed
away from tb_cfg_request_find() or scheduled to run. Then instead of
relying on the worker to clean up the request we will do it in
tb_cfg_request_cancel() after the work is canceled from running. Make
tb_cfg_request_dequeue() release the request only if it was actually
removed from the queue.

## Affected

- `Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 < 71b3c517e02af2c46ad58d4b3706b7c3cb24936d`
- `Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 < f18faa3d3b810d60a3005ae1b1d1866faa67d343`
- `Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 < 08287212b622039212c972806f896f078dfd28e2`
- `Linux >= d7f781bfdbf4eb7c5706c9974b8bf6d3c82e69c1 < a02188ddc24b7872f0c5e0c5873f827318717803`
- `Linux 4.13`

## Remediation

Refer to the linked advisories for vendor-supplied fixes and affected version ranges.
