Back to index

glibc  2.9
check_fds.c
Go to the documentation of this file.
00001 /* Copyright (C) 2000 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <fcntl.h>
00020 #include <paths.h>
00021 #include <unistd.h>
00022 
00023 #include <hurd.h>
00024 #include <hurd/fd.h>
00025 
00026 #include <set-hooks.h>
00027 
00028 /* Try to get a machine dependent instruction which will make the
00029    program crash.  This is used in case everything else fails.  */
00030 #include <abort-instr.h>
00031 #ifndef ABORT_INSTRUCTION
00032 /* No such instruction is available.  */
00033 # define ABORT_INSTRUCTION
00034 #endif
00035 
00036 static void
00037 check_one_fd (int fd, int mode)
00038 {
00039   struct hurd_fd *d;
00040 
00041   d = _hurd_fd_get (fd);
00042   if (d == NULL)
00043     {
00044       /* This descriptor hasn't been opened.  We try to allocate the
00045          descriptor and open /dev/null on it so that the SUID program
00046          we are about to start does not accidently use this
00047          descriptor.  */
00048       d = _hurd_alloc_fd (NULL, fd);
00049       if (d != NULL)
00050        {
00051          mach_port_t port;
00052 
00053          port = __file_name_lookup (_PATH_DEVNULL, mode, 0);
00054          if (port)
00055            {
00056              /* Since /dev/null isn't supposed to be a terminal, we
00057                avoid any ctty magic.  */
00058              d->port.port = port;
00059              d->flags = 0;
00060 
00061              __spin_unlock (&d->port.lock);
00062              return;
00063            }
00064        }
00065       
00066       /* We cannot even give an error message here since it would run
00067         into the same problems.  */
00068       while (1)
00069        /* Try for ever and ever.  */
00070        ABORT_INSTRUCTION;
00071     }
00072 }
00073 
00074 static void
00075 check_standard_fds (void)
00076 {
00077   /* Check all three standard file descriptors.  */
00078   check_one_fd (STDIN_FILENO, O_RDONLY);
00079   check_one_fd (STDOUT_FILENO, O_RDWR);
00080   check_one_fd (STDERR_FILENO, O_RDWR);
00081 }
00082 
00083 static void
00084 init_standard_fds (void)
00085 {
00086   /* Now that we have FDs, make sure that, if this is a SUID program,
00087      FDs 0, 1 and 2 are allocated.  If necessary we'll set them up
00088      ourselves.  If that's not possible we stop the program.  */
00089   if (__builtin_expect (__libc_enable_secure, 0))
00090     check_standard_fds ();
00091 
00092   (void) &init_standard_fds;       /* Avoid "defined but not used" warning.  */
00093 }
00094 text_set_element (_hurd_fd_subinit, init_standard_fds);
00095 
00096 
00097 #ifndef SHARED
00098 void
00099 __libc_check_standard_fds (void)
00100 {
00101   /* We don't check the standard file descriptors here.  They will be
00102      checked when we initialize the file descriptor table, as part of
00103      the _hurd_fd_subinit hook.
00104      
00105      This function is only present to make sure that this module gets
00106      linked in when part of the static libc.  */
00107 }
00108 #endif