Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

I had to do a dirty Linux hack for somebody so they could start a printer with the cupsenable printername shell command while being a non-root user. I didn't want them to be able to use the entirety of the cupsenable syntax as root, so I just wrote a C wrapper that sanitizes the input in argv[1] and calls system("cupsenable sanitizedprintername").

I made the program setuid root, but even so, cupsenable failed with "permission denied". Then I inserted a setuid(0) call before system() and, lo and behold, it worked.

Disregard the issue of there being a better way to give users control of the printer. There probably is a better way. What I'm interested in are the intricacies of chmod u+s vs. setuid(0) vs. system(). Why did it behave that way?

like image 321
JCCyC Avatar asked Jun 26 '09 21:06

JCCyC


People also ask

Why is setuid needed?

The Unix access rights flags setuid and setgid (short for set user identity and set group identity) allow users to run an executable with the file system permissions of the executable's owner or group respectively and to change behaviour in directories.

What does setuid 0 mean?

SETUID 0 or root means that when the program is run it is as if root ran it - which leaves you open to all the usual security risks of running something at high permission levels - it could potentially do anything to your system - so generally the number of applications that require SETUID should be minimised on a Unix ...

What is a setuid root?

If a file is “setuid” and is owned by the user “root” then a user that has the ability to execute that program will do so as the user root instead of themselves. The most common example of this in Linux is 'sudo'.

What security problems a setuid root program may cause?

setuid and setgid files are dangerous because they might give an unauthorized user root access, or at least access to run a program in another user's name. To make a program setuid root, the user must be root.


1 Answers

From man system:

Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup.

And from man bash:

If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id.

It appears your setuid(0) call circumvented that protection.

like image 66
John Kugelman Avatar answered Oct 15 '22 14:10

John Kugelman