Tainted, potentially mutilated, or out-of-domain integer values are used in a restricted sink
Tainted, potentially mutilated, or out-of-domain integer values are used in a restricted sink.[1]
This checker checks for these issues:
Tainted size of variable length array.
Pointer dereference with tainted offset.
Array access with tainted index.
Tainted size of variable length array detects variable length arrays (VLA) whose size is 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.
#include<stdio.h>
#inclule<stdlib.h>
#define LIM 40
long squaredSum(int size) {
int tabvla[size];
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;
}Pointer dereference with tainted offset detects pointer dereferencing, either reading or writing, using an offset variable from an unknown or unsecure source.
This check focuses on dynamically allocated buffers. For static
buffer offsets, see Array access with tainted index.
The index might be outside the valid array range. If the tainted index is outside the array range, it can cause:
Buffer underflow/underwrite, or writing to memory before the beginning of the buffer.
Buffer overflow, or writing to memory after the end of a buffer.
Over reading a buffer, or accessing memory after the end of the targeted buffer.
Under-reading a buffer, or accessing memory before the beginning of the targeted buffer.
An attacker can use an invalid read or write to compromise your program.
Validate the index before you use the variable to access the pointer. Check to make sure that the variable is inside the valid range and does not overflow.
#include <stdio.h>
#include <stdlib.h>
enum {
SIZE10 = 10,
SIZE100 = 100,
SIZE128 = 128
};
extern void read_pint(int*);
int taintedptroffset(void) {
int offset;
scanf("%d",&offset);
int* pint = (int*)calloc(SIZE10, sizeof(int));
int c = 0;
if(pint) {
/* Filling array */
read_pint(pint);
c = pint[offset];
free(pint);
}
return c;
}In this example, the function initializes an integer
pointer pint. The pointer is dereferenced using the input
index offset. The value of offset could be
outside the pointer range, causing an out-of-range error.
One possible correction is to validate the value of the index. If the index is inside the valid range, continue with the pointer dereferencing.
#include <stdlib.h>
#include <stdio.h>
enum {
SIZE10 = 10,
SIZE100 = 100,
SIZE128 = 128
};
extern void read_pint(int*);
int taintedptroffset(void) {
int offset;
scanf("%d",&offset);
int* pint = (int*)calloc(SIZE10, sizeof(int));
int c = 0;
if (pint) {
/* Filling array */
read_pint(pint);
if (offset>0 && offset<SIZE10) {
c = pint[offset];
}
free(pint);
}
return c;
}Array access with tainted index detects reading or writing to an array by using a tainted index that has not been validated.
The index might be outside the valid array range. If the tainted index is outside the array range, it can cause:
Buffer underflow/underwrite — writing to memory before the beginning of the buffer.
Buffer overflow — writing to memory after the end of a buffer.
Over-reading a buffer — accessing memory after the end of the targeted buffer.
Under-reading a buffer, or accessing memory before the beginning of the targeted buffer.
An attacker can use an invalid read or write operation create to problems in your program.
Before using the index to access the array, validate the index value to make sure that it is inside the array range.
#include <stdlib.h>
#include <stdio.h>
#define SIZE100 100
extern int tab[SIZE100];
static int tainted_int_source(void) {
return strtol(getenv("INDEX"),NULL,10);
}
int taintedarrayindex(void) {
int num = tainted_int_source();
return tab[num];
}In this example, the index num accesses the
array tab. The function does not check to see if num is
inside the range of tab.
One possible correction is to check that num is
in range before using it.
#include <stdlib.h>
#include <stdio.h>
#define SIZE100 100
extern int tab[SIZE100];
static int tainted_int_source(void) {
return strtol(getenv("INDEX"),NULL,10);
}
int taintedarrayindex(void) {
int num = tainted_int_source();
if (num >= 0 && num < SIZE100) {
return tab[num];
} else {
return -1;
}
}| Decidability: Undecidable |
[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.