Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
Similarly, Section 7.14.1 paragraph 5 of C99 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] states that:

If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t, or the signal handler calls any function in the standard library other than the abort function, the _Exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler.

...

This program has two potential problems. The first is that the free() function is not asynchronous-safe, and its invocation from within a signal handler is a violation of this rule. If an interrupt signal is received during the free() call in main(), the heap may be corrupted.

Wiki MarkupThe second problem is if {{SIGINT}} occurs after the call to {{free()}}, resulting in the memory referenced by {{foo()}} being freed twice. This is a violation of \[[MEM31-C. Free dynamically allocated memory exactly once]\] and also \[[SIG31-C. Do not access or modify shared objects in signal handlers]\].

The _Exit() function called from within the int_handler() signal handler causes immediate program termination , and is asynchronous-safe, whereas exit() may call cleanup routines first, and consequently is consequently not asynchronous-safe.

Implementation Details

...

Wiki Markup
The following table from the the Open Group Base Specifications \[[Open Group 04|AA. C References#Open Group 04]\] defines a set of functions that are asynchronous-signal-safe. Applications may consequently invoke them, without restriction, from signal-catching functions:.

_Exit()

_exit()

abort()

accept()

access()

aio_error()

aio_return()

aio_suspend()

alarm()

bind()

cfgetispeed()

cfgetospeed()

cfsetispeed()

cfsetospeed()

chdir()

chmod()

chown()

clock_gettime()

close()

connect()

creat()

dup()

dup2()

execle()

execve()

fchmod()

fchown()

fcntl()

fdatasync()

fork()

fpathconf()

fstat()

fsync()

ftruncate()

getegid()

geteuid()

getgid()

getgroups()

getpeername()

getpgrp()

getpid()

getppid()

getsockname()

getsockopt()

getuid()

kill()

link()

listen()

lseek()

lstat()

mkdir()

mkfifo()

open()

pathconf()

pause()

pipe()

poll()

posix_trace_event()

pselect()

raise()

read()

readlink()

recv()

recvfrom()

recvmsg()

rename()

rmdir()

select()

sem_post()

send()

sendmsg()

sendto()

setgid()

setpgid()

setsid()

setsockopt()

setuid()

shutdown()

sigaction()

sigaddset()

sigdelset()

sigemptyset()

sigfillset()

sigismember()

sleep()

signal()

sigpause()

sigpending()

sigprocmask()

sigqueue()

sigset()

sigsuspend()

sockatmark()

socket()

socketpair()

stat()

symlink()

sysconf()

tcdrain()

tcflow()

tcflush()

tcgetattr()

tcgetpgrp()

tcsendbreak()

tcsetattr()

tcsetpgrp()

time()

timer_getoverrun()

timer_gettime()

timer_settime()

times()

umask()

uname()

unlink()

utime()

wait()

waitpid()

write()

 

 

All functions not in the this table are considered to be unsafe with respect to signals. In the presence of signals, all functions defined by IEEE Std standard 1003.1-2001 behave as defined when called from or interrupted by a signal-catching function, with a single exception: when a signal interrupts an unsafe function and the signal-catching function calls an unsafe function, the behavior is undefined.

Wiki MarkupNote that while {{raise()}} is on the list of asynchronous-safe functions, it is specifically covered by \[[SIG33-C. Do not recursively invoke the raise() function]\].

OpenBSD

The OpenBSD signal() man page identifies functions that are asynchronous-signal safe. Applications may consequently invoke them, without restriction, from signal-catching functions.

The OpenBSD signal() man page also says:

Code Block
A few other functions are signal race safe in OpenBSD but
     probably not on other systems:

           snprintf()    Safe.
           vsnprintf()   Safe.
           syslog_r()    Safe if the syslog_data struct is initialized
                         as a local variable.

...

Code Block
bgColor#ccccff
#include <signal.h>

void int_handler() {
  _Exit(0);
}

int main(void) {
  char *foo = (char *)malloc(sizeof("Hello World."));
  if (foo == NULL) {
    /* handle error condition */
  }
  signal(SIGINT, int_handler);
  strcpy(foo, "Hello World.");
  puts(foo);
  free(foo);
  return 0;
}

Risk Assessment

Wiki MarkupInvoking functions that are not asynchronous-safe from within a signal handler may result in privilege escalation and other attacks.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SIG30-C

3 (high)

3 (likely)

1 (high)

P9

L2

Automated Detection

The tool Compass Rose can detect violations of the rule for single-file programs.

Related Vulnerabilities

Wiki Markup
 attacks. For an overview of some related software vulnerabilities, see Zalewski's paper on understanding, exploiting, and preventing signal-handling related vulnerabilities \[[Zalewski 01|AA. C References#Zalewski 01]\]. [VU #834865|http://www.kb.cert.org/vuls/id/834865] describes a vulnerability resulting from a violation of this rule.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SIG30-C

3 (high)

3 (likely)

1 (high)

P9

L2

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Automated Detection

The tool Compass Rose can detect violations of the rule for single-file programs.

References

Wiki Markup
\[[Dowd 06|AA. C References#Dowd 06]\] Chapter 13, "Synchronization and State"
\[[ISO/IEC 03|AA. C References#ISO/IEC 03]\] Section 5.2.3, "Signals and interrupts"
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.14, "Signal handling <signal.h>"
\[[Open Group 04|AA. C References#Open Group 04]\] [longjmp|http://www.opengroup.org/onlinepubs/000095399/functions/longjmp.html]
\[[OpenBSD|AA. C References#OpenBSD]\] [{{signal()}} Man Page|http://www.openbsd.org/cgi-bin/man.cgi?query=signal]
\[[Zalewski 01|AA. C References#Zalewski 01]\]

...