 
                            The tss_create() function creates a thread-specific storage pointer identified by a key. Threads can allocate thread-specific storage and associate the storage with a key that uniquely identifies the storage by calling the tss_set() function. If not properly freed, this memory may be leaked. Ensure that thread-specific storage is freed.
Noncompliant Code Example
In this noncompliant code example, each thread dynamically allocates storage in the get_data() function, which is then associated with the global key by the call to tss_set() in the add_data() function. This memory is subsequently leaked when the threads terminate.
#include <threads.h>
#include <stdlib.h>
/* Global key to the thread-specific storage */
tss_t key;
enum { MAX_THREADS = 3 };
int *get_data(void) {
  int *arr = (int *)malloc(2 * sizeof(int));
  if (arr == NULL) {
    return arr;  /* Report error  */
  }
  arr[0] = 10;
  arr[1] = 42;
  return arr;
}
int add_data(void) {
  int *data = get_data();
  if (data == NULL) {
    return -1;	/* Report error */
  }
  if (thrd_success != tss_set(key, (void *)data)) {
    /* Handle error */
  }
  return 0;
}
void print_data(void) {
  /* Get this thread's global data from key */
  int *data = tss_get(key);
  if (data != NULL) {
    /* Print data */
  } 
}
int function(void *dummy) {
  if (add_data() != 0) {
    return -1;	/* Report error */
  }
  print_data();
  return 0;
}
int main(void) {
  thrd_t thread_id[MAX_THREADS];
  /* Create the key before creating the threads */
  if (thrd_success != tss_create(&key, NULL)) {
    /* Handle error */
  }
  /* Create threads that would store specific storage */
  for (size_t i = 0; i < MAX_THREADS; i++) {
    if (thrd_success != thrd_create(&thread_id[i], function, NULL)) {
      /* Handle error */
    }
  }
  for (size_t i = 0; i < MAX_THREADS; i++) {
    if (thrd_success != thrd_join(thread_id[i], NULL)) {
      /* Handle error */
    }
  }
  tss_delete(key);
  return 0;
}
Compliant Solution
In this compliant solution, each thread explicitly frees the thread-specific storage returned by the tss_get() function before terminating:
#include <threads.h>
#include <stdlib.h>
 
/* Global key to the thread-specific storage */
tss_t key;
 
int function(void *dummy) {
  if (add_data() != 0) {
    return -1;	/* Report error */
  }
  print_data();
  free(tss_get(key));
  return 0;
}
/* ... Other functions are unchanged */
Compliant Solution
This compliant solution invokes a destructor function registered during the call to tss_create() to automatically free any thread-specific storage:
#include <threads.h>
#include <stdlib.h>
/* Global key to the thread-specific storage */
tss_t key;
enum { MAX_THREADS = 3 };
/* ... Other functions are unchanged */
void destructor(void *data) {
  free(data);
}
 
int main(void) {
  thrd_t thread_id[MAX_THREADS];
  /* Create the key before creating the threads */
  if (thrd_success != tss_create(&key, destructor)) {
    /* Handle error */
  }
  /* Create threads that would store specific storage */
  for (size_t i = 0; i < MAX_THREADS; i++) {
    if (thrd_success != thrd_create(&thread_id[i], function, NULL)) {
      /* Handle error */
    }
  }
  for (size_t i = 0; i < MAX_THREADS; i++) {
    if (thrd_success != thrd_join(thread_id[i], NULL)) {
      /* Handle error */
    }
  }
  tss_delete(key);
  return 0;
}
Risk Assessment
Failing to free thread-specific objects results in memory leaks and could result in a denial-of-service attack.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| CON30-C | Medium | Unlikely | Medium | P4 | L3 | 
Automated Detection
| Tool | Version | Checker | Description | 
|---|---|---|---|
| Astrée | 25.10 | Supported, but no explicit checker | |
| Coverity | 2017.07 | ALLOC_FREE_MISMATCH | Partially implemented, correct implementation is more involved | 
| Parasoft C/C++test | 2024.2 | CERT_C-CON30-a | Ensure resources are freed | 
| R2025b | CERT C: Rule CON30-C | Checks for thread-specific memory leak (rule fully covered) | 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.


