IssueThis issue occurs when you call sensitive standard functions, but you:
For this defect, two type of functions are considered: sensitive and critical
sensitive.
A sensitive function is a
standard function that can encounter:
Exhausted system resources (for example, when allocating resources)
Changed privileges or permissions
Tainted sources when reading, writing, or converting data from external
sources
Unsupported features despite an existing API
A critical sensitive function is
a sensitive function that performs one of these critical or vulnerable tasks:
Set privileges (for example, setuid)
Create a jail (for example, chroot)
Create a process (for example, fork)
Create a thread (for example, pthread_create)
Lock or unlock mutex (for example, pthread_mutex_lock)
Lock or unlock memory segments (for example, mlock)
RiskIf you do not check the return value of functions that perform sensitive or critical
sensitive tasks, your program can behave unexpectedly. Errors from these functions can
propagate throughout the program causing incorrect output, security vulnerabilities, and
possibly system failures.
FixBefore continuing with the program, test the return value of critical
sensitive functions.
For sensitive functions, you can explicitly ignore a return value
by casting the function to void. Polyspace® does not raise this defect for sensitive functions cast to void. This
resolution is not accepted for critical sensitive functions because
they perform more vulnerable tasks.
Example – Sensitive Function Return Ignored#include <pthread.h>
void initialize() {
pthread_attr_t attr;
pthread_attr_init(&attr);
}This example shows a call to the sensitive function
pthread_attr_init. The return value of
pthread_attr_init is ignored, causing a defect.
Correction 1 – Cast Function to (void)One possible correction is to cast the function to void. This fix informs Polyspace and any reviewers that you are explicitly
ignoring the return value of the sensitive function.
#include <pthread.h>
void initialize() {
pthread_attr_t attr;
(void)pthread_attr_init(&attr);
} Correction 2 – Test Return ValueOne possible correction is to test the return value of
pthread_attr_init to check for errors.
#include <pthread.h>
#include <stdlib.h>
#define fatal_error() abort()
void initialize() {
pthread_attr_t attr;
int result;
result = pthread_attr_init(&attr);
if (result != 0) {
/* Handle error */
fatal_error();
}
} Example – Critical Function Return Ignored#include <pthread.h>
extern void *start_routine(void *);
void returnnotchecked() {
pthread_t thread_id;
pthread_attr_t attr;
void *res;
(void)pthread_attr_init(&attr);
(void)pthread_create(&thread_id, &attr, &start_routine, ((void *)0));
pthread_join(thread_id, &res);
}
In this example, two critical functions are called: pthread_create
and pthread_join. The return value of the
pthread_create is ignored by casting to void, but because
pthread_create is a critical function (not just a sensitive
function), Polyspace does not ignore this Return value of a sensitive function
not checked defect. The other critical function,
pthread_join, returns value that is ignored implicitly.
pthread_join uses the return value of
pthread_create, which was not checked.
Correction — Test the Return Value of Critical FunctionsThe correction for this defect is to check the return value of these critical
functions to verify the function performed as expected.
#include <pthread.h>
#include <stdlib.h>
#define fatal_error() abort()
extern void *start_routine(void *);
void returnnotchecked() {
pthread_t thread_id;
pthread_attr_t attr;
void *res;
int result;
(void)pthread_attr_init(&attr);
result = pthread_create(&thread_id, &attr, &start_routine, NULL);
if (result != 0) {
/* Handle error */
fatal_error();
}
result = pthread_join(thread_id, &res);
if (result != 0) {
/* Handle error */
fatal_error();
}
}