Invoking an executable that you don't own is nothing remarkable. Most executables on the system belong to root, and running them does not give the user any extra privileges.
It's only setuid executables that start with the effective UID set to the owner of the executable while the real UID remains the real UID of the invoking process.
sudo
is setuid root, so it runs with the effective UID 0 and your real UID. But when it invokes another command, it sets both the effective UID and the real UID to the target user. You'd have to catch sudo
itself in order to observe an EUID that differs from the RUID. This will be too quick to see unless sudo
prompts you for a password.
You can easily observe the differing UIDs by running the passwd
command as a non-root user. While the prompt is being displayed, run ps
in another temrinal:
ps -o user,ruser -C passwd
To find all running processes with differing EUID and RUID, you can use
ps -e -o user= -o ruser= | awk '$1 != $2'
It's normal not to find any, most setuid processes are short-lived.
Root is user 0
The key thing is the user ID 0. There are many places in the kernel that check the user ID of the calling process and grant permission to do something only if the user ID is 0.
The user name is irrelevant; the kernel doesn't even know about user names.
Android's permission mechanism is identical at the kernel level but completely different at the application level. Android has a root user (UID 0), just like any other system based on a Linux kernel. Android doesn't have user accounts though, and on most setups doesn't allow the user (as in the human operating and owning the device) to perform actions as the root user. A “rooted” Android is a setup that does allow the device owner/user to perform actions as root.
How setuid works
A setuid executable runs as the user who owns the executable. For example, su
is setuid and owned by root, so when any user runs it, the process running su
runs as the root user. The job of su
is to verify that the user that calls it is allowed to use the root account, to run the specified command (or a shell if no command is specified) if this verification succeeds, and to exit if this verification fails. For example, su
might ask the user to prove that they know the root password.
In more detail, a process has three user IDs: the effective UID, which is used for security checks; the real UID, which is used in a few privilege checks but is mainly useful as a backup of the original user ID, and the saved user ID which allows a process to temporarily switch its effective UID to the real user ID and then go back to the former effective UID (this is useful e.g. when a setuid program needs to access a file as the original user). Running a setuid executable sets the effective UID to the owner of executable and retains the real UID.
Running a setuid executable (and similar mechanisms, e.g. setgid) is the only way to elevate the privileges of a process. Pretty much everything else can only decrease the privileges of a process.
Beyond traditional Unix
Until now I described traditional Unix systems. All of this is true on a modern Linux system, but Linux brings several additional complications.
Linux has a capability system. Remember how I said that the kernel has many checks where only processes running as user ID 0 are allowed? In fact, each check gets its own capability (well, not quite, some checks use the same capability). For example, there's a capability for accessing raw network sockets, and another capability for rebooting the system. Each process has a set of capabilities along side its users and groups. The process passes the check if it is running as user 0 or if it has the capability that corresponds to the check. A process that requires a specific privilege can run as a non-root user but with the requisite capability; this limits the impact if the process has a security hole. An executable can be setcap to one or more capabilities: this is similar to setuid, but works on the process's capability set instead of the process's user ID. For example, ping only needs raw network sockets, so it can be setcap CAP_NET_RAW
instead of setuid root.
Linux has several security modules, the best known being SELinux. Security modules introduce additional security checks, which can apply even to processes running as root. For example, it's possible (not easy!) to set up SELinux so as to run a process as user ID 0 but with so many restrictions that it can't actually do anything.
Linux has user namespaces. Inside the kernel, a user is in fact not just a user ID, but a pair consisting of a user ID and a namespace. Namespaces form a hierarchy: a child namespace refines permissions within its parent. The all-powerful user is user 0 in the root namespace. User 0 in a namespace has powers only inside that namespace. For example, user 0 in a user namespace can impersonate any user of that namespace; but from the outside all the processes in that namespace run as the same user.
Best Answer
Here are the answers:
root
has always full access to files and directories. The owner of the file usually has them too, but this is not always true. For example:user1
is the owner; however they can only read and execute, butroot
still has full access (rwx) to the file.RUID is the Real User ID and it never (almost) changes. If
user2
logs in to the system, the shell is then launched with its real ID set touser2
. All processes they start from the shell will inherit the real IDuser2
as their real ID.EUID is the Effective User ID, it changes for processes (not for the user) that the user executes that have set the setuid bit.
If
user2
executesfile.bin
, the RUID will beuser2
and the EUID of the process started will beuser1
.Let's use the case of
passwd
:When
user2
wants to change their password, they execute/usr/bin/passwd
.The RUID will be
user2
but the EUID of that process will beroot
.user2
can usepasswd
to change only their own password because internallypasswd
checks the RUID and, if it is notroot
, its actions will be limited to real user's password.It's neccesary that the EUID becomes
root
in the case ofpasswd
because the process needs to write to/etc/passwd
and/or/etc/shadow
.