Unix/Linux Go Back    


NetBSD 6.1.5 - man page for setuid (netbsd section 7)

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:   man
Select Man Page Set:       apropos Keyword Search (sections above)


SETUID(7)		       BSD Miscellaneous Information Manual			SETUID(7)

NAME
     setuid -- checklist for security of setuid programs

DESCRIPTION
     Please note: This manual page was written long ago, and is in need of updating to match
     today's systems.  We think it is valuable enough to include, even though parts of it are
     outdated.	A carefully-researched updated version would be very useful, if anyone is feeling
     enthusiastic...

     Writing a secure setuid (or setgid) program is tricky.  There are a number of possible ways
     of subverting such a program.  The most conspicuous security holes occur when a setuid pro-
     gram is not sufficiently careful to avoid giving away access to resources it legitimately
     has the use of.  Most of the other attacks are basically a matter of altering the program's
     environment in unexpected ways and hoping it will fail in some security-breaching manner.
     There are generally three categories of environment manipulation: supplying a legal but
     unexpected environment that may cause the program to directly do something insecure, arrang-
     ing for error conditions that the program may not handle correctly, and the specialized sub-
     category of giving the program inadequate resources in hopes that it won't respond properly.

     The following are general considerations of security when writing a setuid program.

     o	 The program should run with the weakest userid possible, preferably one used only by
	 itself.  A security hole in a setuid program running with a highly-privileged userid can
	 compromise an entire system.  Security-critical programs like passwd(1) should always
	 have private userids, to minimize possible damage from penetrations elsewhere.

     o	 The result of getlogin(2) or ttyname(3) may be wrong if the descriptors have been med-
	 dled with.  There is no foolproof way to determine the controlling terminal or the login
	 name (as opposed to uid) on V7.

     o	 On some systems, the setuid bit may not be honored if the program is run by root, so the
	 program may find itself running as root.

     o	 Programs that attempt to use creat(3) for locking can foul up when run by root; use of
	 link(2) is preferred when implementing locking.  Using chmod(2) for locking is an obvi-
	 ous disaster.

     o	 Breaking an existing lock is very dangerous; the breakdown of a locking protocol may be
	 symptomatic of far worse problems.  Doing so on the basis of the lock being 'old' is
	 sometimes necessary, but programs can run for surprising lengths of time on heavily-
	 loaded systems.

     o	 Care must be taken that user requests for I/O are checked for permissions using the
	 user's permissions, not the program's.  Use of access(2) is recommended.

     o	 Programs executed at user request (e.g. shell escapes) must not receive the setuid pro-
	 gram's permissions; use of daughter processes and ``setuid(getuid())'' plus
	 ``setgid(getgid())'' after fork(2) but before exec(3) is vital.

     o	 Similarly, programs executed at user request must not receive other sensitive resources,
	 notably file descriptors.  Use of fcntl(2) F_CLOSEM, FILENO_STDERR + 1 (close all fd's
	 greater than stderr) and/or fcntl(2) F_SETFD, FD_CLOEXEC (close-on-exec) arrangements on
	 systems which have them is recommended.

	 Other resources should also be examined for sanity and possibly set to desired settings,
	 such as the current working directory, signal disposition, resource limits, environment,
	 umask, group membership, chroot.

	 Programs activated by one user but handling traffic on behalf of others (e.g. daemons)
	 should avoid doing ``setuid(getuid())'' or ``setgid(getgid())'', since the original
	 invoker's identity is almost certainly inappropriate.	On systems which permit it, use
	 of ``setuid(geteuid())'' and ``setgid(getegid())'' is recommended when performing work
	 on behalf of the system as opposed to a specific user.

     o	 There are inherent permission problems when a setuid program executes another setuid
	 program, since the permissions are not additive.  Care should be taken that created
	 files are not owned by the wrong person.  Use of ``setuid(geteuid())'' and its gid coun-
	 terpart can help, if the system allows them.

     o	 Care should be taken that newly-created files do not have the wrong permission or owner-
	 ship even momentarily.  Permissions should be arranged by using umask(2) in advance,
	 rather than by creating the file wide-open and then using chmod(2).  Ownership can get
	 sticky due to the limitations of the setuid concept, although using a daughter process
	 connected by a pipe can help.

     o	 Setuid programs should be especially careful about error checking, and the normal
	 response to a strange situation should be termination, rather than an attempt to carry
	 on.

     The following are ways in which the program may be induced to carelessly give away its spe-
     cial privileges.

     o	 The directory the program is started in, or directories it may plausibly chdir(2) to,
	 may contain programs with the same names as system programs, placed there in hopes that
	 the program will activate a shell with a permissive PATH setting.  PATH should always be
	 standardized before invoking a shell (either directly or via popen(3) or execvp(3) or
	 execlp(3)).

     o	 Similarly, a bizarre IFS setting may alter the interpretation of a shell command in
	 really strange ways, possibly causing a user-supplied program to be invoked.  IFS too
	 should always be standardized before invoking a shell.

     o	 Environment variables in general cannot be trusted.  Their contents should never be
	 taken for granted.

     o	 Setuid shell files (on systems which implement such) simply cannot cope adequately with
	 some of these problems.  They also have some nasty problems like trying to run a
	 .profile when run under a suitable name.  They are terminally insecure, and must be
	 avoided.

     o	 Relying on the contents of files placed in publically-writable directories, such as
	 /tmp, is a nearly-incurable security problem.	Setuid programs should avoid using /tmp
	 entirely, if humanly possible.  The sticky-directories modification (sticky bit on for a
	 directory means only owner of a file can remove it) helps, but is not a complete solu-
	 tion.

     o	 A related problem is that spool directories, holding information that the program will
	 trust later, must never be publically writable even if the files in the directory are
	 protected.  Among other sinister manipulations that can be performed, note that on many
	 Unixes, a core dump of a setuid program is owned by the program's owner and not by the
	 user running it.

     The following are unusual but possible error conditions that the program should cope with
     properly (resource-exhaustion questions are considered separately, see below).

     o	 The value of argc might be 0.

     o	 The setting of the umask(2) might not be sensible.  In any case, it should be standard-
	 ized when creating files not intended to be owned by the user.

     o	 One or more of the standard descriptors might be closed, so that an opened file might
	 get (say) descriptor 1, causing chaos if the program tries to do a printf(3).

     o	 The current directory (or any of its parents) may be unreadable and unsearchable.  On
	 many systems pwd(1) does not run setuid-root, so it can fail under such conditions.

     o	 Descriptors shared by other processes (i.e., any that are open on startup) may be manip-
	 ulated in strange ways by said processes.

     o	 The standard descriptors may refer to a terminal which has a bizarre mode setting, or
	 which cannot be opened again, or which gives end-of-file on any read attempt, or which
	 cannot be read or written successfully.

     o	 The process may be hit by interrupt, quit, hangup, or broken-pipe signals, singly or in
	 fast succession.  The user may deliberately exploit the race conditions inherent in
	 catching signals; ignoring signals is safe, but catching them is not.

     o	 Although non-keyboard signals cannot be sent by ordinary users in V7, they may perhaps
	 be sent by the system authorities (e.g. to indicate that the system is about to shut
	 down), so the possibility cannot be ignored.

     o	 On some systems there may be an alarm(3) signal pending on startup.

     o	 The program may have children it did not create.  This is normal when the process is
	 part of a pipeline.

     o	 In some non-V7 systems, users can change the ownerships of their files.  Setuid programs
	 should avoid trusting the owner identification of a file.

     o	 User-supplied arguments and input data must be checked meticulously.  Overly-long input
	 stored in an array without proper bound checking can easily breach security.  When soft-
	 ware depends on a file being in a specific format, user-supplied data should never be
	 inserted into the file without being checked first.  Meticulous checking includes allow-
	 ing for the possibility of non-ASCII characters.

     o	 Temporary files left in public directories like /tmp might vanish at inconvenient times.

     The following are resource-exhaustion possibilities that the program should respond properly
     to.

     o	 The user might have used up all of his allowed processes, so any attempt to create a new
	 one (via fork(2) or popen(3)) will fail.

     o	 There might be many files open, exhausting the supply of descriptors.	Running fcntl(2)
	 F_CLOSEM on systems which have it, is recommended.

     o	 There might be many arguments.

     o	 The arguments and the environment together might occupy a great deal of space.

     Systems which impose other resource limitations can open setuid programs to similar
     resource-exhaustion attacks.

     Setuid programs which execute ordinary programs without reducing authority pass all the
     above problems on to such unprepared children.  Standardizing the execution environment is
     only a partial solution.

SEE ALSO
     passwd(1), pwd(1), access(2), chdir(2), chroot(2), execve(2), fcntl(2), fork(2),
     getlogin(2), link(2), setegid(2), seteuid(2), setgid(2), setgroups(2), setrlimit(2),
     setuid(2), sigaction(2), umask(2), alarm(3), creat(3), execvp(3), popen(3), printf(3),
     ttyname(3)

HISTORY
     Written by Henry Spencer, and based on additional outside contributions.

AUTHORS
     Henry Spencer <henry@spsystems.net>

BUGS
     The list really is rather long...	and probably incomplete.

BSD					February 26, 2009				      BSD
Unix & Linux Commands & Man Pages : ©2000 - 2018 Unix and Linux Forums


All times are GMT -4. The time now is 05:21 AM.