Coccinelle есть и для Rust.

Coccinelle это такая штука, которая позволяет с помощью семантических патчей анализировать и модифицировать код. Например такой патч

@ depends on !context && patch && !org && !report @
expression x;
@@

- ERR_PTR(PTR_ERR(x))
+ ERR_CAST(x)


сделает такое изменение:

diff -u -p a/crypto/ctr.c b/crypto/ctr.c
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
- return ERR_PTR(PTR_ERR(alg));
+ return ERR_CAST(alg);

/* Block size must be >= 4 bytes. */
err = -EINVAL;


Можно делать неинтерактивные рефакторинги.
CI/CD: Continuous Integration / Continuous Disintegration
Please open Telegram to view this post
VIEW IN TELEGRAM
(Я обычно не пишу про уязвимости, чтобы не отбирать хлеб у каналов про инфобез, но сегодня тяжело было, удержаться, извините.)

CVE-2025-0395: Переполнение буфера в реализации функции assert(). Статус уязвимости минорный, но тем не менее.

Карточка уязвимости на сайте NIST: https://nvd.nist.gov/vuln/detail/CVE-2025-0395

Описание PoC: https://www.openwall.com/lists/oss-security/2025/01/22/4
Один из докладов на FOSDEM был про стат. анализатор для Github Actions - zizmor. Github всё ещё остаётся самой популярной платформой разработки ПО с открытым исходным кодом и, как следствие, эти проекты используют GitHub Actions для CI/CD. То есть GitHub Actions имеет первостепенное значение для безопасности мирового программного обеспечения. Автор zizmor рассказывает о гибкости YAML в Github Actions, приводит реальные примеры сбоев безопасности и неожиданных путей эксплуатации, которые повторяются в широко используемых действиях и рабочих процессах. Потом рассказывает про инструмент статического анализа для GitHub Actions, который помогает обнаружить многие из наиболее распространенных (и серьезных) уязвимостей.

А помните как все начиналось? Travis CI добавил возможность CI/CD-as-a-code - декларативно описывать пайплайн на YAML и этот конфиг версионировался в самом репозитории, это было удобно и проще, чем скрипты на Groovy или ручное конфигурирование в UI (как в Jenkins). Microsoft добавляла всё больше и больше возможностей в Github Actions и теперь это превратилось в ужасное недопрограммирование в YAML, который к тому же теперь позволяет делать вставки на обычном ЯП (Javascript) и теперь ещё нужен отдельный стат. анализатор для поиска проблем. Кажется, что стало только хуже.

https://fosdem.org/2025/schedule/event/fosdem-2025-6543-hunting-for-github-actions-bugs-with-zizmor/
Please open Telegram to view this post
VIEW IN TELEGRAM
Вдогонку к предыдущем посту.

Расскажите, оптимизируете ли вы время сборки проекта и время запуска тестов. Измеряете время запуска тестов? Выявляете и регулярно чините флакающие тесты? Используете ли шардирование для запуска тестов?

Источник диаграммы - ежегодный опрос JetBrains.
По умолчанию Clang записывает сырые данные о покрытии кода в файл default.profraw в текущей директории. Имя файла можно переопределить с помощью переменной окружения LLVM_PROFILE_FILE и дополнительно использовать паттерны, которые при создании файла заменяются на реальные данные (PID процесса, имя машины и т.д.)

Но с этим есть проблема, из-за которой сбор сырых данных о покрытии кода работает некорректно. Clang генерирует файлы, в именах которых используется некий хеш, если использовать паттерн %m. Хеш слабый и при запуске в несколько потоков достаточно быстро находится коллизия, несколько потоков начинают писать в один и тот же файл и всё ломается.

$ cat src1.c
int main(void) { return 0; }
void www1(void) { }

$ cat src2.c
int main(void) { return 0; }
void www2(int *a) { *a+=10; }

clang -O0 -g -fprofile-instr-generate -fcoverage-mapping src1.c -o src1
clang -O0 -g -fprofile-instr-generate -fcoverage-mapping src2.c -o src2

