История (не)успеха
Есть такой проект FreeRDP, в рамках которого разрабатывается библиотека для работы по протоколу RDP (Remote Desktop Protocol). Я когда-то давно делал несколько патчей для FreeRDP и их приняли в основную ветку, так что проект не был мне совсем чужим. Позднее я решил нанести ещё немного пользы проекту и интегрировать его в OSS Fuzz, чтобы фаззинг-тесты помогли разработчикам сделать код библиотеки более надежным. Помимо моего желания была ещё одна причина - периодически в библиотеке находили CVE и один из докладов на BlackHat был целиком посвящен "дырявости" FreeRDP - "Fuzzing and Exploiting Virtual Channels in Microsoft Remote Desktop Protocol for Fun and Profit". Чтобы сделать интеграцию проекта в OSS Fuzz надо сделать как минимум три вещи: добавить хотя бы один фаззинг тест в проект, сделать статическую сборку фаззинг-тестов в проекте и добавить сборочные скрипты в репозиторий OSS Fuzz.
Итак, в феврале 2020 году я выбрал для фаззинг-тестов самые простые цели в FreeRDP - небольшие модули, которые уже были покрыты юнит-тестами, и сделал для них обёртки для LibFuzzer. Всё это я делал в свободное время и задачка немного растянулась во времени, первые патчи с тестами смержили только через год - в декабре 2020. Следом за тестами добавил в проект отдельную CMake-опцию для включения сборки фаззинг-тестов. Нужно отдать должное ментейнерам проекта - ревью моих патчей почти всегда было оперативным.
Тесты были добавлены в проект и я сделал патч для OSS Fuzz. В теории работа это несложная: выбрать CMake-опции, с которыми собирать проект, чтобы не собрать лишнее, убедиться, что тесты собираются статически, есть аппрув от ментейнеров проекта и это наверное всё. На первом запуске CI для моего патча случилось страшное:
clang-15: error: unable to execute command: Segmentation fault (core dumped)
Хм, но Clang это не какой-то местечковый проект, почему он сегфолтит? Пока я думал и пытался отладить проблему мой PR закрыл один из ментейнеров OSS Fuzz, потому что "I was cleaning out some old issues/PRs, didn't realise this one was still active.". Я перестал проявлять активность в PR и его хотели прикрыть.
Пока идей с фиксом проблемы для Clang не было я сделал патч для статической сборки FreeRDP. Его закатали в основную ветку супер быстро - за 8 дней.
Проблема с Clang не решена. Тем временем код фаззинг-тестов собирается только под отдельной опцией в FreeRDP и может начать протухать - в одном из патчей переделали API и один из тестов сломался. Поэтому сделал отдельный воркфлоу в CI FreeRDP, чтобы собирать фаззинг-тесты на каждый коммит и проверять, что они не сломаны. Патч залили за 1 день.
Прошло 3 года. Я попробовал убрать опцию для LTO в FreeRDP и Clang перестал сегфолтить. Патч для интеграции FreeRDP наконец-то залили в OSS Fuzz.
Год 2023. Тесты запускаются в OSS Fuzz, всё работает. Потом сборка тестов в OSS Fuzz внезапно ломается. Нахожу коммит в FreeRDP, который сломал сборку. В переписке с ментейнером FreeRDP я пытаюсь аккуратно узнать почему на "красный" CI залили патч. Проблема в том, что все зависимости FreeRDP для сборки фаззинг-тестов описаны в репозитории OSS Fuzz, а разработчики не могут сами делать патчи для OSS Fuzz и при добавлении новых зависимостей всё ломается. Потом ещё раза два так сборка ломалась и я перестал уже обращать внимание на письма от OSS Fuzz про сломанную сборку. А разработчики FreeRDP и вовсе отключили в CI фаззинг.
Весной 2024 ментейнер FreeRDP делает патч, который переносит сборочные скрипты из репозитория OSS Fuzz в репозиторий FreeRDP. Сборка работает.
В апреле 2024 сотрудник Kaspersky сделал фаззинг-тест, который нашел несколько уязвимостей (Integer overflow & OutOfBound Write) в коде FreeRDP.
Ментейнеры в оперативном порядке исправляют уязвимости и выпускают новую версию с исправлениями:
https://github.com/FreeRDP/FreeRDP/releases/tag/2.11.6
https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-q5h8-7j42-j4r9