Search code examples
clinuxpermissionsforkglibc

If a C program executing as root executes another binary by calling system(someprog) does that program also run as root?


It seems like the system(someprog) call from a C program would execute the someprog binary with the same permissions as the C program has, but the docs for the system() call don't say anything about permissions of the forked process.


Solution

  • The privileges of the child process are the same as those of the parent process. If the parent runs as root, so does the child, unless the executed process is itself SUID to some other user (and the group might change if the executed process is SGID to another group). This is one of the many reasons why root has to be careful about what they execute.

    Underlying the system() call, you traditionally find fork() and execl() (or one of its close relatives) — there's a chance that Linux uses different detailed calls (clone(), or maybe the posix_spawn() family of functions). The basic underlying ideas will be the same. The forked child process has the same permissions as the parent process. When the child executes another process, it has the same permissions as the child process had — unless the executable is SUID or SGID. If you think about, when root runs a shell and the shell runs commands on behalf of root, those commands have the privileges of root — normally. This is no different from that.

    Be wary of the security implications!

    Of course, the executed program may do things about the permissions it runs with. See also Calling a script from a setuid root C program - script does not run as root, mentioned by that other guy in a comment.

    Note that system() often runs the equivalent of:

    /bin/sh -c "the string you passed it with spaces preserved"
    

    Therefore, it is important to understand the behaviour of the shell /bin/sh. Perl analyzes the string you pass to its system and avoids invoking the shell unless there are shell meta-characters in it. The standard C system() function is probably not that clever.

    If it matters to you, consider not using the standard system() function. Write your own that invokes execvp() or whatever after parsing the command string. Be aware that it is not trivial to handle this because things like signals and process groups complicate it. Study a competent book, or the source code for various open source library implementations of system().