CWE-479: Signal Handler Use of a Non-reentrant Function

Learn about CWE-479 (Signal Handler Use of a Non-reentrant Function), its security impact, exploitation methods, and prevention guidelines.

What is Signal Handler Use of a Non-reentrant Function?

• Overview: Signal Handler Use of a Non-reentrant Function is a vulnerability where a signal handler in a program calls a function that is not safe to be interrupted and recalled, leading to potential memory corruption and unpredictable system behavior.

• Exploitation Methods:

  • Attackers can exploit this vulnerability by sending signals to a program at specific times to cause the non-reentrant function to be called in an unsafe manner.
  • Common attack patterns include crafting scenarios where signals are sent during critical operations in non-reentrant functions like syslog(), malloc(), or free().

• Security Impact:

  • Direct consequences include memory corruption, leading to system instability or crashes.
  • Potential cascading effects can involve denial of service or arbitrary code execution if the memory corruption is leveraged appropriately.
  • Business impact includes potential service downtime, loss of data integrity, and breaches impacting customer trust and organizational reputation.

• Prevention Guidelines:

  • Specific code-level fixes involve ensuring that only reentrant functions are called within signal handlers.
  • Security best practices include designing signal handlers to perform minimal processing and deferring complex operations to the main program flow.
  • Recommended tools and frameworks involve using static analysis tools to detect non-reentrant function calls in signal handlers and employing coding standards that discourage the use of non-reentrant functions in critical sections.
Corgea can automatically detect and fix Signal Handler Use of a Non-reentrant Function in your codebase. [Try Corgea free today](https://corgea.app).

Technical Details

Likelihood of Exploit: Low

Affected Languages: C, C++

Affected Technologies: Not specified

Vulnerable Code Example

C Example

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// Signal handler function
void signal_handler(int signum) {
    // Vulnerable code: printf is a non-reentrant function
    printf("Received signal %d\n", signum);
}

int main() {
    // Register the signal handler
    signal(SIGINT, signal_handler);

    // Infinite loop to keep the program running
    while(1) {
        pause(); // Wait for signal
    }

    return 0;
}

Explanation

The above code registers a signal handler for SIGINT using the signal function. The handler uses printf, which is a non-reentrant function. This is problematic because printf may use internal static data structures, and if a signal interrupts printf and the handler is invoked, it can lead to undefined behavior, such as data corruption or crashes. This is a classic example of CWE-479: Signal Handler Use of a Non-reentrant Function.

How to fix Signal Handler Use of a Non-reentrant Function?

To fix this vulnerability, avoid using non-reentrant functions like printf within a signal handler. Instead, use reentrant functions such as write, which directly interacts with file descriptors and does not depend on shared data. Alternatively, set a volatile flag in the handler and perform the non-reentrant operations outside the signal handler in a safe context.

Fixed Code Example

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// Signal handler function
void signal_handler(int signum) {
    // Fixed: Use a reentrant function like write instead of printf
    const char msg[] = "Received signal\n";
    write(STDOUT_FILENO, msg, sizeof(msg) - 1);
}

int main() {
    // Register the signal handler
    signal(SIGINT, signal_handler);

    // Infinite loop to keep the program running
    while(1) {
        pause(); // Wait for signal
    }

    return 0;
}

Explanation

In this fixed version, the write function is used to output a message to standard output. Unlike printf, write is a reentrant function because it directly writes to a file descriptor without relying on any internal static state. This ensures that the signal handler remains safe to execute even when signals are delivered asynchronously. Using write in this manner prevents potential race conditions and maintains the integrity of the program's behavior.

Corgea Logo

Find this vulnerability and fix it with Corgea

Scan your codebase for CWE-479: Signal Handler Use of a Non-reentrant Function and get remediation guidance

Start for free and no credit card needed.