passenger 4.0.37 → 4.0.38

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzY2YjMwZGFkMjkzNDNlMjgwYWIwZjM0OTk4OTEzZDczYmNhZTUxNw==
4
+ NWY2M2JhYzAwOWI1NGJiNDQ0YmNhYjFkZjk3ZjUxMGUxZDQxYjM2MQ==
5
5
  data.tar.gz: !binary |-
6
- NjMwYmQ4ZWM4ZWZkOTc1OWY2NTk0OGFjYTdjYjllZGE0ZWFkMTlhMQ==
6
+ M2FiN2YwZTg5MDYzZjRkM2ZmYjE4YWIyNTk4MDM5YWY0NmM0NWE1MA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZWY2OGFiZTMxNTMxMmNkZGFhYTQ4Nzk3OWM4MTNlNjJjZGQ1MDkwZTA0ZTNl
10
- MDY2N2FhOWFkNjdkYWYzYTgzNzMxMmE5ZGMzNjU2MmUwYjA4MDRlMDZmZDg2
11
- YTk1MTlmMjJmYmI5OWQ0ZjU4YzU5MDI0M2ZkMzU2NGRkNWU5Mzk=
9
+ Y2E0ZTUwNWQxZTkyZjAyYWI5MTgyMDg5MzYxNzQ2OGEwYjlmYjNiMjMyZjJm
10
+ YmYyNTVlNmFlYzVlNjRkZDQxYTk2YTFjMzAzZmQyNTY5ZTJmZTg3ZmYzZmMw
11
+ YmU4OGIyZGI5YjAxZjYwOTI0NmJkNjQxNGIxODI4NWJmMTdjNjc=
12
12
  data.tar.gz: !binary |-
13
- ODFhMDg0OWU1YmY2MjRiNWZjYjFkY2ZjN2MwMTZhYjA5YmNjM2E3ZDMwNTMx
14
- M2ExZDYxZGQyNWQ2ZjFjNzA4MDhjZjIzMzA5YTQyN2E1MjVmOTQyMzU4YzBi
15
- OGM2NDliMWNkMjQwYTBhYmFhNzhmZTZkNTUyMTVjMWE2Nzc3NTM=
13
+ NTUwMTlmOWJjZTFhMzdhMDEwNTRkY2RjY2MxOTllOThiMGUzYjJjNGVkZDRh
14
+ N2Q4MDY0ODQ4MmRhYzkwZjE4NWI5OGM0YTkzOTYwMmFiZGRlMDEwOTVkN2I2
15
+ OGQxMjZkN2MzM2RjNzE0NmJmZjM4MjAyYzU1NTgwYmEwZDg4YTg=
checksums.yaml.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJS6CPIAAoJECrHRaUKISqMBzMIAJc+WtmkHIzclF/yuMagWa40
6
- 0p9dz6CINEmYQ4gCabMeRhBa/VeQauXhvR3d2cm7TyCyLqfoN6YLHnesVwGGI2vu
7
- Kt5HbgOYGTT6cyf8QmGjubNC+VslKTZIyoapRigRRtX10tLsvAYyC9WnaOMGikWS
8
- OKpNucWMA7UnXfsfyNa/u4L0c+pNI15DM5asjMPG46QHiYDfAKIhRzGTRovjBAOW
9
- WaLu+qtfMJ9ui261i9KBJuPjIbbIeHZQeGDA70tvnm6na5W8A11XilYav4T8Qcv+
10
- fGoDcJ88M6q3cYspeOJPsEEICFHvhjQ0wMm5qT/YHhLd1dqxapCidmj+nqFwxuQ=
11
- =6pys
5
+ iQEcBAABAgAGBQJTHZ8EAAoJECrHRaUKISqMsBMH+gK3TAtT8EgtFuBgW/FTpWA+
6
+ GQYAdza0FIpBDcLrXuvzU/SYot8j+/FZdwYEqi1xp/IYyX6wjNsfmB9rnUKCnADK
7
+ UsotDRNQ9QNitAcwy3/HYpq2qMArMrQAVUg9uQ6whL+h9UCKmIt2Behn0QL8YITY
8
+ OcUuoy+0CkCcGiJuni3TEkPOpjrRZk7E2+7igTyEkN1cMseMOo06q+hCneCDJ9Uy
9
+ PSxQ/BZReTBWbVHKJwwAEe3yEfZPKnjawxkvgtTsO4iHZQj2FbeS/Nnl0/WVKxzp
10
+ CysaDlfon1bTDktijbN+ZhsSqavFtIVXIk9Pnba8KViVsHFn2R9/uXh5c7FkkFM=
11
+ =kE6h
12
12
  -----END PGP SIGNATURE-----
