ISO/IEC TS 17961 [nullref]

Разыменование указателя вне основной области

Описание

Управляйте определением

Разыменование указателя вне основной области. [1]

Примеры

развернуть все

Описание

Проблема происходит, когда указатель, следующий из арифметики на операнде указателя, не обращается к элементу того же массива как тот операнд указателя.

Polyspace® отмечает это правило во время анализа как:

Средство поиска ошибки и Программа автоматического доказательства Кода проверяют это правило по-другому и могут показать различные результаты для этого правила. В Программе автоматического доказательства Кода можно также видеть различие в результатах на основе выбора для опции Verification level (-to). Смотрите проверку на кодирование стандартных нарушений.

Риск

Используя неверный массив индекс может привести к ошибочному поведению программы. Выведенные индексы времени выполнения массивов особенно неприятны, потому что они не могут легко проверяться ручным анализом или статическим анализом.

Стандарт C задает создание указателя на один вне конца массива. Правило разрешает Стандарт C. Разыменование указателя на один вне конца массива вызывает неопределенное поведение и несовместимо.

Описание

Недопустимое использование стандартной стандартной программы библиотеки memory происходит, когда библиотечная функция памяти вызвана недействительными аргументами. Например, memcpy функционируйте копирует в массив, который не может разместить количество скопированных байтов.

Риск

Использование библиотечной функции памяти с недействительными аргументами может привести к проблемам, таким как переполнение буфера.

Фиксация

Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.

Пример - недопустимое использование стандартной ошибки стандартной программы библиотеки Memory

#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void)
 {
  char str1[10],str2[5];

  printf("Enter string:\n");
  scanf("%s",str1);

  memcpy(str2,str1,6); 
  /* Defect: Arguments of memcpy invalid: str2 has size < 6 */

  return str2;
 }

Размер строки str2 5, но шесть символов строки str1 копируются в str2 использование memcpy функция.

Коррекция — вызывает функцию с допустимыми аргументами

Одна возможная коррекция должна настроить размер str2 так, чтобы это разместило символы, скопированные с memcpy функция.

#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void)
 {
  /* Fix: Declare str2 with size 6 */
  char str1[10],str2[6]; 

  printf("Enter string:\n");
  scanf("%s",str1);

  memcpy(str2,str1,6);
  return str2;
 }

Описание

Нулевой указатель происходит, когда вы используете указатель со значением NULL как будто это указывает на допустимую ячейку памяти.

Риск

Разыменование нулевого указателя является неопределенным поведением. В большинстве реализаций разыменовывание может заставить вашу программу отказывать.

Фиксация

Проверяйте указатель на NULL прежде разыменовывают.

Если проблема происходит несмотря на более раннюю проверку на NULL, ищите промежуточные события между проверкой, и последующие разыменовывают. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.

Смотрите примеры мер ниже.

Пример - Ошибка пустого указателя

#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 int* p=NULL;

 *p=arr[0];
 /* Defect: Null pointer dereference */

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}

Указатель p инициализируется со значением NULL. Однако, когда значение arr[0] записан в *pP принят, чтобы указать на допустимую ячейку памяти.

Коррекция — адрес присвоения к нулевому указателю прежде разыменовывает

Одна возможная коррекция должна инициализировать p с действительным адресом памяти прежде разыменовывают.

#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 /* Fix: Assign address to null pointer */
 int* p=&arr[0];       

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}

Описание

Арифметическая операция с Нулевым указателем происходит, когда арифметическая операция включает указатель, значением которого является NULL.

Риск

Выполнение адресной арифметики с указателями на нулевом указателе и разыменование получившегося указателя являются неопределенным поведением. В большинстве реализаций разыменовывание может заставить вашу программу отказывать.

Фиксация

Проверяйте указатель на NULL перед арифметическими операциями на указателе.

Если проблема происходит несмотря на более раннюю проверку на NULL, ищите промежуточные события между проверкой, и последующие разыменовывают. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.

Смотрите примеры мер ниже.

Пример - арифметическая операция с ошибкой пустого указателя

#include<stdlib.h>

int Check_Next_Value(int *loc, int val) 
 {
  int *ptr = loc, found = 0; 
  
  if (ptr==NULL)
   { 
      ptr++; 
      /* Defect: NULL pointer shifted */

      if (*ptr==val) found=1;
   } 
   
  return(found);    
 }

Когда ptr NULL указатель, код вводит if тело оператора. Поэтому NULL указатель смещен в операторе ptr++.

Коррекция — избегает арифметики нулевого указателя

Одна возможная коррекция должна выполнить арифметическую операцию когда ptr не NULL.

#include<stdlib.h>

