Испорченные, потенциально изувеченные или внедоменные целочисленные значения используются в ограниченном приемнике
Испорченные, потенциально изувеченные или внедоменные целочисленные значения используются в ограниченном приемнике.[1]
Эта проверка проверяет на наличие следующих проблем:
Испорченный размер массива переменной длины.
Разыменование указателя с испорченным смещением.
Доступ к массиву с испорченным индексом.
Испорченный размер массива переменной длины обнаруживает массивы переменной длины (VLA), размер которых получен из небезопасного источника.
Если атакующий изменил размер вашего VLA на неожиданное значение, это может привести к сбою или неожиданному поведению вашей программы.
Если размер не положителен, поведение VLA не определено. Ваша программа работает не так, как ожидалось.
Если размер не ограничен, VLA может вызвать истощение памяти или переполнение стека.
Проверьте размер VLA, чтобы убедиться, что он положительный и меньше максимального значения.
#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;
}
В этом примере размер массива переменной длины основан на входном параметре. Поскольку этот входной параметр не проверен, размер может быть отрицательным или слишком большим.
Одной из возможных коррекций является проверка переменной size перед созданием массива переменной длины. Этот пример проверяет, больше ли размер 0 и меньше 40, перед созданием 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;
}Разыменование указателя с испорченным смещением обнаруживает разыгрывание указателя, чтение или запись, с помощью переменной смещения от неизвестного или небезопасного источника.
Эта проверка фокусируется на динамически выделенных буферах. Для статических смещений буфера смотрите Array access with tainted index.
Возможно, индекс находится вне допустимой области значений массивов. Если испорченный индекс находится вне области значений массивов, это может вызвать:
Подземный поток буфера/андеррайт или запись в память перед началом буфера.
Переполнение буфера или запись в память после окончания буфера.
Над чтением буфера или доступом к памяти после окончания целевого буфера.
Недостаточное чтение буфера или доступ к памяти перед началом целевого буфера.
Атакующий может использовать недопустимое чтение или запись, чтобы скомпрометировать вашу программу.
Проверьте индекс перед использованием переменной для доступа к указателю. Проверьте, что переменная находится внутри допустимой области значений и не переполнена.
#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;
}В этом примере функция инициализирует целочисленный указатель pint. Удаление указателя осуществляется с помощью индекса входа offset. Значение offset может находиться вне области значений указателя, вызывая ошибку вне области допустимого значения.
Одной из возможных коррекций является подтверждение значения индекса. Если индекс находится внутри допустимой области значений, продолжите разыменование указателя.
#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;
}Доступ к массиву с испорченным индексом обнаруживает чтение или запись в массив с помощью испорченного индекса, который не был проверен.
Возможно, индекс находится вне допустимой области значений массивов. Если испорченный индекс находится вне области значений массивов, это может вызвать:
Buffer underflow/underwrite - запись в память перед началом буфера.
Переполнение буфера - запись в память после окончания буфера.
Перечитывание буфера - доступ к памяти после окончания целевого буфера.
Недостаточное чтение буфера или доступ к памяти перед началом целевого буфера.
Атакующий может использовать недопустимую операцию чтения или записи, созданную для проблем в вашей программе.
Прежде чем использовать индекс для доступа к массиву, проверьте значение индекса, чтобы убедиться, что он находится внутри области значений массива.
#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];
}В этом примере индекс num обращается к массиву tab. Функция не проверяет, если num находится внутри области значений tab.
Одной из возможных коррекций является проверка того num находится в области значений перед использованием.
#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;
}
}| Решимость: Undecidable |
[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.