export LLVM_PROFILE_FILE="code-%m.profraw"
./src1
./src2

LLVM Profile Warning: Unable to merge profile data: source profile file is not compatible.
LLVM Profile Error: Profile Merging of file /tmp/profile-test/code-15822683945683506682_0.profraw failed: File exists
LLVM Profile Error: Failed to write file "/tmp/profile-test/code-15822683945683506682_0.profraw": File exists


Проблема была найдена сотрудниками PostgresPro и исправлена сотрудником ИСП РАН из компиляторного отдела. Был подготовлен патч, добавляющий binary ID в имя файлов покрытия, и тем самым добавляющий уникальности в имя генерируемых файлов. А вчера патч был принят в основную ветку.

Интересно, что OSS Fuzz покрытие фаззинг тестами генерируется с помощью тулинга LLVM, в LLVM_PROFILE_FILE так же используется %m. Так что возможно результаты покрытия проектов фаззинг тестами поменяются после обновления Clang в OSS Fuzz.

https://github.com/llvm/llvm-project/pull/123963
Please open Telegram to view this post
VIEW IN TELEGRAM
Фаззинг-тесты, которые мы изначально делали для нашего форка LuaJIT, так же используются для непрерывного фаззинга оригинального проекта LuaJIT и интерпретатора PUC Rio Lua. Результат двухлетней работы: 6 багов в PUC Rio Lua, превентивно найденные до публичных релизов, и 23 бага в LuaJIT. Всё были исправлены. Использование одних и тех же тестов для разных проектов оказалось возможным благодаря тому, что PUC Rio Lua и LuaJIT предоставляют один и тот же Lua C API.

Если в этих проектах получилось успешно использовать фаззинг, то было бы здорово применить их и для другого Lua рантайма, подумал я.

Для Go есть популярный среди гоферов проект - GopherLua, это реализация Lua на Go. Для проекта написано много расширений, которые добавляют функциональность со стороны Lua. В Go есть встроенный тулинг для написания фаззинг-тестов: нужно всего лишь написать обёртку для функции, собрать специальной командой и вообщем-то всё. Но я не знаю про аналог libprotobuf-mutator в Go (гоферы,
подскажете аналог?). Поэтому сделать фаззеры для GopherLua с неструктурированными данными проще простого, а чтобы фаззинг-тест генерировал структурированные валидные данные я не смог найти решения.

Я решил попробовать изобразить из GopherLua библиотеку с Lua C API, чтобы эту библиотеку можно было скомпоновать с моими тестами и переиспользовать фаззинг для Lua применительно к GopherLua. Для интеграции Go с C есть cgo, который предоставляет возможность использования C-библиотек в Go и экспорта Go функций в интерфейс C (генерация заголовочного файла). Если кратко, то LuaJIT C FFI мне показался удобнее, чем использование cgo.

Из того, с чем я столкнулся:

- В коде Go нельзя указать макросы, чтобы потом эти макросы cgo добавил в сгенерированный заголовочной файл. Поэтому часть макросов из lua.h пришлось принести в сам тест.
- в Go нельзя никак указать, что функция не принимает аргументов, чтобы в заголовочном файле у функции в параметрах был void. На эту тему есть тикет и вроде даже патч.
- В Lua C API каждая функция первым аргументом принимает указатель на L, структуру, описывающую Lua стек. Я не придумал, как возвращать из Go/cgo эту структуру, поэтому мой модуль может работать с единственной копией стека. Но для моих целей этого достаточно.

В результате этой работы можно собрать тест, который по грамматике генерирует программы на Lua и исполняет их в GopherLua. Правда не все программы исполняются одинаково успешно и иногда случаются проблемы работы с памятью (runtime error: invalid memory address or nil pointer dereference). Такие дела.
Получил доступ к SourceCraft и есть первое впечатление от сервиса.

