func = (int (*)()) code;
code
, будучи массивом, неявно преобразуется в указатель на его первый элемент (он распадается на такой указатель). Затем этот указатель преобразуется в указатель на функцию.
Это отличное поведение вызывает неопределенное поведение. Но «большую часть времени», вероятно, приведет к указателю функции, указывающему на адрес массива. Когда вы его вызываете, тогда управление переходит к этому массиву. Если он содержит строковые данные, скорее всего, вы получите недопустимый код операции операции или сегментацию. Но если этот массив содержит какой-то пользовательский ввод, злоумышленник мог бы вставить (скомпилированный) код в него, делая всевозможные забавные (или менее забавные) вещи.
В качестве примера рассмотрим приведенный выше код, запущенный на каком-то сервере, который вводится пользователем через какой-либо веб-сайт. Затем можно заменить программу на for example /bin/sh
и таким образом получить доступ к оболочке на этом сервере.
Это очень хороший пример того, что вы, вероятно, не должны делать .... function pointer casts _almost_ always UB. –
присваивает адрес первого элемента массива 'code []' функции указателю func –
Скомпилирует ли это? –