Fabian
Fabian

Reputation: 847

setuid(0) with CAP_SETUID

I am trying to change my uid to 0 as non-root with the CAP_SETUID capability. I have the following program:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/capability.h>
#include <sys/prctl.h>

int main(int argc, char *argv[])
{
    printf("cap setuid in bset: %d\n", prctl(PR_CAPBSET_READ, CAP_SETUID, 0, 0, 0));
    printf("%s\n", cap_to_text(cap_get_file(argv[0]), NULL));
    printf("%s\n", cap_to_text(cap_get_proc(), NULL));
    printf("uid: %d\n", (int) getuid());
    setresuid(0, 0, 0);
    printf("uid: %d\n", (int) getuid());
    return 0;
}

I assign the setuid capability as follows:

sudo /sbin/setcap cap_setuid=ep ./capsetuid

And I get the following output

cap setuid in bset: 1
= cap_setuid+ep
=
uid: 1000
uid: 1000

I would expect the second printf() to also show the CAP_SETUID capability. Somehow my process does not get the setuid file capability. What am I doing wrong here?

Upvotes: 5

Views: 13846

Answers (3)

jshen28
jshen28

Reputation: 51

Filesysem with mount option nosuid set could be another reason. tmpfs for example sets nosuid and thus causes setcap does not take effect at all.

Upvotes: 0

Fabian
Fabian

Reputation: 847

Just found out that file capabilities need to be enabled on the kernel commandline with file_caps=1.

Upvotes: 3

caf
caf

Reputation: 239011

setuid() sets the effective user-id of the process, but getuid() gets the real user-id.

Change the getuid() to geteuid() and it should work.

Upvotes: 2

Related Questions