CWE Rule 253
Description
Rule Description
The software incorrectly checks a return value from a function, which prevents the software from detecting errors or exceptional conditions.
Polyspace Implementation
The rule checker checks for these issues:
Errno not reset
Unprotected dynamic memory allocation
Examples
Errno not reset
This issue occurs when
you do not reset errno
before calling a function
that sets errno
to indicate error conditions. However,
you check errno
for those error conditions after
the function call.
The errno
is not clean and can contain values
from a previous call. Checking errno
for errors
can give the false impression that an error occurred.
errno
is set to zero at program startup but
subsequently, errno
is not reset by a C standard
library function. You must explicitly set errno
to
zero when required.
Before calling a function that sets errno
to
indicate error conditions, reset errno
to zero
explicitly.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <float.h> #define fatal_error() abort() double func(const char *s1, const char *s2) { double f1; f1 = strtod (s1, NULL); //Noncompliant if (0 == errno) { double f2 = strtod (s2, NULL); if (0 == errno) { long double result = (long double)f1 + f2; if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) { return (double)result; } } } fatal_error(); return 0.0; }
In this example, errno
is not reset to 0
before the first call to strtod
. Checking errno
for
0 later can lead to a false positive.
errno
Before CallOne possible correction is to reset errno
to
0 before calling strtod
.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <float.h> #define fatal_error() abort() double func(const char *s1, const char *s2) { double f1; errno = 0; f1 = strtod (s1, NULL); if (0 == errno) { double f2 = strtod (s2, NULL); if (0 == errno) { long double result = (long double)f1 + f2; if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) { return (double)result; } } } fatal_error(); return 0.0; }
Unprotected dynamic memory allocation
This issue occurs when you access dynamically allocated memory without first checking if the prior memory allocation succeeded.
When memory is dynamically allocated using malloc
,
calloc
, or realloc
, it returns a value
NULL
if the requested memory is not available. If the code
following the allocation accesses the memory block without checking for this
NULL
value, this access is not protected from
failures.
Check the return value of malloc
, calloc
, or realloc
for NULL before accessing the allocated memory location.
int *ptr = malloc(size * sizeof(int)); if(ptr) /* Check for NULL */ { /* Memory access through ptr */ }
#include <stdlib.h> void Assign_Value(void) { int* p = (int*)calloc(5, sizeof(int)); *p = 2; //Noncompliant /* Defect: p is not checked for NULL value */ free(p); }
If the memory allocation fails, the function calloc
returns NULL
to p
.
Before accessing the memory through p
, the code
does not check whether p
is NULL
One possible correction is to check whether p
has
value NULL
before dereference.
#include <stdlib.h> void Assign_Value(void) { int* p = (int*)calloc(5, sizeof(int)); /* Fix: Check if p is NULL */ if(p!=NULL) *p = 2; free(p); }
#include <stdlib.h> #include<string.h> typedef struct recordType { const char* id; const char* data; } RECORD; RECORD* MakerecordType(const char *id,unsigned int size){ RECORD *rec = (RECORD *)calloc(1, sizeof(RECORD)); rec->id = strdup(id); //Noncompliant const char *newData = (char *)calloc(1, size); rec->data = newData; return rec; }
In this example, the checker raises a defect when you dereference the pointer rec
without checking for a NULL
value from the prior dynamic memory allocation.
A similar issue happens with the pointer newData
. However, a defect is not
raised because the pointer is not dereferenced but simply copied over to
rec->data
. Simply copying over a possibly null pointer is not an
issue by itself. For instance, callers of the recordType_new
function
might check for NULL
value of rec->data
before
dereferencing, thereby avoiding a null pointer dereference.
Check Information
Category: Error Conditions, Return Values, Status Codes |
Version History
Introduced in R2023a
See Also
External Websites
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 (한국어)