int Check_Next_Value(int *loc, int val) 
 {
  int *ptr = loc, found = 0; 
  
  /* Fix: Perform operation when ptr is not NULL */
  if (ptr!=NULL)
   { 
      ptr++;

      if (*ptr==val) found=1;
   }
   
  return(found);    
 }

Описание

Недопустимое использование стандартной стандартной программы строки библиотеки происходит, когда библиотечная функция строки вызвана недействительными аргументами.

Риск

Риск зависит от типа недействительных аргументов. Например, использование strcpy функция с исходным аргументом, больше, чем целевой аргумент, может привести к переполнению буфера.

Фиксация

Фиксация зависит от стандартной библиотечной функции, вовлеченной в дефект. В некоторых случаях можно ограничить аргументы функции перед вызовом функции. Например, если strcpy функция:

char * strcpy(char * destination, const char* source)
попытки скопировать слишком много байтов в целевой аргумент по сравнению с доступным буфером, ограничьте исходный аргумент перед вызовом strcpy. В некоторых случаях можно использовать альтернативную функцию, чтобы избежать ошибки. Например, вместо strcpy, можно использовать strncpy управлять количеством скопированных байтов.

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.

Пример - недопустимое использование стандартной ошибки стандартной программы строки библиотеки

 #include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  char gbuffer[5],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text); 
  /* Error: Size of text is less than gbuffer */

  return(res);
 }

Строка text больше в размере, чем gbuffer. Поэтому функциональный strcpy не может скопировать text в gbuffer.

Коррекция — использует допустимые аргументы

Одна возможная коррекция должна объявить целевую строку gbuffer с равным или большим размером, чем исходная строка text.

#include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  /*Fix: gbuffer has equal or larger size than text */
  char gbuffer[20],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text);

  return(res);
 }

Описание

Использование испорченного дефекта указателя повышено когда:

  • Испорченный Нулевой указатель — указатель не подтвержден против NULL.

  • Испорченный указатель размера — размер зоны памяти, на которую указывает указатель, не подтвержден.

Примечание

На одном указателе ваш код может иметь экземпляры Использования испорченного указателя, Указатель разыменовывают с испорченным смещением, и Испорченным NULL или не пустой отключенной строкой. Средство поиска ошибки повышает только первый испорченный дефект указателя, который оно находит.

Риск

Атакующий может дать вашей программе подсказку, которая указывает на неожиданные ячейки памяти. Если указатель разыменовывается, чтобы записать, атакующий может:

  • Измените переменные состояния критической программы.

  • Заставьте свою программу отказывать.

  • Выполните нежелательный код.

Если указатель разыменовывается, чтобы читать, атакующий может:

  • Считайте уязвимые данные.

  • Заставьте свою программу отказывать.

  • Измените переменную программы к неожиданному значению.

Фиксация

Избегайте использования указателей из внешних источников.

В качестве альтернативы, если вы доверяете внешнему источнику, санируете указатель, прежде чем разыменуют. В отдельной функции санитизации:

  • Проверяйте, что указатель не является ПУСТЫМ.

  • Проверяйте размер ячейки памяти (если возможный). Эта вторая проверка подтверждает, ожидает ли размер данных, указатель указывает на соответствия размеру вашу программу.

Дефект все еще появляется в теле функции санитизации. Однако, если вы используете функцию санитизации вместо нескольких случаев, дефект появляется только однажды. Можно выровнять по ширине дефект и скрыть его в более поздних отзывах при помощи аннотаций кода. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.

Пример - функция, которая разыменовывает внешний указатель

void taintedptr(int* p, int i) {
    *p = i; 
}

В этом примере, указатель *p передается в качестве аргумента, и значение изменяется. Указатель может быть пустым или указать на неизвестную память, которая может быть уязвимой.

Коррекция — избегает использования внешних указателей

Одна возможная коррекция должна избежать указателей из внешних источников.

int *taintedptr(int i) {
    /* Use heap memory allocated in the application */ 
    int *p = (int *)malloc(sizeof (int)); 
    if (p != NULL) { /* Check for success */
        *p = i;
    }
return p;
}

Коррекция — указатель проверки

Другая возможная коррекция должна санировать указатель перед использованием его. Этот пример использует вторую функцию, чтобы проверять, является ли указатель пустым и может быть разыменован.

#include <stdlib.h>

int* sanitize_ptr(int* p) {
    int* res = NULL;
    if (p && *p) { /* Tainted pointer detected here, used as "firewall" */
        /* Pointer is not null and dereference ok */
        res = p;
    }
    return res;
}
void taintedptr(int* p, int i) {
    p = sanitize_ptr(p);
    if (p) {
        *p = i;
    }
}

Проверяйте информацию

Разрешимость: неразрешимый

Введенный в R2019a


[1]  Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.