Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

permanently drop root privileges on modern Linux

After start up I'd like my Linux program to drop root privileges and switch to a non-privileged account. I've found various examples online but nothing canonical for my requirements, specifically:

  1. this is a permanent drop
  2. both (e)uid and (e)gid should switch to non-root
  3. only Linux support (kernel > 2.6.32)
  4. no need for supplemental groups

The best approach I've found is:

uid_t new_uid = ...;
gid_t new_gid = ...;

gid_t rgid, egid, sgid;
if (setresgid(new_gid, new_gid, new_gid) < 0)
{
    perror("setresgid");
    exit(EXIT_FAILURE);
}
if (getresgid(&rgid, &egid, &sgid) < 0)
{
    perror("getresgid");
    exit(EXIT_FAILURE);
}
if (rgid != new_gid || egid != new_gid || sgid != new_gid)
{
    printf("unexpected gid");
    exit(EXIT_FAILURE);
}

if (setgroups(0, 0) != 0)
{
    perror("setgroups");
    exit(EXIT_FAILURE);
}

uid_t ruid, euid, suid;
if (setresuid(new_uid, new_uid, new_uid) < 0)
{
    perror("setresuid");
    exit(EXIT_FAILURE);
}
if (getresuid(&ruid, &euid, &suid) < 0)
{
    perror("getresuid");
    exit(EXIT_FAILURE);
}
if (ruid != new_uid || euid != new_uid || suid != new_uid)
{
    printf("unexpected uid");
    exit(EXIT_FAILURE);
}

I can wrap this in an exe and demonstrate that the uid's and gid's appear correct using:

ps -eO user,uid,ruid,suid,group,gid,rgid,sgid

The program can't bind to a privileged port or manipulate most root-owned files, so that's all good.

I've also found the captest program (included in libcap-ng-utils) which verifies that the process does not have any unexpected capabilities(7).

However, since security is a concern I'd like to be more confident that I've dropped all non-essential privileges correctly. How can I be certain?

Thanks.

like image 791
bfallik-bamboom Avatar asked Sep 05 '12 18:09

bfallik-bamboom


1 Answers

The "canonical" way to do this was implemented by D.J.Bernstein in his 'setuidgid' code, which was originally used into his QMail program, nowadays included in 'daemontools'.

The actual code used in GNU coreutils is based on DJB's description of the procedure, its code is visible here https://github.com/wertarbyte/coreutils/blob/master/src/setuidgid.c

like image 100
Jaromil Avatar answered Nov 05 '22 03:11

Jaromil