Оптимизация кода компилятором может привести к появлению проблем безопасности в приложениях
Например, компилятор исключает неопределённые или нестабильные участки кода, которые на деле могут выступать проверками на появление нулевого указателя или выхода за границы области памяти (например, оптимизатор может заменить "data + x < data" на "x < 0" или считает всегда истинным "-k >= 0" если ранее была проверка "if (k < 0)"). В итоге, данные проверки не включаются в исполняемый файл, и безопасное на уровне исходных текстов приложение становится подвержено уязвимостям на уровне исполняемого кода. Проблеме подвержено большинство современных компиляторов, включая GCC, Clang, ICC, MSVC, open64, pathcc, suncc и т.д.
Например, оптимизатор GCC удалит вторую проверку из следующего кода:
char *buf = ...; char *buf_end = ...; unsigned int len = ...; if (buf + len >= buf_end) return; /* len too large */ if (buf + len < buf) return; /* overflow, buf+len wrapped around write to buf[0..len-1] */
Программист использует условие "buf + len < buf" для проверки на переполнение указателя, подразумевая, что при очень большом значении будет осуществлено переполнение размерности типа. GCC оперирует тем, что по стандарту языка C указатель не должен выходить за пределы объекта более чем на единицу, а в противном случае поведение программы не определено.
В качестве другого примера можно привести код для которого будет удалена проверка на нулевой указатель (gcc считает, что tun не может принимать значение NULL после того, как был произведен доступ к tun->sk):
struct tun_struct *tun = ...; struct sock *sk = tun->sk; if (!tun) return POLLERR; /* write to address based on tun */
Для выявления проблемных мест в коде на языках C и C++, которые могут быть удалены на стадии оптимизации, исследователями подготовлен специальный статический анализатор STACK. Изучение при помощи STACK типовых открытых проектов выявило 160 подобных проблем, из которых 32 присутствуют в ядре Linux, 3 в Mozilla, 9 в PostgreSQL, 4 в QEMU, 21 в FFmpeg, 3 в Xen, 5 в Python.
Более широкая проверка исходных текстов показала, что нестабильные блоки кода присутствуют в 3471 пакете из 8575 пакетов, доступных в репозиториях Debian. Наибольшее число выявленных проблем (59230 проблем в 2800 пакетах) связано с разыменованием нулевого указателя, 5795 проблем могут привести к переполнению буфера, 4364 к проблемам целочисленной арифметики, 3680 - проблемам с переполнением указателя. Таким образом, описанные в работе проблемы не являются единичными, а широко распространены и могут быть использованы злоумышленниками для организации атак.
Источник: http://www.opennet.ru/opennews/art.shtml?num=38293
|
0 | Tweet | Нравится |
|