~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-security

« back to all changes in this revision

Viewing changes to common/exechelp.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2009-08-04 12:27:49 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090804122749-q0j52zp6xmzvyall
Tags: 2.0.12-0ubuntu1
* New upstream release.
* Add 01-scd-pw2.patch, 03-opgp-writekey.patch, and 06-opgp-sign3072.patch
  from https://bugs.g10code.com/gnupg/issue1094 to make OpenPGP 2.0
  smartcards work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* exechelp.c - fork and exec helpers
2
 
 *      Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
40
40
#include <sys/wait.h>
41
41
#endif
42
42
 
 
43
#ifdef HAVE_GETRLIMIT
 
44
#include <sys/time.h>
 
45
#include <sys/resource.h>
 
46
#endif /*HAVE_GETRLIMIT*/
 
47
 
 
48
#ifdef HAVE_STAT
 
49
# include <sys/stat.h>
 
50
#endif
 
51
 
 
52
 
43
53
#include "util.h"
44
54
#include "i18n.h"
 
55
#include "sysutils.h"
45
56
#include "exechelp.h"
46
57
 
47
58
/* Define to 1 do enable debugging.  */
48
59
#define DEBUG_W32_SPAWN 1
49
60
 
50
61
 
51
 
#ifdef _POSIX_OPEN_MAX
52
 
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
53
 
#else
54
 
#define MAX_OPEN_FDS 20
55
 
#endif
56
 
 
57
62
/* We have the usual problem here: Some modules are linked against pth
58
63
   and some are not.  However we want to use pth_fork and pth_waitpid
59
64
   here. Using a weak symbol works but is not portable - we should
85
90
#endif
86
91
 
87
92
 
 
93
/* Return the maximum number of currently allowed open file
 
94
   descriptors.  Only useful on POSIX systems but returns a value on
 
95
   other systems too.  */
 
96
int
 
97
get_max_fds (void)
 
98
{
 
99
  int max_fds = -1;
 
100
#ifdef HAVE_GETRLIMIT
 
101
  struct rlimit rl;
 
102
 
 
103
# ifdef RLIMIT_NOFILE
 
104
  if (!getrlimit (RLIMIT_NOFILE, &rl))
 
105
    max_fds = rl.rlim_max;
 
106
# endif
 
107
 
 
108
# ifdef RLIMIT_OFILE
 
109
  if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
 
110
    max_fds = rl.rlim_max;
 
111
 
 
112
# endif
 
113
#endif /*HAVE_GETRLIMIT*/
 
114
 
 
115
#ifdef _SC_OPEN_MAX
 
116
  if (max_fds == -1)
 
117
    {
 
118
      long int scres = sysconf (_SC_OPEN_MAX);
 
119
      if (scres >= 0)
 
120
        max_fds = scres;
 
121
    }
 
122
#endif
 
123
 
 
124
#ifdef _POSIX_OPEN_MAX
 
125
  if (max_fds == -1)
 
126
    max_fds = _POSIX_OPEN_MAX;
 
127
#endif
 
128
 
 
129
#ifdef OPEN_MAX
 
130
  if (max_fds == -1)
 
131
    max_fds = OPEN_MAX;
 
132
#endif
 
133
 
 
134
  if (max_fds == -1)
 
135
    max_fds = 256;  /* Arbitrary limit.  */
 
136
 
 
137
  return max_fds;
 
138
}
 
139
 
 
140
 
 
141
/* Close all file descriptors starting with descriptor FIRST.  If
 
142
   EXCEPT is not NULL, it is expected to be a list of file descriptors
 
143
   which shall not be closed.  This list shall be sorted in ascending
 
144
   order with the end marked by -1.  */
 
145
void
 
146
close_all_fds (int first, int *except)
 
147
{
 
148
  int max_fd = get_max_fds ();
 
149
  int fd, i, except_start;
 
150
 
 
151
  if (except)
 
152
    {
 
153
      except_start = 0;
 
154
      for (fd=first; fd < max_fd; fd++)
 
155
        {
 
156
          for (i=except_start; except[i] != -1; i++)
 
157
            {
 
158
              if (except[i] == fd)
 
159
                {
 
160
                  /* If we found the descriptor in the exception list
 
161
                     we can start the next compare run at the next
 
162
                     index because the exception list is ordered.  */
 
163
                except_start = i + 1;
 
164
                break;
 
165
                }
 
166
            }
 
167
          if (except[i] == -1)
 
168
            close (fd);
 
169
        }
 
170
    }
 
171
  else
 
172
    {
 
173
      for (fd=first; fd < max_fd; fd++)
 
174
        close (fd);
 
175
    }
 
176
 
 
177
  errno = 0;
 
178
}
 
