[PATCH v3 3/7] treewide: Replace memcpy(..., current->comm) with copy_task_comm()

From: André Almeida

Date: Fri Jun 12 2026 - 12:21:18 EST


In order to increase the size of current->comm[] and to avoid breaking any
existing code, replace memcpy() with copy_task_comm(). This new function
makes sure that the copy is NUL terminated. This is crucial given that the
source buffer might be larger than the destination buffer and could
truncate the NUL character out of it.

Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx>
---
Changes from v3:
- Bring back custom function.

Changes from v2:
- New patch, dropped strtostr() from last version
---
include/linux/coredump.h | 2 +-
include/linux/sched.h | 17 +++++++++++++++++
include/linux/tracepoint.h | 4 ++--
include/trace/events/block.h | 10 +++++-----
include/trace/events/coredump.h | 2 +-
include/trace/events/f2fs.h | 4 ++--
include/trace/events/oom.h | 2 +-
include/trace/events/osnoise.h | 2 +-
include/trace/events/sched.h | 10 +++++-----
include/trace/events/signal.h | 2 +-
include/trace/events/task.h | 7 ++++---
kernel/printk/nbcon.c | 2 +-
kernel/printk/printk.c | 2 +-
13 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 68861da4cf7c..461254cd9ccc 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -54,7 +54,7 @@ extern void vfs_coredump(const kernel_siginfo_t *siginfo);
do { \
char comm[TASK_COMM_LEN]; \
/* This will always be NUL terminated. */ \
- memcpy(comm, current->comm, sizeof(comm)); \
+ copy_task_comm(comm, current, sizeof(comm)); \
printk_ratelimited(Level "coredump: %d(%*pE): " Format "\n", \
task_tgid_vnr(current), (int)strlen(comm), comm, ##__VA_ARGS__); \
} while (0) \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b6de742b1155..6b9408128fef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2000,6 +2000,23 @@ extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec
__set_task_comm(tsk, from, false); \
})

+/*
+ * Copy task name to a buffer. Final result is always a NUL-terminated string.
+ */
+#define copy_task_comm(dst, tsk, len) \
+{ \
+ const char *_src = (tsk)->comm; \
+ size_t _dst_len = len + __must_be_array(dst), _src_len = sizeof(_src); \
+ char *_dst = dst; \
+ \
+ if (_dst_len <= _src_len) { \
+ memcpy(_dst, _src, _dst_len); \
+ dst[_dst_len - 1] = '\0'; \
+ } else { \
+ strscpy_pad(_dst, _src, _dst_len); \
+ } \
+}
+
static __always_inline void scheduler_ipi(void)
{
/*
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 763eea4d80d8..4bdb34f628a2 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -615,10 +615,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
* *
*
* TP_fast_assign(
- * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ * copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
* __entry->prev_pid = prev->pid;
* __entry->prev_prio = prev->prio;
- * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ * copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
* __entry->next_pid = next->pid;
* __entry->next_prio = next->prio;
* ),
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 6aa79e2d799c..70d552b9347e 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -213,7 +213,7 @@ DECLARE_EVENT_CLASS(block_rq,

blk_fill_rwbs(__entry->rwbs, rq->cmd_flags);
__get_str(cmd)[0] = '\0';
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("%d,%d %s %u (%s) %llu + %u %s,%u,%u [%s]",
@@ -351,7 +351,7 @@ DECLARE_EVENT_CLASS(block_bio,
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio_sectors(bio);
blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("%d,%d %s %llu + %u [%s]",
@@ -434,7 +434,7 @@ TRACE_EVENT(block_plug,
),

TP_fast_assign(
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("[%s]", __entry->comm)
@@ -453,7 +453,7 @@ DECLARE_EVENT_CLASS(block_unplug,

TP_fast_assign(
__entry->nr_rq = depth;
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
@@ -504,7 +504,7 @@ TRACE_EVENT(block_split,
__entry->sector = bio->bi_iter.bi_sector;
__entry->new_sector = new_sector;
blk_fill_rwbs(__entry->rwbs, bio->bi_opf);
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("%d,%d %s %llu / %llu [%s]",
diff --git a/include/trace/events/coredump.h b/include/trace/events/coredump.h
index c7b9c53fc498..fdd20bc46bb0 100644
--- a/include/trace/events/coredump.h
+++ b/include/trace/events/coredump.h
@@ -32,7 +32,7 @@ TRACE_EVENT(coredump,

TP_fast_assign(
__entry->sig = sig;
- memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, current, TASK_COMM_LEN);
),

TP_printk("sig=%d comm=%s",
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index b5188d2671d7..b02f6ccb6c3d 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -2505,7 +2505,7 @@ TRACE_EVENT(f2fs_lock_elapsed_time,

TP_fast_assign(
__entry->dev = sbi->sb->s_dev;
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
__entry->pid = p->pid;
__entry->prio = p->prio;
__entry->ioprio_class = IOPRIO_PRIO_CLASS(ioprio);
@@ -2558,7 +2558,7 @@ DECLARE_EVENT_CLASS(f2fs_priority_update,

TP_fast_assign(
__entry->dev = sbi->sb->s_dev;
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
__entry->pid = p->pid;
__entry->lock_name = lock_name;
__entry->is_write = is_write;
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 9f0a5d1482c4..8bcdc4ffc8d3 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -23,7 +23,7 @@ TRACE_EVENT(oom_score_adj_update,

TP_fast_assign(
__entry->pid = task->pid;
- memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
__entry->oom_score_adj = task->signal->oom_score_adj;
),

diff --git a/include/trace/events/osnoise.h b/include/trace/events/osnoise.h
index 3f4273623801..2cf047bb9fb7 100644
--- a/include/trace/events/osnoise.h
+++ b/include/trace/events/osnoise.h
@@ -116,7 +116,7 @@ TRACE_EVENT(thread_noise,
),

TP_fast_assign(
- memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, t, TASK_COMM_LEN);
__entry->pid = t->pid;
__entry->start = start;
__entry->duration = duration;
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 535860581f15..afb24e9dac91 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -152,7 +152,7 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
),

TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
__entry->pid = p->pid;
__entry->prio = p->prio; /* XXX SCHED_DEADLINE */
__entry->target_cpu = task_cpu(p);
@@ -237,11 +237,11 @@ TRACE_EVENT(sched_switch,
),

TP_fast_assign(
- memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->prev_comm, prev, TASK_COMM_LEN);
__entry->prev_pid = prev->pid;
__entry->prev_prio = prev->prio;
__entry->prev_state = __trace_sched_switch_state(preempt, prev_state, prev);
- memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->next_comm, next, TASK_COMM_LEN);
__entry->next_pid = next->pid;
__entry->next_prio = next->prio;
/* XXX SCHED_DEADLINE */
@@ -346,7 +346,7 @@ TRACE_EVENT(sched_process_exit,
),

