В ограниченном приемнике используются запятнанные, потенциально искалеченные или вне домена целочисленные значения
В ограниченном приемнике используются запятнанные, потенциально искалеченные или вне домена целочисленные значения. [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;
}
В этом примере размер массива переменной длины основан на входном аргументе. Поскольку это значение входного аргумента не проверяется, размер может быть отрицательным или слишком большим.
Одной из возможных корректировок является проверка переменной размера перед созданием массива переменной длины. В этом примере перед созданием VLA проверяется, превышает ли размер 0 и меньше 40.
#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;
}Доступ к массиву с поврежденным индексом обнаруживает чтение или запись в массив с помощью поврежденного индекса, который не был проверен.
Возможно, индекс находится за пределами допустимого диапазона массива. Если запятнанный индекс находится вне диапазона массива, это может привести к следующему:
Underflow/underbrite буфера - запись в память перед началом буфера.
Переполнение буфера - запись в память после окончания буфера.
Перечитывание буфера - доступ к памяти после окончания целевого буфера.
Недостаточное чтение буфера или доступ к памяти перед началом целевого буфера.
Злоумышленник может использовать недопустимую операцию чтения или записи, созданную для устранения проблем в программе.
Прежде чем использовать индекс для доступа к массиву, проверьте значение индекса, чтобы убедиться, что он находится внутри диапазона массива.
#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;
}
}| Разрешимость: неразрешимая |
[1] Выдержки из стандарта «ISO/IEC TS 17961 Technical Specification - 2013-11-15» воспроизводятся с согласия AFNOR. Нормативную ценность имеет только оригинальный и полный текст стандарта, опубликованный изданиями AFNOR - доступный через веб-сайт www.boutique.afnor.org.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.