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

1 view
Skip to first unread message

Yunseong Kim

unread,
Jun 11, 2026, 12:21:52 PMJun 11
to Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak, Andrey Konovalov, Alexander Potapenko, Dmitry Vyukov, Andrew Morton, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Nathan Chancellor, Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt, Kees Cook, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Shuah Khan, Jonathan Corbet, Shuah Khan, Yunseong Kim, linux-...@vger.kernel.org, kasa...@googlegroups.com, rust-fo...@vger.kernel.org, linux-...@vger.kernel.org, ll...@lists.linux.dev, linu...@kvack.org, linux-k...@vger.kernel.org, work...@vger.kernel.org, linu...@vger.kernel.org, Yeoreum Yun, sashiko-bot
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 <sashi...@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260603-kcov-dataflow-next-20260603-v2-0-fee0939de2c4%40est.tech
Signed-off-by: Yunseong Kim <yunseo...@est.tech>
---
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

Reply all
Reply to author
Forward
0 new messages