ISO/IEC TS 17961 [liberr]

Сбой обнаружить и обработать стандартные ошибки библиотеки

Описание

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

Сбой обнаружить и обработать стандартную библиотеку errors.[1]

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

  • Возвращенное значение чувствительной функции, не проверяемой.

  • Незащищенное динамическое выделение памяти.

Примеры

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

Проблема

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

  • Проигнорируйте возвращаемое значение.

  • Используйте выход или возвращаемое значение, не тестируя валидность возвращаемого значения.

Для этого дефекта рассматриваются два типа функций: чувствительный и очень важный чувствительный.

Чувствительная функция является стандартной функцией, которая может столкнуться:

  • Исчерпанные системные ресурсы (например, при выделении ресурсов)

  • Измененные привилегии или полномочия

  • Испорченные источники при чтении, при записи или преобразовании данных из внешних источников

  • Неподдерживаемые функции несмотря на существующий API

Критическая чувствительная функция является чувствительной функцией, которая выполняет одну из этих критических или уязвимых задач:

  • Установите привилегии (например, setuid)

  • Создайте тюрьму (например, chroot)

  • Создайте процесс (например, fork)

  • Создайте поток (например, thrd_create)

  • Заблокируйте или разблокируйте сегменты памяти (например, mlock)

Риск

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

Фиксация

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

Для чувствительных функций можно явным образом проигнорировать возвращаемое значение путем кастинга функции к void. Polyspace® не повышает этот дефект для чувствительного броска функций, чтобы освободить. Это разрешение не принято для критических чувствительных функций, потому что они выполняют более уязвимые задачи.

Пример - чувствительный функциональный проигнорированный возврат
#include<stdio.h>
void initialize() {
	int n = 1;
	scanf("%d",&n); 
}

Этот пример показывает вызов чувствительного функционального scanf(). Возвращаемое значение scanf() проигнорирован, вызвав дефект.

Коррекция — функция броска к (void)

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

#include<stdio.h>
void initialize() {
	int n = 1;
	(void) scanf("%d",&n); 
}
Коррекция — тестирует возвращаемое значение

Одна возможная коррекция должна протестировать возвращаемое значение scanf проверять ошибки.

#include<stdio.h>
void initialize() {
	int n,flag ;
	flag = scanf("%d",&n); 
	if(flag>0){
		//...
	}
}
Пример - критический функциональный проигнорированный возврат
#include <threads.h>
int thrd_func(void);
void initialize() {
    thrd_t thr;
	int n = 1;

    (void) thrd_create(&thr,thrd_func,&n); 
}

В этом примере, критическом функциональном thrd_create называется и его возвращаемое значение проигнорировано путем кастинга, чтобы освободить, но потому что thrd_create критическая функция, Polyspace не игнорирует это Возвращаемое значение чувствительной функции не проверяемый дефект.

Коррекция — тестирует возвращаемое значение критических функций

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

#include <threads.h>
int thrd_func(void);
void initialize() {
	thrd_t thr;
	int n = 1;
	if( thrd_success!= thrd_create(&thr,thrd_func,&n) ){
		// handle error
		
	}
}
Проблема

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

Риск

Когда память динамически выделяется с помощью malloc, calloc, или realloc, это возвращает значение NULL если требуемая память не доступна. Если код после выделения получает доступ к блоку памяти, не проверяя на этот NULL значение, этот доступ не защищен от отказов.

Фиксация

Проверяйте возвращаемое значение malloc, calloc, или realloc для NULL прежде, чем получить доступ к выделенной ячейке памяти.

#define SIZE 10
int *ptr = malloc(SIZE * sizeof(int));

if(ptr) /* Check for NULL */ 
{
   /* Memory access through ptr */
}

Пример - Незащищенная ошибка динамического выделения памяти
#include <stdlib.h>

void Assign_Value(void) 
{
  int* p = (int*)calloc(5, sizeof(int));

  *p = 2;  
  /* Defect: p is not checked for NULL value */

  free(p);
}

Если выделение памяти перестало работать, функциональный calloc возвращает NULL к p. Прежде, чем получить доступ к памяти через p, код не проверяет ли p isNull

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

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

#include <stdlib.h>

void Assign_Value(void)
 {
   int* p = (int*)calloc(5, sizeof(int));

   /* Fix: Check if p is NULL */
   if(p!=NULL) *p = 2; 

   free(p);
 }

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

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

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