If a task exits without calling KCOV_DF_DISABLE, the kcov_df_enabled flag and area pointer remain set on the freed task_struct. If that memory is reallocated, subsequent writes could corrupt arbitrary memory.
Add kcov_dataflow_task_exit() which clears the dataflow fields, called from kernel/exit.c alongside kcov_task_exit(). This matches how kcov_task_exit() cleans up the legacy kcov state. Reported-by: sashiko-bot <[email protected]> Closes: https://sashiko.dev/#/patchset/20260603-kcov-dataflow-next-20260603-v2-0-fee0939de2c4%40est.tech Signed-off-by: Yunseong Kim <[email protected]> --- include/linux/kcov.h | 2 ++ kernel/exit.c | 1 + kernel/kcov_dataflow.c | 11 +++++++++++ 3 files changed, 14 insertions(+) diff --git a/include/linux/kcov.h b/include/linux/kcov.h index e9822b02982b..07d7823e5d6f 100644 --- a/include/linux/kcov.h +++ b/include/linux/kcov.h @@ -30,8 +30,10 @@ void kcov_task_exit(struct task_struct *t); #if defined(CONFIG_KCOV_DATAFLOW_ARGS) || defined(CONFIG_KCOV_DATAFLOW_RET) void kcov_dataflow_task_init(struct task_struct *t); +void kcov_dataflow_task_exit(struct task_struct *t); #else static inline void kcov_dataflow_task_init(struct task_struct *t) {} +static inline void kcov_dataflow_task_exit(struct task_struct *t) {} #endif #define kcov_prepare_switch(t) \ diff --git a/kernel/exit.c b/kernel/exit.c index 1056422bc101..af2314500791 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -935,6 +935,7 @@ void __noreturn do_exit(long code) kthread_do_exit(kthread, code); kcov_task_exit(tsk); + kcov_dataflow_task_exit(tsk); kmsan_task_exit(tsk); synchronize_group_exit(tsk, code); diff --git a/kernel/kcov_dataflow.c b/kernel/kcov_dataflow.c index 7cfe2495275a..df037b7e90eb 100644 --- a/kernel/kcov_dataflow.c +++ b/kernel/kcov_dataflow.c @@ -196,6 +196,17 @@ void kcov_dataflow_task_init(struct task_struct *t) t->kcov_df_enabled = false; } +/* Called from kernel/exit.c to clear state on task exit. */ +void kcov_dataflow_task_exit(struct task_struct *t) +{ + if (t->kcov_df_enabled) { + t->kcov_df_enabled = false; + barrier(); + t->kcov_df_area = NULL; + t->kcov_df_size = 0; + } +} + /* File operations for /sys/kernel/debug/kcov_dataflow */ static int kcov_df_open(struct inode *inode, struct file *filep) -- 2.43.0

