Let's say the following program is executed from a setuid-root binary, by a non-root user:
int main()
{
if (fork()) {
/* Parent process */
int wstatus; wait(&wstatus);
if (WEXITSTATUS(wstatus) == 0) {
/* Child process exited with return code indicating success */
do_something_potentially_dangerous();
return 0;
} else {
/* Child process exited with return code indicating failure */
puts("Access denied");
return 1;
}
} else {
/* Child process */
setuid(getuid());
/*
...
*/
return do_critical_security_check(); /* let's say this returns 0 if it's safe */
}
}
A setuid program normally runs with extra security measures that prevent the user who started it from tampering with its (privileged) execution. I can only assume this status is preserved when it forks a child process.
But when the child process drops root privileges, does it also drop any of this protection? Barring a vulnerability in the child process's code, would the unprivileged user be able to interfere with do_critical_security_check()
, or otherwise force the child process to return 0 when it shouldn't? (Assume kernel.yama.ptrace_scope
is set to 0.)