passenger 4.0.4 → 4.0.5

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.

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
- iQEcBAABAgAGBQJRo8yCAAoJECrHRaUKISqMlDcH+gJX2c+V84Rj7ZqJDWegW3DL
6
- Ve1y0leJszFGTxU5IO8HdbqlPeJNeoBzIoLrzPxb4cOhGvhvoQLATsm4oPup1hG9
7
- ZXen2bpAdZL+e/r6CoVcK1Ft4PjVfBzBlF91SE1yAx1VCNexcTPbkXsBjZbFOujR
8
- oE5U5p2YgmydxQE6LjEG7ipNbEJrQrfQJ3l32L8OYAAmlBHWO2DFfm9UE6FPBUgj
9
- KXgUmFUHvnfrXuO+3KaV1L9YsWMUe/jo4QjafOS5jFoKh3jUjHz4bJfkcAeSR+eb
10
- /XxJor58BsuOX5IUOQj9koM2WZj8Tc18YHncY6pmG/o6jTlO9xKO9cotYwMYSKQ=
11
- =RoSQ
5
+ iQEcBAABAgAGBQJRpgpHAAoJECrHRaUKISqMmNkIAIbfyHTRn7w8hubsVIbNhaTn
6
+ wbgIkDW2N7y9RQXCtjiCp8niJB5J0nguVsrU+vykoEPcQ8YVsDeo2OMrnWqZOQ3Y
7
+ k94g/ZDDXg+g9FkaQ/6U1B0au48qqwJVquBz6rL8awkgWd8yve6UAO9i5Oum3YWz
8
+ tuj1abiJxxZOOKhu6lGSe51nephHG35BUh0eNtO/PQCDptfjNBnEmDTmZL1xs3GM
9
+ W/lwx8q4AQJU4gpA31qtRDDP7GSL/2OKE0rBUfXSaMF88X3SotNr+ohZSUm6siHG
10
+ 4R2m469J8+RBNOnjNY6xILrrC+/WYM5G5GTKtjP8lwL6RD5xJ9JtyEOuYT0UrAc=
11
+ =TDNl
12
12
  -----END PGP SIGNATURE-----
data/NEWS CHANGED
@@ -1,3 +1,32 @@
1
+ Release 4.0.5
2
+ -------------
3
+
4
+ * [Standalone] Fixed a regression that prevented Passenger Standalone
5
+ from starting. Fixes issue #899.
6
+ * Fixed security vulnerability CVE-2013-2119.
7
+
8
+ Urgency: low
9
+ Scope: local exploit
10
+ Summary: denial of service and arbitrary code execution by hijacking temp files
11
+ Affected versions: all versions
12
+ Fixed versions: 3.0.21 and 4.0.5
13
+
14
+ Description:
15
+ Phusion Passenger's code did not always create temporary files and directories in a secure manner. Temporary files and directories were sometimes created with a predictable filename. A local attacker can pre-create temporary files, resulting in a denial of service. In addition, this vulnerability allows a local attacker to run arbitrary code as another user, by hijacking temporary files.
16
+
17
+ By pre-creating certain temporary files with certain permissions, attackers can prevent Passenger Standalone from starting (denial of service).
18
+
19
+ By pre-creating certain temporary files with certain other permissions, attackers can trick `passenger start` and the build system (which is invoked by `passenger-install-apache2-module`/`passenger-install-nginx-module`) to run arbitrary code. The user that the code is run as, is equal to the user that ran `passenger start` or the build system. Attacks of this nature have to be timed exactly right. The attacker must overwrite the file contents right after Phusion Passenger has created the file contents, but right before the file is used. In the context of `passenger start`, the vulnerable window begins right after Passenger Standalone has created the Nginx config file, and ends when Nginx has read the config file. Once Nginx has started and initialized, the system is no longer vulnerable. `passenger stop` and other Passenger Standalone commands besides `start` are not vulnerable. In the context of the build system, the vulnerable window begins when `passenger-install-apache2-module`/`passenger-install-nginx-module` prints its first dependency checking message, and ends when it prints the first compiler command.
20
+
21
+ Only the `passenger start` command, the `passenger-install-apache2-module` command and the `passenger-install-nginx-module` commands are vulnerable. Phusion Passenger for Apache and Phusion Passenger for Nginx (once they are installed) are not vulnerable.
22
+
23
+ Fixed versions:
24
+ 3.0.21 and 4.0.5 have been released to address this issue.
25
+
26
+ Workaround:
27
+ You can use this workaround if you are unable to upgrade. Before invoking any Phusion Passenger command, set the `TMPDIR` environment variable to a directory that is not world-writable. Special care must be taken when you use sudo: sudo resets all environment variables, so you should either invoke sudo with `-E`, or you must set the environment variable after gaining root privileges with sudo.
28
+
29
+
1
30
  Release 4.0.4
