The Linux Programming Interface

(nextflipdebug5) #1

784 Chapter 38


38.1 Is a Set-User-ID or Set-Group-ID Program Required?


One of the best pieces of advice concerning set-user-ID and set-group-ID programs
is to avoid writing them whenever possible. If there is an alternative way of per-
forming a task that doesn’t involve giving a program privilege, we should generally
employ that alternative, since it eliminates the possibility of a security compromise.
Sometimes, we can isolate the functionality that needs privilege into a separate
program that performs a single task, and exec that program in a child process as
required. This technique can be especially useful for libraries. One example of such
a use is provided by the pt_chown program described in Section 64.2.2.
Even in cases where a set-user-ID or set-group-ID is needed, it isn’t always nec-
essary for a set-user-ID program to give a process root credentials. If giving a pro-
cess some other credentials suffices, then this option should be preferred, since
running with root privileges opens the gates to possible security compromises.
Consider a set-user-ID program that needs to allow users to update a file on
which they do not have write permission. A safer way to do this is to create a dedi-
cated group account (group ID) for this program, change the group ownership of
the file to that group (and make the file writable by that group), and write a set-
group-ID program that sets the process’s effective group ID to the dedicated
group ID. Since the dedicated group ID is not otherwise privileged, this greatly
limits the damage that can be done if the program contains bugs or can otherwise
be subverted.

38.2 Operate with Least Privilege


A set-user-ID (or set-group-ID) program typically requires privileges only to per-
form certain operations. While the program (especially one assuming superuser
privileges) is performing other work, it should disable these privileges. When privileges
will never again be required, they should be dropped permanently. In other words,
the program should always operate with the least privilege required to accomplish the
tasks that it is currently performing. The saved set-user-ID facility was designed for
this purpose (Section 9.4).

Hold privileges only while they are required
In a set-user-ID program, we can use the following sequence of seteuid() calls to tem-
porarily drop and then reacquire privileges:

uid_t orig_euid;

orig_euid = geteuid();
if (seteuid(getuid()) == -1) /* Drop privileges */
errExit("seteuid");

/* Do unprivileged work */

if (seteuid(orig_euid) == -1) /* Reacquire privileges */
errExit("seteuid");

/* Do privileged work */
Free download pdf