You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

In threading, pthreads have the option of being set to cancel immediately or defer until a specific cancellation point. Canceling asynchronously (immediately) is dangerous, however, because most threads are in fact not safe to cancel immediately. IEEE states that:

only functions that are cancel-safe may be called from a thread that is asynchronously cancelable.

Not only that, but canceling asynchronously is akin to SIG02-C. Avoid using signals to implement normal functionality, since normal functionality is to use the pthread_cancel method, as shown in POS44-C. Do not use signals to terminate threads

This issue is also addressed in Java by the deprecation of Thread.stop() and CON13-J. Ensure that threads are stopped cleanly .

Noncompliant Code Example

In this noncompliant code example the thread is doing something as simple as swapping a and b repeatedly. However, this thread is not asynchronously cancel-safe. Because an asynchronous cancel can happen at ANY time, it could cancel right before the last line (a = c) and there one would lose the old value of b.

volatile int a, b;

void main(void) {
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);
  /* do stuff */
  if (done)
  {
    pthread_cancel(thread_identifier);
  }
}
void thread(void) {
  int i, c;
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&i);
  while (1)
  {
    c = b;
    b = a;
    a = c;
  }
}

Compliant Solution

From IEEE standards page:

The cancelability state and type of any newly created threads, including the thread in which main() was first invoked, shall be PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_DEFERRED respectively.

Since the default condition according to the IEEE standards for POSIX is PTHREAD_CANCEL_DEFERRED, one would simply not set cancel type for the compliant solution.

However, since not all compilers are necessarily guaranteed to follow standards, one could also explicitly call pthread_setcanceltype with PTHREAD_CANCEL_DEFERRED.

volatile int a, b;

void main(void) {
  pthread_create(&thread_identifier,NULL,(void*)thread, NULL);
  /* do stuff */
  if (done)
  {
    pthread_cancel(thread_identifier);
    /* pthread_join waits for the thread to finish up before continuing */
    pthread_join(thread_identifier, 0);
  }
}
void thread(void) {
  int i, c;
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&i);
  while (1)
  {
    c = b;
    b = a;
    a = c;
    /* now we're safe to cancel, creating cancel point */
    pthread_testcancel();
  }
}

Risk Assessment

Incorrectly using threads that asynchronously cancel may result in silent corruption and, in the worst case, unpredictable interactions.

Automated Detection

TODO

Related Vulnerabilities

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

Other Languages

CON13-J. Ensure that threads are stopped cleanly

References

[[MKS]] pthread_cancel() Man Page
[[Open Group 04]] Threads Overview

  • No labels