cateof
cateof

Reputation: 6758

setuid(0) and system fails

I have a program running in C. This needs to execute an "iptables" command using system.

I tried

setuid(0); 
system("iptables .... ");

setuid and system do not coexist. from the system man page

Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set- group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup. (Debian uses a modified bash which does not do this when invoked as sh.)

how can I overcome my problem?

Thanks

Upvotes: 2

Views: 1807

Answers (3)

cnicutar
cnicutar

Reputation: 182609

Something like this might help. It's untested but should work.

    char * const argv[] = {"/sbin/iptables", "-L", NULL};

    pid = fork();
    switch (pid) {
            case -1:
                    /* handle error */
            case 0:
                    execv("/sbin/iptables", argv);
                    /* handle error if you get here */
            break;
            default:
                    waitpid(pid, &status, 0);
                    /* check waitpid return code */
            break;
    }

Upvotes: 1

mah
mah

Reputation: 39807

system() will work in conjunction with setuid() but that's the problem: major security risk. The problem is system() starts a shell (bash, sh, etc.) using whatever environment is in place, and when you intend for it to run "iptables", my PATH could point to my own version of iptables which I could easily convince you to run for me, as root. You can seem to solve that by using a full path to iptables, but other environment variables (LD_PRELOAD_PATH, for example) can be used to convince tools to load rogue shared libraries -- again, running things as root which were not intended.

For what you need to do, securely, you must use one of the exec() family, and you must take control over its operating environment. Anything else is asking for security abuse. http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.html appears to be a good place to learn more.

Upvotes: 4

Carl Norum
Carl Norum

Reputation: 224844

Why do you need to use system()? The man page is telling you exactly what to do:

Use the exec(3) family of functions instead, but not execlp(3) or execvp(3).

You will probably be interested in the fork(2) and wait(2) system calls as well.

Upvotes: 2

Related Questions