how to gain then drop privs

I often read about Linux programs that are suid root but then acquire what they need and drop privs. I thought I’d add this to Wine so it can raise thread priorities but without needing to run as root. So imagine my surprise when I found that code to do this is nowhere to be found. It seems nearly nothing uses POSIX capabilities, and the man pages are (as usual) obscure.

So here’s some example code.

#include <sys/capability.h>
#include <sys/prctl.h>

void setup_security()
{
    cap_t cap;

    /* don't do anything if we were started as root, or are not suid */
    if (geteuid() != 0) return;
    if (getuid() == 0) return;

    /* keep root capabilities as we transition to the regular user */
    prctl( PR_SET_KEEPCAPS, 1, 0, 0, 0 );

    /* switch back to user that run us */
    setuid( getuid() );

    /* drop all privs except CAP_SYS_NICE */
    if (cap_set_proc((cap = cap_from_text( "CAP_SYS_NICE+pe" ))) < 0)
    {
        perror( "cap_set_proc: failed to drop privs, aborting" );
        exit( 1 );
    }
    cap_free(cap);
}

Just make sure you do it early on in the code, before any potentially exploitable code has run. That includes loading libraries relative to the $ORIGIN. Go index it Google!

About these ads

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: