Setuid on an Executable Doesn't Seem to Work

setuid on an executable doesn't seem to work

First and foremost, setuid bit simply allows a script to set the uid. The script still needs to call setuid() or setreuid() to run in the the real uid or effective uid respectively. Without calling setuid() or setreuid(), the script will still run as the user who invoked the script.

Avoid system and exec as they drop privileges for security reason. You can use kill() to kill the processes.

Check These out.

http://linux.die.net/man/2/setuid

http://man7.org/linux/man-pages/man2/setreuid.2.html

http://man7.org/linux/man-pages/man2/kill.2.html

Why is setuid not running as the owner?

The suid bit works only on binary executable programs, not on shell scripts. You can find more info here: https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts

set-UID bit not working as intended

I've had similar issue with setuid bit and some versions of bash. In my case the solution was to write the program like this:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
// circumvent busybox ash dropping privileges
uid_t uid = geteuid();
setreuid(uid, uid);

system("do something....");
return 0;
}

I hope this will help you too.

Using $ORIGIN with setuid application does not fail as expected

I expected main to fail since $ORIGIN is not expanded in setuid applications.
Surprisingly, it works.

Glibc has a long history of expanding $ORIGIN even for suid binaries (see e.g. CVE-2010-3847). The motivation behind this is that suid binaries that use $ORIGIN for rpath are broken by design so Glibc developers were never very bothered to fix this. Some downstream distros provided patches on top of stock Glibc which disable ORIGIN-expansion so exact situation depends on your distro.

Funny enough, only free-standing $ORIGIN will be expanded - if you replace it with e.g. $ORIGIN/libs it'll start to fail.

Why does it work when I run main from its containing directory?

Once you move your file, $ORIGIN will expand to different folder which no longer contains the required library.

Why does SETUID not work on Raspberry Pi?

system() runs the program via a shell, and running a shell from any setuid program is extremely dangerous from a security perspective; there are lots of ways a user can hijack it to do other things (look up ways of abusing IFS, for instance). To mitigate this, commonly used shells will try to notice when they are being run under setuid (by noticing that the real and effective uids are different) and drop privileges.

So a safer alternative is to run poweroff via execle instead. (execl will also work, but it is risky to pass through environment variables that you don't control, so better to have your program set an environment that's known to be safe.)

You still have a problem in that your setuid program is runnable by anyone, so any unprivileged local user on the server would be able to shut it down. You'll want to make sure that it can only be executed by the user your app runs as. Since the owner of the file has to be root for setuid to work, this will require some juggling with groups.

You can avoid all this hassle and risk by instead setting up sudo to allow your app's user to run the poweroff command without a password, using the NOPASSWD directive in /etc/sudoers. This will:

  • restrict it to the desired user only

  • clean the environment

  • avoid the risks inherent to having an extra setuid program around that you have to maintain (e.g. future libc bugs, or you get tempted to add features, etc)

See https://unix.stackexchange.com/questions/18830/how-to-run-a-specific-program-as-root-without-a-password-prompt for more.



Related Topics



Leave a reply



Submit