Difference between Real User ID, Effective User ID and Saved User ID
Asked Answered
H

5

192

I am already aware of the real user id. It is the unique number for a user in the system.

On my system, my uid is

$ echo $UID
1014
$

What do the other two IDs stands for?

And what is the use of effective user id and saved user id and where do we use them in the system?

Handmedown answered 8/9, 2015 at 10:43 Comment(2)
FYI - there is also the file system user id, as outlined on the Wikipedia page: en.wikipedia.org/wiki/User_identifierEdirne
I think he didn't mention it because (from your wiki link): "Since kernel 2.0, the existence of fsuid is no longer necessary because Linux adheres to SUSv3 rules for sending signals, but fsuid remains for compatibility reasons."Irvine
I
225

The distinction between a real and an effective user id is made because you may have the need to temporarily take another user's identity (most of the time, that would be root, but it could be any user). If you only had one user id, then there would be no way of changing back to your original user id afterwards (other than taking your word for granted, and in case you are root, using root's privileges to change to any user).

So, the real user id is who you really are (the one who owns the process), and the effective user id is what the operating system looks at to make a decision whether or not you are allowed to do something (most of the time, there are some exceptions).

When you log in, the login shell sets both the real and effective user id to the same value (your real user id) as supplied by the password file.

Now, it also happens that you execute a setuid program, and besides running as another user (e.g. root) the setuid program is also supposed to do something on your behalf. How does this work?
After executing the setuid program, it will have your real id (since you're the process owner) and the effective user id of the file owner (for example root) since it is setuid.

The program does whatever magic it needs to do with superuser privileges and then wants to do something on your behalf. That means, attempting to do something that you shouldn't be able to do should fail. How does it do that? Well, obviously by changing its effective user id to the real user id!

Now that setuid program has no way of switching back since all the kernel knows is your id and... your id. Bang, you're dead.

This is what the saved set-user id is for.

Iatric answered 8/9, 2015 at 11:38 Comment(5)
For more clarity on that last point about saved-set user id, see Wikipedia.Silsbye
Can you point me to some readings where I can find which sys call check the Real uid instead? thank youAntiar
@mik1904: The most important one that you are likely to use which really checks real UID is access. That's 99.9% of it. Also setfsuid (but rarely needed), and some very low level funcs, and you need (but aren't checked for) the real user ID for getting/setting priorities or scheduler, and the IDs passed to signal handlers or returned by wait et al. are real IDs. execvedoes not check, but can fail if you've changed real user id. Also fork does not check, but can fail if you reach the maximum process quota on the real UID. Google with site:man7.org is your friend here.Iatric
"the ping command needs to open up a socket and the Linux kernel demands root privilege for that." this isn't really accurate. ping needs a raw socket. any user can (usually) open a socket, and for listening, above 1024.Innovate
@DanielFarrell it depends on how ping is implemented to use ICMP, tcp or udp, for icmp it requires the raw sockets and the privilegesFungosity
I
139

I'll try to explain step by step with some examples.

Short background

Each process has its own 'Process credentials' which include attributes like PID, the PPID, PGID, session ID and also the real and effective user and group IDs: RUID, EUID, RGID, EGID.

We'll focus on those.


Part 1: Understand UID and GID

Now I'll log into a shell with my credentials and run:

$ grep $LOGNAME /etc/passwd
rotem:x:1000:1000:rotem,,,:/home/rotem:/bin/bash

You can see my logname (rotem), the UID and GID which are both 1000, and other details like the shell I'm logged into.


Part 2: Understand RUID and RGID

Every process has an owner and belongs to a group. In our shell, every process that we'll now run will inherit the privileges of my user account and will run with the same UID and GID.

Let's run a simple command to check it:

$ sleep 10 & ps aux | grep 'sleep'

And check for the process UID and GID:

$ stat -c "%u %g" /proc/$pid/
1000 1000

Those are the real user ID (RUID) and real group ID (RGID) of the process.

(*) Check other options to view the UID and GID and ways to get this in a single line.

For now, accept the fact that the EUID and EGID attributes are 'redundant' and just equals to RUID and RGID behind the scenes.


Part 3: Understand EUID and EGID

Let's take the ping command as an example.

Search for the binary location with the which command then run ls -la:

-rwsr-xr-x  1 root root   64424 Mar 10  2017  ping

You can see that the owner and the group of the file are root. This is because the ping command needs to open up a special socket and the Linux kernel demands root privilege for that.

But how can I use ping if I don't have root privilege?

Notice the 's' letter instead of 'x' in the owner part of the file permission.

This is a special permission bit for specific binary executable files (like ping and sudo) which is known as setuid.

This is where EUID and EGID come into play.

What will happen is when a setuid binary like ping executes, the process changes its Effective User ID (EUID) from the default RUID to the owner of this special binary executable file which in this case is - root.

