From: Kees Cook > Sent: 30 November 2024 04:49 > > Instead of adding a new use of the ambiguous strncpy(), we'd want to > use memtostr_pad() which enforces being able to check at compile time > that sizes are sensible, but this requires being able to see string > buffer lengths. Instead of trying to inline __set_task_comm() (which > needs to call trace and perf functions), just open-code it. But to > make sure we're always safe, add compile-time checking like we already > do for get_task_comm(). ... > Here's what I'd prefer to use to clean up set_task_comm(). I merged > Linus and Eric's suggestions and open-coded memtostr_pad(). > --- > fs/exec.c | 12 ++++++------ > include/linux/sched.h | 9 ++++----- > io_uring/io-wq.c | 2 +- > io_uring/sqpoll.c | 2 +- > kernel/kthread.c | 3 ++- > 5 files changed, 14 insertions(+), 14 deletions(-) > > diff --git a/fs/exec.c b/fs/exec.c > index e0435b31a811..5f16500ac325 100644 > --- a/fs/exec.c > +++ b/fs/exec.c > @@ -1200,16 +1200,16 @@ char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk) > EXPORT_SYMBOL_GPL(__get_task_comm); > > /* > - * These functions flushes out all traces of the currently running executable > - * so that a new one can be started > + * This is unlocked -- the string will always be NUL-terminated, but > + * may show overlapping contents if racing concurrent reads. > */ > - > void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec) > { > - task_lock(tsk); > + size_t len = min(strlen(buf), sizeof(tsk->comm) - 1); > + > trace_task_rename(tsk, buf); > - strscpy_pad(tsk->comm, buf, sizeof(tsk->comm)); > - task_unlock(tsk); > + memcpy(tsk->comm, buf, len); > + memset(&tsk->comm[len], 0, sizeof(tsk->comm) - len); > perf_event_comm(tsk, exec); Why not do strscpy_pad() into a local char[16] and then do a 16 byte memcpy() into the target buffer? Then non-constant input data will always give a valid '\0' terminated string regardless of how strscpy_pad() is implemented. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)