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.

We strongly recommend against performing complex operations in a signal handler.<br />

If you feel that it’s necessary, be aware that it can be done but is error-prone and will<br />

negatively affect program performance.<br />

As an example of what you must do to safely use malloc( ) (whether directly or indirectly)<br />

from inside a signal handler, note that any time malloc( ) needs to be called<br />

inside or outside the signal handler, signal delivery will need to be blocked before the<br />

call to malloc( ) and unblocked again after the call. Changing the signal delivery<br />

often incurs a context switch from user mode to kernel mode; when such switching<br />

is done so frequently, it can quickly add up to a significant decrease in performance.<br />

In addition, because you may never be certain which functions may call malloc( )<br />

under the covers, you may need to protect everything, which can easily result in forgotten<br />

protections in places.<br />

Discussion<br />

As we have already mentioned, there is unfortunately no cookie-cutter solution to<br />

writing safe signal handlers. The code presented here is simply an example of how<br />

signal handlers can be properly written. A much more detailed discussion of signal<br />

handling, which includes real-world examples of how improperly written signal handlers<br />

can be exploited, can be found in Michal Zalewski’s paper, “Delivering Signals<br />

for Fun and Profit,” which is available at http://www.netsys.com/library/papers/<br />

signals.txt. Another excellent source of information regarding the proper way to<br />

write signal handlers is Advanced Programming in the Unix Environment by W. Richard<br />

Stevens (Addison Wesley).<br />

#include <br />

#include <br />

#include <br />

int sigint_received = 0;<br />

int sigterm_received = 0;<br />

int sigquit_received = 0;<br />

void handle_sigint(int sig) { sigint_received = 1; }<br />

void handle_sigterm(int sig) { sigterm_received = 1; }<br />

void handle_sigquit(int sig) { sigquit_received = 1; }<br />

static void setup_signal_handler(int sig, void (*handler)( )) {<br />

#if _POSIX_VERSION > 198800L<br />

struct sigaction action;<br />

action.sa_handler = handler;<br />

sigemptyset(&(action.sa_mask));<br />

sigaddset(&(action.sa_mask), sig);<br />

action.sa_flags = 0;<br />

sigaction(sig, &action, 0);<br />

#else<br />

signal(sig, handler);<br />

714 | Chapter 13: Other Topics<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!