This is all done by the simple fact that this file has the setuid bit.

The kernel makes the decision whether this process has the privilege by looking on the EUID of the process. Because now the EUID points to root, the operation won't be rejected by the kernel.

Notice: On latest Linux releases the output of the ping command will look different because of the fact that they adopted the Linux Capabilities approach instead of this setuid approach - for those who are not familiar - read here.

Part 4: What about SUID and SGID?

The Saved user ID (SUID) is being used when a privileged process is running (as root for example) and it needs to do some unprivileged tasks.

In that case, the effective UID (EUID) from before will be saved inside SUID and then changed to an unprivileged task. When the unprivileged task is completed, the EUID will be taken from the value of SUID and switch back to privileged account.

Irvine answered 26/9, 2019 at 19:57 Comment(4)
Clear answer except for the last para on SUID. Got confused with privileged and privileged tasks. Useful if an example is provided. Thanks.Wore
en.wikipedia.org/wiki/User_identifier#Saved_user_ID points to a use caseFungosity
does the process owner's id == RUID?? @FungosityDuggan
@KMABadshah When you fork a new process, the process inherits the parent's RUID. Normally the parent's RUID is of your shell and it has a your UID. So the new process has RUID of your UID. Normally this is not changed, and only root can change it. As an example for that, think about that init process forks your login shell. During forks, the shell would have root's RUID(because the shell's parent is init). But, the init process changes the shell's RUID to your UID using /etc/passwd. So, thereafter the login shell's RUID would be your UID, not root. So, we can say RUID is of process owner.Dissimulate
D
4

This is how I understand it. The file an user executes(equivalent to starting a process) will have a RUID equal to that user's id. Important thing to note here is that the uid which created a file is not the same as the uid that executes the file. They can be the same or different. So, RUID may vary depending on the UID that executes the file. When a file has the setuid bit on it, whenever an uid executes that file, that uid will temporary be replaced with the file owner's uid. So, if we have a file owned by uid 456 and has the setuid bit on it, whenever uid 123 executes that file, that file will be executed with the uid 456. In this scenario, uid 123 is the RUID and uid 456 is the EUID.

Duggan answered 28/2, 2021 at 11:40 Comment(0)
C
4

Real user id is the user that spawned the process.

Effective user id is the user determined by the setuid bit on the binary being executed.

Here are some truths about uids and euids, with the manual sources for each:

You can use euid when you're spawning as root and you need to temporarily drop privileges and still be able to regain root privileges after, as in man setuid(2):

Thus, a set-user-ID-root program wishing to temporarily drop root privileges, as‐
sume the identity of an unprivileged user, and then regain root privileges after‐
ward cannot use setuid().  You can accomplish this with seteuid(2).

You can also use it to raise your privileges from a setuid program. If your effective user id is root, everything will react as if you are root, except I think the only exception is file access checks will check your real user id rather than effective user id, which is a source of confusion, as in man access(2):

The check is done using the calling process's real UID and GID,  rather
than the effective IDs as is done when actually attempting an operation
(e.g., open(2)) on the file.  Similarly, for the root user,  the  check
uses the set of permitted capabilities rather than the set of effective
capabilities; and for non-root users, the check uses an  empty  set  of
capabilities.

When calling bash, it doesn't propagate euid unless you pass -p as in man bash(1):

If the shell is started with the effective user (group) id not equal to the  real
user  (group)  id,  and the -p option is not supplied, no startup files are read,
shell functions are not inherited from the environment, the SHELLOPTS,  BASHOPTS,
CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored,
and the effective user id is set to the real user id.  If the -p option  is  sup‐
plied  at invocation, the startup behavior is the same, but the effective user id
is not reset.

When using sudo, both effective and real user id's are set as in man sudo(8):

When sudo executes a command, the security policy specifies the execution environ‐
ment for the command.  Typically, the real and effective user and group and IDs are
set to match those of the target user, as specified in the password database, and
the group vector is initialized based on the group database (unless the -P option
was specified).
Cnossus answered 16/5, 2022 at 20:24 Comment(0)
C
0

The answer by @Rotem jackoby is good. As a fallow up, you can see my answer to this post. It contains an example C program that you can run, to see with your own eyes the differences between the Real User ID (RUID), the Effective User ID (EUID) and the Saved User ID (SUID), of a process in Linux.

Here I just want to point out that the official documentation for all Unix-like systems, including Linux of course, of The Open Group Base Specifications Issue 7, 2018 edition (see "3. Definitions" here), states that the concepts of RUID, EUID and SUID apply "When the identity of a user is associated with a process" (see 3.436 User ID here). In other words, if a user has not launched or spawn any process, it makes no sense to talk about RUID, EUID or SUID, but only about the user ID (UID) and that's it.

Chaco answered 6/12, 2023 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.