exponenta event banner

ISO/IEC TS 17961 [liber]

Ошибка при обнаружении и обработке стандартных библиотечных ошибок

Описание

Определение правила

Ошибка при обнаружении и обработке стандартных библиотечных ошибок. [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 не игнорирует это значение Return чувствительной функции, не проверенной на дефект.

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

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

 #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 является NULL

Исправление - проверка значения NULL

Одной из возможных корректировок является проверка 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 Technical Specification - 2013-11-15» воспроизводятся с согласия AFNOR. Нормативную ценность имеет только оригинальный и полный текст стандарта, опубликованный изданиями AFNOR - доступный через веб-сайт www.boutique.afnor.org.