Main Content

ISO/IEC TS 17961 [nullref]

Dereferencing an out-of-domain pointer

Description

Rule Definition

Dereferencing an out-of-domain pointer.1

Polyspace Implementation

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.

A default Bug Finder analysis might not raise a violation of this rule when the input values are unknown and only a subset of inputs can cause an issue. To check for violations caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.

Extend Checker

When the input values are unknown and only a subset of inputs cause an issue, Bug Finder might not detect a Null pointer. To check for violations caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.

Examples

expand all

Issue

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® reports violations of this rule when your code has these issues:

Risk

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.

Issue

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.

Risk

Use of a memory library function with invalid arguments can result in issues such as buffer overflow.

Fix

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:

Example - Invalid Use of Standard Library Memory Routine Error
#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.

Correction — Call Function with Valid Arguments

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;
 }
Issue

Null pointer occurs when you use a pointer with a value of NULL as if it points to a valid memory location.

Risk

Dereferencing a null pointer is undefined behavior. In most implementations, the dereference can cause your program to crash.

Fix

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.

Example - Null pointer error
#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.

Correction — Assign Address to Null Pointer Before Dereference

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;
}
Issue

Arithmetic operation with NULL pointer occurs when an arithmetic operation involves a pointer whose value is NULL.

Risk

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.

Fix

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.

Example - Arithmetic Operation with NULL Pointer Error
#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++.

Correction — Avoid NULL Pointer Arithmetic

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);    
 }
Issue

Invalid use of standard library string routine occurs when a string library function is called with invalid arguments.

Risk

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.

Fix

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);
tries to copy too many bytes into the destination argument compared to the available buffer, constrain the source argument before the call to 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:

Example - Invalid Use of Standard Library String Routine Error
 #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.

Correction — Use Valid Arguments

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);
 }

Check Information

Decidability: Undecidable

Version History

Introduced in R2019a


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.