Question

My C code does a

 seteuid (euid);
 popen("/root/bin/iptables ....", "r");

and it fails even if I call with seteuid(0). (The executables has setuid on).

It seems that seteuid and popen do not work together.

When popen called it prints in stderr the following msg

iptables v1.4.6: can't initialize iptables table : Permission denied (you must be root)

In other words popen "succeeds", but because a new shell is created the permissions are not maintained and the use case fails.

How can I solve the problem?

Was it helpful?

Solution

Your are invoking a setuid script by calling popen. Many distibutions of Linux, for example, have checks in shell invocation to prevent a script begin run setuid or seteuid. The problem is not popen, is is /bin/sh, which is the default shell popen uses. In Linux /bin/sh is normally bash.

I believe it calls getresuid() and checks the saved uid, which has to be root.

You can work around this by calling an exec function to a shell that does not perform these checks, or writing all of your code in C (no shell calls) - which is the real intent of the security check.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top