21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

is unchanged so that the effective ID can later be restored to the higher privilege.<br />

These rules apply to both group and user IDs.<br />

One more issue needs to be addressed with regard to dropping privileges. In addition<br />

to the effective, real, and saved group IDs of a process, a process also has ancillary<br />

groups. Ancillary groups are inherited by a process from its parent process, and<br />

they can only be altered by a process with superuser privileges. Therefore, if a process<br />

with superuser privileges is dropping these privileges, it must also be sure to<br />

drop any ancillary groups it may have. This is achieved by calling setgroups( ) with a<br />

single group, which is the real group ID for the process. Because the setgroups( ) system<br />

call is guarded by requiring the effective user ID of the process to be that of the<br />

superuser, it must be done prior to dropping root privileges. Ancillary groups should<br />

be dropped regardless of whether privileges are being dropped permanently or temporarily.<br />

In the case of a temporary privilege drop, the process can restore the ancillary<br />

groups if necessary when elevated privileges are restored.<br />

The first of two functions, spc_drop_privileges( ) drops any extra group or user privileges<br />

either permanently or temporarily, depending on the value of its only argument.<br />

If a nonzero value is passed, privileges will be dropped permanently; otherwise, the<br />

privilege drop is temporary. The second function, spc_restore_privileges( ), restores<br />

privileges to what they were at the last call to spc_drop_privileges( ). If either function<br />

encounters any problems in attempting to perform its respective task, abort( ) is<br />

called, terminating the process immediately. If any manipulation of privileges cannot<br />

complete successfully, it’s safest to assume that the process is in an unknown state,<br />

and you should not allow it to continue.<br />

Recalling our earlier discussion regarding subtle differences in the semantics for<br />

changing a process’s group and user IDs, you’ll notice that spc_drop_privileges( ) is<br />

littered with preprocessor conditionals that test for the platform on which the code is<br />

being compiled. For the BSD-derived platforms (Darwin, FreeBSD, NetBSD, and<br />

OpenBSD), dropping privileges involves a simple call to setegid( ) or seteuid( ), followed<br />

by a call to either setgid( ) or setuid( ) if privileges are being permanently<br />

dropped. The setgid( ) and setuid( ) system calls adjust the process’s saved group<br />

and user IDs, respectively, as well as the real group or user ID.<br />

On Linux and Solaris, the setgid( ) and setuid( ) system calls do not alter the process’s<br />

saved group and user IDs in all cases. (In particular, if the effective ID is not<br />

the superuser, the saved ID is not altered; otherwise, it is.). That means that these<br />

calls can’t reliably be used to permanently drop privileges. Instead, setregid( ) and<br />

setreuid( ) are used, which actually simplifies the process except that these two system<br />

calls have different semantics on the BSD-derived platforms.<br />

18 | Chapter 1: Safe Initialization<br />

As discussed above, always drop group privileges before dropping user<br />

privileges; otherwise, group privileges may not be able to be fully<br />

dropped.<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!