#1144314 unprivileged user-triggerable use-after-free host panic bug

Package:
src:linux
Source:
src:linux
Submitter:
Noah Elias Feldt
Date:
2026-08-21 17:01:01 UTC
Severity:
normal
Tags:
#1144314#5
Date:
2026-08-13 14:38:34 UTC
From:
To:
Dear Maintainer,

An unprivileged local user can panic the entire host. Reading a cgroup's
world-readable cgroup.procs triggers a use-after-free of struct task_struct in
css_task_iter_next(), ending in "Kernel panic - not syncing: Fatal exception in
interrupt".
Nodes hard-panic and reboot organically under normal load on
the affected kernel. It also reproduces deterministically within seconds with
the attached PoC as an ordinary user (no root, no capabilities, no namespaces).

*** Reporter, please consider answering these questions, where appropriate ***

   * What led up to the situation?
     An unprivileged process reads its own world-readable cgroup.procs while,
     on the same CPU, thread-group leaders in that cgroup exit and are
     mass-reaped (attached poc.c). Not only synthetic: several of our production
     nodes have already panicked this way organically under normal container
     workload (Kubernetes / cri-o) on the affected kernel.

   * What exactly did you do?
     Ran the reproducer as an ordinary user on an Debian 13 KVM guest
     (trixie-backports kernel)

   * What was the outcome?
     In ~12-70 s: "refcount_t: addition on 0" in css_task_iter_next()
     (get_task_struct on usage==0) -> premature free -> NULL rcu_head.func in
     rcu_do_batch (RIP:0x0) -> "Kernel panic - not syncing". Host dead -- same
     signature as the organic production panics. Full trace attached (dmesg.log).

   * What outcome did you expect instead?
     Reading cgroup.procs must never crash the host.

#1144314#18
Date:
2026-08-14 19:36:27 UTC
From:
To:
Hi Noah,

I can reproduce the issue up to the current kernel version
7.2~rc7-1~exp1 in experimental. Are you able to narrow down more the
range and would you be able to bisect the issue?

I will see if I can otherwise poin point it as well and if there are
already upstream issues reported about this.

Regards,
Salvatore

#1144314#23
Date:
2026-08-15 12:59:39 UTC
From:
To:
We also fully reproduced it on our production system with a second, more targeted reproducer: inside an unprivileged container on a stock 7.0.13 node, the bare-metal host panicked within seconds. I didn't attach it since I think, it shouldn't be public yet. I can send it to you privately.

Sincerely,
Noah Feldt

#1144314#28
Date:
2026-08-15 17:43:32 UTC
From:
To:
Hi,

Thanks for sharing that, I initially wrongly guessed to be a
regression from 7.0 to 7.1-rc1 but it looks it is just bit harder to
trigger on older versions.

I think we can next forward this to upstream.

Regards,
Salvatore

#1144314#33
Date:
2026-08-15 19:15:55 UTC
From:
To:
Hi,
dying_tasks cleanup from cgroup_task_release() to
cgroup_task_free()"). But it is nearby to the commit you are spotting.

I will forward the issue upstream.

Regards,
Salvatore

#1144314#42
Date:
2026-08-15 19:41:14 UTC
From:
To:
Hi Tejun, Johannes and Michael,

In Debian Noah Elias Feldt reported a UAF which is hit in production
and provided a reproducer for the issue (attached as well), the
bugreport can be found at https://bugs.debian.org/1144314 . First
quoting the orignal post:

With an additional reproducer provided by Noah, I could bisect the
change down to

	commit 260fbcb92bbeacfcd050410fdc2d24ab15044400
	Author: Tejun Heo <tj@kernel.org>
	Date:   Tue Oct 28 20:19:16 2025 -1000

	    cgroup: Move dying_tasks cleanup from cgroup_task_release() to cgroup_task_free()

	    Currently, cgroup_task_exit() adds thread group leaders with live member
	    threads to their css_set's dying_tasks list (so cgroup.procs iteration can
	    still see the leader), and cgroup_task_release() later removes them with
	    list_del_init(&task->cg_list).

	    An upcoming patch will defer the dying_tasks list addition, moving it from
	    cgroup_task_exit() (called from do_exit()) to a new function called from
	    finish_task_switch(). However, release_task() (which calls
	    cgroup_task_release()) can run either before or after finish_task_switch(),
	    creating a race where cgroup_task_release() might try to remove the task from
	    dying_tasks before or while it's being added.

	    Move the list_del_init() from cgroup_task_release() to cgroup_task_free() to
	    fix this race. cgroup_task_free() runs from __put_task_struct(), which is
	    always after both paths, making the cleanup safe.

	    Cc: Dan Schatzberg <dschatzberg@meta.com>
	    Cc: Peter Zijlstra <peterz@infradead.org>
	    Signed-off-by: Tejun Heo <tj@kernel.org>