data.tar.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJS6CPIAAoJECrHRaUKISqMvrEIAKw15y9cgHaX26Mh6AYj+Bj1
6
- jQ2aTpVBoNwhxX6dGEvLhpxxknTmvaryffRxYJX7eE8JJKP526RzJogkbgBMktqY
7
- vxSRNSzpZpvoEztvpiy+UGVtgaUjTEaIFl9daOQbWxQkiLmvglRPMBFu7j30fU9B
8
- 56vdqzGxqZ9eSHMqd3B+kVSnpoiVOgRCigVocU/hoblLBDankxuzNkj6tAtlX+G3
9
- zmX0QZ+QBfWDqEvw2mVbXIQFwz9+tMCnybEctz5VJIPHaO8cco129jXYo+hcdu1Q
10
- EUlt3bcb0/w7a2giU2WuzYdRJqQFdTF24XOOwLozx0Kf8HizpQCU7dJaz3hE79E=
11
- =0LER
5
+ iQEcBAABAgAGBQJTHZ8EAAoJECrHRaUKISqM5lYH/3XJx9eqN+CwmPt3TuntozWD
6
+ cG+UX9LbGUSol+BGvE5wwuKfa10n0Gt7o8/OjsiWgmeI2RcgTrP8YcLSH/dsqRNB
7
+ DZdzpdq+03fJrgysYriG1e2UKhoG0BvY89Ux9ZncB3iiyteF+TMVdswdgwJiCVLF
8
+ miWYlX7efLoQu9ii7iDYWQq3nCImeefl3ei6lopS7lpAEdWplTQf2dUEGzJyCzd2
9
+ r1F2pN4gIUFDE/hOg8g/bQIs/HeZq3hlcDKJ3nXWpiSlgpT6Ywrs0kuIUE2KGDzJ
10
+ gW9SEsBgnV5RuC0kIYsVBGv+//hxoCvj22eZUz1cfvhZagAHzcL1n+t7+LRHkuY=
11
+ =28wv
12
12
  -----END PGP SIGNATURE-----
