(root)/
glibc-2.38/
stdlib/
tst-secure-getenv.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  /* Test that secure_getenv works by invoking the test as a SGID
      19     program with a group ID from the supplementary group list.  This
      20     test can fail spuriously if the user is not a member of a suitable
      21     supplementary group.  */
      22  
      23  #include <errno.h>
      24  #include <fcntl.h>
      25  #include <stdlib.h>
      26  #include <stdint.h>
      27  #include <stdio.h>
      28  #include <string.h>
      29  #include <sys/stat.h>
      30  #include <sys/wait.h>
      31  #include <unistd.h>
      32  
      33  #include <support/check.h>
      34  #include <support/support.h>
      35  #include <support/capture_subprocess.h>
      36  #include <support/test-driver.h>
      37  
      38  static char MAGIC_ARGUMENT[] = "run-actual-test";
      39  
      40  static int
      41  do_test (void)
      42  {
      43    if (getenv ("PATH") == NULL)
      44      {
      45        printf ("PATH not set\n");
      46        exit (1);
      47      }
      48    if (secure_getenv ("PATH") == NULL)
      49      {
      50        printf ("PATH not set according to secure_getenv\n");
      51        exit (1);
      52      }
      53    if (strcmp (getenv ("PATH"), secure_getenv ("PATH")) != 0)
      54      {
      55        printf ("PATH mismatch (%s, %s)\n",
      56  	      getenv ("PATH"), secure_getenv ("PATH"));
      57        exit (1);
      58      }
      59  
      60    int status = support_capture_subprogram_self_sgid (MAGIC_ARGUMENT);
      61  
      62    if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
      63      return EXIT_UNSUPPORTED;
      64  
      65    if (!WIFEXITED (status))
      66      FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
      67  
      68    return 0;
      69  }
      70  
      71  static void
      72  alternative_main (int argc, char **argv)
      73  {
      74    if (argc == 2 && strcmp (argv[1], MAGIC_ARGUMENT) == 0)
      75      {
      76        if (getgid () == getegid ())
      77  	/* This can happen if the file system is mounted nosuid.  */
      78  	FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
      79  		   (intmax_t) getgid ());
      80        if (getenv ("PATH") == NULL)
      81  	FAIL_EXIT (3, "PATH variable not present\n");
      82        if (secure_getenv ("PATH") != NULL)
      83  	FAIL_EXIT (4, "PATH variable not filtered out\n");
      84  
      85        exit (EXIT_SUCCESS);
      86      }
      87  }
      88  
      89  #define PREPARE alternative_main
      90  #include <support/test-driver.c>