Dereferencing an out-of-domain pointer
Dereferencing an out-of-domain pointer.[1]
This checker checks for these issues:
Unsafe pointer arithmetic.
Invalid use of standard library memory routine.
Null pointer.
Arithmetic operation with NULL pointer.
Invalid use of standard library string routine.
The issue occurs when a pointer resulting from arithmetic on a pointer operand does not address an element of the same array as that pointer operand.
Polyspace® flags this rule during the analysis as:
Bug Finder — Array
access out-of-bounds and Pointer
access out-of-bounds
Code Prover — and
Bug Finder and Code Prover check this rule differently and can show different results for this
rule. In Code Prover, you can also see a difference in results based on your
choice for the option Verification
level (-to) (Polyspace Code Prover). See
Check for Coding Standard Violations.
Using an invalid array subscript can lead to erroneous behavior of the program. Run-time derived array subscripts are especially troublesome because they cannot be easily checked by manual review or static analysis.
The C Standard defines the creation of a pointer to one beyond the end of the array. The rule permits the C Standard. Dereferencing a pointer to one beyond the end of an array causes undefined behavior and is noncompliant.
Invalid use of standard library memory routine occurs when a
memory library function is called with invalid arguments. For instance, the
memcpy function copies to an array that cannot accommodate the
number of bytes copied.
Use of a memory library function with invalid arguments can result in issues such as buffer overflow.
The fix depends on the root cause of the defect. Often the result details show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show the event history, you can trace back using right-click options in the source code and see previous related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See Address Polyspace Results Through Bug Fixes or Justifications.
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void)
{
char str1[10],str2[5];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
/* Defect: Arguments of memcpy invalid: str2 has size < 6 */
return str2;
}The size of string str2 is
5, but six characters of string str1 are copied
into str2 using the memcpy function.
One possible correction is to adjust the size
of str2 so that it accommodates the characters
copied with the memcpy function.
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void)
{
/* Fix: Declare str2 with size 6 */
char str1[10],str2[6];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
return str2;
}Null pointer occurs when you
use a pointer with a value of NULL as if it points
to a valid memory location.
Dereferencing a null pointer is undefined behavior. In most implementations, the dereference can cause your program to crash.
Check a pointer for NULL before dereference.
If the issue occurs despite an earlier check
for NULL, look for intermediate events between the check and the
subsequent dereference. Often the result details show a sequence of events that led
to the defect. You can implement the fix on any event in the sequence. If the result
details do not show the event history, you can trace back using right-click options
in the source code and see previous related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface.
See examples of fixes below.
#include <stdlib.h>
int FindMax(int *arr, int Size)
{
int* p=NULL;
*p=arr[0];
/* Defect: Null pointer dereference */
for(int i=0;i<Size;i++)
{
if(arr[i] > (*p))
*p=arr[i];
}
return *p;
}
The pointer p is initialized
with value of NULL. However, when the value arr[0] is
written to *p, p is assumed
to point to a valid memory location.
One possible correction is to initialize p with
a valid memory address before dereference.
#include <stdlib.h>
int FindMax(int *arr, int Size)
{
/* Fix: Assign address to null pointer */
int* p=&arr[0];
for(int i=0;i<Size;i++)
{
if(arr[i] > (*p))
*p=arr[i];
}
return *p;
}
Arithmetic operation with NULL pointer occurs
when an arithmetic operation involves a pointer whose value is NULL.
Performing pointer arithmetic on a null pointer and dereferencing the resulting pointer is undefined behavior. In most implementations, the dereference can cause your program to crash.
Check a pointer for NULL before arithmetic operations on the
pointer.
If the issue occurs despite an earlier check for NULL, look for
intermediate events between the check and the subsequent dereference. Often the
result details show a sequence of events that led to the defect. You can implement
the fix on any event in the sequence. If the result details do not show the event
history, you can trace back using right-click options in the source code and see
previous related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface.
See examples of fixes below.
#include<stdlib.h>
int Check_Next_Value(int *loc, int val)
{
int *ptr = loc, found = 0;
if (ptr==NULL)
{
ptr++;
/* Defect: NULL pointer shifted */
if (*ptr==val) found=1;
}
return(found);
}When ptr is a NULL pointer,
the code enters the if statement body. Therefore,
a NULL pointer is shifted in the statement ptr++.
One possible correction is to perform the arithmetic
operation when ptr is not NULL.
#include<stdlib.h>
int Check_Next_Value(int *loc, int val)
{
int *ptr = loc, found = 0;
/* Fix: Perform operation when ptr is not NULL */
if (ptr!=NULL)
{
ptr++;
if (*ptr==val) found=1;
}
return(found);
}Invalid use of standard library string routine occurs when a string library function is called with invalid arguments.
The risk depends on the type of invalid arguments. For instance, using the
strcpy function with a source argument larger than the
destination argument can result in buffer overflows.
The fix depends on the standard library
function involved in the defect. In some cases, you can constrain the function
arguments before the function call. For instance, if the
strcpy
function:
char * strcpy(char * destination, const char* source);
strcpy. In some cases, you can use an alternative
function to avoid the error. For instance, instead of strcpy,
you can use strncpy to control the number of bytes
copied.See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See Address Polyspace Results Through Bug Fixes or Justifications.
#include <string.h>
#include <stdio.h>
char* Copy_String(void)
{
char *res;
char gbuffer[5],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
/* Error: Size of text is less than gbuffer */
return(res);
}
The string text is larger
in size than gbuffer. Therefore, the function strcpy cannot
copy text into gbuffer.
One possible correction is to declare the destination
string gbuffer with equal or larger size than the
source string text.
#include <string.h>
#include <stdio.h>
char* Copy_String(void)
{
char *res;
/*Fix: gbuffer has equal or larger size than text */
char gbuffer[20],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
return(res);
}
| Decidability: Undecidable |
[1] Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.