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

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

Описание

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

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

Риск

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

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

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

Примеры

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

#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