Назад к блогу

Google перевела giflib с C на Rust: как устроен конвейер проверки и что он показал

Google перевела giflib с C на Rust: как устроен конвейер проверки и что он показал

Google переписала giflib с C на Rust силами Gemini, а результат выложила в открытый доступ как giflib-rs — ABI-совместимую замену исходной библиотеки. Корректность подтверждали непрерывным сравнением двух реализаций, и в ходе проверки в старом C-коде нашлась запись за границы, тянущаяся из более раннего патча. Разбор интересен тем, что показывает реальный конвейер миграции: где справляется модель, а где всё ещё нужен человек.

Google переписала библиотеку giflib с C на Rust и опубликовала результат как открытый проект giflib-rs. Библиотека задумана как эталонная реализация для команд, которые оценивают автоматизированные переходы между языками для базовых утилит.

Перевод выполнялся не вручную: логику C-библиотеки перенесла модель Gemini, а корректность проверялась непрерывным сравнением двух реализаций. Отдельный результат проверки — найденная в исходном C-коде внутренняя запись за границы, внесённая более ранним патчем.

Что именно изменилось

Переписывалась giflib — библиотека обработки изображений объёмом около 3000 строк кода. Чтобы новая реализация заменяла существующий shared object прозрачно, инженеры сохранили исходные экспортируемые символы и определения структур. Это делает giflib-rs ABI-совместимой заменой.

Совместимость с C-вызовами обеспечивается тем, что экспортируемая функция помечена атрибутом #[no_mangle] — он запрещает компилятору менять имя символа, поэтому C-код находит функцию по прежнему имени, — и объявлена как pub unsafe extern "C" — соглашение о вызовах C, без которого вызывающий код не смог бы передать аргументы так, как ожидает функция. Внутри сырой указатель проверяется на null, и из него восстанавливается безопасный Rust-дескриптор: Box::from_raw забирает владение памятью, выделенной под структуру, обратно в Rust, чтобы дальше работать с ней как с обычным значением, а не как с сырым указателем. Так FFI-обёртка не допускает undefined behaviour при передаче указателей через границу C.

Предыстория

Вместо многолетних ручных преобразований или полной опоры на проверку границ во время выполнения инженеры Google применили трёхэтапный автоматизированный процесс миграции, построенный вокруг автономного цикла обратной связи.

В обсуждениях на r/rust и Hacker News участники противопоставляли подходу Google с одноразовым переводом идею детерминированных транспайлеров, таких как c2rust, с последующим AI-рефакторингом в безопасный идиоматичный Rust.

Отдельная линия предыстории — OSS-Fuzz, описанный как непрерывный фаззинг для open-source ПО. По состоянию на май 2025 года он помог выявить и исправить более 13 000 уязвимостей и 50 000 багов в 1 000 проектов.

Почему это сделали

Задача формулируется как устранение унаследованных уязвимостей памяти в старой инфраструктуре: повреждения памяти составляют около 70% серьёзных уязвимостей в зрелых стеках C и C++. Целевая библиотека показательна тем, что часто декодирует недоверенный пользовательский ввод без песочницы.

Конвейер проверки выявил необработанный крайний случай в LZW-декомпрессоре и внутреннюю унаследованную запись за границы, внесённую более ранним внутренним патчем в исходный C-код. Команда также сообщает, что нейтрализовала неустранённую heap write zero-day до её публичной каталогизации как CVE-2026-26740. Позже внешний исследователь обнаружил запись за границы кучи в upstream giflib, каталогизированную под тем же номером, а продакшн-узлы на скомпилированной Rust-замене оказались структурно невосприимчивы к дефекту до публичного раскрытия.

Как проверяли эквивалентность

Семантическую эквивалентность устанавливали против исторической реализации на C тремя способами.

Массовое регрессионное декодирование более 30 миллионов реальных GIF-файлов проверяло побитовое совпадение рендеринга. Параллельно автоматический дифференциальный фаззер непрерывно прогонял обе среды бок о бок шесть дней и набрал 200 миллионов итераций без функциональных отклонений. Дополнительно в набор тестов входили состязательные промпты для LLM.

Именно автоматические движки дифференциального тестирования находили расхождения и передавали трассировки сбоев обратно модели для итеративного синтеза патчей.

Роль ИИ и роль человека

Первый этап — однократный промпт к Gemini для переноса всей логики C-библиотеки в Rust. Дальше начинается то, что автоматизировать не удалось: моделирование FFI изначально вносило небезопасную семантику сырых указателей, и экспертам-людям пришлось проверять и уточнять инварианты владения указателями и времени жизни. Обёртки FFI, по признанию авторов, всё ещё требуют человеческой предметной экспертизы, чтобы предотвратить утечки времени жизни и сохранить инварианты потокобезопасности.

Что это меняет на практике

Для разработчиков, использующих giflib, миграция не требует изменения кода: ABI-совместимая замена сохраняет исходные экспортируемые символы и определения структур, поэтому существующие вызовы C-функций продолжают работать без перекомпиляции.

Телеметрия продакшена глобальных кластеров декодирования изображений подтвердила, что Rust-бинарник работал на уровне производительности оригинального C-бинарника. Снятие изоляции процессов дало заметное снижение p99 tail latency. Результат опубликован как открытый проект giflib-rs.

Ограничения и открытые вопросы

Авторы подчёркивают, что переводы с помощью ИИ не являются полностью автоматическим решением. Ответвление upstream-зависимостей C в Rust-репозитории создаёт постоянное расхождение в сопровождении при каждом выпуске новых функций или архитектурных изменений upstream.

В обсуждениях участники подробно разбирали подход с одноразовым переводом, отмечая, что человеческие усилия по аудиту тонких семантических регрессий и исправлению небезопасных границ C FFI часто превышают объём самой генерации кода. Высказывалось мнение, что детерминированные транспайлеры вроде c2rust с последующим ИИ-рефакторингом в безопасный идиоматичный Rust могут оказаться надёжнее по мере роста библиотек за пределы простых самодостаточных целей вроде giflib.

Источники

Похожее