next up previous
Next: I'm not scared yet, Up: Setuid applications Previous: Closing open files

Dropping privileges with popen

The popen function is quite similar to system, because it also runs an external command using the shell. The difference is that popen lets you attach the command's standard input or output to a file pointer, and use that in the calling function to communicate with the subprocess.

When you want to invoke an external command from a set-user application in this was, and want to drop privilege at the same time, you need to use the fork/exec combo as well, but with a little twist in order to attach to the command's standard input or output.

This twist is the use of the pipe system call that creates a pair of file descriptors that form a Unix pipe. The second descriptor is for writing; whatever you write to this descriptor can be read from the first.

In the following example, we use this to read from a sub-process. First, the pipe is created, then we fork. After forking, the parent process closes the writing side of the pipe, and attaches the read file descriptor to a FILE object.

The child process, on the other hand, closes the reading end of the pipe, and attaches the writing side to its standard output and standard error (file descriptors 1 and 2) using the dup2 system call. It then proceeds to drop privileges as described above, and execute the external program.

    int     fds[2], pid;

    if (pipe(fds) < 0) {
        perror("pipe() failed");
        return NULL;
    }
    if ((pid = fork()) < 0) {
        perror("fork failed");
        close(fds[0]); close(fds[1]);
        return NULL;
    }
    if (pid != 0) {
        /* parent process: return FILE pointer for reading
         * from sub-process */
        close(fds[1]);
        return fdopen(fds[0], "r");
    }

    close(fds[0]);
    dup2(fds[1], 1); /* attach pipe to stdout ... */
    dup2(fds[1], 2); /* ... and stderr */

    /* drop privilege and run command as above */


next up previous
Next: I'm not scared yet, Up: Setuid applications Previous: Closing open files
Olaf Kirch 2002-01-16