But there was the suspect that the matching commit might be
d245698d727a ("cgroup: Defer task cgroup unlink until after the task
is done switching out").

Using the provided reproducer in the Debian bug this leads to:

[ 2686.174523] ------------[ cut here ]------------
[ 2686.175443] refcount_t: addition on 0; use-after-free.
[ 2686.176414] WARNING: lib/refcount.c:25 at refcount_warn_saturate+0x6a/0x90, CPU#0: 1144314-poc/1170
[ 2686.178044] Modules linked in: binfmt_misc intel_rapl_msr intel_rapl_common kvm_amd ccp iTCO_wdt intel_pmc_bxt watchdog kvm i2c_i801 vga16fb i2c_smbus vgastate irqbypass lpc_ich pcspkr virtio_net button virtio_balloon net_failover failover joydev evdev nfsd auth_rpcgss nfs_acl lockd grace sunrpc drm efi_pstore configfs vsock_loopback vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common vsock ext4 crc16 mbcache jbd2 crc32c_cryptoapi ahci xhci_pci libahci xhci_hcd libata usbcore scsi_mod psmouse virtio_blk scsi_common usb_common serio_raw dm_mirror dm_region_hash dm_log dm_mod qemu_fw_cfg virtio_rng autofs4 aesni_intel gf128mul
[ 2686.187398] CPU: 0 UID: 1000 PID: 1170 Comm: 1144314-poc Not tainted 7.2-amd64 #1 PREEMPT(lazy)  Debian 7.2~rc7-1~exp1
[ 2686.189214] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2686.190800] RIP: 0010:refcount_warn_saturate+0x6a/0x90
[ 2686.191731] Code: 00 48 8d 3d 88 8f 8d 01 67 48 0f b9 3a e9 2e 37 73 00 48 8d 3d 87 8f 8d 01 67 48 0f b9 3a e9 1d 37 73 00 48 8d 3d 86 8f 8d 01 <67> 48 0f b9 3a e9 0c 37 73 00 48 8d 3d 85 8f 8d 01 67 48 0f b9 3a
[ 2686.194789] RSP: 0018:ffffcb9443cafa40 EFLAGS: 00010046
[ 2686.195752] RAX: ffff8b12532c8fa8 RBX: ffff8b1265ae6018 RCX: 0000000000000025
[ 2686.197023] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffffffffb15746b0
[ 2686.198268] RBP: 0000000000000206 R08: 0000000000000007 R09: 0000000000000004
[ 2686.199530] R10: ffff8b12673b3c40 R11: 0000000000000fdd R12: ffffcb9443cafb08
[ 2686.200782] R13: ffff8b1253899b40 R14: ffff8b124fbf0000 R15: 0000000000000000
[ 2686.202029] FS:  00007f0fff4266c0(0000) GS:ffff8b1309d55000(0000) knlGS:0000000000000000
[ 2686.203462] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2686.204506] CR2: 00005639b734d010 CR3: 0000000115a8d000 CR4: 0000000000350ef0
[ 2686.205780] Call Trace:
[ 2686.206308]  <TASK>
[ 2686.206781]  css_task_iter_next+0xcc/0xf0
[ 2686.207552]  kernfs_seq_next+0x2a/0xa0
[ 2686.208291]  ? cgroup_procs_show+0x2a/0x40
[ 2686.209075]  seq_read_iter+0x2f5/0x490
[ 2686.209798]  vfs_read+0x268/0x390
[ 2686.210454]  ksys_read+0x73/0xf0
[ 2686.211114]  do_syscall_64+0xe1/0x640
[ 2686.211828]  ? do_syscall_64+0x11e/0x640
[ 2686.212580]  ? kernfs_seq_start+0x53/0xb0
[ 2686.213340]  ? __pfx_cgroup_seqfile_stop+0x10/0x10
[ 2686.214233]  ? __mod_memcg_state+0xd7/0x1d0
[ 2686.215035]  ? seq_read_iter+0x214/0x490
[ 2686.215782]  ? __memcg_slab_free_hook+0x16c/0x1c0
[ 2686.216664]  ? __memcg_slab_free_hook+0x16c/0x1c0
[ 2686.217594]  ? kmem_cache_free+0x25f/0x440
[ 2686.218490]  ? __x64_sys_close+0x3d/0x80
[ 2686.219281]  ? do_syscall_64+0x11e/0x640
[ 2686.220044]  ? __mod_memcg_state+0xd7/0x1d0
[ 2686.220839]  ? __memcg_slab_free_hook+0x16c/0x1c0
[ 2686.221719]  ? __memcg_slab_free_hook+0x16c/0x1c0
[ 2686.222616]  ? kmem_cache_free+0x25f/0x440
[ 2686.223403]  ? __x64_sys_close+0x3d/0x80
[ 2686.224167]  ? do_syscall_64+0x11e/0x640
[ 2686.224927]  ? do_syscall_64+0x11e/0x640
[ 2686.225686]  ? do_syscall_64+0x11e/0x640
[ 2686.226446]  ? do_syscall_64+0x98/0x640
[ 2686.227193]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 2686.228121] RIP: 0033:0x7f1010cea19e
[ 2686.228828] Code: 08 0f 85 35 4a ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 90 48 83 ec 08 bf 01 00 00 00 e8 82 dc 05 00 bf 01 00 00 00 89
[ 2686.231921] RSP: 002b:00007f0fff415e08 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[ 2686.233234] RAX: ffffffffffffffda RBX: 00007f0fff4266c0 RCX: 00007f1010cea19e
[ 2686.234465] RDX: 0000000000010000 RSI: 00007f0fff415e90 RDI: 0000000000000029
[ 2686.235710] RBP: 00007f0fff425ea0 R08: 0000000000000000 R09: 0000000000000000
[ 2686.236959] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc3405bde0
[ 2686.238197] R13: 00007ffc3405bed6 R14: 00007f0fff426ce4 R15: 00007f0ffec26000
[ 2686.239444]  </TASK>
[ 2686.239922] ---[ end trace 0000000000000000 ]---
[ 2686.244408] ------------[ cut here ]------------
[ 2686.245246] WARNING: kernel/fork.c:790 at __put_task_struct+0x150/0x1c0, CPU#0: 1144314-poc/1164
[ 2686.246763] Modules linked in: binfmt_misc intel_rapl_msr intel_rapl_common kvm_amd ccp iTCO_wdt intel_pmc_bxt watchdog kvm i2c_i801 vga16fb i2c_smbus vgastate irqbypass lpc_ich pcspkr virtio_net button virtio_balloon net_failover failover joydev evdev nfsd auth_rpcgss nfs_acl lockd grace sunrpc drm efi_pstore configfs vsock_loopback vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common vsock ext4 crc16 mbcache jbd2 crc32c_cryptoapi ahci xhci_pci libahci xhci_hcd libata usbcore scsi_mod psmouse virtio_blk scsi_common usb_common serio_raw dm_mirror dm_region_hash dm_log dm_mod qemu_fw_cfg virtio_rng autofs4 aesni_intel gf128mul
[ 2686.255681] CPU: 0 UID: 1000 PID: 1164 Comm: 1144314-poc Tainted: G        W           7.2-amd64 #1 PREEMPT(lazy)  Debian 7.2~rc7-1~exp1
[ 2686.257660] Tainted: [W]=WARN
[ 2686.258228] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2686.259718] RIP: 0010:__put_task_struct+0x150/0x1c0
[ 2686.260570] Code: fe ff ff 48 89 cf be 03 00 00 00 e8 7a 73 72 00 48 89 df 48 83 c4 08 5b e9 2d fe ff ff 0f 0b 8b 43 28 85 c0 0f 84 da fe ff ff <0f> 0b 65 48 3b 1d ae ec 94 02 0f 85 d8 fe ff ff 0f 0b e9 d1 fe ff
[ 2686.263431] RSP: 0018:ffffcb9440003ed0 EFLAGS: 00010286
[ 2686.264319] RAX: 00000000c0000000 RBX: ffff8b12532c8000 RCX: ffff8b124022fac0
[ 2686.265494] RDX: ffffffffaf5743e0 RSI: 0000000000000001 RDI: ffff8b12532c8000
[ 2686.266667] RBP: ffff8b12bbc33500 R08: ffff8b125368b700 R09: ffffffffaf66e8e3
[ 2686.267832] R10: fffff61cc44da200 R11: ffff8b124022a700 R12: ffffcb9440003f10
[ 2686.269010] R13: ffff8b12468cb700 R14: 0000000000000003 R15: 0000000000000000
[ 2686.270176] FS:  00007f100242c6c0(0000) GS:ffff8b1309d55000(0000) knlGS:0000000000000000
[ 2686.271594] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2686.272640] CR2: 00007f9e074e6b20 CR3: 0000000115a8d000 CR4: 0000000000350ef0
[ 2686.273817] Call Trace:
[ 2686.274307]  <IRQ>
[ 2686.274744]  rcu_do_batch+0x1b3/0x4f0
[ 2686.275413]  rcu_core+0x131/0x2b0
[ 2686.276030]  handle_softirqs+0xd8/0x310
[ 2686.276734]  ? clockevents_program_event+0xf5/0x1e0
[ 2686.277577]  __irq_exit_rcu+0x9e/0xf0
[ 2686.278243]  sysvec_apic_timer_interrupt+0x71/0x90
[ 2686.279087]  </IRQ>
[ 2686.279527]  <TASK>
[ 2686.279968]  asm_sysvec_apic_timer_interrupt+0x1a/0x20
[ 2686.280856] RIP: 0010:_raw_spin_unlock_irqrestore+0x1d/0x40
[ 2686.281795] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 e8 f2 07 00 00 90 f7 c6 00 02 00 00 74 06 fb 0f 1f 44 00 00 <65> ff 0d 5c 66 af 01 74 05 e9 65 24 00 00 e8 10 2d 0e ff e9 5b 24
[ 2686.284661] RSP: 0018:ffffcb9443c7fcf0 EFLAGS: 00000206
[ 2686.285549] RAX: 0000000000000001 RBX: ffff8b1265ae0558 RCX: ffff8b1261d4ac00
[ 2686.286727] RDX: ffff8b12485b5330 RSI: 0000000000000206 RDI: ffffffffb1f81d88
[ 2686.287891] RBP: 0000000000000206 R08: 0000000000000003 R09: 0000000000000004
[ 2686.289065] R10: ffff8b12673b3f50 R11: 0000000000000ff1 R12: ffffcb9443c7fdb8
[ 2686.290230] R13: ffff8b12665eb180 R14: ffff8b1240338000 R15: 0000000000000000
[ 2686.291402]  css_task_iter_next+0x95/0xf0
[ 2686.292117]  kernfs_seq_next+0x2a/0xa0
[ 2686.292806]  ? cgroup_procs_show+0x2a/0x40
[ 2686.293534]  seq_read_iter+0x2f5/0x490
[ 2686.294217]  vfs_read+0x268/0x390
[ 2686.294842]  ksys_read+0x73/0xf0
[ 2686.295447]  do_syscall_64+0xe1/0x640
[ 2686.296114]  ? kmem_cache_free+0x25f/0x440
[ 2686.296851]  ? __x64_sys_close+0x3d/0x80
[ 2686.297554]  ? do_syscall_64+0x11e/0x640
[ 2686.298257]  ? do_syscall_64+0x11e/0x640
[ 2686.298967]  ? do_syscall_64+0x11e/0x640
[ 2686.299777]  ? do_syscall_64+0x98/0x640
[ 2686.300606]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 2686.301529] RIP: 0033:0x7f1010cea19e
[ 2686.302231] Code: 08 0f 85 35 4a ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 90 48 83 ec 08 bf 01 00 00 00 e8 82 dc 05 00 bf 01 00 00 00 89
[ 2686.305341] RSP: 002b:00007f100241be08 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[ 2686.306708] RAX: ffffffffffffffda RBX: 00007f100242c6c0 RCX: 00007f1010cea19e
[ 2686.308108] RDX: 0000000000010000 RSI: 00007f100241be90 RDI: 000000000000002a
[ 2686.309527] RBP: 00007f100242bea0 R08: 0000000000000000 R09: 0000000000000000
[ 2686.310935] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc3405bde0
[ 2686.312388] R13: 00007ffc3405bed6 R14: 00007f100242cce4 R15: 00007f1001c2c000
[ 2686.313805]  </TASK>
[ 2686.314326] ---[ end trace 0000000000000000 ]---
[ 2691.097916]  slab task_struct start ffff8b12532c8000 pointer offset 2600 size 7040
[ 2691.099234] list_del corruption. next->prev should be ffff8b124f3e0a28, but was ffff8b12514d8a28. (next=ffff8b12532c8a28)
[ 2691.101069] ------------[ cut here ]------------
[ 2691.101915] kernel BUG at lib/list_debug.c:65!
[ 2691.102745] Oops: invalid opcode: 0000 [#1] SMP NOPTI
[ 2691.103662] CPU: 0 UID: 1000 PID: 9204 Comm: 1144314-poc Tainted: G        W           7.2-amd64 #1 PREEMPT(lazy)  Debian 7.2~rc7-1~exp1
[ 2691.105695] Tainted: [W]=WARN
[ 2691.106288] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 2691.107892] RIP: 0010:__list_del_entry_valid_or_report+0x10a/0x120
[ 2691.108989] Code: 89 d7 48 89 14 24 e8 25 3c be ff 48 8b 14 24 48 8b 74 24 08 48 c7 c7 18 12 a7 b0 48 8b 42 08 48 89 d1 48 89 c2 e8 b6 d1 74 ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00
[ 2691.112049] RSP: 0018:ffffcb944927fb68 EFLAGS: 00010046
[ 2691.112991] RAX: 000000000000006d RBX: 0000000000000011 RCX: 0000000000000027
[ 2691.114228] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8b12bbc1d100
[ 2691.115474] RBP: ffff8b124f306300 R08: 0000000000000000 R09: ffffcb944927fa10
[ 2691.116712] R10: ffffffffb12f24b0 R11: 3fffffffffffefff R12: ffff8b1241f5d540
[ 2691.117950] R13: ffff8b124f3e4250 R14: ffff8b12508f8d80 R15: ffff8b124f3e0000
[ 2691.119196] FS:  0000000000000000(0000) GS:ffff8b1309d55000(0000) knlGS:0000000000000000
[ 2691.120587] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2691.121611] CR2: 00007f1010e48000 CR3: 0000000161e2a000 CR4: 0000000000350ef0
[ 2691.122857] Call Trace:
[ 2691.123372]  <TASK>
[ 2691.123834]  release_task+0x436/0x560
[ 2691.124539]  do_exit+0x6a2/0xaa0
[ 2691.125178]  do_group_exit+0x2d/0xc0
[ 2691.125868]  __x64_sys_exit_group+0x18/0x20
[ 2691.126662]  x64_sys_call+0x102c/0x1530
[ 2691.127393]  do_syscall_64+0xe1/0x640
[ 2691.128098]  ? file_update_time_flags+0x81/0x110
[ 2691.128951]  ? fault_dirty_shared_page+0xa2/0x160
[ 2691.129816]  ? do_fault+0x146/0x580
[ 2691.130493]  ? __pte_offset_map+0x1b/0x100
[ 2691.131273]  ? __handle_mm_fault+0x960/0xf60
[ 2691.132074]  ? count_memcg_events+0xd9/0x210
[ 2691.132875]  ? handle_mm_fault+0x1e5/0x2f0
[ 2691.133643]  ? do_user_addr_fault+0x2b4/0x7b0
[ 2691.134456]  ? irqentry_exit+0x43/0x730
[ 2691.135194]  ? do_syscall_64+0x98/0x640
[ 2691.135927]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 2691.136843] RIP: 0033:0x7f1010d2c438
[ 2691.137540] Code: Unable to access opcode bytes at 0x7f1010d2c40e.
[ 2691.138633] RSP: 002b:00007ffc3405bf98 EFLAGS: 00000202 ORIG_RAX: 00000000000000e7
[ 2691.139859] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1010d2c438
[ 2691.141027] RDX: 0000000000000002 RSI: ffffffffffffffb0 RDI: 0000000000000000
[ 2691.142186] RBP: 00007ffc3405bfb0 R08: 0000000000000000 R09: 0000000000000000
[ 2691.143352] R10: 0000000000000000 R11: 0000000000000202 R12: 00000000000003e8
[ 2691.144512] R13: 0000000000000002 R14: 0000000000000030 R15: 00005639b734cdd8
[ 2691.145673]  </TASK>
[ 2691.146124] Modules linked in: binfmt_misc intel_rapl_msr intel_rapl_common kvm_amd ccp iTCO_wdt intel_pmc_bxt watchdog kvm i2c_i801 vga16fb i2c_smbus vgastate irqbypass lpc_ich pcspkr virtio_net button virtio_balloon net_failover failover joydev evdev nfsd auth_rpcgss nfs_acl lockd grace sunrpc drm efi_pstore configfs vsock_loopback vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common vsock ext4 crc16 mbcache jbd2 crc32c_cryptoapi ahci xhci_pci libahci xhci_hcd libata usbcore scsi_mod psmouse virtio_blk scsi_common usb_common serio_raw dm_mirror dm_region_hash dm_log dm_mod qemu_fw_cfg virtio_rng autofs4 aesni_intel gf128mul
[ 2691.154482] ---[ end trace 0000000000000000 ]---
[ 2691.155292] RIP: 0010:__list_del_entry_valid_or_report+0x10a/0x120
[ 2691.156315] Code: 89 d7 48 89 14 24 e8 25 3c be ff 48 8b 14 24 48 8b 74 24 08 48 c7 c7 18 12 a7 b0 48 8b 42 08 48 89 d1 48 89 c2 e8 b6 d1 74 ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00
[ 2691.159161] RSP: 0018:ffffcb944927fb68 EFLAGS: 00010046
[ 2691.160045] RAX: 000000000000006d RBX: 0000000000000011 RCX: 0000000000000027
[ 2691.161204] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8b12bbc1d100
[ 2691.162364] RBP: ffff8b124f306300 R08: 0000000000000000 R09: ffffcb944927fa10
[ 2691.163532] R10: ffffffffb12f24b0 R11: 3fffffffffffefff R12: ffff8b1241f5d540
[ 2691.164691] R13: ffff8b124f3e4250 R14: ffff8b12508f8d80 R15: ffff8b124f3e0000
[ 2691.165852] FS:  0000000000000000(0000) GS:ffff8b1309d55000(0000) knlGS:0000000000000000
[ 2691.167168] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2691.168129] CR2: 00007f1010e48000 CR3: 0000000161e2a000 CR4: 0000000000350ef0
[ 2691.169290] note: 1144314-poc[9204] exited with irqs disabled
[ 2691.170276] note: 1144314-poc[9204] exited with preempt_count 3
[ 2691.171334] Fixing recursive fault but reboot is needed!

