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.

should call pclose( ) to clean up the file descriptors and reap the child process created<br />

by the call to fork( ).<br />

You should also avoid using popen( ) and its accompanying pclose( ) function, but<br />

popen( ) does have utility that is worth duplicating in a secure fashion. The following<br />

implementation with a similar API does not make use of the shell.<br />

If you do wish to use either system( ) or popen( ), be extremely careful. First, make<br />

sure that the environment is properly set, so that there are no Trojan environment<br />

variables. Second, remember that the command you’re running will be run in a Unix<br />

shell. This means that you must ensure that there is no way an attacker can pass<br />

malicious data to the shell command. If possible, pass in a fixed string that the<br />

attacker cannot manipulate. If the user must be allowed to manipulate the input,<br />

only very careful filtering will accomplish this securely. We recommend that you<br />

avoid this scenario at all costs.<br />

The following code implements secure versions of popen( ) and pclose( ) using the<br />

spc_fork( ) code from Recipe 1.6. Our versions differ slightly in both interface and<br />

function, but not by too much.<br />

The function spc_popen( ) requires the same arguments execve( ) does. In fact, the<br />

arguments are passed directly to execve( ) without any modification. If the operation<br />

is successful, an SPC_PIPE object is returned; otherwise, NULL is returned. When<br />

communication with the new program is complete, call spc_pclose( ), passing the<br />

SPC_PIPE object returned by spc_popen( ) as its only argument. If the new program<br />

has not yet terminated when spc_pclose( ) is called in the original program, the call<br />

will block until the new program does terminate.<br />

If spc_popen( ) is successful, the SPC_PIPE object it returns contains two FILE objects:<br />

• read_fd can be used to read data written by the new program to its stdout file<br />

descriptor.<br />

• write_fd can be used to write data to the new program for reading from its stdin<br />

file descriptor.<br />

Unlike popen( ), which in its most portable form is unidirectional, spc_popen( ) is<br />

bidirectional.<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

typedef struct {<br />

FILE *read_fd;<br />

FILE *write_fd;<br />

pid_t child_pid;<br />

} SPC_PIPE;<br />

Executing External Programs Securely | 31<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!