In UNIX environment, each process has three user id: real user id, effective user id, saved set-user-id. How these three UID are set is depended on whether the setuid bit of executable file has been set. The table bellow shows how these three UID will change after a exec system call.

setuid bit real user id effective user id saved set-user-id
set unchanged the owner of executable file copy from effective user id
unset unchanged unchanged copy from effective user id

Here is a demo, I first compile a simple program into a.out, then use chown root:root a.out to change the ower of the executable file, after that I use chmod +s a.out to set setuid bit. The output of ls -l a.out is: -rwsrwsr-x 1 root root 14600 Apr 24 08:02 a.out. After start a.out, the output of ps -o pid,ppid,euid,ruid,suid,cmd -p 16990,17210 is:

PID PPID EUID RUID SUID CMD
16990 16989 1001 1001 1001 -bash
17210 16990 0 1001 0 ./a.out

We can notice that EUID of a.out is root, RUID keeps same as its parent process, SUID is same as EUID.


Permission check is based on effective user id. UNIX system provides these system calls to manipulate these three UID: setuid, seteuid. How these system call affect three UID is based on whether the process has root privilege.

system call ID root privilege non root privilege
setuid(uid) real user id set to uid unchanged
setuid(uid) effective user id set to uid set to uid. uid must equal to ruid or suid, else return error
setuid(uid) saved set-user-id set to uid unchanged
system call ID root privilege non root privilege
seteuid(uid) real user id unchanged unchanged
seteuid(uid) effective user id set to uid set to uid. uid must equal to ruid or suid, else return error
seteuid(uid) saved set-user-id unchanged unchanged

One use case of this model is a program we all familiar with: sudo, ll /usr/bin/sudo: -rwsr-xr-x 1 root root 149080 Jan 18 2018 /usr/bin/sudo.
We can see that sudo has setuid bit setted. What happened after we type sudo some-command. The shell will start sudo with some-command as its arguments. As sudo has setuid bit set, so sudo will have ruid set to normal user, euid and suid set to root. Then sudo call setuid(0) change all three UID to root, after that sudo will fork and exec our command, so our command will be executed as all three UID set to root. This is just a brief process, permission check and ask password stuff all ignored.