Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3805 (closed defect: wontfix)

Opened 5 years ago

Last modified 3 years ago

Very large multipart forms crash the FastCGI or Mongrel process

Reported by: yon-rubyonrails@milliped.com Assigned to: nzkoz
Priority: normal Milestone:
Component: ActionPack Version: 1.0.0
Severity: normal Keywords:
Cc:

Description

Here is the error message produced when such a form is submitted:

[11/Feb/2006:15:32:40 :: 145] Dispatcher failed to catch: Too many open files - /tmp/CGI145.246 (Errno::EMFILE)
  /opt/local/lib/ruby/1.8/tempfile.rb:55:in `initialize'
  /opt/local/lib/ruby/1.8/tempfile.rb:55:in `initialize'
  /opt/local/lib/ruby/1.8/cgi.rb:988:in `read_multipart'
  /opt/local/lib/ruby/1.8/cgi.rb:984:in `read_multipart'
  /opt/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/cgi_ext/raw_post_data_fix.rb:20:in `initialize_query'
  /opt/local/lib/ruby/1.8/cgi.rb:2270:in `initialize'
  (eval):16:in `initialize'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:600:in `each_cgi'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:117:in `session'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:104:in `each_request'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:36:in `each'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:597:in `each_cgi'
  /opt/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:52:in `process!'
  /opt/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:22:in `process!'
  /Users/yon/Sites/qreatives/public/dispatch.fcgi:24
almost killed by this error
[11/Feb/2006:15:32:40 :: 145] Dispatcher failed to catch: Bad file descriptor (Errno::EBADF)
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:24:in `for_fd'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:24:in `is_cgi?'
  /opt/local/lib/ruby/vendor_ruby/1.8/fcgi.rb:593:in `each_cgi'
  /opt/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:52:in `process!'
  /opt/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:22:in `process!'
  /Users/yon/Sites/qreatives/public/dispatch.fcgi:24
killed by this error

Change History

02/11/06 19:15:34 changed by anonymous

  • summary changed from Very large <b>multipart</b> forms crash the FastCGI process to Very large multipart forms crash the FastCGI process.

02/11/06 23:51:12 changed by nzkoz

  • owner changed from David to nzkoz.
  • status changed from new to assigned.

We've tested strongspace with 1G files and never hit these problems. You're running out of file descriptors, how big are the files you're uploading.

Is this fcgi with lighttpd or apache? I take it it's mac OS x with ruby from darwin ports?

02/11/06 23:55:28 changed by yon-rubyonrails@milliped.com

I ran into this with both lighttpd and webrick. And it does not seem to have to do with the size of the file but more with the number of form elements (inputs) I believe. I was running into this with files of less than 40KB.

02/11/06 23:57:27 changed by nzkoz

40 'file' inputs, or just any old input?

02/11/06 23:59:46 changed by yon-rubyonrails@milliped.com

Any old inputs will do, but like 100. I even removed the "file" inputs from the form and left the "multipart" declaration and it still occurred.

02/12/06 00:05:50 changed by yon-rubyonrails@milliped.com

Should i post the form that caused this error? (It's big).

02/26/06 18:37:40 changed by nzkoz

Please attach the form which causes this error.

(in reply to: ↑ description ) 10/26/06 05:13:03 changed by tietew

This problem seems to be a bug of cgi.rb.

cgi.rb tries to create a Tempfile object per field when multipart/form-data. Many number of fields will exceed process file handle limit.

11/13/06 07:44:21 changed by bitsweat

  • status changed from assigned to closed.
  • resolution set to wontfix.
  • component changed from Web to ActionPack.
  • severity changed from major to normal.

This is expected - better to create tempfiles than keep them all in memory. If you wish to change the behavior of Ruby CGI, pursue the issue on the Ruby mailing list.

(in reply to: ↑ description ) 07/20/07 16:25:25 changed by marsipan

  • summary changed from Very large multipart forms crash the FastCGI process to Very large multipart forms crash the FastCGI or Mongrel process.

I've encountered this problem (using Mongel), and it seems like a DoS vulnerability to me. A carefully crafted multipart POST to a Rails action (not blocked by a before_filter) will cause the process to stop responding to further requests.

I realize that this is not a problem with Rails specifically, so this ticket remains closed.

The error now occurs in cgi_multipart_eof_fix.rb:

Wed Jul 18 00:28:41 CDT 2007: Error calling Dispatcher.dispatch #<Errno::EMFILE: Too many open files - /tmp/CGI6434.246>
/usr/local/lib/ruby/1.8/tempfile.rb:55:in `initialize'
/usr/local/lib/ruby/1.8/tempfile.rb:55:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/cgi_multipart_eof_fix-2.1/lib/cgi_multipart_eof_fix.rb:28:in `read_multipart'
/usr/local/lib/ruby/gems/1.8/gems/cgi_multipart_eof_fix-2.1/lib/cgi_multipart_eof_fix.rb:24:in `read_multipart'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/cgi_ext/raw_post_data_fix.rb:38:in `initialize_query'
/usr/local/lib/ruby/1.8/cgi.rb:2270:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/cgi.rb:50:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:69:in `process'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:618:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:617:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:271:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:270:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:127:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/command.rb:211:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:243
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:60
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/server.rb:39
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3
no such file to load -- script/../config/../config/routes.rb
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:1165:in `load_routes!'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:1157:in `reload'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/dispatcher.rb:105:in `prepare_application'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/dispatcher.rb:39:in `dispatch'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:78:in `process'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:76:in `process'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:618:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:617:in `process_client'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:271:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/configurator.rb:270:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:127:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/command.rb:211:in `run'
/usr/local/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:243
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:488:in `load'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:60
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/server.rb:39
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3