CWE Rule 789
Description
Rule Description
The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated.
Polyspace Implementation
The rule checker checks for these issues:
Memory allocation with tainted size
Tainted size of variable length array
Wrong type used in sizeof
Examples
Memory allocation with tainted size
This issue occurs when a memory allocation function, such as calloc
or
malloc
, uses a size argument from an unsecure
source.
Uncontrolled memory allocation can cause your program to request too much system memory. This consequence can lead to a crash due to an out-of-memory condition, or assigning too many resources.
Before allocating memory, check the value of your arguments to check that they do not exceed the bounds.
By default, Polyspace® assumes that data from external sources are tainted.
See Sources of Tainting in a Polyspace Analysis. To consider any data that does not originate in the current
scope of Polyspace analysis as tainted, use the command line option
-consider-analysis-perimeter-as-trust-boundary
.
#include<stdio.h> #include <stdlib.h> int* bug_taintedmemoryallocsize(void) { size_t size; scanf("%zu", &size); int* p = (int*)malloc(size);//Noncompliant return p; }
In this example, malloc
allocates
size
bytes of memory for the pointer p
. The
variable size
comes from the user of the program. Its value is not
checked, and it could be larger than the amount of available memory. If
size
is larger than the number of available bytes, your program could
crash.
One possible correction is to check the size of the memory that you want to allocate before
performing the malloc
operation. This example checks to see if
size
is positive and less than the maximum size.
#include<stdio.h> #include <stdlib.h> enum { SIZE10 = 10, SIZE100 = 100, SIZE128 = 128 }; int* corrected_taintedmemoryallocsize(void) { size_t size; scanf("%zu", &size); int* p = NULL; if (size>0 && size<SIZE128) { /* Fix: Check entry range before use */ p = (int*)malloc((unsigned int)size); } return p; }
Tainted size of variable length array
This issue occurs when the size of a variable length array (VLA) is obtained from an unsecure source.
If an attacker changed the size of your VLA to an unexpected value, it can cause your program to crash or behave unexpectedly.
If the size is non-positive, the behavior of the VLA is undefined. Your program does not perform as expected.
If the size is unbounded, the VLA can cause memory exhaustion or stack overflow.
Validate your VLA size to make sure that it is positive and less than a maximum value.
By default, Polyspace assumes that data from external
sources are tainted. See Sources of Tainting in a Polyspace Analysis. To consider any data that does not originate in
the current scope of Polyspace analysis as tainted,
use the command line option -consider-analysis-perimeter-as-trust-boundary
.
#include<stdio.h> #inclule<stdlib.h> #define LIM 40 long squaredSum(int size) { int tabvla[size]; //Noncompliant long res = 0; for (int i=0 ; i<LIM-1 ; ++i) { tabvla[i] = i*i; res += tabvla[i]; } return res; } int main(){ int size; scanf("%d",&size); //... long result = squaredSum(size); //... return 0; }
In this example, a variable length array size is based on an input argument. Because this input argument value is not checked, the size may be negative or too large.
One possible correction is to check the size variable before creating the variable length array. This example checks if the size is larger than 0 and less than 40, before creating the VLA
#include <stdio.h> #include <stdlib.h> #define LIM 40 long squaredSum(int size) { long res = 0; if (size>0 && size<LIM){ int tabvla[size]; for (int i=0 ; i<size || i<LIM-1 ; ++i) { tabvla[i] = i*i; res += tabvla[i]; } }else{ res = -1; } return res; } int main(){ int size; scanf("%d",&size); //... long result = squaredSum(size); //... return 0; }
Wrong type used in sizeof
This issue occurs when both of the following conditions hold:
You assign the address of a block of memory to a pointer, or transfer data between two blocks of memory. The assignment or copy uses the
sizeof
operator.For instance, you initialize a pointer using
malloc(sizeof(
or copy data between two addresses usingtype
))memcpy(
.destination_ptr
,source_ptr
, sizeof(type
))You use an incorrect type as argument of the
sizeof
operator. For instance:You might be using the pointer type instead of the type that the pointer points to. For example, to initialize a
pointer, you might be usingtype
*malloc(sizeof(
instead oftype
*))malloc(sizeof(
.type
))You might be using a completely unrelated type as
sizeof
argument. For example, to initialize a
pointer, you might be usingtype
*malloc(sizeof(
.anotherType
))
Irrespective of what type
stands
for, the expression sizeof(
always
returns a fixed size. The size returned is the pointer size on your
platform in bytes. The appearance of type
*)sizeof(
often
indicates an unintended usage. The error can cause allocation of a
memory block that is much smaller than what you need and lead to weaknesses
such as buffer overflows.type*
)
For instance, assume that structType
is a
structure with ten int
variables. If you initialize
a structType*
pointer using malloc(sizeof(structType*))
on
a 32-bit platform, the pointer is assigned a memory block of four
bytes. However, to be allocated completely for one structType
variable,
the structType*
pointer must point to a memory
block of sizeof(structType) = 10 * sizeof(int)
bytes.
The required size is much greater than the actual allocated size of
four bytes.
To initialize a
pointer,
replace type
*sizeof(
in
your pointer initialization expression with type
*)sizeof(
.type
)
#include <stdlib.h> void test_case_1(void) { char* str; str = (char*)malloc(sizeof(char*) * 5); //Noncompliant free(str); }
In this example, memory is allocated for the character pointer str
using
a malloc
of five char pointers. However, str
is
a pointer to a character, not a pointer to a character pointer. Therefore
the sizeof
argument, char*
,
is incorrect.
sizeof
ArgumentOne possible correction is to match the argument
to the pointer type. In this example, str
is a
character pointer, therefore the argument must also be a character.
#include <stdlib.h> void test_case_1(void) { char* str; str = (char*)malloc(sizeof(char) * 5); free(str); }
Check Information
Category: Others |
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 (한국어)