popen fails when called after seteuid(0)
Вопрос
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?
Решение
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.