Imported Upstream version 2.1.9
[platform/upstream/gpg2.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 #include "util.h"
71 #include "i18n.h"
72 #include "sysutils.h"
73 #include "exechelp.h"
74
75
76 /* Return the maximum number of currently allowed open file
77    descriptors.  Only useful on POSIX systems but returns a value on
78    other systems too.  */
79 int
80 get_max_fds (void)
81 {
82   int max_fds = -1;
83 #ifdef HAVE_GETRLIMIT
84   struct rlimit rl;
85
86 # ifdef RLIMIT_NOFILE
87   if (!getrlimit (RLIMIT_NOFILE, &rl))
88     max_fds = rl.rlim_max;
89 # endif
90
91 # ifdef RLIMIT_OFILE
92   if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
93     max_fds = rl.rlim_max;
94
95 # endif
96 #endif /*HAVE_GETRLIMIT*/
97
98 #ifdef _SC_OPEN_MAX
99   if (max_fds == -1)
100     {
101       long int scres = sysconf (_SC_OPEN_MAX);
102       if (scres >= 0)
103         max_fds = scres;
104     }
105 #endif
106
107 #ifdef _POSIX_OPEN_MAX
108   if (max_fds == -1)
109     max_fds = _POSIX_OPEN_MAX;
110 #endif
111
112 #ifdef OPEN_MAX
113   if (max_fds == -1)
114     max_fds = OPEN_MAX;
115 #endif
116
117   if (max_fds == -1)
118     max_fds = 256;  /* Arbitrary limit.  */
119
120   /* AIX returns INT32_MAX instead of a proper value.  We assume that
121      this is always an error and use an arbitrary limit.  */
122 #ifdef INT32_MAX
123   if (max_fds == INT32_MAX)
124     max_fds = 256;
125 #endif
126
127   return max_fds;
128 }
129
130
131 /* Close all file descriptors starting with descriptor FIRST.  If
132    EXCEPT is not NULL, it is expected to be a list of file descriptors
133    which shall not be closed.  This list shall be sorted in ascending
134    order with the end marked by -1.  */
135 void
136 close_all_fds (int first, int *except)
137 {
138   int max_fd = get_max_fds ();
139   int fd, i, except_start;
140
141   if (except)
142     {
143       except_start = 0;
144       for (fd=first; fd < max_fd; fd++)
145         {
146           for (i=except_start; except[i] != -1; i++)
147             {
148               if (except[i] == fd)
149                 {
150                   /* If we found the descriptor in the exception list
151                      we can start the next compare run at the next
152                      index because the exception list is ordered.  */
153                 except_start = i + 1;
154                 break;
155                 }
156             }
157           if (except[i] == -1)
158             close (fd);
159         }
160     }
161   else
162     {
163       for (fd=first; fd < max_fd; fd++)
164         close (fd);
165     }
166
167   gpg_err_set_errno (0);
168 }
169
170
171 /* Returns an array with all currently open file descriptors.  The end
172    of the array is marked by -1.  The caller needs to release this
173    array using the *standard free* and not with xfree.  This allow the
174    use of this fucntion right at startup even before libgcrypt has
175    been initialized.  Returns NULL on error and sets ERRNO
176    accordingly.  */
177 int *
178 get_all_open_fds (void)
179 {
180   int *array;
181   size_t narray;
182   int fd, max_fd, idx;
183 #ifndef HAVE_STAT
184   array = calloc (1, sizeof *array);
185   if (array)
186     array[0] = -1;
187 #else /*HAVE_STAT*/
188   struct stat statbuf;
189
190   max_fd = get_max_fds ();
191   narray = 32;  /* If you change this change also t-exechelp.c.  */
192   array = calloc (narray, sizeof *array);
193   if (!array)
194     return NULL;
195
196   /* Note:  The list we return is ordered.  */
197   for (idx=0, fd=0; fd < max_fd; fd++)
198     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
199       {
200         if (idx+1 >= narray)
201           {
202             int *tmp;
203
204             narray += (narray < 256)? 32:256;
205             tmp = realloc (array, narray * sizeof *array);
206             if (!tmp)
207               {
208                 free (array);
209                 return NULL;
210               }
211             array = tmp;
212           }
213         array[idx++] = fd;
214       }
215   array[idx] = -1;
216 #endif /*HAVE_STAT*/
217   return array;
218 }
219
220
221 /* The exec core used right after the fork. This will never return. */
222 static void
223 do_exec (const char *pgmname, const char *argv[],
224          int fd_in, int fd_out, int fd_err,
225          void (*preexec)(void) )
226 {
227   char **arg_list;
228   int i, j;
229   int fds[3];
230
231   fds[0] = fd_in;
232   fds[1] = fd_out;
233   fds[2] = fd_err;
234
235   /* Create the command line argument array.  */
236   i = 0;
237   if (argv)
238     while (argv[i])
239       i++;
240   arg_list = xcalloc (i+2, sizeof *arg_list);
241   arg_list[0] = strrchr (pgmname, '/');
242   if (arg_list[0])
243     arg_list[0]++;
244   else
245     arg_list[0] = xstrdup (pgmname);
246   if (argv)
247     for (i=0,j=1; argv[i]; i++, j++)
248       arg_list[j] = (char*)argv[i];
249
250   /* Assign /dev/null to unused FDs. */
251   for (i=0; i <= 2; i++)
252     {
253       if (fds[i] == -1 )
254         {
255           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
256           if (fds[i] == -1)
257             log_fatal ("failed to open '%s': %s\n",
258                        "/dev/null", strerror (errno));
259         }
260     }
261
262   /* Connect the standard files.  */
263   for (i=0; i <= 2; i++)
264     {
265       if (fds[i] != i && dup2 (fds[i], i) == -1)
266         log_fatal ("dup2 std%s failed: %s\n",
267                    i==0?"in":i==1?"out":"err", strerror (errno));
268     }
269
270   /* Close all other files. */
271   close_all_fds (3, NULL);
272
273   if (preexec)
274     preexec ();
275   execv (pgmname, arg_list);
276   /* No way to print anything, as we have closed all streams. */
277   _exit (127);
278 }
279
280
281 static gpg_error_t
282 do_create_pipe (int filedes[2])
283 {
284   gpg_error_t err = 0;
285
286   if (pipe (filedes) == -1)
287     {
288       err = gpg_error_from_syserror ();
289       filedes[0] = filedes[1] = -1;
290     }
291
292   return err;
293 }
294
295 /* Portable function to create a pipe.  Under Windows the write end is
296    inheritable.  */
297 gpg_error_t
298 gnupg_create_inbound_pipe (int filedes[2])
299 {
300   return do_create_pipe (filedes);
301 }
302
303
304 /* Portable function to create a pipe.  Under Windows the read end is
305    inheritable.  */
306 gpg_error_t
307 gnupg_create_outbound_pipe (int filedes[2])
308 {
309   return do_create_pipe (filedes);
310 }
311
312
313
314 static gpg_error_t
315 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
316                          int outbound, int nonblock,
317                          gpg_err_source_t errsource)
318 {
319   gpg_error_t err;
320
321   if (pipe (filedes) == -1)
322     {
323       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
324       log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
325       filedes[0] = filedes[1] = -1;
326       *r_fp = NULL;
327       return err;
328     }
329
330   if (outbound)
331     *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
332   else
333     *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
334   if (!*r_fp)
335     {
336       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
337       log_error (_("error creating a stream for a pipe: %s\n"),
338                  gpg_strerror (err));
339       close (filedes[0]);
340       close (filedes[1]);
341       filedes[0] = filedes[1] = -1;
342       return err;
343     }
344   return 0;
345 }
346
347
348
349 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
350 gpg_error_t
351 gnupg_spawn_process (const char *pgmname, const char *argv[],
352                      gpg_err_source_t errsource,
353                      void (*preexec)(void), unsigned int flags,
354                      estream_t *r_infp,
355                      estream_t *r_outfp,
356                      estream_t *r_errfp,
357                      pid_t *pid)
358 {
359   gpg_error_t err;
360   int inpipe[2] = {-1, -1};
361   int outpipe[2] = {-1, -1};
362   int errpipe[2] = {-1, -1};
363   estream_t infp = NULL;
364   estream_t outfp = NULL;
365   estream_t errfp = NULL;
366   int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK);
367
368   if (r_infp)
369     *r_infp = NULL;
370   if (r_outfp)
371     *r_outfp = NULL;
372   if (r_errfp)
373     *r_errfp = NULL;
374   *pid = (pid_t)(-1); /* Always required.  */
375
376   if (r_infp)
377     {
378       err = create_pipe_and_estream (inpipe, &infp, 0, nonblock, errsource);
379       if (err)
380         return err;
381     }
382
383   if (r_outfp)
384     {
385       err = create_pipe_and_estream (outpipe, &outfp, 1, nonblock, errsource);
386       if (err)
387         {
388           if (infp)
389             es_fclose (infp);
390           else if (inpipe[1] != -1)
391             close (inpipe[1]);
392           if (inpipe[0] != -1)
393             close (inpipe[0]);
394
395           return err;
396         }
397     }
398
399   if (r_errfp)
400     {
401       err = create_pipe_and_estream (errpipe, &errfp, 1, nonblock, errsource);
402       if (err)
403         {
404           if (infp)
405             es_fclose (infp);
406           else if (inpipe[1] != -1)
407             close (inpipe[1]);
408           if (inpipe[0] != -1)
409             close (inpipe[0]);
410
411           if (outfp)
412             es_fclose (outfp);
413           else if (outpipe[0] != -1)
414             close (outpipe[0]);
415           if (outpipe[1] != -1)
416             close (outpipe[1]);
417
418           return err;
419         }
420     }
421
422
423   *pid = fork ();
424   if (*pid == (pid_t)(-1))
425     {
426       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
427       log_error (_("error forking process: %s\n"), gpg_strerror (err));
428
429       if (infp)
430         es_fclose (infp);
431       else if (inpipe[1] != -1)
432         close (inpipe[1]);
433       if (inpipe[0] != -1)
434         close (inpipe[0]);
435
436       if (outfp)
437         es_fclose (outfp);
438       else if (outpipe[0] != -1)
439         close (outpipe[0]);
440       if (outpipe[1] != -1)
441         close (outpipe[1]);
442
443       if (errfp)
444         es_fclose (errfp);
445       else if (errpipe[0] != -1)
446         close (errpipe[0]);
447       if (errpipe[1] != -1)
448         close (errpipe[1]);
449       return err;
450     }
451
452   if (!*pid)
453     {
454       /* This is the child. */
455       gcry_control (GCRYCTL_TERM_SECMEM);
456       es_fclose (outfp);
457       es_fclose (errfp);
458       do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], preexec);
459       /*NOTREACHED*/
460     }
461
462   /* This is the parent. */
463   if (inpipe[0] != -1)
464     close (inpipe[0]);
465   if (outpipe[1] != -1)
466     close (outpipe[1]);
467   if (errpipe[1] != -1)
468     close (errpipe[1]);
469
470   if (r_infp)
471     *r_infp = infp;
472   if (r_outfp)
473     *r_outfp = outfp;
474   if (r_errfp)
475     *r_errfp = errfp;
476
477   return 0;
478 }
479
480
481
482 /* Simplified version of gnupg_spawn_process.  This function forks and
483    then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
484    and ERRFD to stderr (any of them may be -1 to connect them to
485    /dev/null).  The arguments for the process are expected in the NULL
486    terminated array ARGV.  The program name itself should not be
487    included there.  Calling gnupg_wait_process is required.
488
489    Returns 0 on success or an error code. */
490 gpg_error_t
491 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
492                         int infd, int outfd, int errfd, pid_t *pid)
493 {
494   gpg_error_t err;
495
496   *pid = fork ();
497   if (*pid == (pid_t)(-1))
498     {
499       err = gpg_error_from_syserror ();
500       log_error (_("error forking process: %s\n"), strerror (errno));
501       return err;
502     }
503
504   if (!*pid)
505     {
506       gcry_control (GCRYCTL_TERM_SECMEM);
507       /* Run child. */
508       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
509       /*NOTREACHED*/
510     }
511
512   return 0;
513 }
514
515
516 /* See exechelp.h for the description.  */
517 gpg_error_t
518 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
519 {
520   gpg_err_code_t ec;
521   int i, status;
522
523   if (r_exitcode)
524     *r_exitcode = -1;
525
526   if (pid == (pid_t)(-1))
527     return gpg_error (GPG_ERR_INV_VALUE);
528
529 #ifdef USE_NPTH
530   i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
531 #else
532   while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
533          && errno == EINTR);
534 #endif
535
536   if (i == (pid_t)(-1))
537     {
538       ec = gpg_err_code_from_errno (errno);
539       log_error (_("waiting for process %d to terminate failed: %s\n"),
540                  (int)pid, strerror (errno));
541     }
542   else if (!i)
543     {
544       ec = GPG_ERR_TIMEOUT; /* Still running.  */
545     }
546   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
547     {
548       log_error (_("error running '%s': probably not installed\n"), pgmname);
549       ec = GPG_ERR_CONFIGURATION;
550     }
551   else if (WIFEXITED (status) && WEXITSTATUS (status))
552     {
553       if (!r_exitcode)
554         log_error (_("error running '%s': exit status %d\n"), pgmname,
555                    WEXITSTATUS (status));
556       else
557         *r_exitcode = WEXITSTATUS (status);
558       ec = GPG_ERR_GENERAL;
559     }
560   else if (!WIFEXITED (status))
561     {
562       log_error (_("error running '%s': terminated\n"), pgmname);
563       ec = GPG_ERR_GENERAL;
564     }
565   else
566     {
567       if (r_exitcode)
568         *r_exitcode = 0;
569       ec = 0;
570     }
571
572   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
573 }
574
575
576 void
577 gnupg_release_process (pid_t pid)
578 {
579   (void)pid;
580 }
581
582
583 /* Spawn a new process and immediately detach from it.  The name of
584    the program to exec is PGMNAME and its arguments are in ARGV (the
585    programname is automatically passed as first argument).
586    Environment strings in ENVP are set.  An error is returned if
587    pgmname is not executable; to make this work it is necessary to
588    provide an absolute file name.  All standard file descriptors are
589    connected to /dev/null. */
590 gpg_error_t
591 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
592                               const char *envp[] )
593 {
594   pid_t pid;
595   int i;
596
597   if (getuid() != geteuid())
598     return gpg_error (GPG_ERR_BUG);
599
600   if (access (pgmname, X_OK))
601     return gpg_error_from_syserror ();
602
603   pid = fork ();
604   if (pid == (pid_t)(-1))
605     {
606       log_error (_("error forking process: %s\n"), strerror (errno));
607       return gpg_error_from_syserror ();
608     }
609   if (!pid)
610     {
611       pid_t pid2;
612
613       gcry_control (GCRYCTL_TERM_SECMEM);
614       if (setsid() == -1 || chdir ("/"))
615         _exit (1);
616
617       pid2 = fork (); /* Double fork to let init take over the new child. */
618       if (pid2 == (pid_t)(-1))
619         _exit (1);
620       if (pid2)
621         _exit (0);  /* Let the parent exit immediately. */
622
623       if (envp)
624         for (i=0; envp[i]; i++)
625           putenv (xstrdup (envp[i]));
626
627       do_exec (pgmname, argv, -1, -1, -1, NULL);
628
629       /*NOTREACHED*/
630     }
631
632   if (waitpid (pid, NULL, 0) == -1)
633     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
634                strerror (errno));
635
636   return 0;
637 }
638
639
640 /* Kill a process; that is send an appropriate signal to the process.
641    gnupg_wait_process must be called to actually remove the process
642    from the system.  An invalid PID is ignored.  */
643 void
644 gnupg_kill_process (pid_t pid)
645 {
646   if (pid != (pid_t)(-1))
647     {
648       kill (pid, SIGTERM);
649     }
650 }