2
31
  -------------
3
32
 
@@ -221,12 +250,16 @@ This is the first beta of Phusion Passenger 4. The changes are numerous.
221
250
  * Better relocatability without wasting space.
222
251
 
223
252
 
224
- Release 3.0.20
253
+ Release 3.0.21
225
254
  --------------
226
255
 
227
256
  * Rebootstrapped the libev configure to fix compilation problems on Solaris 11.
228
257
  * Fixed support for RVM mixed mode installations. Fixes issue #828.
229
258
  * Fixed encoding problems in Phusion Passenger Standalone.
259
+ * Changed preferred Nginx version to 1.2.9.
260
+ * Catch exceptions raised by Rack application objects.
261
+ * Fix for CVE-2013-2119. Details can be found in the announcement for version 4.0.5.
262
+ * Version 3.0.20 was pulled because its fixes were incomplete.
230
263
 
231
264
 
232
265
  Release 3.0.19
@@ -32,6 +32,7 @@ require 'optparse'
32
32
  require 'fileutils'
33
33
  require 'phusion_passenger/platform_info/ruby'
34
34
  require 'phusion_passenger/abstract_installer'
35
+ require 'phusion_passenger/utils/tmpio'
35
36
 
36
37
  class Installer < PhusionPassenger::AbstractInstaller
37
38
  include PhusionPassenger
@@ -122,14 +123,12 @@ class Installer < PhusionPassenger::AbstractInstaller
122
123
  def before_install
123
124
  super
124
125
  myself = `whoami`.strip
125
- @working_dir = "/tmp/#{myself}-passenger-#{Process.pid}"
126
- FileUtils.rm_rf(@working_dir)
127
- FileUtils.mkdir_p(@working_dir)
126
+ @working_dir = PhusionPassenger::Utils.mktmpdir("passenger.", PlatformInfo.tmpexedir)
128
127
  end
129
128
 
130
129
  def after_install
131
130
  super
132
- FileUtils.rm_rf(@working_dir)
131
+ FileUtils.remove_entry_secure(@working_dir) if @working_dir
133
132
  end
134
133
 
135
134
  private
@@ -207,7 +207,8 @@ end
207
207
  # If you add a new shared definition file, don't forget to update
208
208
  # lib/phusion_passenger/packaging.rb!
209
209
 
210
- file 'ext/common/Constants.h' => ['ext/common/Constants.h.erb', 'lib/phusion_passenger/constants.rb'] do
210
+ dependencies = ['ext/common/Constants.h.erb', 'lib/phusion_passenger.rb', 'lib/phusion_passenger/constants.rb']
211
+ file 'ext/common/Constants.h' => dependencies do
211
212
  require 'phusion_passenger/constants'
212
213
  template = TemplateRenderer.new('ext/common/Constants.h.erb')
213
214
  template.render_to('ext/common/Constants.h')
@@ -70,7 +70,7 @@
70
70
 
71
71
  #define PROCESS_SHUTDOWN_TIMEOUT_DISPLAY "1 minute"
72
72
 
73
- #define PASSENGER_VERSION "4.0.3"
73
+ #define PASSENGER_VERSION "4.0.5"
74
74
 
75
75
  #define SERVER_INSTANCE_DIR_STRUCTURE_MAJOR_VERSION 1
76
76
 
@@ -29,7 +29,7 @@ module PhusionPassenger
29
29
  ###### Version numbers ######
30
30
 
31
31
  PACKAGE_NAME = 'passenger'
32
- VERSION_STRING = '4.0.4'
32
+ VERSION_STRING = '4.0.5'
33
33
 
34
34
  PREFERRED_NGINX_VERSION = '1.4.1'
35
35
  NGINX_SHA256_CHECKSUM = 'bca5d1e89751ba29406185e1736c390412603a7e6b604f5b4575281f6565d119'
