sections in this module City College of San Francisco - CS260A - Unix/Linux System Administration
Module: Virtual Machines
module list

Set-Uid and Set-Gid

As we know, when you run a program, it executes as you and with the permissions of the groups you are a member of. Set-user-id and set-group-id programs have special permissions that cause them to become another user (or group) when they execute. The most familiar example of such a program is the passwd program.

The passwd program modifies two crucial system configuration files /etc/passwd and the shadow file, which is often also in /etc. These files are writable only by root. Without the set-uid permission, if you executed the passwd program it would execute as you and the attempted modification would fail due to a permissions violation. Since the program is set-uid to root, it executes as root and the modification succeeds. If you look at the passwd program, you will see that the set-user-id permission is indicated by the s in the position for 'user execute permission'.

$ ls -l /usr/bin/passwd
-r-s--x--x  1 root root 21200 Jun 17  2005 /usr/bin/passwd
$

Since passwd has a very specific task that it must do as root, it is an ideal candidate for a set-uid program. Remember, anything the program does, it does as root. This means you must know exactly what a program is capable of before you allow anyone to become root while using it. Before we continue, let's examine what the special permissions do and how they are represented.

Special permissions bits

The set-user-id permission is one of three special permissions that are not taught in introductory Unix courses. Most of us are used to permissions being represented as three-digit octal numbers, indicating a total of nine permission bits. There are actually twelve permission bits: the first three are the special permissions. These would be represented by a fourth octal digit, the most significant one, whose value is zero on normal Unix files. This first octal digit has the bits

4 - set-user-id
2 - set-group-id
1 - sticky

In an ls -l listing, the special permissions are represented by changing the execute permissions:

If the x permission is changed due to the special permissions, you might wonder how the presence or absence of the x permission is indicated. This is done by the case of the letter. Normally, the x permission is set when any of these special permissions is used. If it is missing, the special permission letter is capitalized. Thus, s in the user execute permission means set-user-id + execute, while S means set-user-id without execute.

Special permissions meanings

Every process has two user ids. The real user id is the user id of the user who executed the process. The effective user id is the user id that is in effect at that moment. Normally, the real and effective user ids are the same for the life of the process. It is possible, however, for a process' effective user id to change. This [obviously privileged operation] is done by a system call, or by the system setting it differently when the process is started. The same is true of the process' group id: there is a real group id and an effective group id.

When the process starts, the effective user id of a set-user-id program (which is abbreviated suid) is set to the owner of the program file used for the process. Although most suid programs are set-user-id to root, this is not necessary. Anyone who can create a set-user-id program that is set-user-id to their login. (Note, however, that set-user-id shell scripts are often disallowed by a system, notably linux.)  Similarly, when a set-group-id program is executed, the process is started with the real group id of the user that started it, and the effective group id of the group the program file was in. Set-group-id programs are rare, however.

Although set-group-id is not very useful for programs, the set-group-id permission can be used to create a directory for collaboration by a group. If a directory is set-group-id, anything created in it will be placed in the same group as the directory. This, in conjunction with the user's umask (to permit read and/or write by group) can then be used to create a repository of data readable (and, perhaps, writable) by members of a group. This facility can be improved by the use of access control lists, which we will cover later.

The sticky permission is leftover from history and is no longer used for files. It is very important when used on a directory, however, and is how public directories like /tmp are implemented. As you know, if a user has write permission to a directory, that user can delete any file in that directory, irrespective of the file's permissions. These semantics change if the directory is sticky. In this case, the only user who can delete a file created in the directory is the owner of the file or the owner of the directory. Thus, if /tmp is sticky, any user can create files in it, but users cannot delete other users files. If a public directory such as /tmp gets deleted for some reason, be sure to recreate it sticky.

Setting special permissions

Normally, setting special permissions is done with chmod in absolute mode. Simply set the object's permissions back to what they are currently, prefixing the appropriate digit for the special permission to the current permissions. If a directory's permissions are 777, setting it to 1777 adds the sticky permission.

$ ls -ld /tmp
drwxrwxrwt  19 root root 4096 Feb  1 18:09 /tmp
$

Setting the set-user-id or set-group-id permission of a file must be done in a strict sequence. For security purposes, the file may not be modified or copied after the special permission is set. Thus, you should

  1. place the file in its target directory
  2. change the owner [group] to the user [group] that the program should run as
  3. add the suid or sgid permission.

After the suid or sgid permission has been set, any modification (including copying) of the program will clear the special permission.

NOTE: the effect of suid permissions may be suppressed on a filesystem when it is mounted.

Use of set-user-id

Set user id programs run as the owner of the program file. In particular, set user id to root programs run as root. Thus, whatever the program does is done as root. Before making a program set-user-id, you must be aware of everything the program can do. You should also be aware of any known vulnerabilities of the program, since vulnerabilites of programs executing as root are the focal point of exploits. In particular, if the process starts another process, the child runs with the same privileges. Thus, you should never use suid permissions on a program that can perform a shell escape, such as more, less or vi.

bash does not allow shell scripts to be run as set-user-id. Although this severely limits the ability to write set-user-id programs on linux, it is wise, if only for this reason:  shell scripts are very easy to mis-write. If the shell-script is not carefully written, its use could compromise the system. On some systems, the Korn shell honored the set-uid permission. Consider the following experiment using a Korn-shell script on a system where ksh honors setuid:

The user gboyd02 does not want the general public to be able to list his directory. However, from time to time, fellow workers need this capability. gboyd02 solved this dilemma by creating a shell script named listall that simply lists his home directory. He then made the shell script set-user-id to gboyd02. Here is his shell script:

$ cat ~gboyd02/listall
#!/usr/bin/ksh
echo "listing all files and directories in" ~gboyd02
ls -l ~gboyd02
$

Another user, who gboyd02 has graced with the location of this shell script, can then list his home directory. Unfortunately, gboyd02 gave his shell script to the wrong person. This user exploited a security issue in the shell script to start a shell. Here is what happened when the user gboyd ran the shell script:

running listall starts a shell as gboyd02

If you notice, there are no files listed in gboyd02's home directory. This is not because it is empty, but because the ls program that ran was not the ls program at all! Instead, a new shell was run as gboyd02. (At this point, the id command was run to prove the euid was now gboyd02!) How was this possible? Simple. gboyd simply created his own shell script named ls with this contents:

$ cat ls
#!/usr/bin/ksh
ksh -i
$

Then gboyd altered his PATH to search his home directory first, and ran gboyd02's shell script. The effect was to give away all access to gboyd02's account. This mistake would have been very easy to avoid, by using a technique very important to writing any shell script that might be run with privileges:

Note: In a recent release of the public-domain version of ksh, it no longer honors the setuid or setgid bits on Korn-shell scripts.

A general-purpose facility named sudo can be used to provide specific access to any command as any user. sudo will be discussed in the next section. Although sudo is very useful, the overriding concern is the same as with a set-user-id program: you must be aware of exactly what the program can do, including its vulnerabilities, before allowing any user access to it as root.


Prev This page was made entirely with free software on linux:  
the Mozilla Project
, Kompozer, and Openoffice.org    
Next

Copyright 2013 Greg Boyd - All Rights Reserved.