860497a
commit a7b8e8ec9b21c7c6d4ec0ba2229abd63dc3a00b2
860497a
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
860497a
Date:   Tue Mar 16 12:37:54 2021 +0530
860497a
860497a
    Enhance setuid-tunables test
860497a
    
860497a
    Instead of passing GLIBC_TUNABLES via the environment, pass the
860497a
    environment variable from parent to child.  This allows us to test
860497a
    multiple variables to ensure better coverage.
860497a
    
860497a
    The test list currently only includes the case that's already being
860497a
    tested.  More tests will be added later.
860497a
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
860497a
    
860497a
    (cherry picked from commit 061fe3f8add46a89b7453e87eabb9c4695005ced)
860497a
860497a
diff --git a/elf/Makefile b/elf/Makefile
860497a
index 4b92f8b3054b556e..28e18aea5d412222 100644
860497a
--- a/elf/Makefile
860497a
+++ b/elf/Makefile
860497a
@@ -1658,8 +1658,6 @@ $(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \
860497a
 
860497a
 tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
860497a
 		     LD_HWCAP_MASK=0x1
860497a
-tst-env-setuid-tunables-ENV = \
860497a
-	GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
860497a
 
860497a
 $(objpfx)tst-debug1: $(libdl)
860497a
 $(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so
860497a
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
860497a
index 50bef8683df0e9c1..3d523875b1e07a74 100644
860497a
--- a/elf/tst-env-setuid-tunables.c
860497a
+++ b/elf/tst-env-setuid-tunables.c
860497a
@@ -25,35 +25,50 @@
860497a
 #include "config.h"
860497a
 #undef _LIBC
860497a
 
860497a
-#define test_parent test_parent_tunables
860497a
-#define test_child test_child_tunables
860497a
-
860497a
-static int test_child_tunables (void);
860497a
-static int test_parent_tunables (void);
860497a
-
860497a
-#include "tst-env-setuid.c"
860497a
+#include <errno.h>
860497a
+#include <fcntl.h>
860497a
+#include <stdlib.h>
860497a
+#include <stdint.h>
860497a
+#include <stdio.h>
860497a
+#include <string.h>
860497a
+#include <sys/stat.h>
860497a
+#include <sys/wait.h>
860497a
+#include <unistd.h>
860497a
+#include <intprops.h>
860497a
+#include <array_length.h>
860497a
+
860497a
+#include <support/check.h>
860497a
+#include <support/support.h>
860497a
+#include <support/test-driver.h>
860497a
+#include <support/capture_subprocess.h>
860497a
+
860497a
+const char *teststrings[] =
860497a
+{
860497a
+  "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
860497a
+};
860497a
 
860497a
-#define CHILD_VALSTRING_VALUE "glibc.malloc.mmap_threshold=4096"
860497a
-#define PARENT_VALSTRING_VALUE \
860497a
-  "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096"
860497a
+const char *resultstrings[] =
860497a
+{
860497a
+  "glibc.malloc.mmap_threshold=4096",
860497a
+};
860497a
 
860497a
 static int
860497a
-test_child_tunables (void)
860497a
+test_child (int off)
860497a
 {
860497a
   const char *val = getenv ("GLIBC_TUNABLES");
860497a
 
860497a
 #if HAVE_TUNABLES
860497a
-  if (val != NULL && strcmp (val, CHILD_VALSTRING_VALUE) == 0)
860497a
+  if (val != NULL && strcmp (val, resultstrings[off]) == 0)
860497a
     return 0;
860497a
 
860497a
   if (val != NULL)
860497a
-    printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
860497a
+    printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
860497a
 
860497a
   return 1;
860497a
 #else
860497a
   if (val != NULL)
860497a
     {
860497a
-      printf ("GLIBC_TUNABLES not cleared\n");
860497a
+      printf ("[%d] GLIBC_TUNABLES not cleared\n", off);
860497a
       return 1;
860497a
     }
860497a
   return 0;
860497a
@@ -61,15 +76,48 @@ test_child_tunables (void)
860497a
 }
860497a
 
860497a
 static int
860497a
-test_parent_tunables (void)
860497a
+do_test (int argc, char **argv)
860497a
 {
860497a
-  const char *val = getenv ("GLIBC_TUNABLES");
860497a
+  /* Setgid child process.  */
860497a
+  if (argc == 2)
860497a
+    {
860497a
+      if (getgid () == getegid ())
860497a
+	/* This can happen if the file system is mounted nosuid.  */
860497a
+	FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
860497a
+			  (intmax_t) getgid ());
860497a
 
860497a
-  if (val != NULL && strcmp (val, PARENT_VALSTRING_VALUE) == 0)
860497a
-    return 0;
860497a
+      int ret = test_child (atoi (argv[1]));
860497a
 
860497a
-  if (val != NULL)
860497a
-    printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
860497a
+      if (ret != 0)
860497a
+	exit (1);
860497a
 
860497a
-  return 1;
860497a
+      exit (EXIT_SUCCESS);
860497a
+    }
860497a
+  else
860497a
+    {
860497a
+      int ret = 0;
860497a
+
860497a
+      /* Spawn tests.  */
860497a
+      for (int i = 0; i < array_length (teststrings); i++)
860497a
+	{
860497a
+	  char buf[INT_BUFSIZE_BOUND (int)];
860497a
+
860497a
+	  printf ("Spawned test for %s (%d)\n", teststrings[i], i);
860497a
+	  snprintf (buf, sizeof (buf), "%d\n", i);
860497a
+	  if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
860497a
+	    exit (1);
860497a
+
860497a
+	  int status = support_capture_subprogram_self_sgid (buf);
860497a
+
860497a
+	  /* Bail out early if unsupported.  */
860497a
+	  if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
860497a
+	    return EXIT_UNSUPPORTED;
860497a
+
860497a
+	  ret |= status;
860497a
+	}
860497a
+      return ret;
860497a
+    }
860497a
 }
860497a
+
860497a
+#define TEST_FUNCTION_ARGV do_test
860497a
+#include <support/test-driver.c>