@@ -111,7 +111,7 @@ class ServerInstance
111
111
  instances = []
112
112
 
113
113
  Dir["#{AdminTools.tmpdir}/passenger.*"].each do |dir|
114
- next if File.basename(dir) !~ /passenger\.#{PhusionPassenger::SERVER_INSTANCE_DIR_STRUCTURE_MAJOR_VERSION}\.(\d+)\.(\d+)\Z/
114
+ next if File.basename(dir) !~ /passenger\.#{PhusionPassenger::SERVER_INSTANCE_DIR_STRUCTURE_MAJOR_VERSION}\.(\d+)\.(.+)\Z/
115
115
  minor = $1
116
116
  next if minor.to_i > PhusionPassenger::SERVER_INSTANCE_DIR_STRUCTURE_MINOR_VERSION
117
117
 
@@ -67,5 +67,7 @@ module PhusionPassenger
67
67
  FEEDBACK_FD = 3
68
68
  end
69
69
 
70
- include SharedConstants
70
+ SharedConstants.constants.each do |name|
71
+ const_set(name, SharedConstants.const_get(name)) unless const_defined? name
72
+ end
71
73
  end
@@ -21,6 +21,8 @@
21
21
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  # THE SOFTWARE.
23
23
 
24
+ require 'phusion_passenger/utils/tmpio'
25
+
24
26
  module PhusionPassenger
25
27
 
26
28
  # This module autodetects various platform-specific information, and
@@ -149,20 +151,18 @@ private
149
151
  private_class_method :reindent
150
152
 
151
153
  def self.create_temp_file(name, dir = tmpdir)
152
- tag = "#{Process.pid}.#{Thread.current.object_id.to_s(16)}"
153
- if name =~ /\./
154
- ext = File.extname(name)
155
- name = File.basename(name, ext) + "-#{tag}#{ext}"
156
- else
157
- name = "#{name}-#{tag}"
158
- end
159
- filename = "#{dir}/#{name}"
160
- f = File.open(filename, "w")
161
- begin
162
- yield(filename, f)
163
- ensure
164
- f.close if !f.closed?
165
- File.unlink(filename) if File.exist?(filename)
154
+ # This function is mostly used for compiling C programs to autodetect
155
+ # system properties. We create a secure temp subdirectory to prevent
156
+ # TOCTU attacks, especially because we don't know how the compiler
157
+ # handles this.
158
+ PhusionPassenger::Utils.mktmpdir("passenger.", dir) do |subdir|
159
+ filename = "#{subdir}/#{name}"
160
+ f = File.open(filename, "w")
161
+ begin
162
+ yield(filename, f)
163
+ ensure
164
+ f.close if !f.closed?
165
+ end
166
166
  end
167
167
  end
168
168
  private_class_method :create_temp_file
@@ -279,16 +279,8 @@ module PlatformInfo
279
279
  # headers are placed into the same directory as the Apache headers,
280
280
  # and so 'apr-config' and 'apu-config' won't be necessary in that case.
281
281
  def self.apr_config_needed_for_building_apache_modules?
282
- filename = File.join("#{tmpexedir}/passenger-platform-check-#{Process.pid}.c")
283
- File.open(filename, "w") do |f|
284
- f.puts("#include <apr.h>")
285
- end
286
- begin
287
- return !system("(gcc #{apache2_module_cflags(false)} -c '#{filename}' -o '#{filename}.o') >/dev/null 2>/dev/null")
288
- ensure
289
- File.unlink(filename) rescue nil
290
- File.unlink("#{filename}.o") rescue nil
291
- end
282
+ return !try_compile("whether APR is needed for building Apache modules",
283
+ :c, "#include <apr.h>\n", apache2_module_cflags(false))
292
284
  end
293
285
  memoize :apr_config_needed_for_building_apache_modules?
294
286
 
@@ -180,9 +180,15 @@ private
180
180
 
181
181
  def write_nginx_config_file
182
182
  require 'phusion_passenger/platform_info/ruby'
183
- ensure_directory_exists(@temp_dir)
183
+ require 'phusion_passenger/utils/tmpio'
184
+ @temp_dir = PhusionPassenger::Utils.mktmpdir(
185
+ "passenger.#{SERVER_INSTANCE_DIR_STRUCTURE_MAJOR_VERSION}.#{SERVER_INSTANCE_DIR_STRUCTURE_MINOR_VERSION}.",
186
+ "/tmp")
187
+ @config_filename = "#{@temp_dir}/config"
188
+ location_config_filename = "#{@temp_dir}/locations.ini"
189
+ File.chmod(0755, @temp_dir)
184
190
 
