Enhance setuid-tunables test

Instead of passing GLIBC_TUNABLES via the environment, pass the
environment variable from parent to child.  This allows us to test
multiple variables to ensure better coverage.

The test list currently only includes the case that's already being
tested.  More tests will be added later.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>

(cherry picked from commit 061fe3f8ad)
This commit is contained in:
Siddhesh Poyarekar 2021-03-16 12:37:54 +05:30
parent 1927d02d19
commit dcfcb1b208
2 changed files with 67 additions and 21 deletions

View File

@ -1465,8 +1465,6 @@ $(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \
tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \ tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
LD_HWCAP_MASK=0x1 LD_HWCAP_MASK=0x1
tst-env-setuid-tunables-ENV = \
GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
$(objpfx)tst-debug1: $(libdl) $(objpfx)tst-debug1: $(libdl)
$(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so $(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so

View File

@ -25,35 +25,50 @@
#include "config.h" #include "config.h"
#undef _LIBC #undef _LIBC
#define test_parent test_parent_tunables #include <errno.h>
#define test_child test_child_tunables #include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <intprops.h>
#include <array_length.h>
static int test_child_tunables (void); #include <support/check.h>
static int test_parent_tunables (void); #include <support/support.h>
#include <support/test-driver.h>
#include <support/capture_subprocess.h>
#include "tst-env-setuid.c" const char *teststrings[] =
{
"glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
};
#define CHILD_VALSTRING_VALUE "glibc.malloc.mmap_threshold=4096" const char *resultstrings[] =
#define PARENT_VALSTRING_VALUE \ {
"glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096" "glibc.malloc.mmap_threshold=4096",
};
static int static int
test_child_tunables (void) test_child (int off)
{ {
const char *val = getenv ("GLIBC_TUNABLES"); const char *val = getenv ("GLIBC_TUNABLES");
#if HAVE_TUNABLES #if HAVE_TUNABLES
if (val != NULL && strcmp (val, CHILD_VALSTRING_VALUE) == 0) if (val != NULL && strcmp (val, resultstrings[off]) == 0)
return 0; return 0;
if (val != NULL) if (val != NULL)
printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val); printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
return 1; return 1;
#else #else
if (val != NULL) if (val != NULL)
{ {
printf ("GLIBC_TUNABLES not cleared\n"); printf ("[%d] GLIBC_TUNABLES not cleared\n", off);
return 1; return 1;
} }
return 0; return 0;
@ -61,15 +76,48 @@ test_child_tunables (void)
} }
static int static int
test_parent_tunables (void) do_test (int argc, char **argv)
{ {
const char *val = getenv ("GLIBC_TUNABLES"); /* Setgid child process. */
if (argc == 2)
{
if (getgid () == getegid ())
/* This can happen if the file system is mounted nosuid. */
FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
(intmax_t) getgid ());
if (val != NULL && strcmp (val, PARENT_VALSTRING_VALUE) == 0) int ret = test_child (atoi (argv[1]));
return 0;
if (val != NULL) if (ret != 0)
printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val); exit (1);
return 1; exit (EXIT_SUCCESS);
}
else
{
int ret = 0;
/* Spawn tests. */
for (int i = 0; i < array_length (teststrings); i++)
{
char buf[INT_BUFSIZE_BOUND (int)];
printf ("Spawned test for %s (%d)\n", teststrings[i], i);
snprintf (buf, sizeof (buf), "%d\n", i);
if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
exit (1);
int status = support_capture_subprogram_self_sgid (buf);
/* Bail out early if unsupported. */
if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
return EXIT_UNSUPPORTED;
ret |= status;
}
return ret;
}
} }
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>