Re: [PATCH 3/3] selftests/mseal_system_mappings: Test vdso unmap and remap
From: Lorenzo Stoakes (ARM)
Date: Tue Oct 27 2026 - 11:04:25 EST
Sorry, in mm we require commit messages. Even for tests :)
On Tue, Oct 27, 2026 at 07:43:25PM +0800, Chris Down wrote:
> Signed-off-by: Chris Down <chris@xxxxxxxxxxxxxx>
> ---
> .../mseal_system_mappings/sysmap_is_sealed.c | 92 +++++++++++++++++++
> 1 file changed, 92 insertions(+)
>
> 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 ea75ad537620..83b4fadfbfe7 100644
> --- a/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c
> +++ b/tools/testing/selftests/mseal_system_mappings/sysmap_is_sealed.c
Why on earth does 'mseal_system_mappings' have its own directory...??
Ugh I don't know how I let this stuff go on the original series :/
Please, for the love of all that's sacred, move these tests over to
tools/selftests/mm/. This is an mm feature, for our sins...
You can do the move as a prerequisite patch in the series.
(And, again, I really do insist on your change doing some cleanup here as
well rather than extending this stuff.)
> @@ -10,6 +10,7 @@
> #include <unistd.h>
> #include <string.h>
> #include <stdbool.h>
> +#include <sys/mman.h>
> #include <sys/utsname.h>
> #include <zlib.h>
>
> @@ -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;
> +}
There's shared code for this kind of thing, please don't duplicate a
/proc/self/maps thing if unnecessary. Also there's a nicer ioctl interface for
all this.
See vm_utils.[ch].
> +
> +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);
I mean arguably this is an mremap test that belongs with mremap? I guess
debatable...
> + 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);
> +}
> +
> TEST_HARNESS_MAIN
> --
> 2.54.0
>
This all just seems like work that should have been done in the past when this
feature was proposed, and doesn't depend on your changes at all AFAICT? Maybe I
missed it though.
Valuable in itself, but probably worth sending separately as a result? Otherwise
it's a little disconnected from the actual change you're making.
--
Cheers, Lorenzo