Versions Compared

Key

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

Mutexes Mutex objects are used to protect shared data structures from being concurrently accessed. If a mutex object is destroyed while a thread is blocked waiting for that mutexthe lockcritical sections and shared data are no longer protected.

The C++ Standard, [thread.mutex.class], paragraph 5 [ISO/IEC 14882-2014], states the following:

The behavior of a program is undefined if it destroys a mutex object owned by any thread or a thread terminates while owning a mutex object.

This statement implies Similar wording exists for std::recursive_mutexstd::timed_mutexstd::recursive_timed_mutex, and std::shared_timed_mutex. These statements imply that destroying a mutex object while a thread is waiting on it is undefined behavior.

...

Code Block
bgColor#ffcccc
langc
#include <mutex>
#include <thread>

const size_t max_threadsmaxThreads = 10;

void do_work(size_t i, std::mutex *lockppm)
 {
  std::lock_guard<std::mutex> guardlk(*lockppm);

  // Access data protected by the lock.
}

void start_threads(void)
 {
  std::thread threads[max_threadsmaxThreads];
  std::mutex lockm;

  for (size_t i = 0; i < max_threadsmaxThreads; ++i) {
    threads[i] = std::thread(do_work, i, &lockm);
  }
}

Compliant Solution

This compliant solution eliminates the race condition by extending the lifetime of the lock:mutex.

Code Block
bgColor#ccccff
langc
#include <mutex>
#include <thread>

const size_t max_threadsmaxThreads = 10;

void do_work(size_t i, std::mutex *lockppm)
 {
  std::lock_guard<std::mutex> guardlk(*lockppm);

  // Access data protected by the lock.
}

std::mutex lockm;

void start_threads(void)
 {
  std::thread threads[max_threadsmaxThreads];

  for (size_t i = 0; i < max_threadsmaxThreads; ++i) {
    threads[i] = std::thread(do_work, i, &lockm);
  }
}

Compliant Solution

This compliant solution eliminates the race condition by joining the threads before the lockmutex's destructor is invoked:.

Code Block
bgColor#ccccff
langc
#include <mutex>
#include <thread>

const size_t max_threadsmaxThreads = 10;

void do_work(size_t i, std::mutex *lockppm)
 {
  std::lock_guard<std::mutex> guardlk(*lockppm);

  // Access data protected by the lock.
}
void run_threads(void)
 {
  std::thread threads[max_threadsmaxThreads];
  std::mutex lockm;

  for (size_t i = 0; i < max_threadsmaxThreads; ++i) {
    threads[i] = std::thread(do_work, i, &lockm);
  }

  for (size_t i = 0; i < max_threadsmaxThreads; ++i) {
    threads[i].join();
  }
}

...

Destroying a mutex while it is locked may result in invalid control flow and data corruption.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON50-CPP

Medium

Probable

High

P4

L3

Automated Detection

Tool

Version

Checker

Description

Fortify SCA

5.0

 

Can detect violations of this rule with CERT C Rule Pack

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

CONCURRENCY.LOCALARG

Local Variable Passed to Thread

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF961, DF4962
Klocwork
Include Page
Klocwork_V
Klocwork_V
CERT.CONC.MUTEX.DESTROY_WHILE_LOCKED
Parasoft C/C++test
9.5BD-RES-FREE, BD-RES-INVFREE

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-CON50-a

Do not destroy another thread's mutex

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: CON50-CPPChecks for destruction of locked mutex (rule partially covered)
 

Related Vulnerabilities

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

Related Guidelines

Bibliography

[ISO/IEC
9899:2011
14882-2014]
7.26
Subclause 30.4.1, "
The mtx_destroy Function
Mutex Requirements"


...

Image Added Image Modified Image Removed  Image Modified