CERT C: Rule ARR38-C
Guarantee that library functions do not form invalid pointers
Description
Rule Definition
Guarantee that library functions do not form invalid pointers.1
Polyspace Implementation
The rule checker checks for these issues:
Mismatch between data length and size.
Invalid use of standard library memory routine.
Possible misuse of sizeof.
Buffer overflow from incorrect string format specifier.
Invalid use of standard library string routine.
Destination buffer overflow in string manipulation.
Destination buffer underflow in string manipulation.
Examples
Mismatch between data length and size
Mismatch between data length and size looks
for memory copying functions such as memcpy
, memset
,
or memmove
. If you do not control the length argument
and data buffer argument properly, Bug Finder raises a defect.
If an attacker can manipulate the data buffer or length argument, the attacker can cause buffer overflow by making the actual data size smaller than the length.
This mismatch in length allows the attacker to copy memory past the data buffer to a new location. If the extra memory contains sensitive information, the attacker can now access that data.
This defect is similar to the SSL Heartbleed bug.
When copying or manipulating memory, compute the length argument directly from the data so that the sizes match.
#include <stdlib.h> #include <string.h> typedef struct buf_mem_st { char *data; size_t max; /* size of buffer */ } BUF_MEM; extern BUF_MEM beta; int cpy_data(BUF_MEM *alpha) { BUF_MEM *os = alpha; int num, length; if (alpha == 0x0) return 0; num = 0; length = *(unsigned short *)os->data; memcpy(&(beta.data[num]), os->data + 2, length); //Noncompliant return(1); }
This function copies the buffer alpha
into
a buffer beta
. However, the length
variable
is not related to data+2
.
One possible correction is to check the length of your buffer
against the maximum value minus 2. This check ensures that you have
enough space to copy the data to the beta
structure.
#include <stdlib.h> #include <string.h> typedef struct buf_mem_st { char *data; size_t max; /* size of buffer */ } BUF_MEM; extern BUF_MEM beta; int cpy_data(BUF_MEM *alpha) { BUF_MEM *os = alpha; int num, length; if (alpha == 0x0) return 0; num = 0; length = *(unsigned short *)os->data; if (length<(os->max -2)) { memcpy(&(beta.data[num]), os->data + 2, length); } return(1); }
Invalid use of standard library memory routine
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 Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
#include <string.h> #include <stdio.h> char* Copy_First_Six_Letters(void) { char str1[10],str2[5]; printf("Enter string:\n"); scanf("%9s",str1); memcpy(str2,str1,6); //Noncompliant /* 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("%9s",str1); memcpy(str2,str1,6); return str2; }
Possible misuse of sizeof
Possible misuse of sizeof occurs
when Polyspace®
Bug Finder™ detects possibly unintended results from
the use of sizeof
operator. For instance:
You use the
sizeof
operator on an array parameter name, expecting the array size. However, the array parameter name by itself is a pointer. Thesizeof
operator returns the size of that pointer.You use the
sizeof
operator on an array element, expecting the array size. However, the operator returns the size of the array element.The size argument of certain functions such as
strncmp
orwcsncpy
is incorrect because you used thesizeof
operator earlier with possibly incorrect expectations. For instance:In a function call
strncmp(string1, string2, num)
,num
is obtained from an incorrect use of thesizeof
operator on a pointer.In a function call
wcsncpy(destination, source, num)
,num
is the not the number of wide characters but a size in bytes obtained by using thesizeof
operator. For instance, you usewcsncpy(destination, source, sizeof(destination) - 1)
instead ofwcsncpy(destination, source, (sizeof(desintation)/sizeof(wchar_t)) - 1)
.
Incorrect use of the sizeof
operator can
cause the following issues:
If you expect the
sizeof
operator to return array size and use the return value to constrain a loop, the number of loop runs are smaller than what you expect.If you use the return value of
sizeof
operator to allocate a buffer, the buffer size is smaller than what you require. Insufficient buffer can lead to resultant weaknesses such as buffer overflows.If you use the return value of
sizeof
operator incorrectly in a function call, the function does not behave as you expect.
Possible fixes are:
Do not use the
sizeof
operator on an array parameter name or array element to determine array size.The best practice is to pass the array size as a separate function parameter and use that parameter in the function body.
Use the
sizeof
operator carefully to determine the number argument of functions such asstrncmp
orwcsncpy
. For instance, for wide string functions such aswcsncpy
, use the number of wide characters as argument instead of the number of bytes.
sizeof
Used Incorrectly to Determine Array
Size#define MAX_SIZE 1024 void func(int a[MAX_SIZE]) { int i; for (i = 0; i < sizeof(a)/sizeof(int); i++) { //Noncompliant a[i] = i + 1; } }
In this example, sizeof(a)
returns the size
of the pointer a
and not the array size.
One possible correction is to use another means to determine the array size.
#define MAX_SIZE 1024 void func(int a[MAX_SIZE]) { int i; for (i = 0; i < MAX_SIZE; i++) { a[i] = i + 1; } }
Buffer overflow from incorrect string format specifier
Buffer overflow from incorrect string
format specifier occurs when the format specifier argument
for functions such as sscanf
leads to an overflow
or underflow in the memory buffer argument.
If the format specifier specifies a precision that is greater than the memory buffer size, an overflow occurs. Overflows can cause unexpected behavior such as memory corruption.
Use a format specifier that is compatible with the memory buffer size.
#include <stdio.h> void func (char *str[]) { char buf[32]; sscanf(str[1], "%33c", buf); //Noncompliant }
In this example, buf
can contain 32 char
elements.
Therefore, the format specifier %33c
causes a buffer
overflow.
One possible correction is to use a smaller precision in the format specifier.
#include <stdio.h> void func (char *str[]) { char buf[32]; sscanf(str[1], "%32c", buf); }
Invalid use of standard library string routine
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 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 Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
#include <string.h> #include <stdio.h> char* Copy_String(void) { char *res; char gbuffer[5],text[20]="ABCDEFGHIJKL"; res=strcpy(gbuffer,text); //Noncompliant /* 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); }
Destination buffer overflow in string manipulation
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
.
Buffer overflow can cause unexpected behavior such as memory corruption or stopping your system. Buffer overflow also introduces the risk of code injection.
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, usesnprintf
,_snprintf
orsprintf_s
instead to enforce length control. Alternatively, useasprintf
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, usevsnprintf
orvsprintf_s
instead to enforce length control.If you use
wcscpy
to copy a wide string, usewcsncpy
,wcslcpy
, orwcscpy_s
instead to enforce length control.
Another possible solution is to increase the buffer size.
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); //Noncompliant }
In this example, buffer
can contain 20 char
elements
but fmt_string
has a greater size.
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); }
Destination buffer underflow in string manipulation
Destination buffer underflow in string manipulation occurs when certain string manipulation functions write to their destination buffer argument at a negative offset from the beginning of the buffer.
For instance, for the function sprintf(char* buffer,
const char* format)
, you obtain the buffer
from
an operation buffer = (char*)arr; ... buffer += offset;
. arr
is
an array and offset
is a negative value.
Buffer underflow can cause unexpected behavior such as memory corruption or stopping your system. Buffer underflow also introduces the risk of code injection.
If the destination buffer argument results from pointer arithmetic, see if you are decrementing a pointer. Fix the pointer decrement by modifying either the original value before decrement or the decrement value.
sprintf
Use#include <stdio.h> #define offset -2 void func(void) { char buffer[20]; char *fmt_string ="Text"; sprintf(&buffer[offset], fmt_string); //Noncompliant }
In this example, &buffer[offset]
is at
a negative offset from the memory allocated to buffer
.
One possible correction is to change the value of offset
.
#include <stdio.h> #define offset 2 void func(void) { char buffer[20]; char *fmt_string ="Text"; sprintf(&buffer[offset], fmt_string); }
Check Information
Group: Rule 06. Arrays (ARR) |
Version History
Introduced in R2019a
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 (한국어)