exponenta event banner

Вызов через указатель без прототипа функции

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

Описание

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

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

Риск

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

Зафиксировать

Перед вызовом функции через указатель укажите прототип функции.

Примеры

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

#include <stdio.h>
#include <limits.h>
#define SIZE2 2

typedef void (*func_ptr)();
extern int getchar_wrapper(void);
extern void restricted_int_sink(int i);
/* Integer value restricted to
range [-1, 255] */
extern void restricted_float_sink(double i);
/* Double value restricted to > 0.0 */

                                              

func_ptr generic_callback[SIZE2] =
{
    (func_ptr)restricted_int_sink,
    (func_ptr)restricted_float_sink
};

void func(void)
{
    int ic;
    ic = getchar_wrapper();             
    /* Wrong index used for generic_callback.
	Negative 'int' passed to restricted_float_sink. */
	(*generic_callback[1])(ic); 
}
        
      

В этом примере вызов через func_ptr проходы ic в качестве аргумента функции generic_callback[1]. Тип ic могут иметь отрицательные значения, в то время как параметр generic_callback[1] ограничивается поплавковыми значениями, превышающими 0.0. Как правило, компиляторы и средства статического анализа не могут выполнять проверку типа, если не предоставлен прототип указателя.

Исправление - предоставление прототипа указателя на функцию

Передать аргумент ic к функции с параметром типа int, с помощью правильно прототипированного указателя.

#include <stdio.h>
#include <limits.h>
#define SIZE2 2

typedef void (*func_ptr_proto)(int);
extern int getchar_wrapper(void);
extern void restricted_int_sink(int i);
/* Integer value restricted to
range [-1, 255] */
extern void restricted_float_sink(double i);
/* Double value restricted to > 0.0 */                                        

func_ptr_proto generic_callback[SIZE2] =
{
    (func_ptr_proto)restricted_int_sink,
    (func_ptr_proto)restricted_float_sink
};

void func(void)
{
    int ic;
    ic = getchar_wrapper();              
    /* ic passed to function through
properly prototyped pointer. */
	(*generic_callback[0])(ic);
} 

Информация о результатах

Группа: Программирование
Язык: C
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: UNPROTOTYPED_FUNC_CALL
Воздействие: среднее
Представлен в R2017b