kernel/fork.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
dup_task_struct() copies the parent's task_struct, including ret_stack.
ftrace_graph_init_task() clears the copied function graph state, but it
currently runs after copy_exec_state().
For non-CLONE_VM forks, copy_exec_state() allocates a new task_exec_state.
If that allocation fails, copy_process() reaches bad_fork_free and
free_task() calls ftrace_graph_exit_task(). Since the child still carries
the parent's ret_stack pointer, the unwind frees the parent's active
function graph return stack. The parent subsequently accesses freed memory
from function_graph_enter_regs().
KASAN reports:
[ 22.190920] ==================================================================
[ 22.195899] BUG: KASAN: slab-use-after-free in function_graph_enter_regs+0xa76/0xb90
[ 22.200747] Write of size 8 at addr ff110000054dc0a8 by task repro/1
[ 22.205134]
[ 22.210770] CPU: 0 UID: 0 PID: 1 Comm: repro Not tainted 7.2.0-07732-g9328b3b03bdc-dirty #3 PREEMPT(lazy)
[ 22.212576] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 22.213750] Call Trace:
[ 22.215271] <TASK>
[ 22.216242] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.217774] dump_stack_lvl+0x4e/0x70
[ 22.220531] print_report+0x157/0x4b4
[ 22.223202] ? fixup_red_left+0x9/0x30
[ 22.224407] ? complete_report_info+0x83/0x110
[ 22.226679] ? function_graph_enter_regs+0xa76/0xb90
[ 22.228084] kasan_report+0xce/0x100
[ 22.230109] ? function_graph_enter_regs+0xa76/0xb90
[ 22.232860] ? stack_trace_save+0x4/0xd0
[ 22.234156] function_graph_enter_regs+0xa76/0xb90
[ 22.236090] ? kasan_save_stack+0x30/0x50
[ 22.237752] ? __pfx_function_graph_enter_regs+0x10/0x10
[ 22.238694] ? ring_buffer_lock_reserve+0x345/0xf80
[ 22.239628] ? stack_trace_save+0x4/0xd0
[ 22.242121] ? stack_trace_save+0x4/0xd0
[ 22.243588] ftrace_graph_func+0xda/0x160
[ 22.245362] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.246520] 0xffffffffa0000095
[ 22.250528] ? stack_trace_save+0x9/0xd0
[ 22.251757] ? ring_buffer_unlock_commit+0x11d/0x5c0
[ 22.253152] stack_trace_save+0x9/0xd0
[ 22.254264] kasan_save_stack+0x30/0x50
[ 22.273631] kasan_save_track+0x14/0x30
[ 22.276763] kasan_save_free_info+0x3b/0x70
[ 22.278296] __kasan_slab_free+0x43/0x70
[ 22.280157] kmem_cache_free+0xbf/0x3b0
[ 22.282963] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.284001] free_task+0xa2/0x160
[ 22.285699] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.286752] copy_process+0x2aae/0x7bc0
Initialize the child function graph state immediately after
dup_task_struct(), before the first fallible operation.
Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
---
Resending v2 as requested by adding Cc: linux-trace-kernel@vger.kernel.org
Changes in v2:
- Add the KASAN report excerpt to the commit message.
- Add a comment documenting why ftrace_graph_init_task() must run before
fallible initialization.
v1: https://lore.kernel.org/all/20260821102207.3626491-2-Jeremy.Jean@oss.cyber.gouv.fr/
kernel/fork.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 1e68404bd773..0d1ad92e2d33 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2139,6 +2139,11 @@ __latent_entropy struct task_struct *copy_process(
p = dup_task_struct(current, node);
if (!p)
goto fork_out;
+ /*
+ * Must run before the first fallible op, so error paths never
+ * free the parent's ret_stack.
+ */
+ ftrace_graph_init_task(p);
retval = copy_exec_state(clone_flags, p);
if (retval)
goto bad_fork_free;
@@ -2165,8 +2170,6 @@ __latent_entropy struct task_struct *copy_process(
*/
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL;
- ftrace_graph_init_task(p);
-
rt_mutex_init_task(p);
raw_spin_lock_init(&p->blocked_lock);
--
2.47.3
On 22 August 2026 20:53:22 BST, "Jérémy Jean"
<Jeremy.Jean@oss.cyber.gouv.fr> wrote:
>dup_task_struct() copies the parent's task_struct, including ret_stack.
>ftrace_graph_init_task() clears the copied function graph state, but it
>currently runs after copy_exec_state().
>
>For non-CLONE_VM forks, copy_exec_state() allocates a new task_exec_state.
>If that allocation fails, copy_process() reaches bad_fork_free and
>free_task() calls ftrace_graph_exit_task(). Since the child still carries
>the parent's ret_stack pointer, the unwind frees the parent's active
>function graph return stack. The parent subsequently accesses freed memory
>from function_graph_enter_regs().
>
>KASAN reports:
>
>[ 22.190920]
>==================================================================
>[ 22.195899] BUG: KASAN: slab-use-after-free in
>function_graph_enter_regs+0xa76/0xb90
>[ 22.200747] Write of size 8 at addr ff110000054dc0a8 by task repro/1
>[ 22.205134]
>[ 22.210770] CPU: 0 UID: 0 PID: 1 Comm: repro Not tainted
>7.2.0-07732-g9328b3b03bdc-dirty #3 PREEMPT(lazy)
>[ 22.212576] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
>1.16.3-debian-1.16.3-2 04/01/2014
>[ 22.213750] Call Trace:
>[ 22.215271] <TASK>
>[ 22.216242] ? ftrace_stub_direct_tramp+0x10/0x10
>[ 22.217774] dump_stack_lvl+0x4e/0x70
>[ 22.220531] print_report+0x157/0x4b4
>[ 22.223202] ? fixup_red_left+0x9/0x30
>[ 22.224407] ? complete_report_info+0x83/0x110
>[ 22.226679] ? function_graph_enter_regs+0xa76/0xb90
>[ 22.228084] kasan_report+0xce/0x100
>[ 22.230109] ? function_graph_enter_regs+0xa76/0xb90
>[ 22.232860] ? stack_trace_save+0x4/0xd0
>[ 22.234156] function_graph_enter_regs+0xa76/0xb90
>[ 22.236090] ? kasan_save_stack+0x30/0x50
>[ 22.237752] ? __pfx_function_graph_enter_regs+0x10/0x10
>[ 22.238694] ? ring_buffer_lock_reserve+0x345/0xf80
>[ 22.239628] ? stack_trace_save+0x4/0xd0
>[ 22.242121] ? stack_trace_save+0x4/0xd0
>[ 22.243588] ftrace_graph_func+0xda/0x160
>[ 22.245362] ? ftrace_stub_direct_tramp+0x10/0x10
>[ 22.246520] 0xffffffffa0000095
>[ 22.250528] ? stack_trace_save+0x9/0xd0
>[ 22.251757] ? ring_buffer_unlock_commit+0x11d/0x5c0
>[ 22.253152] stack_trace_save+0x9/0xd0
>[ 22.254264] kasan_save_stack+0x30/0x50
>[ 22.273631] kasan_save_track+0x14/0x30
>[ 22.276763] kasan_save_free_info+0x3b/0x70
>[ 22.278296] __kasan_slab_free+0x43/0x70
>[ 22.280157] kmem_cache_free+0xbf/0x3b0
>[ 22.282963] ? ftrace_stub_direct_tramp+0x10/0x10
>[ 22.284001] free_task+0xa2/0x160
>[ 22.285699] ? ftrace_stub_direct_tramp+0x10/0x10
>[ 22.286752] copy_process+0x2aae/0x7bc0
>
>Initialize the child function graph state immediately after
>dup_task_struct(), before the first fallible operation.
>
>Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information")
>Cc: stable@vger.kernel.org
>Assisted-by: Codex:gpt-5
Where's my R-B, nothing changed also, it's V3!!!!
>Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
>---
>Resending v2
(no! V3!!)
>as requested by adding Cc:
>linux-trace-kernel@vger.kernel.org
>
>Changes in v2:
>- Add the KASAN report excerpt to the commit message.
>- Add a comment documenting why ftrace_graph_init_task() must run before
> fallible initialization.
>
>v1: https://lore.kernel.org/all/20260821102207.3626491-2-Jeremy.Jean@oss.cyber.gouv.fr/
>
> kernel/fork.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
>diff --git a/kernel/fork.c b/kernel/fork.c
>index 1e68404bd773..0d1ad92e2d33 100644
>--- a/kernel/fork.c
>+++ b/kernel/fork.c
>@@ -2139,6 +2139,11 @@ __latent_entropy struct task_struct *copy_process(
> p = dup_task_struct(current, node);
> if (!p)
> goto fork_out;
>+ /*
>+ * Must run before the first fallible op, so error paths never
>+ * free the parent's ret_stack.
>+ */
>+ ftrace_graph_init_task(p);
> retval = copy_exec_state(clone_flags, p);
> if (retval)
> goto bad_fork_free;
>@@ -2165,8 +2170,6 @@ __latent_entropy struct task_struct *copy_process(
> */
> p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL;
>
>- ftrace_graph_init_task(p);
>-
> rt_mutex_init_task(p);
> raw_spin_lock_init(&p->blocked_lock);
>
>
Thanks!
On Sat, 22 Aug 2026 20:58:15 +0100
Bradley Morgan <include@grrlz.net> wrote:
> >Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information")
> >Cc: stable@vger.kernel.org
> >Assisted-by: Codex:gpt-5
>
> Where's my R-B, nothing changed also, it's V3!!!!
No need to get so excited ;-)
Anyway, as there was no change, it should have included your
Reviewed-by tag, as it will not be automatically added from the
previous thread.
>
> >Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
> >---
> >Resending v2
>
> (no! V3!!)
Right, when resending, it is best to add "[RESEND]" to the subject:
[RESEND][PATCH v2] fork: initialize function graph state before copy_exec_state()
And below the '---' have:
- Resend to include linux-trace-kernel mailing list.
Previous sent patch: https://lore.kernel.org/all/20260822195321.962383-2-Jeremy.Jean@oss.cyber.gouv.fr/
-- Steve
On Sat, 22 Aug 2026 17:09:28 -0400 Steven Rostedt <rostedt@goodmis.org> wrote: > > >Resending v2 > > > > (no! V3!!) > > Right, when resending, it is best to add "[RESEND]" to the subject: I shouldn't have said "right" because it wasn't. You add "RESEND" not v3. You should not up the version if the patch has not changed and you are only resending to update the Cc. I do that all the time. -- Steve > > [RESEND][PATCH v2] fork: initialize function graph state before copy_exec_state()
On 2026-08-22 23:09, Steven Rostedt wrote:
> On Sat, 22 Aug 2026 20:58:15 +0100
> Bradley Morgan <include@grrlz.net> wrote:
>
>> >Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information")
>> >Cc: stable@vger.kernel.org
>> >Assisted-by: Codex:gpt-5
>>
>> Where's my R-B, nothing changed also, it's V3!!!!
>
> No need to get so excited ;-)
>
> Anyway, as there was no change, it should have included your
> Reviewed-by tag, as it will not be automatically added from the
> previous thread.
>
>>
>> >Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
>> >---
>> >Resending v2
>>
>> (no! V3!!)
>
> Right, when resending, it is best to add "[RESEND]" to the subject:
>
> [RESEND][PATCH v2] fork: initialize function graph state before
> copy_exec_state()
>
> And below the '---' have:
>
> - Resend to include linux-trace-kernel mailing list.
> Previous sent patch:
> https://lore.kernel.org/all/20260822195321.962383-2-Jeremy.Jean@oss.cyber.gouv.fr/
>
> -- Steve
Oops, I did not know that, sorry.
Do you want me to resend once more, or that's okay?
Jérémy
On Sat, 22 Aug 2026 23:12:35 +0200 Jérémy Jean <jeremy.jean@oss.cyber.gouv.fr> wrote: > Oops, I did not know that, sorry. > Do you want me to resend once more, or that's okay? No need. It's in patchwork and I'll manually add Bradley's R-B tag and start testing it. -- Steve
On 22 August 2026 22:40:53 BST, Steven Rostedt <rostedt@goodmis.org> wrote: >On Sat, 22 Aug 2026 23:12:35 +0200 >Jérémy Jean <jeremy.jean@oss.cyber.gouv.fr> wrote: > >> Oops, I did not know that, sorry. >> Do you want me to resend once more, or that's okay? > >No need. It's in patchwork and I'll manually add Bradley's R-B tag and >start testing it. > Will you merge it to one of your very cool tree(s)? I've merged it to my friends distro tree, not maintainer tree or anything, but I do tests, I guess that's like future learning! ;d >-- Steve > Thanks!
On Sat, 22 Aug 2026 22:47:36 +0100 Bradley Morgan <include@grrlz.net> wrote: > Will you merge it to one of your very cool tree(s)? I've merged it to my > friends distro tree, not maintainer tree or anything, but I do tests, I > guess that's like future learning! ;d After my tests are done, I'll move it into my fixes branch. I have other fixes that need to happen too that need to pass my tests and I push them all together. -- Steve
On 2026-08-22 23:40, Steven Rostedt wrote: > On Sat, 22 Aug 2026 23:12:35 +0200 > Jérémy Jean <jeremy.jean@oss.cyber.gouv.fr> wrote: > >> Oops, I did not know that, sorry. >> Do you want me to resend once more, or that's okay? > > No need. It's in patchwork and I'll manually add Bradley's R-B tag and > start testing it. Noted, thanks Steve. Regards, Jérémy
© 2016 - 2026 Red Hat, Inc.