Setuid is an API available on many Unix type operating systems, including the Linux OS. It is used to change the effective user ID of an executing process, to alter the access the program has within the system.

Unix-type OS'es use the concept of role-based permissions, wherein what one can do on a system depends on who you are, and what type of user you are. Who you are is determined by your user ID, which is usually seen to you as a name (much like your E2 user ID). To the underlying operating system, who you are is, alas, just one more number. This number is your UID, user ID.

What type of user you are is determined by what group you belong in. Just like high school, in a way. Your group is given a number, called the GID, or group ID.

This system has a number of nice benefits. The OS has the ability to restrict access to files based on your user ID number. So, I can make sure that I can read and write to my secret journal of nefarious deeds, but that no-one else (with the exception of root or the superuser) can read it. Alternatively, I can give access to a certain group, perhaps to allow someone to collaborate with me, giving them write access to a select number of files based on GID. Or I can publish, letting the whole world read my web diary, but allowing only me to write to it. You get the idea.

Where a problem emerges is when you realize that I need to have access to from time to time, that I really don't need all the time, and maybe shouldn't have. The classic example is the password file. To save administrative headaches, and to improve security, I need to be able to change my own password without having to go through an intermediary. This means that I need to have write access to the file that stores the passwords, or their representation to the system. Well, say I'm not the nice guy that I am, and while I'm there I decide to change the passwords for everyone else in the system, or give myself access to restricted files. An uh-oh has just occured.

What, then, can we do? Well, one solution is to decentralize the password file. Everyone has their own password file, which the computer reads in order to authenticate you. Well, now instead of having one password file to secure, we may have several thousand. We also have a chicken and the egg problem- I need access to my account to be authenticated, but I must be authenticated in order to access my account. Keep in mind that every single program on a Unix type system must be running on behalf of someone- their must be a user ID associated with every single process. And every program I run, in the simple model, must use my user ID.

So setuid enhances the simple model. It says, here write a program that will run with a user ID other than that of the person running the program. The setuid API does just that, changes the effective user ID with which a program executes. Now, the password changing program is the 'user' that owns the password file. When I run the program, the setuid command causes it to run as the password program user, not as whatever my UID is. This means that when I need to change my password, I can invoke the program without I myself having write access to the password file. The program can also act as an intermediary, and ensure that I only change the entry that belongs to me in the file. Problem solved.

Unfortunately, in a rather trite bit of melodrama, the problems are just beginning. We've solved the problem of users needing partial access to restricted files through the use of setuid. But now, we have numerous programs running around on our computer that have access to files and resources that we don't want users to have. This means that there are still significant vulnerabilities. What happens when such a program crashes? It may just dump the user out of the operation they were performing. But it may leave the restricted file in an unknown state, or allow access to it by someone who shouldn't have it. Worse yet, particularly if the program is running setuid root, a program failure may dump the user to a shell with the effective UID of the program, allowing a malicious or inane user to cause some serious trouble. As such, writing secure setuid programs is a challenge, and they have been a source of numerous security problems over the years.

As such, setuid programs are typically written with access to the smallest pool of resources they need to get the job done, but no more. Creating a UID that is used only for running a particular setuid program is a common practice along this vein. The programmer may also try to ensure that the program drops some or all of its privileges before invoking another process on its behalf, where possible. Another security measure is to invoke chroot on a setuid program, to try to ensure that if the security of the program is violated, the potential damage to the system can be limited and isolated.

There are two different, but related, concepts on Unix and Unix-like operating systems, both of which use the term setuid.

  • The setuid system call
  • The setuid bit in a file's mode
Both effect a change in the userid associated with a process. (And each has an analogue which deals with groupids.)

The setuid system call

This function changes the userid associated with the running process that calls it. It can only be used if the process is currently running as the superuser (i.e., has a userid of zero) [1]. When the function returns, the userid of the process has been changed to the requested value.[1] The most usual purpose of doing this is to drop superuser privileges and become a normal user. This, for example, is how you become you when you login. The login program is running with superuser privileges; after validating your username and password, it uses setuid(your userid) to become you, and then invokes your designated shell program which sets up your login session using your credentials.

Were it not for the setuid function, everybody would always have superuser privileges, since all processes are descendants of init, which is created during system boot as a superuser process.

The setuid mode bit

This mode bit (value 40008; 20008 in the case of the setgid bit) causes the userid of a process to change (to the owner of the executable file[2]) when the process execs an executable file with the bit set.[3] The purpose of this is to allow (usually system-supplied) programs that require a particular user's privilege to be run by other users (for example, you). For example, you don't have sufficient privilege to alter the system's password database; nonetheless, it would be ridiculous if you had to find someone with superuser access to change your password for you. Instead, the program that you use to change your password is installed with the setuid bit on, and is owned by root. Thus, when you run it, it has superuser privilege and is able to set your new password.

A previous writeup by Spasemunki talks only about the mode bit, but uses the term API, which would refer to the system function. E may also imply (one can't quite tell from his wording) that it is possible for a user to gain the privileges conferred upon a process that received them pursuant to a setuid mode setting if the program crashes, but this is not true.


[1] Technically not true, as each process has 2 different userids (called the real and effective userids. On some systems, there is even a third, called the saved userid.) The effective user id is what the system refers to when it decides to allow or not allow a process's request (to open a file, for example), and it is the effective userid that the setuid function changes. But all of that goes out the window if the calling process has superuser privilege -- in that case, both (or all three) of the ids are changed. This issue is very sensitive, and has been thought through by very smart people.

[2] All of these operating systems allow the setuid process to be applied to any native executable. Some also allow executable files which require an interpreter (which is how many programs are implemented these days) to use the setuid feature.

[3] Actually, only the effective id is changed.

Log in or registerto write something here or to contact authors.