data/{NEWS → CHANGELOG} RENAMED
@@ -1,3 +1,46 @@
1
+ Release 4.0.38
2
+ --------------
3
+
4
+ * Added support for the new Ruby 2.1.0 out-of-band garbage collector.
5
+ This can much improve garbage collection performance, and drastically
6
+ reduce request times.
7
+ * Fixed a symlink-related security vulnerability.
8
+
9
+ Urgency: low
10
+ Scope: local exploit
11
+ Summary: writing files to arbitrary directory by hijacking temp directories
12
+ Affected versions: 4.0.37
13
+ Fixed versions: 4.0.38
14
+ CVE-2014-1832
15
+
16
+ Description:
17
+ This issue is related to CVE-2014-1831 (the security issue as mentioned in
18
+ the 4.0.37 release notes). The previous fix was incomplete, and still has a
19
+ (albeit smaller) small attack time window in between two filesystem
20
+ checks. This attack window is now gone.
21
+ * Passenger Standalone is now compatible with IPv6.
22
+ * Fixed some compilation problems on Solaris. See issue #1047.
23
+ * passenger-install-apache2-module and passenger-install-nginx-module
24
+ now automatically run in `--auto` mode if stdin is not a TTY. Fixes
25
+ issue #1030.
26
+ * Fixed an issue with non-bundled Meteor apps not correctly running in
27
+ production mode.
28
+ * The `PassengerPreStart` option is now compatible with IPv6 server sockets.
29
+ * When running Python WSGI apps, `wsgi.run_once` is now set to False.
30
+ This should improve the performance of certain apps and frameworks.
31
+ * When handling HTTP requests with chunked transfer encoding, the
32
+ 'Transfer-Encoding' header is no longer passed to the application.
33
+ This is because the web server already buffers and dechunks the
34
+ request body.
35
+ * Fixed a possible hang in Phusion Passenger for Nginx when Nginx
36
+ is instructed to reload or reopen log files. Thanks to Feng Gu,
37
+ [pull request #97](https://github.com/phusion/passenger/pull/97).
38
+ * The preferred Nginx version has been upgraded to 1.4.6.
39
+ * Fixed a problem with running passenger-install-apache2-module and
40
+ passenger-install-nginx-module on JRuby. They were not able to accept
41
+ any terminal input after displaying the programming language menu.
42
+
43
+
1
44
  Release 4.0.37
2
45
  --------------
3
46
 
@@ -15,7 +58,7 @@ Release 4.0.37
15
58
  effect to killing the application process directly with `kill <PID>`,
16
59
  but killing directly may cause the HTTP client to see an error, while
17
60
  using this command guarantees that clients see no errors.
18
- * Fixed a crash occurs when an application fails to spawn, but the HTTP
61
+ * Fixed a crash that occurs when an application fails to spawn, but the HTTP
19
62
  client disconnects before the error page is generated. Fixes issue #1028.
20
63
  * Fixed a symlink-related security vulnerability.
21
64
 
@@ -24,6 +67,7 @@ Release 4.0.37
24
67
  Summary: writing files to arbitrary directory by hijacking temp directories
25
68
  Affected versions: 4.0.5 and later
26
69
  Fixed versions: 4.0.37
70
+ CVE-2014-1831
27
71
 
28
72
  Description:
29
73
  Phusion Passenger creates a "server instance directory" in /tmp during startup,
data/build/misc.rb CHANGED
@@ -64,7 +64,7 @@ def extract_latest_news_contents_and_items
64
64
  # Release y.y.y
65
65
  # -------------
66
66
  # .....
67
- contents = File.read("NEWS")
67
+ contents = File.read("CHANGELOG")
68
68
 
69
69
  # We're only interested in the latest release, so extract the text for that.
70
70
  contents =~ /\A(Release.*?)^(Release|Older releases)/m
@@ -79,8 +79,8 @@ def extract_latest_news_contents_and_items
79
79
  return [contents, items]
80
80
  end
81
81
 
82
- desc "Convert the NEWS items for the latest release to HTML"
83
- task :news_as_html do
82
+ desc "Convert the Changelog items for the latest release to HTML"
83
+ task :changelog_as_html do
84
84
  require 'cgi'
85
85
  contents, items = extract_latest_news_contents_and_items
86
86
 
@@ -112,8 +112,8 @@ task :news_as_html do
112
112
  puts "</ul>"
113
113
  end
114
114
 
115
- desc "Convert the NEWS items for the latest release to Markdown"
116
- task :news_as_markdown do
115
+ desc "Convert the Changelog items for the latest release to Markdown"
116
+ task :changelog_as_markdown do
117
117
  contents, items = extract_latest_news_contents_and_items
118
118
 
119
119
  # Auto-link to issue tracker.
@@ -30,7 +30,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
30
30
  #else
31
31
  ruby-rack,
32
32
  #endif
33
- ruby-daemon-controller
33
+ ruby-daemon-controller (>= 1.2.0)
34
34
  Recommends: passenger-doc (= ${binary:Version}), passenger-dev (= ${binary:Version}),
35
35
  crash-watch
36
36
  Suggests: python
@@ -1,4 +1,4 @@
1
1
  CONTRIBUTING.md
2
2
  README.md
3
- NEWS
3
+ CHANGELOG
4
4
  debian/README.Debian
@@ -57,7 +57,7 @@ endif::[]
57
57
  [[install_on_debian_ubuntu]]
58
58
  === Installing or upgrading on Debian or Ubuntu
59
59
 
60
- We provide and official Phusion Passenger APT repository. This APT repository contains Phusion Passenger packages for multiple versions of Debian and Ubuntu. These packages are automatically built by our build server after we push out a source release, and thus are always up to date with the official source releases.
60
+ We provide an official Phusion Passenger APT repository. This APT repository contains Phusion Passenger packages for multiple versions of Debian and Ubuntu. These packages are automatically built by our build server after we push out a source release, and thus are always up to date with the official source releases.
61
61
 
62
62
  If you use these packages to install Phusion Passenger then you do not need to run `passenger-install-apache2-module` or `passenger-install-nginx-module`. These packages contain all the binaries that you need.
63
63
 
@@ -460,7 +460,7 @@ Here are some of the environment variables which are passed to all hooks, unless
460
460
 
461
461
  ==== Blocking and concurrency
462
462
 
463
- All hooks block. That is, Phusion Passenger waits until your hook command is finished. You should therefore be careful when writing hook scripts: if your script never finishes, so Phusion Passenger does not do that either.
463
+ All hooks block in the background. That is, while your hook command is running, Phusion Passenger can still handle web requests, but the background thread which is running your hook will be blocked and won't be able to perform any further operations. For example, if you wrote a hook script for the `attached_process` event, then Phusion Passenger won't be able to attach further processes until your hook script finishes. You should therefore be careful when writing hook scripts.
464
464
 
465
465
  If you have a bug in your script and it blocks, then you will be able to see that using the command `passenger-status --show=backtraces` which prints the backtraces of all threads in the Phusion Passenger HelperAgent. Look for the `runSingleHookScript` function in the backtrace. The following example shows at line 2 that Phusion Passenger is waiting for the hook script `/home/phusion/badscript.sh`.
466
466
 
@@ -471,7 +471,7 @@ Thread 'Group process spawner: /home/phusion/webapp.test#default' (0x1062d4000):
471
471
  in 'void Passenger::ApplicationPool2::Group::spawnThreadRealMain(const SpawnerPtr &, const Passenger::ApplicationPool2::Options &, unsigned int)' (Implementation.cpp:878)
472
472
  ---------------------------------------------------------------------------------------------------
473
473
 
474
- Hooks may be called concurrently. For example, while the `attached_process` hook is being called, a `detached_process` hook may be called, perhaps even for the same application. It is your responsibility to ensure that your hook scripts are concurrency-safe, e.g. by employing locks and other concurrency control techniques.
474
+ Hooks may be called concurrently, because Phusion Passenger sometimes uses multiple background threads. For example, while the `attached_process` hook is being called, a `detached_process` hook may be called, perhaps even for the same application. It is your responsibility to ensure that your hook scripts are concurrency-safe, e.g. by employing locks and other concurrency control techniques.
475
475
 
476
476
  ==== Error handling
477
477
 
@@ -496,6 +496,7 @@ Because hooks are inherently tied to the implementation of Phusion Passenger, th
496
496
  - Phusion Passenger has shut down a process because it's been idle for too long.
497
497
  - The administrator configured different resource limits, and Phusion Passenger is starting or shutting down processes in response.
498
498
  - Phusion Passenger itself is shutting down.
499
+
499
500
  +
500
501
  Extra environment variables: `PASSENGER_PROCESS_PID`, `PASSENGER_APP_ROOT`. Errors in the hook script are ignored.
501
502
 
@@ -773,11 +773,21 @@ private:
773
773
  }