179
 
 
180
 
 
181
/* Returns an array with all currently open file descriptors.  The end
 
182
   of the array is marked by -1.  The caller needs to release this
 
183
   array using the *standard free* and not with xfree.  This allow the
 
184
   use of this fucntion right at startup even before libgcrypt has
 
185
   been initialized.  Returns NULL on error and sets ERRNO
 
186
   accordingly.  */
 
187
int *
 
188
get_all_open_fds (void)
 
189
{
 
190
  int *array;
 
191
  size_t narray;
 
192
  int fd, max_fd, idx;
 
193
#ifndef HAVE_STAT
 
194
  array = calloc (1, sizeof *array);
 
195
  if (array)
 
196
    array[0] = -1;
 
197
#else /*HAVE_STAT*/
 
198
  struct stat statbuf;
 
199
 
 
200
  max_fd = get_max_fds ();
 
201
  narray = 32;  /* If you change this change also t-exechelp.c.  */
 
202
  array = calloc (narray, sizeof *array);
 
203
  if (!array)
 
204
    return NULL;
 
205
  
 
206
  /* Note:  The list we return is ordered.  */
 
207
  for (idx=0, fd=0; fd < max_fd; fd++)
 
208
    if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
 
209
      {
 
210
        if (idx+1 >= narray)
 
211
          {
 
212
            int *tmp;
 
213
 
 
214
            narray += (narray < 256)? 32:256;
 
215
            tmp = realloc (array, narray * sizeof *array);
 
216
            if (!tmp)
 
217
              {
 
218
                free (array);
 
219
                return NULL;
 
220
              }
 
221
            array = tmp;
 
222
          }
 
223
        array[idx++] = fd;
 
224
      }
 
225
  array[idx] = -1;
 
226
#endif /*HAVE_STAT*/
 
227
  return array;
 
228
}
 
229
 
 
230
 
 
231
 
88
232
#ifdef HAVE_W32_SYSTEM
89
233
/* Helper function to build_w32_commandline. */
90
234
static char *
216
360
         void (*preexec)(void) )
217
361
{
218
362
  char **arg_list;
219
 
  int n, i, j;
 
363
  int i, j;
220
364
  int fds[3];
221
365
 
222
366
  fds[0] = fd_in;
259
403
    }
260
404
 
261
405
  /* Close all other files. */
262
 
  n = sysconf (_SC_OPEN_MAX);
263
 
  if (n < 0)
264
 
    n = MAX_OPEN_FDS;
265
 
  for (i=3; i < n; i++)
266
 
    close(i);
267
 
  errno = 0;
 
406
  close_all_fds (3, NULL);
268
407
  
269
408
  if (preexec)
270
409
    preexec ();
333
472
          This flag is only useful under W32 systems, so that no new
334
473
          console is created and pops up a console window when
335
474
          starting the server
 
475
 
 
476
   Bit 6: On W32 run AllowSetForegroundWindow for the child.  Due to
 
477
          error problems this actually allows SetForegroundWindow for
 
478
          childs of this process.
336
479
 
337
480
   Returns 0 on success or an error code. */
338
481
gpg_error_t
430
573
/*              " dwProcessID=%d dwThreadId=%d\n", */
431
574
/*              pi.hProcess, pi.hThread, */
432
575
/*              (int) pi.dwProcessId, (int) pi.dwThreadId); */
 
576
  
 
577
  /* Fixme: For unknown reasons AllowSetForegroundWindow returns an
 
578
     invalid argument error if we pass the correct processID to
 
579
     it.  As a workaround we use -1 (ASFW_ANY).  */
 
580
  if ( (flags & 64) )
 
581
    gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
433
582
 
434
583
  /* Process has been created suspended; resume it now. */
435
584
  ResumeThread (pi.hThread);