How do the internals of sudo work?

14,590

Solution 1

If you take a look at the executable sudo:

$ which sudo
/usr/bin/sudo
$ ls -la /usr/bin/sudo
---s--x--x 2 root root 208808 Jun  3  2011 /usr/bin/sudo

You'll notice that it carries the permission bits ---s--x--x. These can be broken down as follows:

-|--s|--x|--x
-      - first dash denotes if a directory or a file ("d" = dir, "-" = file)  
--s    - only the setuid bit is enabled for user who owns file
--x    - only the group execute bit is enabled
--x    - only the other execute bit is enabled

So when a program has it's setuid bit enabled (also referred to as SUID) it means that when someone runs this program it will run with the credentials of the user that owns the file, aka. root in this case.

Example

If I run the following command as user saml:

$ whoami
saml

$ sudo su -
[sudo] password for saml: 

You'll notice that the execution of sudo actually is running as root:

$ ps -eaf|grep sudo
root     20399  2353  0 05:07 pts/13   00:00:00 sudo su -

setuid mechanism

If you're curious how SUID works take a look at man setuid. Here's an excerpt from the man page that explains it better than I could:

setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set. Under Linux, setuid() is implemented like the POSIX version with the _POSIX_SAVED_IDS feature. This allows a set-user-ID (other than root) program to drop all of its user privileges, do some un-privileged work, and then reengage the original effective user ID in a secure manner.

If the user is root or the program is set-user-ID-root, special care must be taken. The setuid() function checks the effective user ID of the caller and if it is the superuser, all process-related user ID's are set to uid. After this has occurred, it is impossible for the program to regain root privileges.

The key concept here is that programs have a real userid (UID) and an effective one (EUID). Setuid is setting the effective userid (EUID) when this bit is enabled.

So from the kernel's perspective it's known that in our example, saml is still the original owner (UID), but the EUID has been set with whomever is the owner of the executable.

setgid

I should also mention that when we're breaking down the permissions on the sudo command the second group of bits were for group permissions. The group bits also has something similar to setuid called set group id (aka. setgid, SGID). This does the same thing as SUID except it runs the process with the group credentials instead of the owner credentials.

References

Solution 2

The real sudo binary is setuid root, and you can't just will files into existence that are set this way.

setuid and setgid (short for "set user ID upon execution" and "set group ID upon execution", respectively)[1] are Unix access rights flags that allow users to run an executable with the permissions of the executable's owner or group respectively and to change behaviour in directories.

Solution 3

To answer the part about syscalls that nobody seems to have touched, one of the important syscalls is either setresuid() or setresgid(). I am sure there are others, but these 2 seem pretty specific to setuid/sudo.

Share:
14,590

Related videos on Youtube

user2914606
Author by

user2914606

Updated on September 18, 2022

Comments

  • user2914606
    user2914606 over 1 year

    How does sudo work internally? How is it possible that it can become root without having the root password, unlike su? What syscalls, etc. are involved in the process? Is it not a gaping security hole in Linux (e.g. why couldn't I compile a heavily-patched sudo that just did whatever regular sudo did, but didn't ask for the unprivileged user's password)?

    I have read login and su internals. I have also read How is sudo intended to be used? but despite the title, they mainly deal with the differences between su and sudo.

  • Totor
    Totor over 10 years
    You should use sudo -s instead of sudo su because it's a useless use of su. :)
  • user253751
    user253751 over 3 years
    --s is setuid and execute, not just setuid