common: Speedup closing fds before an exec.
[gnupg.git] / common / exechelp-posix.c
1 /* exechelp.c - Fork and exec helpers for POSIX
2  * Copyright (C) 2004, 2007, 2008, 2009,
3  *               2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * This file is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, see <http://www.gnu.org/licenses/>.
29  */
30
31 #include <config.h>
32
33 #if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
34 #error This code is only used on POSIX
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #ifdef HAVE_STDINT_H
40 # include <stdint.h>
41 #endif
42 #include <string.h>
43 #include <errno.h>
44 #include <assert.h>
45 #ifdef HAVE_SIGNAL_H
46 # include <signal.h>
47 #endif
48 #include <unistd.h>
49 #include <fcntl.h>
50
51 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
52 #undef HAVE_NPTH
53 #undef USE_NPTH
54 #endif
55
56 #ifdef HAVE_NPTH
57 #include <npth.h>
58 #endif
59 #include <sys/wait.h>
60
61 #ifdef HAVE_GETRLIMIT
62 #include <sys/time.h>
63 #include <sys/resource.h>
64 #endif /*HAVE_GETRLIMIT*/
65
66 #ifdef HAVE_STAT
67 # include <sys/stat.h>
68 #endif
69
70 #if __linux__
71 # include <sys/types.h>
72 # include <dirent.h>
73 #endif /*__linux__ */
74
75 #include "util.h"
76 #include "i18n.h"
77 #include "sysutils.h"
78 #include "exechelp.h"
79
80
81 /* Helper */
82 static inline gpg_error_t
83 my_error_from_syserror (void)
84 {
85   return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
86 }
87
88 static inline gpg_error_t
89 my_error (int errcode)
90 {
91   return gpg_err_make (default_errsource, errcode);
92 }
93
94
95 /* Return the maximum number of currently allowed open file
96    descriptors.  Only useful on POSIX systems but returns a value on
97    other systems too.  */
98 int
99 get_max_fds (void)
100 {
101   int max_fds = -1;
102 #ifdef HAVE_GETRLIMIT
103   struct rlimit rl;
104
105   /* Under Linux we can figure out the highest used file descriptor by
106    * reading /proc/PID/fd.  This is in the common cases much fast than
107    * for example doing 4096 close calls where almost all of them will
108    * fail.  On a system with a limit of 4096 files and only 8 files
109    * open with the highest number being 10, we speedup close_all_fds
110    * from 125ms to 0.4ms including readdir.
111    *
112    * Another option would be to close the file descriptors as returned
113    * from reading that directory - however then we need to snapshot
114    * that list before starting to close them.  */
115 #ifdef __linux__
116   {
117     char dirname[50];
118     DIR *dir = NULL;
119     struct dirent *dir_entry;
120     const char *s;
121     int x;
122
123     snprintf (dirname, sizeof dirname, "/proc/%u/fd", (unsigned int)getpid ());
124     dir = opendir (dirname);
125     if (dir)
126       {
127         while ((dir_entry = readdir (dir)))
128           {
129             s = dir_entry->d_name;
130             if ( *s < '0' || *s > '9')
131               continue;
132             x = atoi (s);
133             if (x > max_fds)
134               max_fds = x;
135           }
136         closedir (dir);
137       }
138     if (max_fds != -1)
139       return max_fds + 1;
140     }
141 #endif /* __linux__ */
142
143
144 # ifdef RLIMIT_NOFILE
145   if (!getrlimit (RLIMIT_NOFILE, &rl))
146     max_fds = rl.rlim_max;
147 # endif
148
149 # ifdef RLIMIT_OFILE
150   if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
151     max_fds = rl.rlim_max;
152
153 # endif
154 #endif /*HAVE_GETRLIMIT*/
155
156 #ifdef _SC_OPEN_MAX
157   if (max_fds == -1)
158     {
159       long int scres = sysconf (_SC_OPEN_MAX);
160       if (scres >= 0)
161         max_fds = scres;
162     }
163 #endif
164
165 #ifdef _POSIX_OPEN_MAX
166   if (max_fds == -1)
167     max_fds = _POSIX_OPEN_MAX;
168 #endif
169
170 #ifdef OPEN_MAX
171   if (max_fds == -1)
172     max_fds = OPEN_MAX;
173 #endif
174
175   if (max_fds == -1)
176     max_fds = 256;  /* Arbitrary limit.  */
177
178   /* AIX returns INT32_MAX instead of a proper value.  We assume that
179      this is always an error and use an arbitrary limit.  */
180 #ifdef INT32_MAX
181   if (max_fds == INT32_MAX)
182     max_fds = 256;
183 #endif
184
185   return max_fds;
186 }
187
188
189 /* Close all file descriptors starting with descriptor FIRST.  If
190    EXCEPT is not NULL, it is expected to be a list of file descriptors
191    which shall not be closed.  This list shall be sorted in ascending
192    order with the end marked by -1.  */
193 void
194 close_all_fds (int first, int *except)
195 {
196   int max_fd = get_max_fds ();
197   int fd, i, except_start;
198
199   if (except)
200     {
201       except_start = 0;
202       for (fd=first; fd < max_fd; fd++)
203         {
204           for (i=except_start; except[i] != -1; i++)
205             {
206               if (except[i] == fd)
207                 {
208                   /* If we found the descriptor in the exception list
209                      we can start the next compare run at the next
210                      index because the exception list is ordered.  */
211                 except_start = i + 1;
212                 break;
213                 }
214             }
215           if (except[i] == -1)
216             close (fd);
217         }
218     }
219   else
220     {
221       for (fd=first; fd < max_fd; fd++)
222         close (fd);
223     }
224
225   gpg_err_set_errno (0);
226 }
227
228
229 /* Returns an array with all currently open file descriptors.  The end
230    of the array is marked by -1.  The caller needs to release this
231    array using the *standard free* and not with xfree.  This allow the
232    use of this function right at startup even before libgcrypt has
233    been initialized.  Returns NULL on error and sets ERRNO
234    accordingly.  */
235 int *
236 get_all_open_fds (void)
237 {
238   int *array;
239   size_t narray;
240   int fd, max_fd, idx;
241 #ifndef HAVE_STAT
242   array = calloc (1, sizeof *array);
243   if (array)
244     array[0] = -1;
245 #else /*HAVE_STAT*/
246   struct stat statbuf;
247
248   max_fd = get_max_fds ();
249   narray = 32;  /* If you change this change also t-exechelp.c.  */
250   array = calloc (narray, sizeof *array);
251   if (!array)
252     return NULL;
253
254   /* Note:  The list we return is ordered.  */
255   for (idx=0, fd=0; fd < max_fd; fd++)
256     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
257       {
258         if (idx+1 >= narray)
259           {
260             int *tmp;
261
262             narray += (narray < 256)? 32:256;
263             tmp = realloc (array, narray * sizeof *array);
264             if (!tmp)
265               {
266                 free (array);
267                 return NULL;
268               }
269             array = tmp;
270           }
271         array[idx++] = fd;
272       }
273   array[idx] = -1;
274 #endif /*HAVE_STAT*/
275   return array;
276 }
277
278
279 /* The exec core used right after the fork. This will never return. */
280 static void
281 do_exec (const char *pgmname, const char *argv[],
282          int fd_in, int fd_out, int fd_err,
283          void (*preexec)(void) )
284 {
285   char **arg_list;
286   int i, j;
287   int fds[3];
288
289   fds[0] = fd_in;
290   fds[1] = fd_out;
291   fds[2] = fd_err;
292
293   /* Create the command line argument array.  */
294   i = 0;
295   if (argv)
296     while (argv[i])
297       i++;
298   arg_list = xcalloc (i+2, sizeof *arg_list);
299   arg_list[0] = strrchr (pgmname, '/');
300   if (arg_list[0])
301     arg_list[0]++;
302   else
303     arg_list[0] = xstrdup (pgmname);
304   if (argv)
305     for (i=0,j=1; argv[i]; i++, j++)
306       arg_list[j] = (char*)argv[i];
307
308   /* Assign /dev/null to unused FDs. */
309   for (i=0; i <= 2; i++)
310     {
311       if (fds[i] == -1 )
312         {
313           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
314           if (fds[i] == -1)
315             log_fatal ("failed to open '%s': %s\n",
316                        "/dev/null", strerror (errno));
317         }
318     }
319
320   /* Connect the standard files.  */
321   for (i=0; i <= 2; i++)
322     {
323       if (fds[i] != i && dup2 (fds[i], i) == -1)
324         log_fatal ("dup2 std%s failed: %s\n",
325                    i==0?"in":i==1?"out":"err", strerror (errno));
326     }
327
328   /* Close all other files. */
329   close_all_fds (3, NULL);
330
331   if (preexec)
332     preexec ();
333   execv (pgmname, arg_list);
334   /* No way to print anything, as we have closed all streams. */
335   _exit (127);
336 }
337
338
339 static gpg_error_t
340 do_create_pipe (int filedes[2])
341 {
342   gpg_error_t err = 0;
343
344   if (pipe (filedes) == -1)
345     {
346       err = my_error_from_syserror ();
347       filedes[0] = filedes[1] = -1;
348     }
349
350   return err;
351 }
352
353
354 static gpg_error_t
355 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
356                          int outbound, int nonblock)
357 {
358   gpg_error_t err;
359
360   if (pipe (filedes) == -1)
361     {
362       err = my_error_from_syserror ();
363       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
364       filedes[0] = filedes[1] = -1;
365       *r_fp = NULL;
366       return err;
367     }
368
369   if (!outbound)
370     *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
371   else
372     *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
373   if (!*r_fp)
374     {
375       err = my_error_from_syserror ();
376       log_error (_("error creating a stream for a pipe: %s\n"),
377                  gpg_strerror (err));
378       close (filedes[0]);
379       close (filedes[1]);
380       filedes[0] = filedes[1] = -1;
381       return err;
382     }
383   return 0;
384 }
385
386
387 /* Portable function to create a pipe.  Under Windows the write end is
388    inheritable.  If R_FP is not NULL, an estream is created for the
389    read end and stored at R_FP.  */
390 gpg_error_t
391 gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
392 {
393   if (r_fp)
394     return create_pipe_and_estream (filedes, r_fp, 0, nonblock);
395   else
396     return do_create_pipe (filedes);
397 }
398
399
400 /* Portable function to create a pipe.  Under Windows the read end is
401    inheritable.  If R_FP is not NULL, an estream is created for the
402    write end and stored at R_FP.  */
403 gpg_error_t
404 gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
405 {
406   if (r_fp)
407     return create_pipe_and_estream (filedes, r_fp, 1, nonblock);
408   else
409     return do_create_pipe (filedes);
410 }
411
412
413 /* Portable function to create a pipe.  Under Windows both ends are
414    inheritable.  */
415 gpg_error_t
416 gnupg_create_pipe (int filedes[2])
417 {
418   return do_create_pipe (filedes);
419 }
420
421
422 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
423 gpg_error_t
424 gnupg_spawn_process (const char *pgmname, const char *argv[],
425                      void (*preexec)(void), unsigned int flags,
426                      estream_t *r_infp,
427                      estream_t *r_outfp,
428                      estream_t *r_errfp,
429                      pid_t *pid)
430 {
431   gpg_error_t err;
432   int inpipe[2] = {-1, -1};
433   int outpipe[2] = {-1, -1};
434   int errpipe[2] = {-1, -1};
435   estream_t infp = NULL;
436   estream_t outfp = NULL;
437   estream_t errfp = NULL;
438   int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK);
439
440   if (r_infp)
441     *r_infp = NULL;
442   if (r_outfp)
443     *r_outfp = NULL;
444   if (r_errfp)
445     *r_errfp = NULL;
446   *pid = (pid_t)(-1); /* Always required.  */
447
448   if (r_infp)
449     {
450       err = create_pipe_and_estream (inpipe, &infp, 1, nonblock);
451       if (err)
452         return err;
453     }
454
455   if (r_outfp)
456     {
457       err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock);
458       if (err)
459         {
460           if (infp)
461             es_fclose (infp);
462           else if (inpipe[1] != -1)
463             close (inpipe[1]);
464           if (inpipe[0] != -1)
465             close (inpipe[0]);
466
467           return err;
468         }
469     }
470
471   if (r_errfp)
472     {
473       err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock);
474       if (err)
475         {
476           if (infp)
477             es_fclose (infp);
478           else if (inpipe[1] != -1)
479             close (inpipe[1]);
480           if (inpipe[0] != -1)
481             close (inpipe[0]);
482
483           if (outfp)
484             es_fclose (outfp);
485           else if (outpipe[0] != -1)
486             close (outpipe[0]);
487           if (outpipe[1] != -1)
488             close (outpipe[1]);
489
490           return err;
491         }
492     }
493
494
495   *pid = fork ();
496   if (*pid == (pid_t)(-1))
497     {
498       err = my_error_from_syserror ();
499       log_error (_("error forking process: %s\n"), gpg_strerror (err));
500
501       if (infp)
502         es_fclose (infp);
503       else if (inpipe[1] != -1)
504         close (inpipe[1]);
505       if (inpipe[0] != -1)
506         close (inpipe[0]);
507
508       if (outfp)
509         es_fclose (outfp);
510       else if (outpipe[0] != -1)
511         close (outpipe[0]);
512       if (outpipe[1] != -1)
513         close (outpipe[1]);
514
515       if (errfp)
516         es_fclose (errfp);
517       else if (errpipe[0] != -1)
518         close (errpipe[0]);
519       if (errpipe[1] != -1)
520         close (errpipe[1]);
521       return err;
522     }
523
524   if (!*pid)
525     {
526       /* This is the child. */
527       gcry_control (GCRYCTL_TERM_SECMEM);
528       es_fclose (outfp);
529       es_fclose (errfp);
530       do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec);
531       /*NOTREACHED*/
532     }
533
534   /* This is the parent. */
535   if (inpipe[0] != -1)
536     close (inpipe[0]);
537   if (outpipe[1] != -1)
538     close (outpipe[1]);
539   if (errpipe[1] != -1)
540     close (errpipe[1]);
541
542   if (r_infp)
543     *r_infp = infp;
544   if (r_outfp)
545     *r_outfp = outfp;
546   if (r_errfp)
547     *r_errfp = errfp;
548
549   return 0;
550 }
551
552
553
554 /* Simplified version of gnupg_spawn_process.  This function forks and
555    then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
556    and ERRFD to stderr (any of them may be -1 to connect them to
557    /dev/null).  The arguments for the process are expected in the NULL
558    terminated array ARGV.  The program name itself should not be
559    included there.  Calling gnupg_wait_process is required.
560
561    Returns 0 on success or an error code. */
562 gpg_error_t
563 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
564                         int infd, int outfd, int errfd, pid_t *pid)
565 {
566   gpg_error_t err;
567
568   *pid = fork ();
569   if (*pid == (pid_t)(-1))
570     {
571       err = my_error_from_syserror ();
572       log_error (_("error forking process: %s\n"), strerror (errno));
573       return err;
574     }
575
576   if (!*pid)
577     {
578       gcry_control (GCRYCTL_TERM_SECMEM);
579       /* Run child. */
580       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
581       /*NOTREACHED*/
582     }
583
584   return 0;
585 }
586
587
588 /* See exechelp.h for a description.  */
589 gpg_error_t
590 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
591 {
592   return gnupg_wait_processes (&pgmname, &pid, 1, hang, r_exitcode);
593 }
594
595 /* See exechelp.h for a description.  */
596 gpg_error_t
597 gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count,
598                       int hang, int *r_exitcodes)
599 {
600   gpg_err_code_t ec = 0;
601   size_t i, left;
602
603   for (i = 0; i < count; i++)
604     {
605       if (r_exitcodes)
606         r_exitcodes[i] = -1;
607
608       if (pids[i] == (pid_t)(-1))
609         return my_error (GPG_ERR_INV_VALUE);
610     }
611
612   left = count;
613   while (left > 0)
614     {
615       pid_t pid;
616       int status;
617
618 #ifdef USE_NPTH
619       pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG);
620 #else
621       while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1)
622              && errno == EINTR);
623 #endif
624
625       if (pid == (pid_t)(-1))
626         {
627           ec = gpg_err_code_from_errno (errno);
628           log_error (_("waiting for processes to terminate failed: %s\n"),
629                      strerror (errno));
630           break;
631         }
632       else if (!pid)
633         {
634           ec = GPG_ERR_TIMEOUT; /* Still running.  */
635           break;
636         }
637       else
638         {
639           for (i = 0; i < count; i++)
640             if (pid == pids[i])
641               break;
642
643           if (i == count)
644             /* No match, ignore this pid.  */
645             continue;
646
647           /* Process PIDS[i] died.  */
648           left -= 1;
649
650           if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
651             {
652               log_error (_("error running '%s': probably not installed\n"),
653                          pgmnames[i]);
654               ec = GPG_ERR_CONFIGURATION;
655             }
656           else if (WIFEXITED (status) && WEXITSTATUS (status))
657             {
658               if (!r_exitcodes)
659                 log_error (_("error running '%s': exit status %d\n"),
660                            pgmnames[i], WEXITSTATUS (status));
661               else
662                 r_exitcodes[i] = WEXITSTATUS (status);
663               ec = GPG_ERR_GENERAL;
664             }
665           else if (!WIFEXITED (status))
666             {
667               log_error (_("error running '%s': terminated\n"), pgmnames[i]);
668               ec = GPG_ERR_GENERAL;
669             }
670           else
671             {
672               if (r_exitcodes)
673                 r_exitcodes[i] = 0;
674             }
675         }
676     }
677
678   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
679 }
680
681
682 void
683 gnupg_release_process (pid_t pid)
684 {
685   (void)pid;
686 }
687
688
689 /* Spawn a new process and immediately detach from it.  The name of
690    the program to exec is PGMNAME and its arguments are in ARGV (the
691    programname is automatically passed as first argument).
692    Environment strings in ENVP are set.  An error is returned if
693    pgmname is not executable; to make this work it is necessary to
694    provide an absolute file name.  All standard file descriptors are
695    connected to /dev/null. */
696 gpg_error_t
697 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
698                               const char *envp[] )
699 {
700   pid_t pid;
701   int i;
702
703   if (getuid() != geteuid())
704     return my_error (GPG_ERR_BUG);
705
706   if (access (pgmname, X_OK))
707     return my_error_from_syserror ();
708
709   pid = fork ();
710   if (pid == (pid_t)(-1))
711     {
712       log_error (_("error forking process: %s\n"), strerror (errno));
713       return my_error_from_syserror ();
714     }
715   if (!pid)
716     {
717       pid_t pid2;
718
719       gcry_control (GCRYCTL_TERM_SECMEM);
720       if (setsid() == -1 || chdir ("/"))
721         _exit (1);
722
723       pid2 = fork (); /* Double fork to let init take over the new child. */
724       if (pid2 == (pid_t)(-1))
725         _exit (1);
726       if (pid2)
727         _exit (0);  /* Let the parent exit immediately. */
728
729       if (envp)
730         for (i=0; envp[i]; i++)
731           putenv (xstrdup (envp[i]));
732
733       do_exec (pgmname, argv, -1, -1, -1, NULL);
734
735       /*NOTREACHED*/
736     }
737
738   if (waitpid (pid, NULL, 0) == -1)
739     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
740                strerror (errno));
741
742   return 0;
743 }
744
745
746 /* Kill a process; that is send an appropriate signal to the process.
747    gnupg_wait_process must be called to actually remove the process
748    from the system.  An invalid PID is ignored.  */
749 void
750 gnupg_kill_process (pid_t pid)
751 {
752   if (pid != (pid_t)(-1))
753     {
754       kill (pid, SIGTERM);
755     }
756 }