(root)/
glibc-2.38/
elf/
tst-env-setuid-tunables.c
       1  /* Copyright (C) 2017-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Verify that tunables correctly filter out unsafe tunables like
      19     glibc.malloc.check and glibc.malloc.mmap_threshold but also retain
      20     glibc.malloc.mmap_threshold in an unprivileged child.  */
      21  
      22  #define _LIBC 1
      23  #include "config.h"
      24  #undef _LIBC
      25  
      26  #include <errno.h>
      27  #include <fcntl.h>
      28  #include <stdlib.h>
      29  #include <stdint.h>
      30  #include <stdio.h>
      31  #include <string.h>
      32  #include <sys/stat.h>
      33  #include <sys/wait.h>
      34  #include <unistd.h>
      35  #include <intprops.h>
      36  #include <array_length.h>
      37  
      38  #include <support/check.h>
      39  #include <support/support.h>
      40  #include <support/test-driver.h>
      41  #include <support/capture_subprocess.h>
      42  
      43  const char *teststrings[] =
      44  {
      45    "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
      46    "glibc.malloc.check=2:glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
      47    "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096:glibc.malloc.check=2",
      48    "glibc.malloc.perturb=0x800",
      49    "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
      50    "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
      51    "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
      52    "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
      53    "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
      54    "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
      55    ":glibc.malloc.garbage=2:glibc.malloc.check=1",
      56    "glibc.malloc.check=1:glibc.malloc.check=2",
      57    "not_valid.malloc.check=2",
      58    "glibc.not_valid.check=2",
      59  };
      60  
      61  const char *resultstrings[] =
      62  {
      63    "glibc.malloc.mmap_threshold=4096",
      64    "glibc.malloc.mmap_threshold=4096",
      65    "glibc.malloc.mmap_threshold=4096",
      66    "glibc.malloc.perturb=0x800",
      67    "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
      68    "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
      69    "glibc.malloc.mmap_threshold=4096",
      70    "glibc.malloc.mmap_threshold=4096",
      71    "",
      72    "",
      73    "",
      74    "",
      75    "",
      76    "",
      77  };
      78  
      79  static int
      80  test_child (int off)
      81  {
      82    const char *val = getenv ("GLIBC_TUNABLES");
      83  
      84    if (val != NULL && strcmp (val, resultstrings[off]) == 0)
      85      return 0;
      86  
      87    if (val != NULL)
      88      printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
      89  
      90    return 1;
      91  }
      92  
      93  static int
      94  do_test (int argc, char **argv)
      95  {
      96    /* Setgid child process.  */
      97    if (argc == 2)
      98      {
      99        if (getgid () == getegid ())
     100  	/* This can happen if the file system is mounted nosuid.  */
     101  	FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
     102  			  (intmax_t) getgid ());
     103  
     104        int ret = test_child (atoi (argv[1]));
     105  
     106        if (ret != 0)
     107  	exit (1);
     108  
     109        exit (EXIT_SUCCESS);
     110      }
     111    else
     112      {
     113        int ret = 0;
     114  
     115        /* Spawn tests.  */
     116        for (int i = 0; i < array_length (teststrings); i++)
     117  	{
     118  	  char buf[INT_BUFSIZE_BOUND (int)];
     119  
     120  	  printf ("Spawned test for %s (%d)\n", teststrings[i], i);
     121  	  snprintf (buf, sizeof (buf), "%d\n", i);
     122  	  if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
     123  	    exit (1);
     124  
     125  	  int status = support_capture_subprogram_self_sgid (buf);
     126  
     127  	  /* Bail out early if unsupported.  */
     128  	  if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
     129  	    return EXIT_UNSUPPORTED;
     130  
     131  	  ret |= status;
     132  	}
     133        return ret;
     134      }
     135  }
     136  
     137  #define TEST_FUNCTION_ARGV do_test
     138  #include <support/test-driver.c>