Out-of-bounds read / Memory safety

HIGH
torvalds/linux
Commit: 613b48bbd465
Affected: < v7.0-rc6
2026-04-16 06:20 UTC

Description

The patch fixes a memory-safety vulnerability by replacing an out-of-bounds read when computing the length to copy into task_struct->comm. Previously __set_task_comm used strlen(buf) to determine the length, which can read past a non-NUL-terminated user-provided buffer. The fix uses strnlen(buf, sizeof(tsk->comm) - 1) to cap the read to the destination buffer, preventing potential over-read and related memory-safety issues or information disclosure. This is a genuine safety improvement in the exec path that updates task names.

Proof of Concept

/* PoC: spawn a child with a argv[0] longer than the task_comm buffer to observe how the kernel handles copying non-terminated data into task_comm. This demonstrates the bound-limiting behavior introduced by the patch. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> extern char **environ; int main(void) { pid_t pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid == 0) { // Child: construct an argv[0] longer than typical TASK_COMM_LEN and exec /bin/true char longname[128]; memset(longname, 'A', sizeof(longname) - 1); longname[sizeof(longname) - 1] = '\0'; char *args[] = { longname, NULL }; execve("/bin/true", args, environ); perror("execve"); _exit(1); } else { // Parent: read the comm for the child from /proc to see how the kernel stored the name char path[256]; snprintf(path, sizeof(path), "/proc/%d/comm", pid); FILE *f = NULL; char buf[256]; for (int i = 0; i < 100; i++) { f = fopen(path, "r"); if (f) { if (fgets(buf, sizeof(buf), f)) { printf("observed comm: %s\n", buf); fclose(f); break; } fclose(f); } usleep(10000); } waitpid(pid, NULL, 0); } return 0; }

Commit Details

Author: Linus Torvalds

Date: 2026-04-14 00:41 UTC

Message:

Merge tag 'execve-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull execve updates from Kees Cook: - use strnlen() in __set_task_comm (Thorsten Blum) - update task_struct->comm comment (Thorsten Blum) * tag 'execve-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: sched: update task_struct->comm comment exec: use strnlen() in __set_task_comm

Triage Assessment

Vulnerability Type: Memory safety

Confidence: HIGH

Reasoning:

The patch changes __set_task_comm to use strnlen() instead of strlen() when computing the length to copy into task_struct->comm, bounded by the destination buffer size. This prevents potential out-of-bounds or overlong reads from a non-NUL-terminated user input buffer, reducing risk of information disclosure or memory safety issues. It also clarifies the intended boundary behavior in the code and comments.

Verification Assessment

Vulnerability Type: Out-of-bounds read / Memory safety

Confidence: HIGH

Affected Versions: < v7.0-rc6

Code Diff

diff --git a/fs/exec.c b/fs/exec.c index 9ea3a775d51e9b..ba12b4c466f6da 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1074,7 +1074,7 @@ static int unshare_sighand(struct task_struct *me) */ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec) { - size_t len = min(strlen(buf), sizeof(tsk->comm) - 1); + size_t len = strnlen(buf, sizeof(tsk->comm) - 1); trace_task_rename(tsk, buf); memcpy(tsk->comm, buf, len); diff --git a/include/linux/sched.h b/include/linux/sched.h index ffb2ad9716f05c..54820a4270142a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1163,12 +1163,9 @@ struct task_struct { /* * executable name, excluding path. * - * - normally initialized begin_new_exec() - * - set it with set_task_comm() - * - strscpy_pad() to ensure it is always NUL-terminated and - * zero-padded - * - task_lock() to ensure the operation is atomic and the name is - * fully updated. + * - normally initialized by begin_new_exec() + * - set it with set_task_comm() to ensure it is always + * NUL-terminated and zero-padded */ char comm[TASK_COMM_LEN];
← Back to Alerts View on GitHub →