Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: formatting

...

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

void log_msg(int signum) {
  /* Log error message */
}

void handler(int signum) {
  /* Do some handling specific to SIGINT */
  if (raise(SIGUSR1) != 0) { /* violation */
    /* Handle error */
  }
}

int main(void) {

  signal(SIGUSR1, log_msg);
  signal(SIGINT, handler);
   
  /* program code */
  if (raise(SIGINT) != 0) {
    /* Handle error */
  }
  /* More code */

  return 0;
}

 

Implementation Details

...

 

POSIX

 

The following table from the the Open Group Base Specifications [Open Group 2004] defines a set of functions that are asynchronous-signal-safe. Applications may invoke these functions, without restriction, from a signal handler.

 

 Asynchronous-Signal-Safe 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 listed in this table are considered to be unsafe with respect to signals. In the presence of signals, all functions defined by IEEE standard 1003.1-2001 behave as defined when called from or interrupted by a signal handler, with a single exception: when a signal interrupts an unsafe function and the signal handler calls an unsafe function, the behavior is undefined.

 

Note that although raise() is on the list of asynchronous-safe functions, it should not be called within a signal handler if the signal occurs as a result of abort() or raise() function. 

Section 7.14.1.1, para. 4, of the C standard [ISO/IEC 9899:2011] states:

 

...

 If the signal occurs as the result of calling the abort or raise function, the signal handler shall not call the raise function.

 (See also undefined behavior 131 of Annex J.) 

 OpenBSD

...

 

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

The OpenBSD signal() manual page lists a few additional functions that are asynchronous-safe in OpenBSD but "probably not on other systems," including snprintf()vsnprintf(),and syslog_r()( but only when the syslog_data struct is initialized as a local variable).

...

Tool

Version

Checker

Description

Compass/ROSE  Can detect violations of the rule for single-file programs.

LDRA tool suite

Include Page
LDRA_V
LDRA_V

88 D
89 D 

Fully implemented.

Splint

Include Page
Splint_V
Splint_V
 

 

 

Related Vulnerabilities

For an overview of software vulnerabilities resulting from improper signal handling, see Zalewski's paper on understanding, exploiting, and preventing signal-handling-related vulnerabilities [Zalewski 2001]. VU #834865 describes a vulnerability resulting from a violation of this rule.

...