Versions Compared

Key

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

...

Using a blocking operation while holding a lock may be unavoidable for a portable solution.   For instance, file access could be protected via a lock to prevent multiple threads from mutating the contents of the file.   Or, a thread may be required to block while holding one or more locks and waiting to acquire another lock.   In these cases, attempt to hold the lock for the least time required.   Additionally, if acquiring multiple locks, the order of locking must avoid deadlock, as specified in CON35-C. Avoid deadlock by locking in a predefined order.

Noncompliant Code Example

This noncompliant example calls fopen() while a mutex is locked.   The calls to fopen() and fclose() are blocking , and may block for an extended period of time if the file resides on a network drive.   While the call is blocked, other threads that are waiting for the lock are also blocked.

Code Block
bgColor#ffcccc
langc
#include <stdio.h>
#include <threads.h>
 
mtx_t mutex;

int thread_foo(void *ptr) {
  int result;
  FILE *fp;

  if ((result = mtx_lock(&mutex)) != thrd_success) {
    /* Handle error */
  }

 
  fp = fopen("SomeNetworkFile", "r");
  if (fp != NULL) {
    /* Work with the file. */
    fclose(fp);
  }
 
  if ((result = mtx_unlock(&mutex)) != thrd_success) {
    /* Handle error */
  }

  return 0;
}

int main(void) {
  thrd_t thread;
  int result;

  if ((result = mtx_init(&mutex, mtx_plain)) != thrd_success) {
    /* Handle error */
  }

  if (thrd_create(&thread, thread_foo, NULL) != thrd_success) {
    /* Handle error */
  }

  /* ... */

  if (thrd_join(thread, NULL) != thrd_success) {
    /* Handle error */
  }

  mtx_destroy(&mutex);

  return 0;
}

...

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <threads.h>
 
mtx_t mutex;
 
int thread_foo(void *ptr) {
  int result;
  FILE *fp = fopen("SomeNetworkFile", "r");
 
  if (fp != NULL) {
    /* Work with the file. */
    fclose(fp);
  }


  if ((result = mtx_lock(&mutex)) != thrd_success) {
    /* Handle error */
  }

  /* ... */

  if ((result = pthread_mutex_unlock(&mutex)) != 0) {
    /* Handle error */
  }

  return 0;
}

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

CON05-C

lowLow

probableProbable

highHigh

P2

L3

Related Vulnerabilities

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

...

 

...

Image Modified Image Modified