774
774
  return 0;
775
775
  }
776
+
777
+ /**
778
+ * Checks case-insensitively whether the given header is "Transfer-Encoding".
779
+ */
780
+ bool headerIsTransferEncoding(const char *headerName, size_t len) const {
781
+ return len == sizeof("transfer-encoding") - 1 &&
782
+ apr_tolower(headerName[0]) == (u_char) 't' &&
783
+ apr_tolower(headerName[sizeof("transfer-encoding") - 2]) == (u_char) 'g' &&
784
+ apr_strnatcasecmp(headerName + 1, "ransfer-encoding") == 0;
785
+ }
776
786
 
777
787
  /**
778
788
  * Convert an HTTP header name to a CGI environment name.
779
789
  */
780
- char *httpToEnv(apr_pool_t *p, const char *headerName) {
790
+ char *httpToEnv(apr_pool_t *p, const char *headerName, size_t len) {
781
791
  char *result = apr_pstrcat(p, "HTTP_", headerName, (char *) NULL);
782
792
  char *current = result + sizeof("HTTP_") - 1;
783
793
 
@@ -931,8 +941,15 @@ private:
931
941
  hdrs_arr = apr_table_elts(r->headers_in);
932
942
  hdrs = (apr_table_entry_t *) hdrs_arr->elts;
933
943
  for (i = 0; i < hdrs_arr->nelts; ++i) {
934
- if (hdrs[i].key) {
935
- addHeader(output, httpToEnv(r->pool, hdrs[i].key), hdrs[i].val);
944
+ if (hdrs[i].key == NULL) {
945
+ continue;
946
+ }
947
+ size_t keylen = strlen(hdrs[i].key);
948
+ // We only pass the Transfer-Encoding header if PassengerBufferUpload is disabled,
949
+ // so that the HelperAgent and the app knows that there is a request body despite
950
+ // there not being a Content-Length header.
951
+ if (!headerIsTransferEncoding(hdrs[i].key, keylen) || config->bufferUpload == DirConfig::DISABLED) {
952
+ addHeader(output, httpToEnv(r->pool, hdrs[i].key, keylen), hdrs[i].val);
936
953
  }
937
954
  }
938
955
 
@@ -406,19 +406,21 @@ public:
406
406
  * we can kill all of our subprocesses in a single killpg().
407
407
  */
408
408
  setsid();
409
-
409
+
410
+ /* We don't know how the web server or the environment affect
411
+ * signal handlers and the signal mask, so reset this stuff
412
+ * just in case. Also, we reset the signal handlers before
413
+ * closing all file descriptors, in order to prevent bugs
414
+ * like this: https://github.com/phusion/passenger/pull/97
415
+ */
416
+ resetSignalHandlersAndMask();
417
+
410
418
  // Make sure the feedback fd is 3 and close all file descriptors
411
419
  // except stdin, stdout, stderr and 3.
412
420
  syscalls::close(fds[0]);
413
421
  installFeedbackFd(fds[1]);
414
422
  closeAllFileDescriptors(FEEDBACK_FD);
415
-
416
- /* We don't know how the web server or the environment affect
417
- * signal handlers and the signal mask, so reset this stuff
418
- * just in case.
419
- */
420
- resetSignalHandlersAndMask();
421
-
423
+
422
424
  if (afterFork) {
423
425
  afterFork();
424
426
  }
@@ -602,7 +602,7 @@ Group::initiateOobw(const ProcessPtr &process) {
602
602
  // Continue code flow.
603
603
  break;
604
604
  case DR_DEFERRED:
605
- // lockAndMaybeInitateOobw() will eventually be called.
605
+ // lockAndMaybeInitiateOobw() will eventually be called.
606
606
  return;
607
607
  case DR_ERROR:
608
608
  case DR_NOOP:
@@ -88,7 +88,7 @@
88
88
 
89
89
  #define NGINX_DOC_URL "http://www.modrails.com/documentation/Users%20guide%20Nginx.html"
90
90
 
91
- #define PASSENGER_VERSION "4.0.37"
91
+ #define PASSENGER_VERSION "4.0.38"
92
92
 
93
93
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
94
94
 
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  #include <Exceptions.h>
27
- #include <cstdlib>
27
+ #include <stdlib.h>
28
28
  #include <string.h>
29
29
 
30
30
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010-2013 Phusion
3
+ * Copyright (c) 2010-2014 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -193,6 +193,9 @@ private:
193
193
 
194
194
  void initialize(const string &path, bool owner) {
195
195
  TRACE_POINT();
196
+ struct stat buf;
197
+ int ret;
198
+
196
199
  this->path = path;
197
200
  this->owner = owner;
198
201
 
@@ -212,18 +215,25 @@ private:
212
215
  * rights though, because we want admin tools to be able to list the available
213
216
  * generations no matter what user they're running as.
214
217
  */
218
+
219
+ do {
220
+ ret = lstat(path.c_str(), &buf);
221
+ } while (ret == -1 && errno == EAGAIN);
215
222
  if (owner) {
216
- switch (getFileTypeNoFollowSymlinks(path)) {
217
- case FT_NONEXISTANT:
223
+ if (ret == 0) {
224
+ if (S_ISDIR(buf.st_mode)) {
225
+ verifyDirectoryPermissions(path, buf);
226
+ } else {
227
+ throw RuntimeException("'" + path + "' already exists, and is not a directory");
228
+ }
229
+ } else if (errno == ENOENT) {
218
230
  createDirectory(path);
219
- break;
220
- case FT_DIRECTORY:
221
- verifyDirectoryPermissions(path);
222
- break;
223
- default:
224
- throw RuntimeException("'" + path + "' already exists, and is not a directory");
231
+ } else {
232
+ int e = errno;
233
+ throw FileSystemException("Cannot lstat '" + path + "'",
234
+ e, path);
225
235
  }
226
- } else if (getFileType(path) != FT_DIRECTORY) {
236
+ } else if (!S_ISDIR(buf.st_mode)) {
227
237
  throw RuntimeException("Server instance directory '" + path +
228
238
  "' does not exist");
229
239
  }
@@ -259,14 +269,10 @@ private:
259
269
  * so that an attacker cannot pre-create a directory with too liberal
260
270
  * permissions.
261
271
  */
262
- void verifyDirectoryPermissions(const string &path) {
272
+ void verifyDirectoryPermissions(const string &path, struct stat &buf) {
263
273
  TRACE_POINT();
264
- struct stat buf;
265
274
 
266
- if (stat(path.c_str(), &buf) == -1) {
267
- int e = errno;
268
- throw FileSystemException("Cannot stat() " + path, e, path);
269
- } else if (buf.st_mode != (S_IFDIR | parseModeString("u=rwx,g=rx,o=rx"))) {
275
+ if (buf.st_mode != (S_IFDIR | parseModeString("u=rwx,g=rx,o=rx"))) {
270
276
  throw RuntimeException("Tried to reuse existing server instance directory " +
271
277
  path + ", but it has wrong permissions");
272
278
  } else if (buf.st_uid != geteuid() || buf.st_gid != getegid()) {
data/ext/common/Utils.cpp CHANGED
@@ -143,35 +143,6 @@ getFileType(const StaticString &filename, CachedFileStat *cstat, unsigned int th
143
143
  }
144
144
  }
145
145
 
146
- FileType
147
- getFileTypeNoFollowSymlinks(const StaticString &filename) {
148
- struct stat buf;
149
- int ret;
150
-
151
- ret = lstat(filename.c_str(), &buf);
152
- if (ret == 0) {
153
- if (S_ISREG(buf.st_mode)) {
154
- return FT_REGULAR;
155
- } else if (S_ISDIR(buf.st_mode)) {
156
- return FT_DIRECTORY;
157
- } else if (S_ISLNK(buf.st_mode)) {
158
- return FT_SYMLINK;
159
- } else {
160
- return FT_OTHER;
161
- }
162
- } else {
163
- if (errno == ENOENT) {
164
- return FT_NONEXISTANT;
165
- } else {
166
- int e = errno;
167
- string message("Cannot lstat '");
168
- message.append(filename);
169
- message.append("'");
170
- throw FileSystemException(message, e, filename);
171
- }
172
- }
173
- }
174
-
175
146
  void
176
147
  createFile(const string &filename, const StaticString &contents, mode_t permissions, uid_t owner,
177
148
  gid_t group, bool overwrite)
@@ -917,14 +888,6 @@ getSignalName(int sig) {
917
888
 
918
889
  void
919
890
  resetSignalHandlersAndMask() {
920
- sigset_t signal_set;
921
- int ret;
922
-
923
- sigemptyset(&signal_set);
924
- do {
925
- ret = sigprocmask(SIG_SETMASK, &signal_set, NULL);
926
- } while (ret == -1 && errno == EINTR);
927
-
928
891
  struct sigaction action;
929
892
  action.sa_handler = SIG_DFL;
930
893
  action.sa_flags = SA_RESTART;
@@ -955,6 +918,21 @@ resetSignalHandlersAndMask() {
955
918
  #endif
956
919
  sigaction(SIGUSR1, &action, NULL);
957
920
  sigaction(SIGUSR2, &action, NULL);
921
+
922
+ // We reset the signal mask after resetting the signal handlers,
923
+ // because prior to calling resetSignalHandlersAndMask(), the
924
+ // process might be blocked on some signals. We want those signals
925
+ // to be processed after installing the new signal handlers
926
+ // so that bugs like https://github.com/phusion/passenger/pull/97
927
+ // can be prevented.
928
+
929
+ sigset_t signal_set;
930
+ int ret;
931
+
932
+ sigemptyset(&signal_set);
933
+ do {
934
+ ret = sigprocmask(SIG_SETMASK, &signal_set, NULL);
935
+ } while (ret == -1 && errno == EINTR);
958
936
  }
959
937
 
960
938
  void