dm thin: make get_first_thin use rcu-safe list first function
The documentation in rculist.h explains the absence of list_empty_rcu()
and cautions programmers against relying on a list_empty() ->
list_first() sequence in RCU safe code. This is because each of these
functions performs its own READ_ONCE() of the list head. This can lead
to a situation where the list_empty() sees a valid list entry, but the
subsequent list_first() sees a different view of list head state after a
modification.
In the case of dm-thin, this author had a production box crash from a GP
fault in the process_deferred_bios path. This function saw a valid list
head in get_first_thin() but when it subsequently dereferenced that and
turned it into a thin_c, it got the inside of the struct pool, since the
list was now empty and referring to itself. The kernel on which this
occurred printed both a warning about a refcount_t being saturated, and
a UBSAN error for an out-of-bounds cpuid access in the queued spinlock,
prior to the fault itself. When the resulting kdump was examined, it
was possible to see another thread patiently waiting in thin_dtr's
synchronize_rcu.
The thin_dtr call managed to pull the thin_c out of the active thins
list (and have it be the last entry in the active_thins list) at just
the wrong moment which lead to this crash.
Fortunately, the fix here is straight forward. Switch get_first_thin()
function to use list_first_or_null_rcu() which performs just a single
READ_ONCE() and returns NULL if the list is already empty.
This was run against the devicemapper test suite's thin-provisioning
suites for delete and suspend and no regressions were observed.
Metrics
Affected Vendors & Products
| Source | ID | Title | 
|---|---|---|
  Debian DLA | 
                DLA-4075-1 | linux security update | 
  Debian DLA | 
                DLA-4076-1 | linux-6.1 security update | 
  EUVD | 
                EUVD-2025-2613 | In the Linux kernel, the following vulnerability has been resolved: dm thin: make get_first_thin use rcu-safe list first function The documentation in rculist.h explains the absence of list_empty_rcu() and cautions programmers against relying on a list_empty() -> list_first() sequence in RCU safe code. This is because each of these functions performs its own READ_ONCE() of the list head. This can lead to a situation where the list_empty() sees a valid list entry, but the subsequent list_first() sees a different view of list head state after a modification. In the case of dm-thin, this author had a production box crash from a GP fault in the process_deferred_bios path. This function saw a valid list head in get_first_thin() but when it subsequently dereferenced that and turned it into a thin_c, it got the inside of the struct pool, since the list was now empty and referring to itself. The kernel on which this occurred printed both a warning about a refcount_t being saturated, and a UBSAN error for an out-of-bounds cpuid access in the queued spinlock, prior to the fault itself. When the resulting kdump was examined, it was possible to see another thread patiently waiting in thin_dtr's synchronize_rcu. The thin_dtr call managed to pull the thin_c out of the active thins list (and have it be the last entry in the active_thins list) at just the wrong moment which lead to this crash. Fortunately, the fix here is straight forward. Switch get_first_thin() function to use list_first_or_null_rcu() which performs just a single READ_ONCE() and returns NULL if the list is already empty. This was run against the devicemapper test suite's thin-provisioning suites for delete and suspend and no regressions were observed. | 
  Ubuntu USN | 
                USN-7379-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7379-2 | Linux kernel (Raspberry Pi) vulnerabilities | 
  Ubuntu USN | 
                USN-7380-1 | Linux kernel (Low Latency) vulnerabilities | 
  Ubuntu USN | 
                USN-7381-1 | Linux kernel (Low Latency) vulnerabilities | 
  Ubuntu USN | 
                USN-7382-1 | Linux kernel (OEM) vulnerabilities | 
  Ubuntu USN | 
                USN-7387-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7387-2 | Linux kernel (FIPS) vulnerabilities | 
  Ubuntu USN | 
                USN-7387-3 | Linux kernel (Real-time) vulnerabilities | 
  Ubuntu USN | 
                USN-7388-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7389-1 | Linux kernel (NVIDIA Tegra) vulnerabilities | 
  Ubuntu USN | 
                USN-7390-1 | Linux kernel (Xilinx ZynqMP) vulnerabilities | 
  Ubuntu USN | 
                USN-7391-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7392-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7392-2 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7392-3 | Linux kernel (AWS) vulnerabilities | 
  Ubuntu USN | 
                USN-7392-4 | Linux kernel (AWS FIPS) vulnerabilities | 
  Ubuntu USN | 
                USN-7393-1 | Linux kernel (FIPS) vulnerabilities | 
  Ubuntu USN | 
                USN-7401-1 | Linux kernel (AWS) vulnerabilities | 
  Ubuntu USN | 
                USN-7407-1 | Linux kernel (HWE) vulnerabilities | 
  Ubuntu USN | 
                USN-7413-1 | Linux kernel (IoT) vulnerabilities | 
  Ubuntu USN | 
                USN-7421-1 | Linux kernel (Azure) vulnerabilities | 
  Ubuntu USN | 
                USN-7458-1 | Linux kernel (IBM) vulnerabilities | 
  Ubuntu USN | 
                USN-7459-1 | Linux kernel (Intel IoTG) vulnerabilities | 
  Ubuntu USN | 
                USN-7459-2 | Linux kernel (GCP) vulnerabilities | 
  Ubuntu USN | 
                USN-7463-1 | Linux kernel (IBM) vulnerabilities | 
  Ubuntu USN | 
                USN-7513-1 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7513-2 | Linux kernel (Real-time) vulnerabilities | 
  Ubuntu USN | 
                USN-7513-3 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7513-4 | Linux kernel (HWE) vulnerabilities | 
  Ubuntu USN | 
                USN-7513-5 | Linux kernel (Oracle) vulnerabilities | 
  Ubuntu USN | 
                USN-7514-1 | Linux kernel (NVIDIA) vulnerabilities | 
  Ubuntu USN | 
                USN-7515-1 | Linux kernel (GKE) vulnerabilities | 
  Ubuntu USN | 
                USN-7515-2 | Linux kernel vulnerabilities | 
  Ubuntu USN | 
                USN-7522-1 | Linux kernel (Azure, N-Series) vulnerabilities | 
  Ubuntu USN | 
                USN-7523-1 | Linux kernel (Raspberry Pi Real-time) vulnerabilities | 
  Ubuntu USN | 
                USN-7524-1 | Linux kernel (Raspberry Pi) vulnerabilities | 
  Ubuntu USN | 
                USN-7539-1 | Linux kernel (Raspberry Pi) vulnerabilities | 
  Ubuntu USN | 
                USN-7540-1 | Linux kernel (Raspberry Pi) vulnerabilities | 
