deardaniel/secdata-raw huggingface dataset:
CVE: CVE-2025-39936
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

crypto: ccp - Always pass in an error pointer to __sev_platform_shutdown_locked()

When

  9770b428b1a2 ("crypto: ccp - Move dev_info/err messages for SEV/SNP init and shutdown")

moved the error messages dumping so that they don't need to be issued by
the callers, it missed the case where __sev_firmware_shutdown() calls
__sev_platform_shutdown_locked() with a NULL argument which leads to
a NULL ptr deref on the shutdown path, during suspend to disk:

  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: Oops: 0000 [#1] SMP NOPTI
  CPU: 0 UID: 0 PID: 983 Comm: hib.sh Not tainted 6.17.0-rc4+ #1 PREEMPT(voluntary)
  Hardware name: Supermicro Super Server/H12SSL-i, BIOS 2.5 09/08/2022
  RIP: 0010:__sev_platform_shutdown_locked.cold+0x0/0x21 [ccp]

That rIP is:

 [PII_REDACTED]0006fd <__sev_platform_shutdown_locked.cold>:
   6fd:   8b 13                   mov    (%rbx),%edx
   6ff:   48 8b 7d 00             mov    0x0(%rbp),%rdi
   703:   89 c1                   mov    %eax,%ecx

  Code: 74 05 31 ff 41 89 3f 49 8b 3e 89 ea 48 c7 c6 a0 8e 54 a0 41 bf 92 ff ff ff e8 e5 2e 09 e1 c6 05 2a d4 38 00 01 e9 26 af ff ff <8b> 13 48 8b 7d 00 89 c1 48 c7 c6 18 90 54 a0 89 44 24 04 e8 c1 2e
  RSP: 0018:ffffc90005467d00 EFLAGS: 00010282
  RAX: 00000000ffffff92 RBX: [PII_REDACTED] RCX: [PII_REDACTED]
  			     ^^^^^^^^^^^^^^^^
and %rbx is nice and clean.

  Call Trace:
   <TASK>
   __sev_firmware_shutdown.isra.0
   sev_dev_destroy
   psp_dev_destroy
   sp_destroy
   pci_device_shutdown
   device_shutdown
   kernel_power_off
   hibernate.cold
   state_store
   kernfs_fop_write_iter
   vfs_write
   ksys_write
   do_syscall_64
   entry_SYSCALL_64_after_hwframe

Pass in a pointer to the function-local error var in the caller.

With that addressed, suspending the ccp shows the error properly at
least:

  ccp 0000:47:00.1: sev command 0x2 timed out, disabling PSP
  ccp 0000:47:00.1: SEV: failed to SHUTDOWN error 0x0, rc -110
  SEV-SNP: Leaking PFN range 0x146800-0x146a00
  SEV-SNP: PFN 0x146800 unassigned, dumping non-zero entries in 2M PFN region: [0x146800 - 0x146a00]
  ...
  ccp 0000:47:00.1: SEV-SNP firmware shutdown failed, rc -16, error 0x0
  ACPI: PM: Preparing to enter system sleep state S5
  kvm: exiting hardware virtualization
  reboot: Power down

Btw, this driver is crying to be cleaned up to pass in a proper I/O
struct which can be used to store information between the different
functions, otherwise stuff like that will happen in the future again.
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/46834d90a9a13549264b9581067d8f746b4b36cc; https://git.kernel.org/stable/c/bc509293c9d4f4f74e776f4a0bbb61f63c041938
CVE: CVE-2025-39937
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

net: rfkill: gpio: Fix crash due to dereferencering uninitialized pointer

Since commit 7d5e9737efda ("net: rfkill: gpio: get the name and type from
device property") rfkill_find_type() gets called with the possibly
uninitialized "const char *type_name;" local variable.

On x86 systems when rfkill-gpio binds to a "BCM4752" or "LNV4752"
acpi_device, the rfkill->type is set based on the ACPI acpi_device_id:

        rfkill->type = (unsigned)id->driver_data;

and there is no "type" property so device_property_read_string() will fail
and leave type_name uninitialized, leading to a potential crash.

rfkill_find_type() does accept a NULL pointer, fix the potential crash
by initializing type_name to NULL.

Note likely sofar this has not been caught because:

1. Not many x86 machines actually have a "BCM4752"/"LNV4752" acpi_device
2. The stack happened to contain NULL where type_name is stored
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/184f608a68f96794e8fe58cd5535014d53622cde; https://git.kernel.org/stable/c/21a39b958b4bcf44f7674bfbbe1bbb8cad0d842d; https://git.kernel.org/stable/c/21ba85d9d508422ca9e6698463ff9357c928c22d
CVE: CVE-2025-39938
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

ASoC: qcom: q6apm-lpass-dais: Fix NULL pointer dereference if source graph failed

If earlier opening of source graph fails (e.g. ADSP rejects due to
incorrect audioreach topology), the graph is closed and
"dai_data->graph[dai->id]" is assigned NULL.  Preparing the DAI for sink
graph continues though and next call to q6apm_lpass_dai_prepare()
receives dai_data->graph[dai->id]=NULL leading to NULL pointer
exception:

  qcom-apm gprsvc:service:2:1: Error (1) Processing 0x01001002 cmd
  qcom-apm gprsvc:service:2:1: DSP returned error[1001002] 1
  q6apm-lpass-dais 30000000.remoteproc:glink-edge:gpr:service@1:bedais: fail to start APM port 78
  q6apm-lpass-dais 30000000.remoteproc:glink-edge:gpr:service@1:bedais: ASoC: error at snd_soc_pcm_dai_prepare on TX_CODEC_DMA_TX_3: -22
  Unable to handle kernel NULL pointer dereference at virtual address[PII_REDACTED]0000a8
  ...
  Call trace:
   q6apm_graph_media_format_pcm+0x48/0x120 (P)
   q6apm_lpass_dai_prepare+0x110/0x1b4
   snd_soc_pcm_dai_prepare+0x74/0x108
   __soc_pcm_prepare+0x44/0x160
   dpcm_be_dai_prepare+0x124/0x1c0
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/01d1ba106c9e02a2e7d41e07be49031a0ff0ecaa; https://git.kernel.org/stable/c/411f7d4f7038200cdf6d4f71ee31026ebf2dfedb; https://git.kernel.org/stable/c/68f27f7c7708183e7873c585ded2f1b057ac5b97
CVE: CVE-2025-39939
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

iommu/s390: Fix memory corruption when using identity domain

zpci_get_iommu_ctrs() returns counter information to be reported as part
of device statistics; these counters are stored as part of the s390_domain.
The problem, however, is that the identity domain is not backed by an
s390_domain and so the conversion via to_s390_domain() yields a bad address
that is zero'd initially and read on-demand later via a sysfs read.
These counters aren't necessary for the identity domain; just return NULL
in this case.

This issue was discovered via KASAN with reports that look like:
BUG: KASAN: global-out-of-bounds in zpci_fmb_enable_device
when using the identity domain for a device on s390.
CVSS Score: 7.8 (HIGH)
CWE: CWE-787
References: https://git.kernel.org/stable/c/17a58caf3863163c4a84a218a9649be2c8061443; https://git.kernel.org/stable/c/b3506e9bcc777ed6af2ab631c86a9990ed97b474
CVE: CVE-2025-39940
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

dm-stripe: fix a possible integer overflow

There's a possible integer overflow in stripe_io_hints if we have too
large chunk size. Test if the overflow happened, and if it did, don't set
limits->io_min and limits->io_opt;
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-190
References: https://git.kernel.org/stable/c/1071d560afb4c245c[PII_REDACTED]df47db5a35708; https://git.kernel.org/stable/c/ee27658c239b27721397f3e4eb16370b5cce596e; https://git.kernel.org/stable/c/f8f64254bca5ae58f3b679441962bda4c409f659
CVE: CVE-2025-39941
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

zram: fix slot write race condition

Parallel concurrent writes to the same zram index result in leaked
zsmalloc handles.  Schematically we can have something like this:

CPU0                              CPU1
zram_slot_lock()
zs_free(handle)
zram_slot_lock()
				zram_slot_lock()
				zs_free(handle)
				zram_slot_lock()

compress			compress
handle = zs_malloc()		handle = zs_malloc()
zram_slot_lock
zram_set_handle(handle)
zram_slot_lock
				zram_slot_lock
				zram_set_handle(handle)
				zram_slot_lock

Either CPU0 or CPU1 zsmalloc handle will leak because zs_free() is done
too early.  In fact, we need to reset zram entry right before we set its
new handle, all under the same slot lock scope.
CVSS Score: 4.7 (MEDIUM)
CWE: CWE-362
References: https://git.kernel.org/stable/c/ce4be9e4307c5a60701ff6e0cafa74caffdc54ce; https://git.kernel.org/stable/c/ff750e9f2c4d63854c33967d1646b5e89a9a19a2
CVE: CVE-2025-39942
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

ksmbd: smbdirect: verify remaining_data_length respects max_fragmented_recv_size

This is inspired by the check for data_offset + data_length.
CVSS Score: 5.5 (MEDIUM)
References: https://git.kernel.org/stable/c/196a3a7676d726ee67621ea2bf3b7815ac2685b4; https://git.kernel.org/stable/c/[PII_REDACTED]c7287e65a7b26e35aa6d2ce3345bcc; https://git.kernel.org/stable/c/c64b915bb3d9339adcae5db4be2c35ffbef5e615
CVE: CVE-2025-39943
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

ksmbd: smbdirect: validate data_offset and data_length field of smb_direct_data_transfer

If data_offset and data_length of smb_direct_data_transfer struct are
invalid, out of bounds issue could happen.
This patch validate data_offset and data_length field in recv_done.
CVSS Score: 7.1 (HIGH)
CWE: CWE-125
References: https://git.kernel.org/stable/c/5282491fc49d5614ac6ddcd012e5743eecb6a67c; https://git.kernel.org/stable/c/529b121b00a6ee3c88fb3c01b443b2b81f686d48; https://git.kernel.org/stable/c/773fddf976d282ef059c36c575ddb81567acd6bc
CVE: CVE-2025-39945
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

cnic: Fix use-after-free bugs in cnic_delete_task

The original code uses cancel_delayed_work() in cnic_cm_stop_bnx2x_hw(),
which does not guarantee that the delayed work item 'delete_task' has
fully completed if it was already running. Additionally, the delayed work
item is cyclic, the flush_workqueue() in cnic_cm_stop_bnx2x_hw() only
blocks and waits for work items that were already queued to the
workqueue prior to its invocation. Any work items submitted after
flush_workqueue() is called are not included in the set of tasks that the
flush operation awaits. This means that after the cyclic work items have
finished executing, a delayed work item may still exist in the workqueue.
This leads to use-after-free scenarios where the cnic_dev is deallocated
by cnic_free_dev(), while delete_task remains active and attempt to
dereference cnic_dev in cnic_delete_task().

A typical race condition is illustrated below:

CPU 0 (cleanup)              | CPU 1 (delayed work callback)
cnic_netdev_event()          |
  cnic_stop_hw()             | cnic_delete_task()
    cnic_cm_stop_bnx2x_hw()  | ...
      cancel_delayed_work()  | /* the queue_delayed_work()
      flush_workqueue()      |    executes after flush_workqueue()*/
                             | queue_delayed_work()
  cnic_free_dev(dev)//free   | cnic_delete_task() //new instance
                             |   dev = cp->dev; //use

Replace cancel_delayed_work() with cancel_delayed_work_sync() to ensure
that the cyclic delayed work item is properly canceled and that any
ongoing execution of the work item completes before the cnic_dev is
deallocated. Furthermore, since cancel_delayed_work_sync() uses
__flush_work(work, true) to synchronously wait for any currently
executing instance of the work item to finish, the flush_workqueue()
becomes redundant and should be removed.

This bug was identified through static analysis. To reproduce the issue
and validate the fix, I simulated the cnic PCI device in QEMU and
introduced intentional delays — such as inserting calls to ssleep()
within the cnic_delete_task() function — to increase the likelihood
of triggering the bug.
CVSS Score: 7.8 (HIGH)
CWE: CWE-416
References: https://git.kernel.org/stable/c/[PII_REDACTED]264ea8fd26f4131466fa7652e5e47d; https://git.kernel.org/stable/c/0627e[PII_REDACTED]cae2df0d85b5ff13e7d24c390; https://git.kernel.org/stable/c/6e33a7eed587062ca8161ad1f4584882a860d697
CVE: CVE-2025-39946
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

tls: make sure to abort the stream if headers are bogus

Normally we wait for the socket to buffer up the whole record
before we service it. If the socket has a tiny buffer, however,
we read out the data sooner, to prevent connection stalls.
Make sure that we abort the connection when we find out late
that the record is actually invalid. Retrying the parsing is
fine in itself but since we copy some more data each time
before we parse we can overflow the allocated skb space.

Constructing a scenario in which we're under pressure without
enough data in the socket to parse the length upfront is quite
hard. syzbot figured out a way to do this by serving us the header
in small OOB sends, and then filling in the recvbuf with a large
normal send.

Make sure that tls_rx_msg_size() aborts strp, if we reach
an invalid record there's really no way to recover.
CVSS Score: 9.8 (CRITICAL)
References: https://git.kernel.org/stable/c/0aeb54ac4cd5cf8f60131b4d9ec0b6dc9c27b20d; https://git.kernel.org/stable/c/208640e6225cc929a05adbf79d1df558add3e231; https://git.kernel.org/stable/c/4cefe5be73886f383639fe0850bb72d5b568a7b9
CVE: CVE-2025-39947
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

net/mlx5e: Harden uplink netdev access against device unbind

The function mlx5_uplink_netdev_get() gets the uplink netdevice
pointer from mdev->mlx5e_res.uplink_netdev. However, the netdevice can
be removed and its pointer cleared when unbound from the mlx5_core.eth
driver. This results in a NULL pointer, causing a kernel panic.

 BUG: unable to handle page fault for address: [PII_REDACTED]
 at RIP: 0010:mlx5e_vport_rep_load+0x22a/0x270 [mlx5_core]
 Call Trace:
  <TASK>
  mlx5_esw_offloads_rep_load+0x68/0xe0 [mlx5_core]
  esw_offloads_enable+0x593/0x910 [mlx5_core]
  mlx5_eswitch_enable_locked+0x341/0x420 [mlx5_core]
  mlx5_devlink_eswitch_mode_set+0x17e/0x3a0 [mlx5_core]
  devlink_nl_eswitch_set_doit+0x60/0xd0
  genl_family_rcv_msg_doit+0xe0/0x130
  genl_rcv_msg+0x183/0x290
  netlink_rcv_skb+0x4b/0xf0
  genl_rcv+0x24/0x40
  netlink_unicast+0x255/0x380
  netlink_sendmsg+0x1f3/0x420
  __sock_sendmsg+0x38/0x60
  __sys_sendto+0x119/0x180
  do_syscall_64+0x53/0x1d0
  entry_SYSCALL_64_after_hwframe+0x4b/0x53

Ensure the pointer is valid before use by checking it for NULL. If it
is valid, immediately call netdev_hold() to take a reference, and
preventing the netdevice from being freed while it is in use.
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/2cb17c88edd3a1c7aa6bc880dcdb35a6866fcb2e; https://git.kernel.org/stable/c/6b4be64fd9fec16418f365c2d8e47a7566e9eba5; https://git.kernel.org/stable/c/8df354eb2dd63d111ed5ae2e956e0dbb22bcf93b
CVE: CVE-2025-39949
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

qed: Don't collect too many protection override GRC elements

In the protection override dump path, the firmware can return far too
many GRC elements, resulting in attempting to write past the end of the
previously-kmalloc'ed dump buffer.

This will result in a kernel panic with reason:

 BUG: unable to handle kernel paging request at ADDRESS

where "ADDRESS" is just past the end of the protection override dump
buffer. The start address of the buffer is:
 p_hwfn->cdev->dbg_features[DBG_FEATURE_PROTECTION_OVERRIDE].dump_buf
and the size of the buffer is buf_size in the same data structure.

The panic can be arrived at from either the qede Ethernet driver path:

    [exception RIP: qed_grc_dump_addr_range+0x108]
 qed_protection_override_dump at ffffffffc02662ed [qed]
 qed_dbg_protection_override_dump at ffffffffc0267792 [qed]
 qed_dbg_feature at ffffffffc026aa8f [qed]
 qed_dbg_all_data at ffffffffc026b211 [qed]
 qed_fw_fatal_reporter_dump at ffffffffc027298a [qed]
 devlink_health_do_dump at ffffffff82497f61
 devlink_health_report at ffffffff8249cf29
 qed_report_fatal_error at ffffffffc0272baf [qed]
 qede_sp_task at ffffffffc045ed32 [qede]
 process_one_work at ffffffff81d19783

or the qedf storage driver path:

    [exception RIP: qed_grc_dump_addr_range+0x108]
 qed_protection_override_dump at ffffffffc068b2ed [qed]
 qed_dbg_protection_override_dump at ffffffffc068c792 [qed]
 qed_dbg_feature at ffffffffc068fa8f [qed]
 qed_dbg_all_data at ffffffffc0690211 [qed]
 qed_fw_fatal_reporter_dump at ffffffffc069798a [qed]
 devlink_health_do_dump at ffffffff8aa95e51
 devlink_health_report at ffffffff8aa9ae19
 qed_report_fatal_error at ffffffffc0697baf [qed]
 qed_hw_err_notify at ffffffffc06d32d7 [qed]
 qed_spq_post at ffffffffc06b1011 [qed]
 qed_fcoe_destroy_conn at ffffffffc06b2e91 [qed]
 qedf_cleanup_fcport at ffffffffc05e7597 [qedf]
 qedf_rport_event_handler at ffffffffc05e7bf7 [qedf]
 fc_rport_work at ffffffffc02da715 [libfc]
 process_one_work at ffffffff8a319663

Resolve this by clamping the firmware's return value to the maximum
number of legal elements the firmware should return.
CVSS Score: 5.5 (MEDIUM)
References: https://git.kernel.org/stable/c/25672c620421fa2105703a94a29a03487245e6d6; https://git.kernel.org/stable/c/56c0a2a9ddc2f5b5078c5fb0f81ab76bbc3d4c37; https://git.kernel.org/stable/c/660b2a8f5a306a28c7efc1b4990ecc4912a68f87
CVE: CVE-2025-39950
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

net/tcp: Fix a NULL pointer dereference when using TCP-AO with TCP_REPAIR

A NULL pointer dereference can occur in tcp_ao_finish_connect() during a
connect() system call on a socket with a TCP-AO key added and TCP_REPAIR
enabled.

The function is called with skb being NULL and attempts to dereference it
on tcp_hdr(skb)->seq without a prior skb validation.

Fix this by checking if skb is NULL before dereferencing it.

The commentary is taken from bpf_skops_established(), which is also called
in the same flow. Unlike the function being patched,
bpf_skops_established() validates the skb before dereferencing it.

int main(void){
	struct sockaddr_in sockaddr;
	struct tcp_ao_add tcp_ao;
	int sk;
	int one = 1;

	memset(&sockaddr,'\0',sizeof(sockaddr));
	memset(&tcp_ao,'\0',sizeof(tcp_ao));

	sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	sockaddr.sin_family = AF_INET;

	memcpy(tcp_ao.alg_name,"cmac(aes128)",12);
	memcpy(tcp_ao.key,"ABCDEFGHABCDEFGH",16);
	tcp_ao.keylen = 16;

	memcpy(&tcp_ao.addr,&sockaddr,sizeof(sockaddr));

	setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tcp_ao,
	sizeof(tcp_ao));
	setsockopt(sk, IPPROTO_TCP, TCP_REPAIR, &one, sizeof(one));

	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htobe16(123);

	inet_aton("127.0.0.1", &sockaddr.sin_addr);

	connect(sk,(struct sockaddr *)&sockaddr,sizeof(sockaddr));

return 0;
}

$ gcc tcp-ao-nullptr.c -o tcp-ao-nullptr -Wall
$ unshare -Urn

BUG: kernel NULL pointer dereference, address:[PII_REDACTED]0000b6
PGD 1f648d067 P4D 1f648d067 PUD 1982e8067 PMD 0
Oops: Oops: 0000 [#1] SMP NOPTI
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop
Reference Platform, BIOS 6.00 11/12/2020
RIP: 0010:tcp_ao_finish_connect (net/ipv4/tcp_ao.c:1182)
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/2e7bba08923ebc675b1f0e0e0959e68e53047838; https://git.kernel.org/stable/c/5f445eb259906b61a518487a790e11d07d31738c; https://git.kernel.org/stable/c/993b734d31ab804747ac961b1ee664b023c3b5fa
CVE: CVE-2025-39951
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

um: virtio_uml: Fix use-after-free after put_device in probe

When register_virtio_device() fails in virtio_uml_probe(),
the code sets vu_dev->registered = 1 even though
the device was not successfully registered.
This can lead to use-after-free or other issues.
CVSS Score: 7.8 (HIGH)
CWE: CWE-416
References: https://git.kernel.org/stable/c/00e98b5a69034b251bb36dc6e7123d7648e218e4; https://git.kernel.org/stable/c/14c231959a16ca41bfdcaede72483362a8c645d7; https://git.kernel.org/stable/c/4f364023ddcfe83f7073b973a9cb98584b7f2a46
CVE: CVE-2025-39952
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

wifi: wilc1000: avoid buffer overflow in WID string configuration

Fix the following copy overflow warning identified by Smatch checker.

 drivers/net/wireless/microchip/wilc1000/wlan_cfg.c:184 wilc_wlan_parse_response_frame()
        error: '__memcpy()' 'cfg->s[i]->str' copy overflow (512 vs 65537)

This patch introduces size check before accessing the memory buffer.
The checks are base on the WID type of received data from the firmware.
For WID string configuration, the size limit is determined by individual
element size in 'struct wilc_cfg_str_vals' that is maintained in 'len' field
of 'struct wilc_cfg_str'.
CVSS Score: 7.8 (HIGH)
CWE: CWE-787
References: https://git.kernel.org/stable/c/2203ef417044b10a8563ade6a17c74183745d72e; https://git.kernel.org/stable/c/6085291a1a5865d4ad70f0e5812d524ebd5d1711; https://git.kernel.org/stable/c/ae50f8562306a7ea1cf3c9722f97ee244f974729
CVE: CVE-2025-39953
Published: 2025-10-04
Description: In the Linux kernel, the following vulnerability has been resolved:

cgroup: split cgroup_destroy_wq into 3 workqueues

A hung task can occur during [1] LTP cgroup testing when repeatedly
mounting/unmounting perf_event and net_prio controllers with
systemd.unified_cgroup_hierarchy=1. The hang manifests in
cgroup_lock_and_drain_offline() during root destruction.

Related case:
cgroup_fj_function_perf_event cgroup_fj_function.sh perf_event
cgroup_fj_function_net_prio cgroup_fj_function.sh net_prio

Call Trace:
	cgroup_lock_and_drain_offline+0x14c/0x1e8
	cgroup_destroy_root+0x3c/0x2c0
	css_free_rwork_fn+0x248/0x338
	process_one_work+0x16c/0x3b8
	worker_thread+0x22c/0x3b0
	kthread+0xec/0x100
	ret_from_fork+0x10/0x20

Root Cause:

CPU0                            CPU1
mount perf_event                umount net_prio
cgroup1_get_tree                cgroup_kill_sb
rebind_subsystems               // root destruction enqueues
				// cgroup_destroy_wq
// kill all perf_event css
                                // one perf_event css A is dying
                                // css A offline enqueues cgroup_destroy_wq
                                // root destruction will be executed first
                                css_free_rwork_fn
                                cgroup_destroy_root
                                cgroup_lock_and_drain_offline
                                // some perf descendants are dying
                                // cgroup_destroy_wq max_active = 1
                                // waiting for css A to die

Problem scenario:
1. CPU0 mounts perf_event (rebind_subsystems)
2. CPU1 unmounts net_prio (cgroup_kill_sb), queuing root destruction work
3. A dying perf_event CSS gets queued for offline after root destruction
4. Root destruction waits for offline completion, but offline work is
   blocked behind root destruction in cgroup_destroy_wq (max_active=1)

Solution:
Split cgroup_destroy_wq into three dedicated workqueues:
cgroup_offline_wq – Handles CSS offline operations
cgroup_release_wq – Manages resource release
cgroup_free_wq – Performs final memory deallocation

This separation eliminates blocking in the CSS free path while waiting for
offline operations to complete.

[1] https://github.com/linux-test-project/ltp/blob/master/runtest/controllers
CVSS Score: 5.5 (MEDIUM)
References: https://git.kernel.org/stable/c/05e0b03447cf215ec384210441b34b7a3b16e8b0; https://git.kernel.org/stable/c/4a1e3ec28e8062cd9f339aa6a942df9c5bcb6811; https://git.kernel.org/stable/c/79f919a89c9d06816dbdbbd168fa41d27411a7f9