Интерфейс и функциональность сильно напоминает GitHub UI, думаю, что на него и ориентировались, так как это самая популярная платформа для разработки. Есть тикетница, непрерывная интеграция и развертывание, конфигурация которых описывается в YAML, пулл-реквесты, то есть всё, к чему привыкли в GitHub/Gitlab. Документация в отличие от самого сервиса открыта для всех, можно в ней подробнее почитать.

Для конфигурации CI/CD, как я понял, используется свой YAML-based формат и это печально. С другой стороны общего формата нет и требовать от Яндекса унификации формата или инициативы по его унификации было бы странно.

Чтобы оценить функциональность SourceCraft я пушнул Git-репозиторий с кодом Tarantool. Вцелом осталось приятное впечатление, всё более-менее работает, но есть недоделки, о которых ниже написал.

Подсветка кода при просмотре файлов не всегда работает, неудобно.

Для любого файла в репозитории можно посмотреть его историю и авторство (git blame). Правда авторство для файла src/main.cc в репозитории tarantool я так и не смог посмотреть, ждал примерно минуту и так ничего и не подгрузилось. В гитхабе подгружается пару секунд.

В репозитории tarantool все релизы тегаются, сейчас примерно 161 тег. Но в SourceCraft в разделе "Теги" не было ни одного тега.

В Github появляется кнопка "Создать Pull Request", когда пушишь новую ветку в репозиторий, в SourceCraft такого нет.

Запушил новую ветку во время создания предложения для изменений нажал кнопку "Создать", реакции никакой не последовало. Я нажал еще несколько раз, потом обновил страницу и вуаля, у меня четыре предложения для изменений.

Перевод текста в UI нравится: "Как только вы удалите репозиторий, пути назад не будет. Пожалуйста, будьте уверены."

Несмотря на небольшие недоработки в SourceCraft уже есть Code Assistant, аналог Github Copilot. Попробовал этого ассистента в редактировании сишного и Lua-кода и, как мне показалось, все предложения были невпопад.

Когда доработают, то думаю SourceCraft будет хорошей альтернативой Github.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
В этом году буду выступать на PHDays. Доклад - развитие темы про фаззинг LuaJIT, про которую я начал рассказывать в докладе на HighLoad 2022.
Ниже описание доклада, которое я готовил для ПК, на сайте конференции его нет:

Представьте, что в основе вашего коммерческого продукта используется компонент с исходным кодом, который написан на смеси языка С и самописного ассемблера. Из-за слабой детерминированности поиск репродьюсеров сложен, а без репродьюсера мейнтейнер проекта заявляет “сделайте так, чтобы я про вас больше не слышал”. Я расскажу как мы построили процесс активной поддержки LuaJIT в СУБД Tarantool, сократили количество инцидентов в продакшене, сократили затраты на бэкпорт патчей из основного проекта, какую роль во всём этом сыграл фаззинг и его специфика.

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

В СУБД Tarantool используется LuaJIT в качестве языкового рантайма, но в Tarantool используется не оригинальный проект, а его форк. Я расскажу как мы прошли путь от пассивного использования кода LuaJIT к процессу поддержки форка, с которым количество инцидентов на продакшене установилось около нуля, сократились усилия по бэкпортингу патчей из основного проекта, а основной проект получил активных контрибьюторов.

Я рассмотрю специфику работы с проектом исходного кода на примере LuaJIT, расскажу как устроено тестирование в нашем форке и какую роль там играет фаззинг. Расскажу о специфике фаззинга LuaJIT и каких результатов мы в этом достигли за последние два года.

Доклад будет 22 мая в 15:00, приходите.
Please open Telegram to view this post
VIEW IN TELEGRAM
Организаторы PHDays выложили запись моего доклада - YouTube, VK Видео, RUTUBE, а я выложил слайды.

Доклад приняли хорошо, было много вопросов по существу после доклада и это классно. Я первый раз был на PHDays и впечатление от конференции исключительно позитивное. Прекрасная организация как для спикеров так и для слушателей, всё спланировано. Если будет подходящий материал для PHDays, то обязательно ещё к ним пойду с докладом.
2025/06/28 17:22:49
Back to Top
HTML Embed Code: