21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

The potential for security vulnerabilities arising from file descriptors being managed<br />

improperly is high in non-setuid programs. For setuid (especially setuid root) programs,<br />

the potential for problems increases dramatically. The problem is so serious<br />

that some variants of Unix (OpenBSD, in particular) will explicitly open stdin,<br />

stdout, and stderr from the execve( ) system call for a setuid process if they’re not<br />

already open.<br />

The following function, spc_sanitize_files( ), first closes all open file descriptors<br />

that are not one of the standard descriptors. Because there is no easy way to tell<br />

whether a descriptor is open, close( ) is called for each one, and any error returned is<br />

ignored. Once all of the nonstandard descriptors are closed, stdin, stdout, and<br />

stderr are checked to ensure that they are open. If any one of them is not open, an<br />

attempt is made to open /dev/null. If/dev/null cannot be opened, the program is terminated<br />

immediately.<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#ifndef OPEN_MAX<br />

#define OPEN_MAX 256<br />

#endif<br />

static int open_devnull(int fd) {<br />

FILE *f = 0;<br />

if (!fd) f = freopen(_PATH_DEVNULL, "rb", stdin);<br />

else if (fd = = 1) f = freopen(_PATH_DEVNULL, "wb", stdout);<br />

else if (fd = = 2) f = freopen(_PATH_DEVNULL, "wb", stderr);<br />

return (f && fileno(f) = = fd);<br />

}<br />

void spc_sanitize_files(void) {<br />

int fd, fds;<br />

struct stat st;<br />

/* Make sure all open descriptors other than the standard ones are closed */<br />

if ((fds = getdtablesize( )) = = -1) fds = OPEN_MAX;<br />

for (fd = 3; fd < fds; fd++) close(fd);<br />

/* Verify that the standard descriptors are open. If they're not, attempt to<br />

* open them using /dev/null. If any are unsuccessful, abort.<br />

*/<br />

for (fd = 0; fd < 3; fd++)<br />

if (fstat(fd, &st) = = -1 && (errno != EBADF || !open_devnull(fd))) abort( );<br />

}<br />

Managing File Descriptors Safely | 25<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!