CertC++-ERR52

Do not use setjmp() or longjmp()

Required inputs: IR

The C standard library facilities setjmp() and longjmp() can be used to simulate throwing and catching exceptions. However, these facilities bypass automatic resource management and can result in undefined behavior, commonly including resource leaks and denial-of-service attacks.

The C++ Standard, [support.runtime], paragraph 4 [ ISO/IEC 14882-2014], states the following:

The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. A setjmp/ longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.

Do not call  setjmp() or  longjmp(); their usage can be replaced by more standard idioms such as  throw expressions and  catch statements.

Noncompliant Code Example

If a  throw expression would cause a nontrivial destructor to be invoked, then calling  longjmp() in the same context will result in  undefined behavior. In the following noncompliant code example, the call to  longjmp() occurs in a context with a local  Counter object. Since this object's destructor is nontrivial, undefined behavior results.

#include <csetjmp>
#include <iostream>

static jmp_buf env;

struct Counter {
  static int instances;
  Counter() { ++instances; }
  ~Counter() { --instances; }
};

int Counter::instances = 0;

void f() {
  Counter c;
  std::cout << "f(): Instances: " << Counter::instances << std::endl;
  std::longjmp(env, 1);
}

int main() {
  std::cout << "Before setjmp(): Instances: " << Counter::instances << std::endl;
  if (setjmp(env) == 0) {
    f();
  } else {
    std::cout << "From longjmp(): Instances: " << Counter::instances << std::endl;
  }
  std::cout << "After longjmp(): Instances: " << Counter::instances << std::endl;
}
Implementation Details

The above code produces the following results when compiled with Clang3.8 for Linux, demonstrating that the program, on this platform, fails to destroy the local  Counter instance when the execution of  f() is terminated. This is permissible as the behavior is undefined.

Before setjmp(): Instances: 0
f(): Instances: 1
From longjmp(): Instances: 1
After longjmp(): Instances: 1
Compliant Solution

This compliant solution replaces the calls to  setjmp() and  longjmp() with a  throw expression and a  catch statement.

#include <iostream>

struct Counter {
  static int instances;
  Counter() { ++instances; }
  ~Counter() { --instances; }
};

int Counter::instances = 0;

void f() {
  Counter c;
  std::cout << "f(): Instances: " << Counter::instances << std::endl;
  throw "Exception";
}

int main() {
  std::cout << "Before throw: Instances: " << Counter::instances << std::endl;
  try {
    f();
  } catch (const char *E) {
    std::cout << "From catch: Instances: " << Counter::instances << std::endl;
  }
  std::cout << "After catch: Instances: " << Counter::instances << std::endl;
}

This solution produces the following output.

Before throw: Instances: 0
f(): Instances: 1
From catch: Instances: 0
After catch: Instances: 0
Risk Assessment

Using setjmp() and longjmp() could lead to a denial-of-service attack due to resources not being properly destroyed.

Rule Severity Likelihood Remediation Cost Priority Level
ERR52-CPP Low Probable Medium P4 L3
Bibliography
[ Henricson 1997] Rule 13.3, Do not use  setjmp() and  longjmp()
[ ISO/IEC 14882-2014] Subclause 18.10, "Other Runtime Support"
Excerpt from SEI CERT C++ Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-cpp-coding-standard/rules/exceptions-and-error-handling-err/err52-cpp], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

jump

Do not use setjmp() or longjmp().

None

False

Options

jump_functions

jump_functions : set[bauhaus.analysis.config.QualifiedName] = {'longjmp', 'setjmp'}

Forbidden jump functions.