[RFC PATCH v2 06/14] kcov: clean up dataflow state on task exit

From: Yunseong Kim

Date: Thu Jun 11 2026 - 12:26:16 EST


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 <sashiko-bot@xxxxxxxxxx>
Closes: https://sashiko.dev/#/patchset/20260603-kcov-dataflow-next-20260603-v2-0-fee0939de2c4%40est.tech
Signed-off-by: Yunseong Kim <yunseong.kim@xxxxxxxx>
---
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