Issetugid() Sadness

fanf21 pts0 comments

issetugid() sadness · GitHub

/" data-turbo-transient="true" />

Skip to content

-->

Search Gists

Search Gists

Sign in

Sign up

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

Instantly share code, notes, and snippets.

nicowilliams/issetugid-sadness.md

Last active<br>July 28, 2026 20:09

Show Gist options

Download ZIP

Star

(6)

You must be signed in to star a gist

Fork

(0)

You must be signed in to fork a gist

Embed

Select an option

Embed<br>Embed this gist in your website.

Share<br>Copy sharable link for this gist.

Clone via HTTPS<br>Clone using the web URL.

No results found

Learn more about clone URLs

Clone this repository at &lt;script src=&quot;https://gist.github.com/nicowilliams/4daf74a3a0c86848d3cbd9d0cdb5e26e.js&quot;&gt;&lt;/script&gt;

" readonly="readonly" data-autoselect="true" data-target="primer-text-field.inputElement " aria-describedby="validation-d37ef857-1969-462b-a06d-ae11e600b63e" class="form-control FormControl-monospace FormControl-input FormControl-small rounded-left-0 rounded-right-0 border-right-0" type="text" name="gist-share-url-sized-down" />

Save nicowilliams/4daf74a3a0c86848d3cbd9d0cdb5e26e to your computer and use it in GitHub Desktop.

Embed

Select an option

Embed<br>Embed this gist in your website.

Share<br>Copy sharable link for this gist.

Clone via HTTPS<br>Clone using the web URL.

No results found

Learn more about clone URLs

Clone this repository at &lt;script src=&quot;https://gist.github.com/nicowilliams/4daf74a3a0c86848d3cbd9d0cdb5e26e.js&quot;&gt;&lt;/script&gt;

" readonly="readonly" data-autoselect="true" data-target="primer-text-field.inputElement " aria-describedby="validation-bd4a0b58-0725-442a-b8a9-cbd1a313c412" class="form-control FormControl-monospace FormControl-input FormControl-small rounded-left-0 rounded-right-0 border-right-0" type="text" name="gist-share-url-original" />

Save nicowilliams/4daf74a3a0c86848d3cbd9d0cdb5e26e to your computer and use it in GitHub Desktop.

Download ZIP

issetugid() sadness

Raw

issetugid-sadness.md

Warning: work in progress. Incomplete

People who have been in security a long time (or even not that long) know that some inputs should be treated<br>as tainted. For example, environment variables from a user should not be used in a<br>set-uid program, inputs from a different user should be validated, etc...<br>Traditionally we say that the environment of a set-uid program is tainted and<br>should not be used (or used with much care).

Therefore we want all set-uid/set-gid programs to treat their environment and user<br>inputs as tainted.

A program's code can tell if it should treat the environment with care because it<br>could check whether getuid() == geteuid() && getgid() == getegid() early on in<br>main().

But! the libraries that the program uses cannot do this because by the<br>time they make this check it might be true even though it was not<br>earlier. To remedy this, in 1996 OpenBSD added<br>issetugid(2), a<br>system call that indicates whether the process gained privilege at exec<br>time by running a set-uid or set-gid program:

The issetugid() function returns 1 if the process was made setuid or<br>setgid as the result of the last or other previous execve() system<br>calls. Otherwise it returns 0.

This system call exists so that library routines (inside libtermlib,<br>libc, or other libraries) can guarantee safe behavior when used<br>inside setuid or setgid programs. Some library routines may be<br>passed insufficient information and hence not know whether the<br>current program was started setuid or setgid because higher level<br>calling code may have made changes to the uid, euid, gid, or egid.<br>Hence these low-level library routines are unable to determine if<br>they are being run with elevated or normal privileges.

In particular, it is wise to use this call to determine if a<br>pathname returned from a getenv() call may safely be used to open()<br>the specified file. Quite often this is not wise because the status<br>of the effective uid is not known. The issetugid() system call's<br>result is unaffected by calls to setuid(), setgid(), or other such<br>calls. In case of a fork(), the child process inherits the same<br>status.

Solaris/Illumos adopted OpenBSD's issetugid(2) with the same semantics.

The other BSDs, and OS X, copied the OpenBSD<br>issetugid(2), but deliberately<br>changed its<br>semantics -- they<br>probably misunderstood the OpenBSD semantics and thought it buggy:

The issetugid() system call returns 1 if the process environment or<br>mem- ory address space is considered ``tainted'', and returns 0<br>otherwise.

A process is tainted if it was created as a result of an execve(2)<br>system call which had either of the setuid or setgid bits set (and<br>extra privi- leges were given as a result) or if it has changed<br>any of its real, effective or saved user or group ID's since...

issetugid gist clone call embed formcontrol

Related Articles