setuid(0) with CAP_SETUID

10,376

Solution 1

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

Solution 2

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.

Share:
10,376
Fabian
Author by

Fabian

Updated on June 04, 2022

Comments

  • Fabian
    Fabian about 2 years

    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?

  • Jonathan Leffler
    Jonathan Leffler over 13 years
    If setuid() sets the effective UID, what does the seteuid() function do? Part of the answer is "the same"; the difference is that setuid() does set the real and effective and saved UID values to the given UID if the process has 'appropriate privileges'. Then the subsidiary question is "does possessing the CAP_SETUID privilege confer the appropriate privileges"?
  • Fabian
    Fabian over 13 years
    euid doesn change neither. The man page says: "If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." I am not root, though, I am priviliged. So I am not sure what happens in my case. I found the problem is in my process not getting the cap_setuid capability. I've updated the question
  • caf
    caf over 13 years
    @Fabian: Does your kernel have file capabilities enabled (CONFIG_SECURITY_FILE_CAPABILITIES=y)? What does ` prctl(PR_CAPBSET_READ, CAP_SETUID, 0, 0, 0)` return?
  • Fabian
    Fabian over 13 years
    My kernel does have file capabilities. prctl() returns 1. So from I understand from the manpage, this means that my process does not get cap_setuid because it is blocked by the bounding capability set. Right? How do I change the bounding cap set?
  • Fabian
    Fabian over 13 years
    the problem was that file capabilities must be enabled on the kernel command line.