185
- File.open(@location_config_filename, 'w') do |f|
191
+ File.open(location_config_filename, 'w') do |f|
186
192
  f.puts '[locations]'
187
193
  f.puts "natively_packaged=false"
188
194
  f.puts "bin=#{PhusionPassenger.bin_dir}"
@@ -200,7 +206,7 @@ private
200
206
  f.puts "apache2_module=#{PhusionPassenger.apache2_module_path}"
201
207
  f.puts "ruby_extension_source=#{PhusionPassenger.ruby_extension_source_dir}"
202
208
  end
203
- puts File.read(@location_config_filename) if debugging?
209
+ puts File.read(location_config_filename) if debugging?
204
210
 
205
211
  File.open(@config_filename, 'w') do |f|
206
212
  f.chmod(0644)
@@ -238,9 +244,6 @@ private
238
244
  def create_nginx_controller(extra_options = {})
239
245
  require_daemon_controller
240
246
  require 'socket' unless defined?(UNIXSocket)
241
- @temp_dir = "/tmp/passenger.#{SERVER_INSTANCE_DIR_STRUCTURE_MAJOR_VERSION}.#{SERVER_INSTANCE_DIR_STRUCTURE_MINOR_VERSION}.#{$$}"
242
- @config_filename = "#{@temp_dir}/config"
243
- @location_config_filename = "#{@temp_dir}/locations.ini"
244
247
  if @options[:socket_file]
245
248
  ping_spec = [:unix, @options[:socket_file]]
246
249
  else
@@ -30,6 +30,7 @@ require 'phusion_passenger/common_library'
30
30
  require 'phusion_passenger/platform_info/ruby'
31
31
  require 'phusion_passenger/platform_info/binary_compatibility'
32
32
  require 'phusion_passenger/standalone/utils'
33
+ require 'phusion_passenger/utils/tmpio'
33
34
 
34
35
  module PhusionPassenger
35
36
  module Standalone
@@ -199,16 +200,14 @@ protected
199
200
  def before_install
200
201
  super
201
202
  @plugin.call_hook(:runtime_installer_start, self) if @plugin
202
- @working_dir = "#{PlatformInfo.tmpexedir}/#{myself}-passenger-standalone-#{Process.pid}"
203
- FileUtils.rm_rf(@working_dir)
204
- FileUtils.mkdir_p(@working_dir)
203
+ @working_dir = PhusionPassenger::Utils.mktmpdir("passenger.", PlatformInfo.tmpexedir)
205
204
  @download_binaries = true if !defined?(@download_binaries)
206
205
  @binaries_url_root ||= STANDALONE_BINARIES_URL_ROOT
207
206
  end
208
207
 
209
208
  def after_install
210
209
  super
211
- FileUtils.rm_rf(@working_dir)
210
+ FileUtils.remove_entry_secure(@working_dir) if @working_dir
212
211
  @plugin.call_hook(:runtime_installer_cleanup) if @plugin
213
212
  end
214
213
 
@@ -105,7 +105,7 @@ class StartCommand < Command
105
105
  end
106
106
  ensure
107
107
  if @temp_dir
108
- FileUtils.rm_rf(@temp_dir) rescue nil
108
+ FileUtils.remove_entry_secure(@temp_dir) rescue nil
109
109
  end
110
110
  @plugin.call_hook(:cleanup)
111
111
  end
@@ -29,5 +29,40 @@ class TmpIO < File
29
29
  end unless File.method_defined?(:size)
30
30
  end
31
31
 
