0

I am trying to make a python script executable with the setuid bit set. The program, belonging to user 'bgmc', must create some files in the directory '/home/bgmc', but is called by another user, 'client'. Indeed, I don't want user 'client' to change the files created by the program. I used a c-wrapper to call the program (see setuid on shell scripts):

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    setuid(0);
    system("/home/bgmc/myprogram.sh");
    return 0;
}

I set the setuid bit of the program on. When the c-compiled program belongs to root, the program runs well and creates the expected file. The properties of the c-compiled program are then:

8 -rws--x--x 1 root root 4657 Mar  2 16:25 myprogram

However, when I change the user-group of myprogram to bgmc:bgmc, the program cannot create the file anymore: "Permission denied". I tried to change the line:

setuid(0);

with:

setuid(1002);

since 1002 is the user id of 'bgmc' (I used command "id -u bgmc" for this) but this didn't help.

I would rather prefer not giving root access to the program. Is there a way to prevent this?

jww
  • 97,681
  • 90
  • 411
  • 885
sarah vb
  • 149
  • 2
  • 12

1 Answers1

3

Not sure about this since your question is very sparse on information, but did you forget to reset the permissions on the file after changing the owner? On most systems, any change of ownership automatically removes the setuid bit and you have to re-add it yourself if you want it.

Also note that setuid shell scripts are a major vulnerability; this is why the kernel does not allow you to make a shell script setuid directly. At the very least you should:

  1. Use execve rather than system to call it, and
  2. Clear out everything from the environment (or pass a new empty environment to execve).

As it is now, anyone who can run the program can make it do whatever they like by controlling environment variables.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Thanks for your answer. Since you said that setuid shell scripts is dangerous to do, I tried to setgid the script instead. However, this doesn't seem to work, eventhough my directory has the right permissions (775). Does setgid of scripts neither have an effet in linux? Should I also make a c-wrapper in that case? – sarah vb Mar 07 '12 at 10:42
  • The issue with setgid is the same as with setuid. Whatever permissions that group had, you might as well give all users on the system those permissions, because it's trivial to exploit the script to obtain them. As such, the kernel does not support setgid on scripts. – R.. GitHub STOP HELPING ICE Mar 07 '12 at 14:12
  • Thanks! I used as you said `execve` (or, to be more precise `execle`, I imagine these are equivalent) and passed an empty environment to it. My question is: what exactly should be cleared that way? Because, by clearing the environment, my program cannot acceed anymore to some libraries in python (with "import"; i.e. "import matplotlib.pyplot"). So, I would rather not clear everything.. – sarah vb Mar 07 '12 at 16:17
  • If you don't want to clear everything, you need to at least choose a limited set of things that are safe to keep. But note that an environment variable storing something like the search path for python is NOT SAFE to keep because an attacker can replace it with an arbitrary path and cause python (with the elevated permissions) to load code that's under the attacker's control. The safe way is to have the wrapper program create a new environment with the correct values for these variables. – R.. GitHub STOP HELPING ICE Mar 07 '12 at 18:09