The C Standard, 7.26.5.6 [ISO/IEC 9899:2011], states that a thread shall not be joined once it was previously joined or detached. Similarly, subclause 7.26.5.3 states that a thread shall not be detached once it was previously joined or detached. Violating either of these subclauses results in undefined behavior.
Noncompliant Code Example
This noncompliant code example detaches a thread that is later joined.
#include <stddef.h> #include <threads.h> int thread_func(void *arg) { /* Do work */ thrd_detach(thrd_current()); return 0; } int main(void) { thrd_t t; if (thrd_success != thrd_create(&t, thread_func, NULL)) { /* Handle error */ return 0; } if (thrd_success != thrd_join(t, 0)) { /* Handle error */ return 0; } return 0; }
Compliant Solution
This compliant solution does not detach the thread. Its resources are released upon successfully joining with the main thread:
#include <stddef.h> #include <threads.h> int thread_func(void *arg) { /* Do work */ return 0; } int main(void) { thrd_t t; if (thrd_success != thrd_create(&t, thread_func, NULL)) { /* Handle error */ return 0; } if (thrd_success != thrd_join(t, 0)) { /* Handle error */ return 0; } return 0; }
Risk Assessment
Joining or detaching a previously joined or detached thread is undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON39-C | Low | Likely | Medium | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Astrée | 24.04 | Supported, but no explicit checker | |
CodeSonar | 8.1p0 | CONCURRENCY.TNJ | Thread is not Joinable |
Helix QAC | 2024.2 | C1776 | |
Parasoft C/C++test | 2023.1 | CERT_C-CON39-a | Do not join or detach a thread that was previously joined or detached |
Polyspace Bug Finder | R2024a | CERT C: Rule CON39-C | Checks for join or detach of a joined or detached thread (rule fully covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Bibliography
[ISO/IEC 9899:2011] | Subclause 7.26.5.3, "The |
1 Comment
Robert Seacord
There seem to be alot of undefined behaviors in C11 dealing with threading that aren't explicitlly listed in Annex J:
The C Standard, subclause 7.26.5.6 [ISO/IEC 9899:2011], specifically states that a thread shall not be joined once it was previously joined or detached. Similarly, subclause 7.26.5.3 states that a thread shall not be detached once it was previously joined or detached.