Difference Between Real User Id, Effective User Id and Saved User Id

Purpose of the saved user ID

It is best to do as much as possible with lower privileges. That way the OS protects you from doing stupid things.

Do as little as possible as root. Many people have logged in as root and really messed things up.

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

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.

What's the purpose of each of the different UIDs a process can have?

Each UNIX process has 3 UIDs associated to it. Superuser privilege is UID=0.

Real UID

This is the UID of the user/process that created THIS process. It can be changed only if the running process has EUID=0.

Effective UID

This UID is used to evaluate privileges of the process to perform a particular action. EUID can be changed either to RUID, or SUID if EUID!=0. If EUID=0, it can be changed to anything.

Saved UID

If you run an executable with the set-UID bit set, then the resulting running process will start off with a real UID of the real user running it, and an effective and saved UID of the owner of the executable file. If the process then calls setuid() or seteuid() to change their effective UID, they can still get back their original privileges again thanks to the saved UID. If the set-UID bit is not set, SUID will be the RUID.

Why saved set userID is needed?

When files are accessed, the system looks at the process's effective UID, its set of GIDs and matches those to the file permissions (and possibly the ACLs on the file).

When files are created, the system looks at the same process values when deciding whether the file can be created, but uses the effective UID to set the UID on the file, and uses either the effective GID or the directory's GID (if the SGID bit is set on the directory, or if you are on MacOS X).

The access() system call checks whether the real UID and real GID (instead of the effective UID and GID) can access the file.

If you have a SUID (setuid) program, then it can use its EUID to access files that it would otherwise not be accessible to its users. However, if it wants to create a file on behalf of the user (the RUID of the person running it), then it needs to drop the SUID privilege so the EUID is the same as the RUID. Once upon not so very long ago, once you dropped the SUID privilege, it was lost for good; you could not get it back. The saved UID value allows you to switch back, which simplifies management of privileges for SUID programs.

difference between euid, suid and ruid in linux systems

A process has an effective, saved, and real UID and GID.

The Effective UID is used for most access checks, and as the owner for files created by the process. An unprivileged process can change its effective UID only to either its saved UID or its real UID.

The Saved UID is used when a process running with elevated privileges needs to temporarily lower its privileges. The process changes its effective UID (usually root) to a unprivileged one, and its privileged effective UID is copied to the saved UID. Later, the process can resume its elevated privileges by resetting its effective UID back to the saved UID.

The Real UID is used to identify the real owner of the process and affect the permissions for sending signals. An unprivileged process can signal another process only if the sender’s real or effective UID matches the receiver's real or saved UID. Child processes inherit the credentials from the parent, so they can signal each other.

How and when does `exec` change the effective user ID, when the set-user-ID is set for the executable file

I'll cover UNIX V7 here. There are dozens of versions of UNIX, but their implementations of exec are pretty similar.

The effective uid is a field in the per-process user structure, and is kept in sync with a similar field in the process structure. In V7, changing the effective uid is done with two simple assignment statements:

/*
* set SUID/SGID protections, if no tracing
*/
if ((u.u_procp->p_flag&STRC)==0) {
if(ip->i_mode&ISUID)
if(u.u_uid != 0) {
u.u_uid = ip->i_uid;
u.u_procp->p_uid = ip->i_uid;
}
if(ip->i_mode&ISGID)
u.u_gid = ip->i_gid;
}

[Exercise: what does the check for (u.u_uid != 0) wind up doing, and why was it dropped from the exec code in subsequent versions of UNIX?]

The first thing exec does is check permissions, by calling access, which uses the process's effective uid and gid. It does this long before the setuid bit of the file is even looked at.

if ((ip = namei(uchar, 0)) == NULL)
return;
if(access(ip, IEXEC))
goto bad;

The uid change is done after all permission and magic number checking and memory allocation has been done. As the code says shortly before the allocation and uid setting:

/*
* allocate and clear core
* at this point, committed
* to the new image
*/

Get current process saved set-user-id

Well, you are not going to like this, but AFAICT, this is the only way to get suid for the process.

suid = `ps -o pid,suid`[/(?<=^#{Process.pid}\s)\s*\d+/].strip
#⇒ "1000"

Probably one should check if suid is available upfront. Basically, this regexp searches for the line starting with the current process’ pid.



Related Topics



Leave a reply



Submit