Solution
No solution given by the vendor.
Workaround
No workaround given by the vendor.
Mon, 03 Nov 2025 21:30:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| References | 
         | 
Fri, 26 Sep 2025 16:30:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| First Time appeared | 
        
        Linux
         Linux linux Kernel  | 
|
| Weaknesses | NVD-CWE-noinfo | |
| CPEs | cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:-:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:rc4:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:rc5:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:rc6:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:rc7:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:3.15:rc8:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc1:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc2:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc3:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc4:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc5:*:*:*:*:*:* cpe:2.3:o:linux:linux_kernel:6.13:rc6:*:*:*:*:*:*  | 
|
| Vendors & Products | 
        
        Linux
         Linux linux Kernel  | 
|
| Metrics | 
        
        
        cvssV3_1
         
  | 
    
        
        
        cvssV3_1
         
  | 
Fri, 14 Mar 2025 03:00:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| Weaknesses | CWE-20 | |
| Metrics | 
        
        
        cvssV3_1
         
  | 
    
        
        
        cvssV3_1
         
  | 
Sun, 02 Feb 2025 10:30:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| References | 
         | 
Mon, 27 Jan 2025 14:30:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| References | 
         | |
| Metrics | 
        
        
        threat_severity
         
  | 
    
        
        cvssV3_1
         
 
  | 
Thu, 23 Jan 2025 17:15:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| References | 
         | 
Tue, 21 Jan 2025 12:30:00 +0000
| Type | Values Removed | Values Added | 
|---|---|---|
| Description | In the Linux kernel, the following vulnerability has been resolved: dm thin: make get_first_thin use rcu-safe list first function The documentation in rculist.h explains the absence of list_empty_rcu() and cautions programmers against relying on a list_empty() -> list_first() sequence in RCU safe code. This is because each of these functions performs its own READ_ONCE() of the list head. This can lead to a situation where the list_empty() sees a valid list entry, but the subsequent list_first() sees a different view of list head state after a modification. In the case of dm-thin, this author had a production box crash from a GP fault in the process_deferred_bios path. This function saw a valid list head in get_first_thin() but when it subsequently dereferenced that and turned it into a thin_c, it got the inside of the struct pool, since the list was now empty and referring to itself. The kernel on which this occurred printed both a warning about a refcount_t being saturated, and a UBSAN error for an out-of-bounds cpuid access in the queued spinlock, prior to the fault itself. When the resulting kdump was examined, it was possible to see another thread patiently waiting in thin_dtr's synchronize_rcu. The thin_dtr call managed to pull the thin_c out of the active thins list (and have it be the last entry in the active_thins list) at just the wrong moment which lead to this crash. Fortunately, the fix here is straight forward. Switch get_first_thin() function to use list_first_or_null_rcu() which performs just a single READ_ONCE() and returns NULL if the list is already empty. This was run against the devicemapper test suite's thin-provisioning suites for delete and suspend and no regressions were observed. | |
| Title | dm thin: make get_first_thin use rcu-safe list first function | |
| References | 
         | 
Status: PUBLISHED
Assigner: Linux
Published:
Updated: 2025-11-03T20:58:40.356Z
Reserved: 2024-12-29T08:45:45.732Z
Link: CVE-2025-21664
No data.
Status : Modified
Published: 2025-01-21T13:15:10.053
Modified: 2025-11-03T21:19:03.373
Link: CVE-2025-21664
                        OpenCVE Enrichment
                    No data.
 Debian DLA
 EUVD
 Ubuntu USN