TP_fast_assign(
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, p, TASK_COMM_LEN);
__entry->pid = p->pid;
__entry->prio = p->prio; /* XXX SCHED_DEADLINE */
__entry->group_dead = group_dead;
@@ -787,7 +787,7 @@ TRACE_EVENT(sched_skip_cpuset_numa,
),

TP_fast_assign(
- memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, tsk, TASK_COMM_LEN);
__entry->pid = task_pid_nr(tsk);
__entry->tgid = task_tgid_nr(tsk);
__entry->ngid = task_numa_group_id(tsk);
diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h
index 1db7e4b07c01..8fffe6d9bdcc 100644
--- a/include/trace/events/signal.h
+++ b/include/trace/events/signal.h
@@ -67,7 +67,7 @@ TRACE_EVENT(signal_generate,
TP_fast_assign(
__entry->sig = sig;
TP_STORE_SIGINFO(__entry, info);
- memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
__entry->pid = task->pid;
__entry->group = group;
__entry->result = result;
diff --git a/include/trace/events/task.h b/include/trace/events/task.h
index b9a129eb54d9..62b7df4d22d0 100644
--- a/include/trace/events/task.h
+++ b/include/trace/events/task.h
@@ -21,7 +21,7 @@ TRACE_EVENT(task_newtask,

TP_fast_assign(
__entry->pid = task->pid;
- memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
+ copy_task_comm(__entry->comm, task, TASK_COMM_LEN);
__entry->clone_flags = clone_flags;
__entry->oom_score_adj = task->signal->oom_score_adj;
),
@@ -46,8 +46,9 @@ TRACE_EVENT(task_rename,

TP_fast_assign(
__entry->pid = task->pid;
- memcpy(entry->oldcomm, task->comm, TASK_COMM_LEN);
- strscpy(entry->newcomm, comm, TASK_COMM_LEN);
+ copy_task_comm(entry->oldcomm, task, TASK_COMM_LEN);
+ memcpy(entry->newcomm, comm, TASK_COMM_LEN);
+ entry->newcomm[TASK_COMM_LEN - 1] = '\0';
__entry->oom_score_adj = task->signal->oom_score_adj;
),

diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index d7044a7a214b..6286286ac2bb 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -952,7 +952,7 @@ static void wctxt_load_execution_ctx(struct nbcon_write_context *wctxt,
{
wctxt->cpu = pmsg->cpu;
wctxt->pid = pmsg->pid;
- memcpy(wctxt->comm, pmsg->comm, sizeof(wctxt->comm));
+ copy_task_comm(wctxt->comm, pmsg, sizeof(wctxt->comm));
static_assert(sizeof(wctxt->comm) == sizeof(pmsg->comm));
}
#else
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 1f04e753ca02..58d58d024cc2 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2255,7 +2255,7 @@ static void pmsg_load_execution_ctx(struct printk_message *pmsg,
{
pmsg->cpu = printk_info_get_cpu(info);
pmsg->pid = printk_info_get_pid(info);
- memcpy(pmsg->comm, info->comm, sizeof(pmsg->comm));
+ copy_task_comm(pmsg->comm, info, sizeof(pmsg->comm));
static_assert(sizeof(pmsg->comm) == sizeof(info->comm));
}
#else

--
2.54.0