[RFC PATCH v2 02/14] kcov: fix INIT_TRACK race in kcov_dataflow

From: Yunseong Kim

Date: Thu Jun 11 2026 - 12:28:56 EST


Two threads calling KCOV_DF_INIT_TRACK concurrently could both observe
df->area == NULL, drop the lock to allocate, and then both assign their
allocation to df->area, leaking one buffer.

Fix by rechecking df->area after re-acquiring the lock. If another
thread won the race, free the allocation and return -EBUSY. This
matches the pattern used by KCOV_INIT_TRACE in kernel/kcov.c.

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>
---
kernel/kcov_dataflow.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/kernel/kcov_dataflow.c b/kernel/kcov_dataflow.c
index 721f742cbfe5..df7e8bf70bfa 100644
--- a/kernel/kcov_dataflow.c
+++ b/kernel/kcov_dataflow.c
@@ -268,11 +268,20 @@ static long kcov_df_ioctl(struct file *filep, unsigned int cmd, unsigned long ar
break;
}
spin_unlock_irqrestore(&df->lock, flags);
- df->area = vmalloc_user(size * sizeof(u64));
- if (!df->area)
- return -ENOMEM;
- spin_lock_irqsave(&df->lock, flags);
- df->size = size;
+ {
+ void *area = vmalloc_user(size * sizeof(u64));
+
+ if (!area)
+ return -ENOMEM;
+ spin_lock_irqsave(&df->lock, flags);
+ if (df->area) {
+ spin_unlock_irqrestore(&df->lock, flags);
+ vfree(area);
+ return -EBUSY;
+ }
+ df->area = area;
+ df->size = size;
+ }
break;

case KCOV_DF_ENABLE:

--
2.43.0