(root)/
glibc-2.38/
elf/
tst-env-setuid.c
       1  /* Copyright (C) 2012-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 environment variables like
      19     MALLOC_CHECK_ and MALLOC_MMAP_THRESHOLD_ but also retain
      20     MALLOC_MMAP_THRESHOLD_ in an unprivileged child.  */
      21  
      22  #include <errno.h>
      23  #include <fcntl.h>
      24  #include <stdlib.h>
      25  #include <stdint.h>
      26  #include <stdio.h>
      27  #include <string.h>
      28  #include <sys/stat.h>
      29  #include <sys/wait.h>
      30  #include <unistd.h>
      31  
      32  #include <support/check.h>
      33  #include <support/support.h>
      34  #include <support/test-driver.h>
      35  #include <support/capture_subprocess.h>
      36  
      37  static char SETGID_CHILD[] = "setgid-child";
      38  
      39  #ifndef test_child
      40  static int
      41  test_child (void)
      42  {
      43    if (getenv ("MALLOC_CHECK_") != NULL)
      44      {
      45        printf ("MALLOC_CHECK_ is still set\n");
      46        return 1;
      47      }
      48  
      49    if (getenv ("MALLOC_MMAP_THRESHOLD_") == NULL)
      50      {
      51        printf ("MALLOC_MMAP_THRESHOLD_ lost\n");
      52        return 1;
      53      }
      54  
      55    if (getenv ("LD_HWCAP_MASK") != NULL)
      56      {
      57        printf ("LD_HWCAP_MASK still set\n");
      58        return 1;
      59      }
      60  
      61    return 0;
      62  }
      63  #endif
      64  
      65  #ifndef test_parent
      66  static int
      67  test_parent (void)
      68  {
      69    if (getenv ("MALLOC_CHECK_") == NULL)
      70      {
      71        printf ("MALLOC_CHECK_ lost\n");
      72        return 1;
      73      }
      74  
      75    if (getenv ("MALLOC_MMAP_THRESHOLD_") == NULL)
      76      {
      77        printf ("MALLOC_MMAP_THRESHOLD_ lost\n");
      78        return 1;
      79      }
      80  
      81    if (getenv ("LD_HWCAP_MASK") == NULL)
      82      {
      83        printf ("LD_HWCAP_MASK lost\n");
      84        return 1;
      85      }
      86  
      87    return 0;
      88  }
      89  #endif
      90  
      91  static int
      92  do_test (int argc, char **argv)
      93  {
      94    /* Setgid child process.  */
      95    if (argc == 2 && strcmp (argv[1], SETGID_CHILD) == 0)
      96      {
      97        if (getgid () == getegid ())
      98  	/* This can happen if the file system is mounted nosuid.  */
      99  	FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
     100  			  (intmax_t) getgid ());
     101  
     102        int ret = test_child ();
     103  
     104        if (ret != 0)
     105  	exit (1);
     106  
     107        exit (EXIT_SUCCESS);
     108      }
     109    else
     110      {
     111        if (test_parent () != 0)
     112  	exit (1);
     113  
     114        int status = support_capture_subprogram_self_sgid (SETGID_CHILD);
     115  
     116        if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
     117  	return EXIT_UNSUPPORTED;
     118  
     119        if (!WIFEXITED (status))
     120  	FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
     121  
     122        return 0;
     123      }
     124  }
     125  
     126  #define TEST_FUNCTION_ARGV do_test
     127  #include <support/test-driver.c>