CERT C: Rec. EXP12-C
Do not ignore values returned by functions
Description
Rule Definition
Do not ignore values returned by functions.1
Polyspace Implementation
The rule checker checks for Returned value of a sensitive function not checked.
Examples
Returned value of a sensitive function not checked
Returned value of a sensitive function not checked occurs when you call sensitive standard functions, but you:
Ignore the return value.
Use an output or a return value without testing the validity of the return value.
Polyspace® does not report a violation of this rule for these cases:
You use the return value of a function in bitwise masking operations using the
&
and~
operators without checking the return value but then check the masked value. For example, in this code, the return valueval
of the sensitive functionbar()
is not checked. Polyspace does not report a violation becauseval
is used in a bitwise masking operation and the result of the operationmasked_val
is checked.void foo(){ int val = bar() // Sensitive function - Compliant int masked_val = val & 0xff; if(masked_val){ //... } }
You call store the value of sensitive functions that are called in each brunch of a conditional statement and then check the value at the end of the conditional statement. For example, this code, the sensitive functions
foo()
andfoo2()
are called in two branches of theif-else
statement. The return value for both are conditionally stored inreturn_value
. Polyspace does not report a violation becausereturn_value
is checked after the conditional statement.void func(){ //... int volatile cond; int returned_val; if(cond){ returned_val = foo(); }else{ returned_val = foo2(); } if(returned_val){ do_something(); } }
For this violation, 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
)
If 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.
Before 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.
By default, this rule checker detects the use of some sensitive and critical sensitive functions. Specify the sensitive and critical sensitive functions in your code by using a datalog file. In the datalog file, include these components:
Include the definitions in the source file
models/interfaces/sensitive_function.dl
.Specify functions as sensitive:
sensitive_function.is_sensitive("bar").
Specify functions as critical:
sensitive_function.is_critical("foo").
You can also configure this rule checker to ignore some functions:
sensitive_function.ignore_all()
— Configures the rule checker to ignore the default functions.sensitive_function.ignore_standard($sensitive_function.
— Configures the rule checker to ignore the sensitive and critical sensitive functions for a specific set, specified bystd
())std
. Possible values ofstd
include:ISO
,POSIX
,OPENSSL
,UNIX
,WINDOWS
.sensitive_function.ignore_function("
— Configures the rule checker to ignore the functionfunc
")func
.
Specify the datalog file as the input to the option -code-behavior-specifications
.
#include <pthread.h> void initialize() { pthread_attr_t attr; pthread_attr_init(&attr); //Noncompliant }
This example shows a call to the sensitive
function pthread_attr_init
. The return value of
pthread_attr_init
is ignored, causing a defect.
(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); }
One 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(); } }
#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)); //Noncompliant pthread_join(thread_id, &res); //Noncompliant }
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.
The 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(); } }
In this example, the function foo()
is a critical sensitive
function and the function bar()
is a sensitive function.
extern int foo(void); /* Critical */ extern int bar(void); /* Senstive */ extern void do_something(void); /* Non-critical/sensitive */ void example() { (void)foo();//Noncompliant int ret = bar(); //Noncompliant do_something(); // Compliant }
Because
foo()
is a critical sensitive function, explicitly ignoring its return value by casting tovoid
is a violation of this rule.The return value of
bar()
is stored in the variableret
but not used or checked in the code. This ignored return value in a violation of this rule.
To specify these two functions as critical sensitive and sensitive, create a datalog file with this content:
.include "models/interfaces/sensitive_function.dl" sensitive_function.is_critical("foo"). sensitive_function.is_sensitive("bar").
-code-behavior-specifications
.Check Information
Group: Rec. 03. Expressions (EXP) |
Version History
Introduced in R2019aR2023b: Violation not reported for some functions
By default, Polyspace no longer reports violations on these functions:
putchar
,putwchar
puts
printf
,vprintf
,wprintf
,vwprintf
memcpy
,wmemcpy
memset
,wmemset
memmove
,wmemmove
strcpy
,wcscpy
strncpy
,wcsncpy
strcat
,wcscat
,strncat
,wcsncat
See Also
External Websites
1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.
ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)