Где гнездятся ошибки
В прикладных программах и серверных приложениях наибольшее количество ошибок сосредоточено в переполняющихся буферах (атака типа buffer overflow или buffer overrun). В ядре так же имеются буфера, некоторые из которых могут быть переполнены, однако, атаки этого типа для него не так характерны.
Вот пять основных источников ошибок— спинлуки (spin lock), неожиданные выходы из функции, ELF-загрузчик, менеджер виртуальной памяти и TCP/IP-стек. Рассмотрим всех кандидатов поподробнее.
Спинлуками называют ячейки памяти, защищающими многозадачный код от воздействия посторонних потоков. При входе в охраняемую зону, процессор устанавливает флаг, а при выходе — сбрасывает. До тех пор пока флаг не будет сброшен, остальные потоки топчутся у выхода и не могут выполнять код. На многопроцессорных ядрах, спинлуки начинаются с префикса LOCK, который легко найти в дизассемблерном тексте, если нажать <ALT-T>. Как мы уже говорили в статье "захватыват ring 0 в Linux" – поддержка многозадачности очень сложная задача и ошибок здесь просто тьма, так что жаловаться на то, что "всех багов уже переловили до нас" никому не приходится. К сожалению, большинство "многозадачных" ошибок имеют многоступенчатый характер, наглядно продемонстрированный в уже упомянутой статье (см. "проблемы многопоточности"), поэтому никаких универсальных методик их поиска не существует. Это работа для настоящих хакеров, способных удержать все ядро в голове и сложить разрозненную мозаику в единую картину. В общем, настоящий хардкор. Это сложно? Ну еще бы! Но мы ведь не ищем легких путей, верно? Зато и удовлетворение от найденной дыры намного больше, чем от просмотра порно.
ernel:C010A65E loc_C010A65E: ; CODE XREF: sub_C010A984+108vj
ernel:C010A65E lock dec byte ptr [ebx-3FCE77F0h]
ernel:C010A665 js loc_C010AA81