(root)/
glibc-2.38/
sysdeps/
mach/
hurd/
check_fds.c
       1  /* Copyright (C) 2000-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  #include <fcntl.h>
      19  #include <paths.h>
      20  #include <unistd.h>
      21  
      22  #include <hurd.h>
      23  #include <hurd/fd.h>
      24  
      25  #include <set-hooks.h>
      26  
      27  /* Try to get a machine dependent instruction which will make the
      28     program crash.  This is used in case everything else fails.  */
      29  #include <abort-instr.h>
      30  #ifndef ABORT_INSTRUCTION
      31  /* No such instruction is available.  */
      32  # define ABORT_INSTRUCTION
      33  #endif
      34  
      35  static void
      36  check_one_fd (int fd, int mode)
      37  {
      38    struct hurd_fd *d;
      39  
      40    d = _hurd_fd_get (fd);
      41    if (d == NULL)
      42      {
      43        /* This descriptor hasn't been opened.  We try to allocate the
      44           descriptor and open /dev/null on it so that the SUID program
      45           we are about to start does not accidentally use this
      46           descriptor.  */
      47        d = _hurd_alloc_fd (NULL, fd);
      48        if (d != NULL)
      49  	{
      50  	  mach_port_t port;
      51  
      52  	  port = __file_name_lookup (_PATH_DEVNULL, mode, 0);
      53  	  if (port)
      54  	    {
      55  	      /* Since /dev/null isn't supposed to be a terminal, we
      56  		 avoid any ctty magic.  */
      57  	      d->port.port = port;
      58  	      d->flags = 0;
      59  
      60  	      __spin_unlock (&d->port.lock);
      61  	      return;
      62  	    }
      63  	}
      64  
      65        /* We cannot even give an error message here since it would run
      66  	 into the same problems.  */
      67        while (1)
      68  	/* Try for ever and ever.  */
      69  	ABORT_INSTRUCTION;
      70      }
      71  }
      72  
      73  static void
      74  check_standard_fds (void)
      75  {
      76    /* Check all three standard file descriptors.  */
      77    check_one_fd (STDIN_FILENO, O_RDONLY);
      78    check_one_fd (STDOUT_FILENO, O_RDWR);
      79    check_one_fd (STDERR_FILENO, O_RDWR);
      80  }
      81  
      82  static void attribute_used_retain
      83  init_standard_fds (void)
      84  {
      85    /* Now that we have FDs, make sure that, if this is a SUID program,
      86       FDs 0, 1 and 2 are allocated.  If necessary we'll set them up
      87       ourselves.  If that's not possible we stop the program.  */
      88    if (__builtin_expect (__libc_enable_secure, 0))
      89      check_standard_fds ();
      90  }
      91  SET_RELHOOK (_hurd_fd_subinit, init_standard_fds);
      92  
      93  
      94  #ifndef SHARED
      95  void
      96  __libc_check_standard_fds (void)
      97  {
      98    /* We don't check the standard file descriptors here.  They will be
      99       checked when we initialize the file descriptor table, as part of
     100       the _hurd_fd_subinit hook.
     101  
     102       This function is only present to make sure that this module gets
     103       linked in when part of the static libc.  */
     104  }
     105  #endif