RealUID, Saved UID, Effective UID. What's going on?

前端 未结 4 409
别跟我提以往
别跟我提以往 2020-12-12 11:59

This is a set-root-uid program

$ls -l
-rwsr-sr-x 1 root root 7406 2011-12-13 22:37 ./x*

The source code:



        
4条回答
  •  死守一世寂寞
    2020-12-12 12:34

    Code:

    #define _GNU_SOURCE
    #include 
    #include 
    
    void print_uid(char *str, int ret)
    {
        uid_t ruid;
        uid_t euid;
        uid_t suid;
        getresuid(&ruid, &euid, &suid);
    
        printf("%s ret:%d\n"
               "Real:%4d  Effective:%4d  Saved:%4d\n",
               str, ret, ruid, euid, suid);
    }
    
    int main(void)
    {
        int ret = 0;
        print_uid("init", ret);            /* Real:1000  Effective:   0  Saved:   0 */
    
        ret = seteuid(600);
        print_uid("seteuid(600)", ret);    /* Real:1000  Effective: 600  Saved:   0 */
    
        ret = setuid(1000);
        print_uid("setuid(1000)", ret);    /* Real:1000  Effective:1000  Saved:   0 */
    
        ret = setuid(0);
        print_uid("setuid(0)", ret);       /* Real:1000  Effective:   0  Saved:   0 */
    
        ret = setuid(1000);
        print_uid("setuid(1000)", ret);    /* Real:1000  Effective:1000  Saved:1000 */
    
        ret = setuid(0);
        print_uid("setuid(0)", ret);       /* Real:1000  Effective:1000  Saved:1000 */
    
        return 0 ;       
    }
    

    sudo chown root setuid_feature
    sudo chmod +s setuid_feature

    There are three uids for a process in Linux: REAL uid, EFFECTIVE uid, SAVED uid.
    Cond 1. When euid is root, setuid or seteuid can be set to any uid, but there is a side effect, when using setuid(not seteuid), all of the three can be set to the same uid which is not ROOT, and then the process can't regain ROOT privilege.
    Cond 2. When euid is not root, setuid or seteuid can be set to ruid or suid, and only euid is changed.

                           |      seteuid             |          setuid  
    Cond 1. (euid == root) | set euid to any uid      | set all three uids to any uid  
    Cond 2. (euid != root) | set euid to ruid or suid | set euid to ruid or suid  
    

    so, there are 5 setuid or seteuid process there in code, let me classify them:
    1. seteuid(600): Cond 1, set euid to 600
    2. setuid(1000): Cond 2, set euid to 1000
    3. setuid(0) : Cond 2, set euid to 0(suid)
    4. setuid(1000): Cond 1, set all three uids to 1000
    5. setuid(0) : Cond 2, all three uids is not equal 0, so can't set to 0, failed with ret = -1

提交回复
热议问题