The SetUID Motivation
Aftab Hussain
January 30, 2020
UNIX SYSTEM ADMINISTRATION
SetUID programs in brief
SetUID programs allow any user to run a program with the privileges of the owner of a program.
You can create any program as a setUID program.
Unix also has setUID programs on offer. These programs are owned by the root, and allow any user to run them with root privileges.
Examples include passwd
and su
. (This passwd
is the binary
which is found in the /usr/bin/
folder. The one in the /etc
folder is the configuration file which
contains passwd
information. /etc
can contain other stuff too. Check this
out on the (evolving) rationale of Unix’s directory structure.)
SetUID is useful, however as explained in a later post it can lead to security flaws. Now let’s dive into this setUID business and see what’s it all about, for real.
What do SetUID programs look like, and how to create one?
Any program can be a setUID program. Unix provides what is known as a setUID bit for
any program.
To realize the setUID1 effect we would be dealing executable programs, which have the setUID bit set.
Recognizing a setUID program is easy in the shell GUI. They are highlighted, when
listed with ls -l
. Another, more sophisticated way of recognizing them is the
presence of s
in their character-based permissions representation, also viewable with
ls -l
:
-rwsr-xr-x
The most accurate way to look at the status of the permission bits in my opinion is just to check out their octal representation, as follows:
$stat -c '%a' /tmp/
$1777
For a setUID program the first octal digit would have a value of at least 4. To know why, take a look here.
1. I admit this word is already getting a bit repetitive, but I can’t think of a cuter synonym as of now, so I would need to stick to it. Sorry.
Creating a setUID program
Just use chmod 4XYZ
(where XYZ are 3 octal digits). There are other ways, but this is the easiest.
So how do setUID programs work?
The key behind understanding the setUID mechanism is understanding who’s in
charge of the setUID program, while the program is running.
So, let’s backtrack a little bit, and ask ourselves how do we know who’s in charge of any running program?
Before knowing this, it’s important to understand that any running program is a process, and in UNIX every process has a set of information associated with them. We can obtain this information by viewing this file:
$ /proc/<process-id>/status
Details about everything in this file can be found here. For this discussion, the following are relevant:
the real user ID (real uid, or ruid), the effective user ID (effective uid, or euid), and the saved user ID (saved uid, or suid).
The real uid identifies the owner of the process.
The effective uid is used in most access control decisions
The saved uid stores a previous user ID so that it can be restored later.
- Chen et al. (UC Berkeley, SRI International), Setuid demystified, USENIX, 2002
Here’s how the relevant line in the status file looks like, showing the above 3 values (we are mainly concerned here with the first two):
Uid: 1000 1000 1000 1000
The fourth number is the file system id, which is discussed here.
The second number, the effective uid, is of most interest to us. This is the id based upon which various accesses are granted by the operating system.
Getting process info with a setUID program in action
Now, let’s run a UNIX setUID program, say su
, from bash, and check out it’s effective user id.
After starting su
, leave it running and open a new terminal. (To the best of my knowledge
once a process is closed, there are no traces of it, unless it has closed due to
an error, in which case there’s a log you can access.)
Next, find the process id of the su
process in any way you like.
You can use pstree -hp
, store it in a file if it is too big, and search there.
Then show the status of the process using it’s process id, using the method shown earlier. You’ll see:
Uid: 1000 0 0 0
The effective userid of the process running su
is 0 (the id of the
owner of the program; that owner is root).
Now what about the userid of the process that called su
. That process is the one running bash. We can
similarly find Uid information for this process as shown below:
Uid: 1000 1000 1000 1000
This little experiment tells us a lot about how setuid programs work. A setuid program in execution
uses the permissions of the owner of the program to do its job. It does not use the permissions of the
owner of the process that called the setuid program, unless of course the owner of that calling process
and the setuid program are the same. (For example a process owned by root calling su
).
Why have setuid?
It allows users to carry out necessary functionalities without giving them total control over how to do it.
su
is one example. /usr/bin/passwd
is another.
passwd
allows a user to change his/her password. As we know
all passwords are stored in encrypted form in the /etc/shadow
file. But if a user is allowed to change it,
wouldn’t this be a breach of security? If we don’t, how do we change the password? Prof. Kevin Du
calls this the “password dilemma”. The trick is to use a program trusted by the root to do the change. The user
is only able to invoke this program, not how it carries out the job.
Reference:
1. Computer Security Course by Prof. Wenliang (Kevin) Du, Syracuse University, New York