Сбой обнаружить и обработать стандартные ошибки библиотеки
Возвращенное значение чувствительной функции, не проверяемой, происходит, когда вы вызываете чувствительные стандартные функции, но вас:
Проигнорируйте возвращаемое значение.
Используйте вывод или возвращаемое значение, не тестируя валидность возвращаемого значения.
Для этого дефекта рассматриваются два типа функций: чувствительный и очень важный чувствительный.
Чувствительная функция является стандартной функцией, которая может столкнуться:
Исчерпанные системные ресурсы (например, при выделении ресурсов)
Измененные привилегии или полномочия
Испорченные источники при чтении, при записи или преобразовании данных из внешних источников
Неподдерживаемые функции несмотря на существующий API
Критическая чувствительная функция является чувствительной функцией, которая выполняет одну из этих критических или уязвимых задач:
Установите привилегии (например, setuid
)
Создайте тюрьму (например, chroot
)
Создайте процесс (например, fork
)
Создайте поток (например, pthread_create
)
Заблокируйте или разблокируйте взаимное исключение (например, pthread_mutex_lock
)
Заблокируйте или разблокируйте сегменты памяти (например, mlock
)
Если вы не проверяете возвращаемое значение функций, которые выполняют чувствительные или критические чувствительные задачи, ваша программа может неожиданно вести себя. Ошибки от этих функций могут распространить в программе, вызывающей неправильный вывод, уязвимости системы обеспечения безопасности, и возможно системные отказы.
Прежде, чем продолжить программу, протестируйте возвращаемое значение критических чувствительных функций.
Для чувствительных функций можно явным образом проигнорировать возвращаемое значение путем кастинга функции к void
. Polyspace® не повышает этот дефект для чувствительного броска функций, чтобы освободить. Это разрешение не принято для критических чувствительных функций, потому что они выполняют более уязвимые задачи.
#include <pthread.h>
void initialize() {
pthread_attr_t attr;
pthread_attr_init(&attr);
}
Этот пример показывает вызов чувствительного функционального pthread_attr_init
. Возвращаемое значение pthread_attr_init
проигнорировано, вызвав дефект.
(void)
Одно возможное исправление должно бросить функцию, чтобы освободить. Эта фиксация сообщает Polyspace и любым рецензентам, что вы явным образом игнорируете возвращаемое значение чувствительной функции.
#include <pthread.h> void initialize() { pthread_attr_t attr; (void)pthread_attr_init(&attr); }
Одно возможное исправление должно протестировать возвращаемое значение pthread_attr_init
, чтобы проверить ошибки.
#include <pthread.h> #include <stdlib.h> #define fatal_error() abort() void initialize() { pthread_attr_t attr; int result; result = pthread_attr_init(&attr); if (result != 0) { /* Handle error */ fatal_error(); } }
#include <pthread.h> extern void *start_routine(void *); void returnnotchecked() { pthread_t thread_id; pthread_attr_t attr; void *res; (void)pthread_attr_init(&attr); (void)pthread_create(&thread_id, &attr, &start_routine, ((void *)0)); pthread_join(thread_id, &res); }
В этом примере вызваны две критических функции: pthread_create
и pthread_join
. Возвращаемое значение pthread_create
проигнорировано путем кастинга, чтобы освободить, но потому что pthread_create
является критической функцией (не только чувствительная функция), Polyspace не игнорирует это Возвращаемое значение чувствительной функции не проверяемый дефект. Другая критическая функция, pthread_join
, возвращает значение, которое проигнорировано неявно. pthread_join
использует возвращаемое значение pthread_create
, который не проверялся.
Исправление для этого дефекта должно проверять возвращаемое значение этих критических функций, чтобы проверить функцию, выполняемую как ожидалось.
#include <pthread.h> #include <stdlib.h> #define fatal_error() abort() extern void *start_routine(void *); void returnnotchecked() { pthread_t thread_id; pthread_attr_t attr; void *res; int result; (void)pthread_attr_init(&attr); result = pthread_create(&thread_id, &attr, &start_routine, NULL); if (result != 0) { /* Handle error */ fatal_error(); } result = pthread_join(thread_id, &res); if (result != 0) { /* Handle error */ fatal_error(); } }
Незащищенное динамическое выделение памяти происходит, когда вы не проверяете после динамического выделения памяти ли выделение памяти, за которым следуют.
Когда память динамически выделяется с помощью malloc
, calloc
или realloc
, это возвращает значение NULL
, если требуемая память не доступна. Если код после выделения получает доступ к блоку памяти, не проверяя на это значение NULL
, этот доступ не защищен от отказов.
Проверяйте возвращаемое значение malloc
, calloc
или realloc
для NULL прежде, чем получить доступ к выделенной ячейке памяти.
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
Одно возможное исправление должно проверять, имеет ли 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); }
Разрешимость: неразрешимый |
[1] Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.