From: sashiko-bot@kernel.org
To: "Chris Down" <chris@chrisdown.name>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Liam R. Howlett" <liam@infradead.org>,
"Lorenzo Stoakes" <ljs@kernel.org>
Cc: "Vlastimil Babka" <vbabka@kernel.org>,
"Jann Horn" <jannh@google.com>,
"Pedro Falcato" <pfalcato@suse.de>,
"David Hildenbrand" <david@kernel.org>,
"Kees Cook" <kees@kernel.org>, "Jeff Xu" <jeffxu@chromium.org>,
"Andrey Vagin" <avagin@gmail.com>,
"Alexander Mikhalitsyn" <alexander@mihalicyn.com>,
"Paul Moore" <paul@paul-moore.com>,
"James Morris" <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
"Shuah Khan" <shuah@kernel.org>,
"Jonathan Corbet" <corbet@lwn.net>,
linux-mm@kvack.org, linux-security-module@vger.kernel.org,
kernel-team@meta.com
Subject: Re: [PATCH 3/3] selftests/mseal_system_mappings: Test vdso unmap and remap
Date: Wed, 28 Oct 2026 11:43:35 +0000 [thread overview]
Message-ID: <sashiko-outbox-187839@kernel.org> (raw)
In-Reply-To: <621847973ba2ec49d0a58e0261da35a9f3a97eda.1793094611.git.chris@chrisdown.name>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] selftests/mseal: SIGSEGV in vdso_munmap() and vdso_mremap() on 32-bit x86
--
commit c39ca555b3d21581707989b9c4e4f219f86ffc25
Author: Chris Down <chris@chrisdown.name>
selftests/mseal_system_mappings: Test vdso unmap and remap
This patch adds vdso_munmap and vdso_mremap tests to
tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c to verify
that unmapping or moving [vdso] fails with EPERM when sealed and succeeds
when unsealed.
> diff --git a/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c b/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c
> index ea75ad537620b..83b4fadfbfe79 100644
> --- a/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c
> +++ b/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c
[ ... ]
> @@ -232,4 +233,95 @@ TEST_F(basic, check_sealed)
> EXPECT_EQ(expected, sealed);
> };
>
> +static bool find_vdso(unsigned long *start, unsigned long *end)
> +{
> + char line[MAX_LINE_LEN];
> + bool found = false;
> + FILE *maps;
> +
> + maps = fopen("/proc/self/maps", "r");
> + if (!maps)
> + return false;
> +
> + while (fgets(line, sizeof(line), maps)) {
> + if (strstr(line, "[vdso]") &&
> + sscanf(line, "%lx-%lx", start, end) == 2) {
> + found = true;
> + break;
> + }
> + }
> +
> + fclose(maps);
> + return found;
> +}
> +
> +static int vdso_is_sealed(void)
> +{
> + int sealed = -1;
> + FILE *maps;
> +
> + maps = fopen("/proc/self/smaps", "r");
> + if (!maps)
> + return -1;
> + if (has_mapping("[vdso]", maps))
> + sealed = mapping_is_sealed(maps);
> + fclose(maps);
> + return sealed;
> +}
> +
> +/*
> + * Unmapping or moving [vdso] must fail with EPERM when it is sealed. When it
> + * is not sealed, it succeeds and leaves glibc with a stale vdso pointer, which
> + * is fine because each test runs in its own forked child.
> + */
> +TEST(vdso_munmap)
> +{
> + int sealed;
> + unsigned long start, end;
> + int ret;
> +
> + if (!find_vdso(&start, &end))
> + SKIP(return, "could not find the mapping, [vdso]");
> + sealed = vdso_is_sealed();
> + if (sealed < 0)
> + SKIP(return, "could not read the [vdso] sealing state");
> +
> + ret = munmap((void *)start, end - start);
> + if (sealed) {
> + EXPECT_EQ(-1, ret);
> + EXPECT_EQ(EPERM, errno);
> + } else {
> + EXPECT_EQ(0, ret);
> + }
> + EXPECT_EQ(sealed, find_vdso(&start, &end));
> +}
> +
> +TEST(vdso_mremap)
> +{
> + int sealed;
> + unsigned long start, end, size, new_start;
> + void *dst, *ret;
> +
> + if (!find_vdso(&start, &end))
> + SKIP(return, "could not find the mapping, [vdso]");
> + sealed = vdso_is_sealed();
> + if (sealed < 0)
> + SKIP(return, "could not read the [vdso] sealing state");
> + size = end - start;
> +
> + dst = mmap(NULL, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> + ASSERT_NE(MAP_FAILED, dst);
> +
> + ret = mremap((void *)start, size, size, MREMAP_MAYMOVE | MREMAP_FIXED,
> + dst);
> + if (sealed) {
> + EXPECT_EQ(MAP_FAILED, ret);
> + EXPECT_EQ(EPERM, errno);
> + } else {
> + EXPECT_EQ(dst, ret);
> + }
> + ASSERT_TRUE(find_vdso(&new_start, &end));
> + EXPECT_EQ(sealed ? start : (unsigned long)dst, new_start);
> +}
[Severity: Medium]
When sealed == 0 on 32-bit x86 (__i386__), will vdso_munmap and vdso_mremap
in tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c crash
with SIGSEGV and cause the test harness to report a failure?
On 32-bit x86, the kernel passes AT_SYSINFO in the ELF auxiliary vector
pointing to __kernel_vsyscall inside [vdso], and glibc caches this pointer
in %gs:0x10 and routes all system calls through it.
Neither vdso_munmap nor vdso_mremap skips on 32-bit builds or when
CONFIG_MSEAL_SYSTEM_MAPPINGS is disabled (which depends on 64BIT, or may be
disabled via CONFIG_CHECKPOINT_RESTORE=y or mseal_system_mappings=0).
In vdso_munmap, when sealed == 0, calling munmap() via glibc enters the
kernel through __kernel_vsyscall inside [vdso] with the userspace return
address pointing to the landing pad in [vdso]. Once [vdso] is unmapped,
returning to userspace or calling find_vdso() and _exit() in the child jumps
to the unmapped [vdso] range and faults with SIGSEGV.
Similarly, in vdso_mremap, when sealed == 0, arch/x86/entry/vdso/vma.c
updates the return instruction pointer for the mremap() syscall itself via
vdso_fix_landing(), but glibc's cached %gs:0x10 pointer still points to the
old unmapped start address. The subsequent find_vdso() call (which invokes
fopen(), fgets(), and fclose()) and _exit() in the test harness jump through
the stale pointer into the unmapped address and fault with SIGSEGV, as noted
in tools/testing/selftests/x86/test_mremap_vdso.c:main():
#ifdef __i386__
/* Glibc is likely to explode now - exit with raw syscall */
asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret));
#else /* __x86_64__ */
syscall(SYS_exit, ret);
#endif
Should vdso_munmap and vdso_mremap be skipped on 32-bit x86 or when
[vdso] is unsealed on __i386__?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793094611.git.chris@chrisdown.name?part=3
next prev parent reply other threads:[~2026-10-28 11:43 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 11:42 [PATCH 0/3] mseal sysmap: Choose system mapping sealing at boot Chris Down
2026-10-27 11:43 ` [PATCH 1/3] mseal sysmap: Add mseal_system_mappings= boot parameter Chris Down
2026-10-27 14:53 ` Lorenzo Stoakes (ARM)
2026-10-27 16:37 ` Chris Down
2026-10-27 16:57 ` Lorenzo Stoakes (ARM)
2026-10-28 4:30 ` Jeff Xu
2026-10-28 5:52 ` Chris Down
2026-10-28 5:55 ` Chris Down
2026-10-28 6:16 ` Jeff Xu
2026-10-28 9:49 ` Lorenzo Stoakes (ARM)
2026-10-28 11:43 ` sashiko-bot
2026-10-28 12:18 ` Pedro Falcato
2026-10-27 11:43 ` [PATCH 2/3] mseal sysmap: Allow with CHECKPOINT_RESTORE, default off Chris Down
2026-10-27 14:57 ` Lorenzo Stoakes (ARM)
2026-10-27 16:37 ` Chris Down
2026-10-27 16:59 ` Lorenzo Stoakes (ARM)
2026-10-28 11:43 ` sashiko-bot
2026-10-27 11:43 ` [PATCH 3/3] selftests/mseal_system_mappings: Test vdso unmap and remap Chris Down
2026-10-27 15:03 ` Lorenzo Stoakes (ARM)
2026-10-27 16:40 ` Chris Down
2026-10-27 17:02 ` Lorenzo Stoakes (ARM)
2026-10-28 11:43 ` sashiko-bot [this message]
2026-10-28 15:34 ` [PATCH 0/3] mseal sysmap: Choose system mapping sealing at boot Andrei Vagin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-187839@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alexander@mihalicyn.com \
--cc=avagin@gmail.com \
--cc=chris@chrisdown.name \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=jannh@google.com \
--cc=jeffxu@chromium.org \
--cc=jmorris@namei.org \
--cc=kees@kernel.org \
--cc=kernel-team@meta.com \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=linux-security-module@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=paul@paul-moore.com \
--cc=pfalcato@suse.de \
--cc=sashiko-reviews@lists.linux.dev \
--cc=serge@hallyn.com \
--cc=shuah@kernel.org \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.