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.
The IEEE standards page 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 Canceling asynchronously would follow the same route as passing a signal in to the thread to kill it, thus posing similarities to POS44-C. Do not use signals to terminate threadsThis issue is also addressed in Java by the deprecation of Thread.stop() and CON13-J. Ensure that threads are stopped cleanly , which is strongly related to SIG02-C. Avoid using signals to implement normal functionality. These expand on the dangers of canceling a thread suddenly as this can create a data race condition.
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-safecan potentially create a data race condition. Because an asynchronous cancel can happen at ANY time, it could cancel right before the last line (a = c) and there one would thereby lose the old value of b.
| Code Block | ||
|---|---|---|
| ||
volatile int a, b;
void main(void) {
int j;
pthread_create(&thread_identifier,NULL,(void*)thread, NULL);
/* do stuff, like data input */
j if= getc(doneSTDIN);
/* since we don't know when the character is read in, the program {
could continue at any time */
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.
...
| Code Block | ||
|---|---|---|
| ||
volatile int a, b;
void main(void) {
pthread_create(&thread_identifier,NULL,(void*)thread, NULL);
/* do stuff, like data input */
j if= getc(doneSTDIN);
/* since we don't know when the character is read in, the program {
could continue at any time */
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();
}
}
|
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
In Java, similar reasoning resulted in the deprecation of Thread.stop() and appears in the Java Secure Coding Standard as CON13-J. Ensure that threads are stopped cleanly .
References
| Wiki Markup |
|---|
\[[MKS|AA. References#MKS]\] [{{pthread_cancel()}} Man Page|http://www.mkssoftware.com/docs/man3/pthread_cancel.3.asp]
\[[Open Group 04|AA. References#Open Group 04]\] [Threads Overview|http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html] |