Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
587 views
in Technique[技术] by (71.8m points)

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

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:

int main(void) {
    printf(
        "         UID           GID  
"
        "Real      %d  Real      %d  
"
        "Effective %d  Effective %d  
",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

seteuid(600);
    printf(
        "         UID           GID  
"
        "Real      %d  Real      %d  
"
        "Effective %d  Effective %d  
",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

setuid(1000);

    printf(
        "         UID           GID  
"
        "Real      %d  Real      %d  
"
        "Effective %d  Effective %d  
",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

setuid(0); // HOW DOES THIS SUCCEED IN SETTING THE EUID BACK TO 0
    printf(
        "         UID           GID  
"
        "Real      %d  Real      %d  
"
        "Effective %d  Effective %d  
",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );

    return 0 ;       
}

OUTPUT

         UID           GID  
Real      1000  Real      1000  
Effective 0  Effective 0  
         UID           GID  
Real      1000  Real      1000  
Effective 600  Effective 0  
         UID           GID  
Real      1000  Real      1000  
Effective 1000  Effective 1000  
         UID           GID  
Real      1000  Real      1000  
Effective 0  Effective 1000  

My question

The man page states that setuid will change the real,saved and effective uid. So after the calling setuid(1000), all three change to 1000. How is that setuid(0) let's me change euid to 0?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are two cases,

  1. You want to temporarily drop root privilege while executing setuid program
  2. You want to permanently drop root privilege while executing setuid program...
  • You can temporarily do it by setting the euid to the real user id and then changing the uid to anything you want.And later when you need the root privilege back you can setuid to root and the effective userid will change back to root. This is because the saved user id is not changed.
  • You can drop privilege permanently by changing the uid straight away to a lesser privileged user id. After this no matter what you cannot get back the root privilege.

Case 1:

After a setuid program starts executing

1.seteuid(600);
2.setuid(1000);
3.setuid(0);

For this case the root privilege can be gained back again.

              +----+------+------------+
              | uid|euid  |saved-uid   |
              |----|------|------------|
            1.|1000| 0    | 0          |
            2.|1000| 600  | 0          |
            3.|1000| 1000 | 0          |
            4.|1000|  0   | 0          |
              |    |      |            |
              +------------------------+

Case 2:

After a setuid program starts executing,

1.setuid(1000);
2.setuid(0);



               +----+------+------------+
               | uid|euid  |saved-uid   |
               |----|------|------------|
             1.|1000|0     | 0          |
             2.|1000|1000  | 1000       |
               |    |      |            |
               +------------------------+

In this case you cannot get back the root privilege. This can be verified by the following command,

cat /proc/PROCID/task/PROCID/status | less

Uid:    1000    0       0       0
Gid:    1000    0       0       0

This command will display a Uid and Gid and it will have 4 fields( the first three fields are the one we are concerned with). Something like the above

The three fields represent uid,euid and saved-user-id. You can introduce a pause (an input from user) in your setuid program and check for each step the cat /proc/PROCID/task/PROCID/status | less command. During each step you can check the saved uid getting changed as mentioned.

If you're euid is root and you change the uid, the privileges gets dropped permanently.If effective user id is not root then saved user id is never touched and you can regain the root privilege back anytime you want in your program.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...