#regzbot introduced: 260fbcb92bbeacfcd050410fdc2d24ab15044400
#regzbot link: https://bugs.debian.org/1144314

Noah Elias Feldt is added here as well to provide more information as
needed.

Regards,
Salvatore

#1144314#49
Date:
2026-08-16 03:33:41 UTC
From:
To:
Salvatore Bonaccorso wrote:

As an extra data point, I couldn't reproduce the problem with 6.12.100+deb13-amd64 on Trixie.

#1144314#56
Date:
2026-08-21 16:59:26 UTC
From:
To:
Hi Salvatore,

thanks for the nice report and sorry for not so prompt response.

Good job.
cgroup_task_release() to cgroup_task_free()") it may be possible that
tasks on the dying_tasks list may drop their ->usage to zero (since the
actual unlinking only happens in __put_task_struct).
Most often those would be skipped due to PF_EXITING except for the case
of thread group leaders (which the reproducer stresses) whose refcount
apparently can drop to zero after task->signal->live > 0 made them
iterable :-/

A band-aid fix could be to use tryget_task_struct() in
css_task_iter_next() (I got that hint from a LLM) and "skip" zeroed
tasks. I see that commit fbe3fb103596b ("sched_ext: Replace
tryget_task_struct() with get_task_struct()"), assumes the iterator
always succeeds in obtaining the task reference (which was the
justification of tryget removal). I expect that sched_ext should still
be fine if dying_tasks with zero references are skipped. (What are they?
Tasks which literally no one should be interested in and they're only
waiting for __put_task_struct_rcu_cb() to be called [*]).

(I'm calling that band-aid because it'd resurrect usage of
tryget_task_struct() and it keeps the dying_tasks list a weird place to
be. If anyone has a better idea?)

The commit d245698d727a ("cgroup: Defer task cgroup unlink until after
the task is done switching out") seems a reasonable separation of the
stages to me.

Regards,
Michal


[*] Except for io_uring_drop_tctx_refs() that calls __put_task_struct()
directly (no RCU) but I'd argue the same, that those should not be
possibly iterated.