Insecure operation - chdir

Y

Yang Zhang

When running rake from a suid binary:

#include <stdlib.h>
int main() {
return system("rake -f /usr/share/redmine/Rakefile
redmine:fetch_changesets RAILS_ENV=production");
}

I'm getting "Insecure operation - chdir":

$ ./update-redmine
rake aborted!
Insecure operation - chdir
/usr/lib/ruby/1.8/rake.rb:2364:in `chdir'
(See full trace by running task with --trace)

When I added --trace to the command, I get:

$ ./update-redmine
rake aborted!
Insecure operation - chdir
/usr/lib/ruby/1.8/rake.rb:2364:in `chdir'
/usr/lib/ruby/1.8/rake.rb:2364:in `find_rakefile_location'
/usr/lib/ruby/1.8/rake.rb:2368:in `raw_load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2017:in `load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/1.8/rake.rb:2016:in `load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2000:in `run'
/usr/lib/ruby/1.8/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/1.8/rake.rb:1998:in `run'
/usr/bin/rake:28

Anybody know what's up with this? Also, is this totally unsafe? I
don't know how safe a program rake is (e.g., can one set env vars to
get it to do arbitrary actions?). Not actually putting this into
deployment on anything but my own box, but would just be good for me
to know, and I'm mostly curious about my original question. Thanks in
advance for any answers.
 
Y

Yang Zhang

When running rake from a suid binary:

#include <stdlib.h>
int main() {
=A0return system("rake -f /usr/share/redmine/Rakefile
redmine:fetch_changesets RAILS_ENV=3Dproduction");
}

I'm getting "Insecure operation - chdir":

$ ./update-redmine
rake aborted!
Insecure operation - chdir
/usr/lib/ruby/1.8/rake.rb:2364:in `chdir'
(See full trace by running task with --trace)

When I added --trace to the command, I get:

$ ./update-redmine
rake aborted!
Insecure operation - chdir
/usr/lib/ruby/1.8/rake.rb:2364:in `chdir'
/usr/lib/ruby/1.8/rake.rb:2364:in `find_rakefile_location'
/usr/lib/ruby/1.8/rake.rb:2368:in `raw_load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2017:in `load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/1.8/rake.rb:2016:in `load_rakefile'
/usr/lib/ruby/1.8/rake.rb:2000:in `run'
/usr/lib/ruby/1.8/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/1.8/rake.rb:1998:in `run'
/usr/bin/rake:28

Anybody know what's up with this? Also, is this totally unsafe? I
don't know how safe a program rake is (e.g., can one set env vars to
get it to do arbitrary actions?). Not actually putting this into
deployment on anything but my own box, but would just be good for me
to know, and I'm mostly curious about my original question. Thanks in
advance for any answers.


To add to the confusion, the rake task runs fine from root's crontab.
I found some information on taint and $SAFE, but it's unclear to me
why things work via cron but not via a suid binary.


--=20
Yang Zhang
http://yz.mit.edu/
 
L

Luis Lavena

To add to the confusion, the rake task runs fine from root's crontab.
I found some information on taint and $SAFE, but it's unclear to me
why things work via cron but not via a suid binary.

You need to cd into the directory where the Rakefile is since most of
the "file" and other relative tasks like FileUtils will be generated
in pwd.

You can safely avoid that by doing "cd /path/to/app && rake "
 
D

David Masover

To add to the confusion, the rake task runs fine from root's crontab.
I found some information on taint and $SAFE, but it's unclear to me
why things work via cron but not via a suid binary.

Well, if the purpose of these things being enabled on setuid is to make it
harder for a user to exploit a poorly-written Ruby script to gain root access,
it makes perfect sense. If the task is in root's crontab, only root can run
it, or do anything to screw with the environment it's being run from. If it's
run setuid, any user on the system can run it whenever and however they want.
 
B

Brian Candler

Yang said:
To add to the confusion, the rake task runs fine from root's crontab.
I found some information on taint and $SAFE, but it's unclear to me
why things work via cron but not via a suid binary.

$SAFE is set to 1 if the code is run setuid.

The actual test is if the real UID is non-zero and the real UID is
different from the effective UID or the real GID is different from the
effective GID. Code from ruby-1.9.2preview1 (ruby.c):

static void
init_ids(struct cmdline_options *opt)
{
rb_uid_t uid = getuid();
rb_uid_t euid = geteuid();
rb_gid_t gid = getgid();
rb_gid_t egid = getegid();

if (uid != euid) opt->setids |= 1;
if (egid != gid) opt->setids |= 2;
if (uid && opt->setids) {
if (opt->safe_level < 1) opt->safe_level = 1;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top