Статический анализ кода STM32. Конкретный пример

от автора

Рендер аппаратного ключа администратора

Рендер аппаратного ключа администратора

Для такого вот аппаратного ключа администратора нам понадобилось провести статический анализ кода. Как мы это делали — в статье.

Добрый день, уважаемые коллеги!

Хотел бы сегодня рассказать о несколько необычном опыте анализа кода. Предваряю возмущение многих – да, мсье действительно знает толк в извращениях 😊

Итак, о них родимых. В одном нашем изделии понадобилось защитить от несанкционированного доступа администраторскую консоль управления, банальный COM-порт с мостиком USB-UART на основе FT232. К сожалению, классическое решение с логином/паролем было обставлено целым частоколом формальных требований в виде (1) срока жизни паролей, (2) логирования успешных/неуспешных попыток, (3) минимальной длины паролей, (4) минимальным их алфавитом, (5) требований к применению больших и малых букв, и цифр, и спезнаков, именно «И», а не «ИЛИ». Перечислять можно бы и дальше, но зачем?

Объехать все эти требования по обочине было решено нестандартным путём – поскольку все требования относились к программному продукту, а про аппаратные устройства ничего не было сказано, то мы просто применили АКА – аппаратный ключ администратора. Он втыкается в разрыв USB-кабеля, идущего от АРМ администратора к устройству, и по свободным линиям обменивается с Изделием сообщениями по схеме challenge-response, не передавая напрямую через линии связи общий секрет, при этом перехват сообщений злоумышленнику не даёт ровно ничего. Если кому интересно, как конкретно это сделано – пишите в комменты или в личку.

Поскольку к историческому моменту принятия решения мы все были в жёстком цейтноте, изготовление АКА поручили стажёру. А он возьми и выбери за основу для разработки «голубую пилюлю (BluePill)» и STM32. Возмущаться, спорить и учить вечному было уже некогда, и тимлид, махнув рукой, согласился. Забегая вперёд, скажу, что отказов и/или сбоев АКА как с самого начала не наблюдалось, так и не наблюдается по сей день. Да, наверное, ПЛК на Ардуине – это уже слишком, но костыль и велосипед проходит вполне (рискую быть бит жёлтыми тряпками, но что было, то было).

Всё это было введение. А теперь про анализ кода. Уполномоченные принимать результат товарищи попросили (таким тоном, что не откажешь) провести ну хотя бы статический анализ кода АКА, чтобы быть уверенными в его качестве. В этом-то и заключалась засада и неприятная неожиданность. Мы рассчитывали на то, что от Ардуинки как от продукта с полностью открытым исходным кодом будет достаточно всех исходников, ан нет.

Шорт-лист продуктов для проверки состоял всего из двух пунктов: Cppcheck и PVS Studio. Гугление, отягощённое признаками ИИ, показало, что последний продукт (А) платный, (Б) больше предназначен для поиска плохо обнаружимых ошибок, не дающих нормально работать гаджету. Жаба оказалась непобедимой и мы выбрали Cppcheck.

Что в Cppcheck хорошо:

  • Можно выбрать нужную архитектуру, STM32 тут имеется. Надо сказать, что работать с кодом для архитектуры ARM Cortex M могут далеко не все анализаторы.

  • Продукт терпим к нестандартному синтаксису, чем обычно знамениты Embedded-приложения.

  • Не требует своего участия в компиляции продукта, работает с чистым исходным кодом.

  • Хорошо детектирует проблемы с неопределённым поведением: с выходом за границы массивов, неинициализированными переменными и утечками памяти.

К сожалению, просто натравить Cppcheck на папку с проектом в Arduino IDE ни к чему хорошему не привело. Первая причина в том, что Arduino IDE по сути работает с неким синтетическим языком (называемым Wired), сделанным в основном из макросов CPP, и пока Cppcheck их все не увидит и не распознает, ничего стоящего не получится.

Вторая причина – Cppcheck по умолчанию не знает, где искать заголовочные файлы для нашего микроконтроллера. Все пути нужно так или иначе указать. И тут вылезает ещё одна засада – сначала мы взяли просто рабочий ноут, на котором разрабатывалось ПО для АКА. Но вот беда – IDE на этом ноуте обросла целой тучей библиотек от других контроллеров, с которыми разработчик имел дело: от ATMega до ESP32. Было даже забавно: первый прогон показал четыре неподключенных библиотеки, мы научили Cppcheck, где их взять, и число нужных include возросло до трёх десятков ☹ В общем, под конец число подключённых библиотек доросло до 6000+

Пришлось собрать «стерильную» IDE на чистом ПК, только с необходимыми библиотеками, и тогда число их немного превышало 2000. В общем, не поленитесь потратить время на чистую сборку – это окупится.

В-третьих, нужно не забыть указать Cppcheck волшебный параметр —platform=arm32-wchar_t4, без которого анализатор не понимает, что имеет дело с архитектурой CortexM.

И наконец, нам оказалось проще расставить в исходном тексте программы в некоторых местах директивы «// cppcheck-suppress <идентификатор_ошибки>», чтобы замаскировать некоторые совсем странные конструкции, которыми иногда пользуется Ардуинка. Опыт показывает, что если этого не делать, то всё равно для того, чтобы аргументированно доказать, что мы имеем дело с ложным срабатыванием анализатора, приходится лезть в исходный код. Пусть уж лучше маскирующая директива и пояснение к ней сразу будут в коде – это экономит время.

К нашему удивлению, Cppcheck на нашем весьма небольшом коде нашёл с десяток недочётов, с которыми автор согласился и исправил. Ещё одно интересное наблюдение – все ошибки находились в написанном нами коде, в библиотеках ни одной Cppcheck не обнаружил. Правда, источником библиотек были Arduino IDE и проект STM32Duino, мусорного кода из сомнительных источников мы не тянули.

В заключение хочу сказать, что если Вам нужно разобраться с нестабильным поведением Вашего Embedded-решения, провести вот прямо очень серьёзный статический анализ, Вы используете серьёзные решения, а не Arduino IDE, то скорее всего Вашим выбором должна стать PVS Studio.

Для полноты картины — рендер обратной стороны АКА. Если кому интересно, пишите в комменты или в личку — выложу фото.

ссылка на оригинал статьи https://habr.com/ru/articles/1023056/