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
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;
}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;
}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
sizeofoperator.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
sizeofoperator. 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
sizeofargument. For example, to initialize apointer, 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.
Website auswählen
Wählen Sie eine Website aus, um übersetzte Inhalte (sofern verfügbar) sowie lokale Veranstaltungen und Angebote anzuzeigen. Auf der Grundlage Ihres Standorts empfehlen wir Ihnen die folgende Auswahl: .
Sie können auch eine Website aus der folgenden Liste auswählen:
So erhalten Sie die bestmögliche Leistung auf der Website
Wählen Sie für die bestmögliche Website-Leistung die Website für China (auf Chinesisch oder Englisch). Andere landesspezifische Websites von MathWorks sind für Besuche von Ihrem Standort aus nicht optimiert.
Amerika
- América Latina (Español)
- Canada (English)
- United States (English)
Europa
- 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)