32
+ # Like Dir.mktmpdir, but creates shorter filenames.
33
+ def self.mktmpdir(prefix_suffix=nil, tmpdir=nil)
34
+ case prefix_suffix
35
+ when nil
36
+ prefix = "d"
37
+ suffix = ""
38
+ when String
39
+ prefix = prefix_suffix
40
+ suffix = ""
41
+ when Array
42
+ prefix = prefix_suffix[0]
43
+ suffix = prefix_suffix[1]
44
+ else
45
+ raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
46
+ end
47
+ tmpdir ||= Dir.tmpdir
48
+ begin
49
+ path = "#{tmpdir}/#{prefix}#{rand(0x100000000).to_s(36)}"
50
+ path << suffix
51
+ Dir.mkdir(path, 0700)
52
+ rescue Errno::EEXIST
53
+ retry
54
+ end
55
+
56
+ if block_given?
57
+ begin
58
+ yield path
59
+ ensure
60
+ FileUtils.remove_entry_secure path
61
+ end
62
+ else
63
+ path
64
+ end
65
+ end
66
+
32
67
  end # module Utils
33
68
  end # module PhusionPassenger
@@ -10,10 +10,12 @@ worker_processes 1;
10
10
  daemon on;
11
11
  error_log '<%= @options[:log_file] %>' <% if debugging? %>info<% end %>;
12
12
  pid '<%= @options[:pid_file] %>';
13
- <% if @options[:user] %>
14
- user <%= @options[:user] %> <%= default_group_for(@options[:user]) %>;
15
- <% else %>
16
- user <%= current_user %> <%= default_group_for(current_user) %>;
13
+ <% if Process.euid == 0 %>
14
+ <% if @options[:user] %>
15
+ user <%= @options[:user] %> <%= default_group_for(@options[:user]) %>;
16
+ <% else %>
17
+ user <%= current_user %> <%= default_group_for(current_user) %>;
18
+ <% end %>
17
19
  <% end %>
18
20
 
19
21
  events {
@@ -24,7 +26,7 @@ http {
24
26
  log_format debug '[$time_local] $msec "$request" $status conn=$connection sent=$bytes_sent body_sent=$body_bytes_sent';
25
27
  include '<%= PhusionPassenger.resources_dir %>/mime.types';
26
28
  passenger_ruby <%= PlatformInfo.ruby_command %>;
27
- passenger_root '<%= @location_config_filename %>';
29
+ passenger_root '<%= location_config_filename %>';
28
30
  passenger_ctl server_instance_dir '<%= @temp_dir %>';
29
31
  passenger_abort_on_startup_error on;
30
32
  passenger_user_switching off;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.4
4
+ version: 4.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-27 00:00:00.000000000 Z
12
+ date: 2013-05-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
metadata.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
- iQEcBAABAgAGBQJRo8yCAAoJECrHRaUKISqMSDkH/RxWUudgepdJIx2wDNN1YwMG
6
- QiHESwcQu9ZcgtSdHsc6BeexfFRTKs8PUatUHikJoOtZI4AOIpozk6RWC+qxC5uO
7
- 5OetfgbH1sDc+TnwJP2Ev49DEcNFAvbSTC5/dw6c8yvACwiwU/uwI+6RDIZ1B0kT
8
- F2iq6LIqxtRsOdd8RWPDnFkrgA9YWtHwcjbXxG3mrL/i2pYghkRukKEkmDpR7P6a
9
- 6SV6wtqWm2IfcGskLIEd/rGNKnZUiRRpLTjY5wuxArUJSr6h6J5W0c9XOv3xQSHL
10
- d40LIN7xtSZ5Ju/1K1G+6E+UZwrM0JVyN8td7wbQKLYX+449/WbAwJJueuG3wBQ=
11
- =kL76
5
+ iQEcBAABAgAGBQJRpgpHAAoJECrHRaUKISqMaUsH/36pNJGxryARsxpddPgRmhUh
6
+ iilOVBDcfD8kun8/OUdfaAdabr3AXsRJsTzYAeac7SM+6FQ2h7rPKOK4eyQCICPm
7
+ bgJ82TXu/TGbiSvzXrNGTg8Lx+xg0p+kv8jhbLN5zZoXFVPbFv0O6A6T8ExU7Fbr
8
+ qNJPFAMdnIN2X4qx6wbCz8mcUDuq8LrQ7wp85+WrsvTam9t6H3MHEnrewC25DTrD
9
+ hlay1dc7o1rb98Skz16rLdoPMiAO7VpBHzxpRBnarnnS0okHNLKzmNEyLGEwuUwj
10
+ WTptq1vvism04T/tY0+m0RZvc8Ev58ydWH6O2ZsI3M6Zu5iZkWqtBj+jU0oZcZQ=
11
+ =nU+e
12
12
  -----END PGP SIGNATURE-----