Main Content

ISO/IEC TS 17961 [libptr]

Forming invalid pointers by library function

Description

Rule Definition

Forming invalid pointers by library function.1

Polyspace Implementation

This checker checks for these issues:

  • Use of path manipulation function without maximum sized buffer checking.

  • Invalid use of standard library memory routine.

  • Invalid use of standard library string routine.

  • Destination buffer overflow in string manipulation.

Examples

expand all

Issue

Use of path manipulation function without maximum-sized buffer checking occurs when the destination argument of a path manipulation function such as realpath or getwd has a buffer size less than PATH_MAX bytes.

Risk

A buffer smaller than PATH_MAX bytes can overflow but you cannot test the function return value to determine if an overflow occurred. If an overflow occurs, following the function call, the content of the buffer is undefined.

For instance, char *getwd(char *buf) copies an absolute path name of the current folder to its argument. If the length of the absolute path name is greater than PATH_MAX bytes, getwd returns NULL and the content of *buf is undefined. You can test the return value of getwd for NULL to see if the function call succeeded.

However, if the allowed buffer for buf is less than PATH_MAX bytes, a failure can occur for a smaller absolute path name. In this case, getwd does not return NULL even though a failure occurred. Therefore, the allowed buffer for buf must be PATH_MAX bytes long.

Fix

Possible fixes are:

  • Use a buffer size of PATH_MAX bytes. If you obtain the buffer from an unknown source, before using the buffer as argument of getwd or realpath function, make sure that the size is less than PATH_MAX bytes.

  • Use a path manipulation function that allows you to specify a buffer size.

    For instance, if you are using getwd to get the absolute path name of the current folder, use char *getcwd(char *buf, size_t size); instead. The additional argument size allows you to specify a size greater than or equal to PATH_MAX.

  • Allow the function to allocate additional memory dynamically, if possible.

    For instance, char *realpath(const char *path, char *resolved_path); dynamically allocates memory if resolved_path is NULL. However, you have to deallocate this memory later using the free function.

Example - Possible Buffer Overflow in Use of getwd Function
#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>

void func(void) {
    char buf[PATH_MAX];
    if (getwd(buf+1)!= NULL)         {
        printf("cwd is %s\n", buf);
    }
}

In this example, although the array buf has PATH_MAX bytes, the argument of getwd is buf + 1, whose allowed buffer is less than PATH_MAX bytes.

Correction — Use Array of Size PATH_MAX Bytes

One possible correction is to use an array argument with size equal to PATH_MAX bytes.

#include <unistd.h>
#include <linux/limits.h>
#include <stdio.h>

void func(void) {
    char buf[PATH_MAX];
    if (getwd(buf)!= NULL)         {
        printf("cwd is %s\n", buf);
    }
}
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

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

Destination buffer overflow in string manipulation occurs when certain string manipulation functions write to their destination buffer argument at an offset greater than the buffer size.

For instance, when calling the function sprintf(char* buffer, const char* format), you use a constant string format of greater size than buffer.

Risk

Buffer overflow can cause unexpected behavior such as memory corruption or stopping your system. Buffer overflow also introduces the risk of code injection.

Fix

One possible solution is to use alternative functions to constrain the number of characters written. For instance:

  • If you use sprintf to write formatted data to a string, use snprintf, _snprintf or sprintf_s instead to enforce length control. Alternatively, use asprintf to automatically allocate the memory required for the destination buffer.

  • If you use vsprintf to write formatted data from a variable argument list to a string, use vsnprintf or vsprintf_s instead to enforce length control.

  • If you use wcscpy to copy a wide string, use wcsncpy, wcslcpy, or wcscpy_s instead to enforce length control.

Another possible solution is to increase the buffer size.

Example - Buffer Overflow in sprintf Use
#include <stdio.h>

void func(void) {
    char buffer[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    sprintf(buffer, fmt_string);
}

In this example, buffer can contain 20 char elements but fmt_string has a greater size.

Correction — Use snprintf Instead of sprintf

One possible correction is to use the snprintf function to enforce length control.

#include <stdio.h>

void func(void) {
    char buffer[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    snprintf(buffer, 20, fmt_string);
}

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.