Linux 30 лет тормозил запуск ELF-файлов. И никто не знал почему

Баг из 1993-го нашёлся в коде ядра.


v1c3wibf65i6xn3do63xy15wtaew87wf.jpg


В ядре Linux наконец могут устранить одну из самых старых и загадочных ограничений, существовавших ещё с 1993 года. Разработчик из Alibaba обнаружил, что скрипт, генерирующий ассемблерный файл, приводит к созданию ELF-файла , который не запускается на ARM64-системе с ядром, использующим стандартный размер страницы 4 КБ. При этом тот же файл работает без проблем, если использовать ядро с размером страницы 64 КБ.

Причина оказалась в древней проверке в коде загрузки ELF-файлов. В ядре присутствует условие, которое блокирует запуск, если размер превышает определённое соотношение между минимальным выравниванием ELF и размером страницы. В случае с 4 КБ это ограничивает число заголовков программы до 74, а у тестового файла их 78. При использовании страниц по 64 КБ допустимое количество заголовков превышает тысячу, и файл запускается нормально.


10xy8bt0yubvizyaa4pfy0ghh71bmnr4.png


Инженер из Alibaba заметил, что при удалении этой проверки бинарный файл успешно работает даже на 4 КБ страницах. Однако не было понятно, зачем вообще была введена такая проверка. Тогда в дело включился ветеран Linux Kees Cook, который нашёл упоминание этого условия в коде версии Linux 0.99.15f, датированной 1993 годом. Примечательно, что в документации того времени не объясняется, зачем понадобилась эта проверка. Её просто добавили — и так она и осталась в коде на три десятилетия.

Поскольку спецификация ELF не содержит ограничений на количество заголовков программы, было предложено удалить эту проверку, которая по сути устарела. Ограничение в 64 КБ на размер заголовков всё ещё сохраняется и считается более чем достаточным.

Исправление уже отправлено на рассмотрение в рамках изменений, связанных с `execve`, для будущего релиза Linux 6.17. Если у Линуса Торвальдса не возникнет возражений, патч будет принят в ближайшее время. Ожидается, что окно слияния для версии 6.17 откроется уже в понедельник, при условии, что версия 6.16 будет выпущена в воскресенье.