Ruby: Could not find a temporary directory
Asked Answered
M

3

17

I am getting some 500 errors in my Passenger Rails app. When looking at the log it appears passenger cannot access the /tmp dir. I have validated that it is there and has RW access to root, and then tried www-data. What is going on here?

 2014-01-14 16:01:16.6573 20624/7fa7c8806700 Pool2/SmartSpawner.h:301 ]: Preloader for /var/www/socialrest_homepage started on PID 20686, listening on unix:/tmp/passenger.1.0.20618/generation-0/backends/preloader.20686
App 20704 stdout: 
[Tue Jan 14 16:01:17 2014] [error] [client 168.215.171.129] Premature end of script headers: 
App 20686 stderr: /usr/local/rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/tmpdir.rb:34:in `tmpdir': could not find a temporary directory (ArgumentError)
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/utils/tmpio.rb:17:in `new'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/utils/tee_input.rb:99:in `initialize'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/rack/thread_handler_extension.rb:55:in `new'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/rack/thread_handler_extension.rb:55:in `process_request'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler/thread_handler.rb:141:in `accept_and_process_next_request'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler/thread_handler.rb:109:in `main_loop'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler.rb:440:in `block (3 levels) in start_threads'
[ 2014-01-14 16:01:21.0163 20624/7fa7cb242700 Pool2/Pool.h:776 ]: Process (pid=20704, group=/var/www/socialrest_homepage#default) no longer exists! Detaching it from the pool.
App 20720 stdout:

Here are my current /tmp, and config/environment.rb ownerships:

drwxrwxrwx   5 root root 4.0K Jan 14 16:01 tmp

-rwxr-xr-x  1 root root  196 Jan 13 20:06 environment.rb
Mcadams answered 14/1, 2014 at 15:55 Comment(0)
M
22

-- Updated -- Secure answer is to use chmod +t /tmp

-- Previous answer --

Not sure what happened here, but I believe it had something to do with the /tmp folder permissions. I thought my /tmp folder was corrupted so I looked around about deleteing that folder and restoring it (I wasn't sure if this folder was especially significant about the way it was created). I found this source that suggested you can simply make the /tmp folder, just as you would any other folder, and then do a chmod 1777 on the newly created folder.

So, instead of deleting my current /tmp, I ran this chmod command and everything appeared to work.

What is strange to me is that I had previously done a chmod 777 and that caused the folder to not work. Weird...

Mcadams answered 14/1, 2014 at 19:19 Comment(3)
life saver. Hit this issue only for certain pages just before start of user testing. First result in bing and resolved it right away. Thanks for sharingGuardado
chmod 777 /tmp removes the sticky bit from the directory. Without the sticky bit, anyone can remove, rename or replace a file from/in the directory at any time. That's a severe security issue.Ileus
An explanation why chmod 777 /tmp is a bad idea: security.stackexchange.com/questions/9115/…Ileus
I
35

The most significant part of the stack trace is the error message:

could not find a temporary directory (ArgumentError)

When you tell Ruby >= 2.0 to create a temporary file, it looks for a directory where it can create a file in a secure way. Creating temporary files in a directory where anybody can replace the file while you are working on it would be a big (and common) security hole!

You have two possibilities:

  • Tell ruby where it can securely create temporary files by setting one of the environment variables TMPDIR or TMP or TEMP to a directory that is secure.

  • Fix up the permissions on a directory that ruby tries to use. Directories that Ruby tries to use by default: systempdir ("/tmp") and the current directory

Ruby deems a directory secure if the directory is either not world writable or has the sticky bit set. (Do not confuse the sticky bit (t) with the seteuid/setgid bit (s)!)

So, instead of setting TMPDIR, you might either make your working directory not world writable or do:

chmod +t /tmp

The manual page of chmod explains the use of the sticky bit:

[It] prevents unprivileged users from removing or renaming a file in the directory unless they own the file or the directory; this is called the restricted deletion flag for the directory, and is commonly found on world-writable directories like /tmp.

Here is what can happen without the sticky bit: https://security.stackexchange.com/questions/9115/can-you-describe-a-real-life-scenario-of-exploiting-sticky-bits/108666#108666

See also: https://blog.diacode.com/fixing-temporary-dir-problems-with-ruby-2

Ileus answered 2/7, 2015 at 10:51 Comment(1)
Yep, that's it. 777 doesn't work. If you do a 777 on your /tmp dir, you can fix this with the chmod +t /tmp @Ileus suggested.Dimorphism
M
22

-- Updated -- Secure answer is to use chmod +t /tmp

-- Previous answer --

Not sure what happened here, but I believe it had something to do with the /tmp folder permissions. I thought my /tmp folder was corrupted so I looked around about deleteing that folder and restoring it (I wasn't sure if this folder was especially significant about the way it was created). I found this source that suggested you can simply make the /tmp folder, just as you would any other folder, and then do a chmod 1777 on the newly created folder.

So, instead of deleting my current /tmp, I ran this chmod command and everything appeared to work.

What is strange to me is that I had previously done a chmod 777 and that caused the folder to not work. Weird...

Mcadams answered 14/1, 2014 at 19:19 Comment(3)
life saver. Hit this issue only for certain pages just before start of user testing. First result in bing and resolved it right away. Thanks for sharingGuardado
chmod 777 /tmp removes the sticky bit from the directory. Without the sticky bit, anyone can remove, rename or replace a file from/in the directory at any time. That's a severe security issue.Ileus
An explanation why chmod 777 /tmp is a bad idea: security.stackexchange.com/questions/9115/…Ileus
R
5
ls -l /

$drwxrwxrw   9 root     root      4096 Jun 26 11:34 tmp

If you don't see that t at the end of the permissions column '/tmp'

chmod o+t /tmp
chmod 1777 /tmp    
$ ls -l / 
drwxrwxrwt   9 root     root      4096 Jun 26 11:35 tmp

reason is Fixing temporary dir problems with Ruby 2

Rejoin answered 1/8, 2015 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.