* + prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator.patch added to mm-nonmm-unstable branch
@ 2026-08-10 22:44 Andrew Morton
0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2026-08-10 22:44 UTC (permalink / raw)
To: mm-commits, gorcunov, adobriyan, include, akpm
The patch titled
Subject: prctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminator
has been added to the -mm mm-nonmm-unstable branch. Its filename is
prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator.patch
This patch will later appear in the mm-nonmm-unstable branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via various
branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there most days
------------------------------------------------------
From: Bradley Morgan <include@grrlz.net>
Subject: prctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminator
Date: Sun, 9 Aug 2026 00:29:01 +0000
prctl_set_auxv() copies the user vector into a stack buffer, forces
AT_NULL on the last two entries there, and then copies only len bytes into
mm->saved_auxv. Which is fine until the vector is shorter than the
buffer, because then the forced terminator sits past the end of the copy
and never lands in saved_auxv at all.
The code even says
/* Make sure the last entry is always AT_NULL */
and it does, just not in the part that gets copied.
So mm->saved_auxv keeps the stale tail from exec. Reproducing it is easy:
from a process with CAP_SYS_RESOURCE (just run it as root), call
prctl(PR_SET_MM, PR_SET_MM_AUXV, ...) with a vector that has a couple of
entries and no AT_NULL inside len (32 bytes on arm64), and then hexdump
/proc/self/auxv, or gcore the process and look at the AUXV note with
readelf -n. This is arm64, the new vector was just { AT_UID, 0x1111,
AT_GID, 0x2222 }:
idx before (from exec) after the prctl
[0] AT_SYSINFO_EHDR 0x7ed1d6e000 AT_UID 0x1111 <- new
[1] AT_MINSIGSTKSZ 0x1270 AT_GID 0x2222 <- new
[2] AT_HWCAP 0x119fff AT_HWCAP 0x119fff <- stale
[3] AT_PAGESZ 0x1000 AT_PAGESZ 0x1000 <- stale
... 16 more entries ... <- stale
[20] AT_NULL 0x0 AT_NULL 0x0
21 entries before the prctl, still 21 after: the two new ones plus all 19
left over from exec.
Every consumer walks the vector until AT_NULL, so what they get now is a
vector that never existed at exec, the head from the prctl glued onto the
tail of the old binary. gdb and crash pull the AUXV note out of coredumps
to find AT_PHDR, AT_ENTRY, AT_SYSINFO_EHDR and friends, and a mixed vector
points them at the wrong layout. /proc/<pid>/auxv and PR_GET_AUXV hand
the same mess out to live processes too. Nothing crashes, everything just
quietly reads a frankenstein auxv.
And callers that terminate their own vector hide the whole thing, which is
likely why nobody noticed since PR_SET_MM_AUXV landed in 2012. Nothing
exciting security wise either, I mean it needs CAP_SYS_RESOURCE to begin
with.
prctl_set_mm_map() right above already copies the whole buffer for exactly
this reason, so just do the same here. user_auxv is zero initialized and
only partially filled from userspace, so the rest is zeros and nothing
leaks.
Link: https://lore.kernel.org/20260809002901.32591-1-include@grrlz.net
Fixes: fe8c7f5cbf91 ("c/r: prctl: extend PR_SET_MM to set up more mm_struct entries")
Signed-off-by: Bradley Morgan <include@grrlz.net>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Cyrill Gorcuno <gorcunov@openvz.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
kernel/sys.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/sys.c~prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator
+++ a/kernel/sys.c
@@ -2189,7 +2189,7 @@ static int prctl_set_auxv(struct mm_stru
BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
task_lock(current);
- memcpy(mm->saved_auxv, user_auxv, len);
+ memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
task_unlock(current);
return 0;
_
Patches currently in -mm which might be from include@grrlz.net are
taskstats-drop-the-dead-null-attribute-check-in-parse.patch
taskstats-fold-the-two-cpumask-handlers-into-one.patch
signal-factor-out-the-kernel-reserved-si_code-check.patch
taskstats-copy-signal-stats-under-siglock-in-taskstats_exit.patch
prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator.patch
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-10 22:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 22:44 + prctl-fix-pr_set_mm_auxv-losing-the-forced-at_null-terminator.patch added to mm-nonmm-unstable branch Andrew Morton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.