| 28.09.2010 07:00 | |
Аннотация
Безопасность программных продуктов становится все более актуальной в мире цифровых технологий. Профессия специалиста по безопасности программного обеспечения становится все более востребованной и уважаемой на рынке. Неотъемлемой частью проверки программного продукта на безопасность является его тестирование с помощью инструментов статического анализа. В статье описывается работа над улучшением качества Intel® Static Security Analyzer и полученные результаты.
Об авторе
Нешляева Арина Владимировна, студентка 4-го курса физического факультета Новосибирского Государственного Университета кафедры автоматизации физико-технических исследований. Стажировку проходила в городе Новосибирске под руководством ментора Николая Ивницкого и менеджера Дмитрия Петунина.
Небольшая хронология
1 век д.н.э. – «Человеку свойственно ошибаться» (Цицерон)
1492 год — Леонардо да Винчи в одном из своих дневников приводит эскиз 13-разрядного суммирующего устройства с десятизубцовыми кольцами.
1843 год - графиня Ада Августа Лавлейс, дочка великого английского поэта Джорджа Байрона, как принято считать, написала первую в истории человечества программу для Аналитической машины.
2002 год – «80% своего времени разработчик тратит на поиск и исправление ошибок» (NIST 2002)
Все эти факты не могли не привести к появлению множества средств для верификации программного обеспечения. Немаловажное место среди всех инструментов верификации занимают статические анализаторы кода.
Статический анализ кода
Статический анализ кода (англ. static code analysis) — анализ программного обеспечения, производимый без реального выполнения исследуемых программ.
Это определение с www.wikipedia.org ни на йоту не раскрывает всей мощи работы алгоритмов статического анализа. К сожалению или к счастью, моя работа не включала в себя изучение теоретической стороны вопроса, поэтому рассмотрим эту технологию с практической точки зрения.
Преимущества использования статического анализа:
- Обнаружение ошибок на ранних этапах разработки
Чем раньше найден баг, тем быстрее и дешевле его исправить:
Используя статический анализ, вы можете анализировать не только полную программу, но и ее часть, даже на самых ранних этапах разработки. - Анализ всех потенциальных путей
Статический анализ проверяет все потенциальные пути, по которым может пойти программа, включая даже те, которые не будут по каким-либо причинам включены в процесс тестирования. - Безопасность
Самое слабое место в программе - это пользовательский ввод. Статический анализ всегда напомнит вам проверить входные данные. Кроме того, он подумает за вас о безопасном межплатформенном переносе. Особенно это касается изменений в размерах различных типов данных. - Репутация
Чем устойчивее программа, тем больше пользователей она привлекает. А чем больше пользователь удовлетворен, тем выше ваша репутация, как разработчика. Статический анализ дисциплинирует и делает вас более ответственным за ошибки в коде. - Удобная командная разработка
Статический анализ помогает найти несоответствия в декларациях и определениях, в именах и типах данных в различных модулях, написанных разными людьми. - Экономия времени
Программист тратит меньше времени на обработку багов и больше - на разработку.
Постановка задачи
Инструмент статического анализа, с которым нам предстояло работать, был Intel® Static Security Analyzer. Планировалось ознакомиться с его функциональностью, проанализировать несколько open source проектов, разработать эффективные методы по его использованию. Результаты оформить в виде статей.
Intel® Static Security Analyzer
Static Security Analyzer – инструмент статического анализа для языков программирования С/С++ и FORTRAN, поддерживающий технологии OpenMP и Cilk. Он является неотъемлемой частью компилятора Intel, поэтому, используя этот компилятор, вы можете пользоваться сразу и статическим анализом. SSA поддерживает операционные системы Windows и Linux, MSVS (2005, 2008, 2010). Для работы GUI требуется Intel ® Parallel/C++ Studio XE.
SSA является частью Intel®Inspector 2011 XE. Пользовательский интерфейс позволяет просматривать список найденных проблем в коде, которые можно отсортировывать по весу, статусу (Fixed, Not Fixed, Confirmed), имени файла. Имеется панель со всевозможными фильтрами, упрощающими анализ диагностики. И окно предпросмотра кода, соответствующего диагностике.
Сообщения, выдаваемые SSA подразделяются на:
- Critical errors – такие как переполнение буфера, неправильное использование указателей, некорректный пользовательский ввод, утечки памяти и.т.д.
- Errors - такие как деление на ноль, неинициализированные переменные, неиспользуемый код и.т.д.
- Warnings - например нарушение инкапсуляции в C++ классе
- Другие recommendations – например большой аргумент, передающийся по значению.
Предложенное решение
Предлагалось проверять возможности SSA на open-source проектах (Media Player Classic, Notepad++, Mozilla Firefox, Mongo DB), анализировать полученную диагностику и создавать небольшие тесты, в случае обнаружения некорректной диагностики.
Однако стоит заметить, что вся наша работа проходила перед релизом SSA и должна была не только максимально улучшить его качество, но и раскрыть возможности SSA в глазах потенциальных пользователей.
На еженедельных митингах нашей команды мы узнали, что SSA обычно предлагают тем, кто или вообще никогда не использовал статический анализ, или использовал для этого аналогичные продукты других компаний. Поэтому в решение нашей поставленной задачи мы включили сравнение SSA с конкурентами и создание новых тестовых баз, основанных на примерах работы этих подуктов.
Процесс анализа работы SSA
- Скачать исходники проекта
- Разобраться со структурой проекта, попробовать его собрать. При этом возможно требуется установить какие-либо библиотеки, утилиты, sdk
- Запустить построение статического анализа (в зависимости от размера проекта может занимать от нескольких минут до 8-10 часов)
- Если произошла внутренняя ошибка построения (а такое бывало часто) – нужно получить стек вызовов и запостить баг
- Если анализ прошел успешно – анализируем диагностику:
- Погружаемся в исследование ошибок многотысячного чужого кода
- При этом имеется GUI вариант, в котором удобно сортировать и фильтровать диагностику, а также переходить на строки исходного кода, вызвавших эту ошибку. И имеется текстовый файл со всей диагностикой, который необходимо «раскрасить»:
+! – ошибки, которые разработчик приложения должен, по нашему мнению, исправить.
++ - правильная диагностика (корректное утверждение о программе. исправление такой диагностики остается на усмотрение разработчика приложения)
+- - правильность диагностики зависит от алгоритма
-+ - false positive. Так называется ситуация, когда статический анализатор пытается анализировать программу "в целом", принимая в расчет все возможные значения входных данных. При этом он может найти ошибку, которой на самом деле в данном конкретном случае нет (пример в главе «Трудности работы с SSA»)
-- - SSA bug. Абсолютно неправильная диагностика. Ошибка в алгоритме SSA. - Для диагностики, помеченной -+ и – нужно запостить баги и создать тесты.
- Такой «раскрашенный» файл является в каком-то роде базой знаний для данного проекта. С его помощью можно сравнивать эффективность работы различных версий SSA.
Результаты работы SSA
С помощью Source Checker мы полностью проанализировали такие проекты, как: decss (библиотека в составе Media Player Classic) (56 диагностики), Notepad ++ v5.7 (986 диагностики), 252.eon (spec 2000)(273 диагностики). Частично проанализировали WinMerge (644 диагностики). Также мы пытались построить анализ для Mozilla Firefox и MongoDB, но ничего не вышло из-за internal error (которую успели исправить только к моменту завершения нашей стажировки). Результаты анализа представлены на следующих диаграммах:
Как можно видеть, SSA сообщает много интересной информации для разработчиков приложений. Полезность этой информации зависит от многих факторов:
- размер проекта. Чем больше анализируемый проект, тем больше в нем зависимостей и условий. Все это усложняет эффективную работу SSA, затрудняет межпроцедурный анализ.
- сложная вложенность функций.
- использование некоторых библиотечных функций SSA не знает пока о многих библиотечных функциях. Это часто приводит к загрублению в обработке их аргументов и возвращаемых значений.
- качество написания проекта Если проект сам по себе написан достаточно хорошо, согласно известным канонам безопасных программ (как, например, notepad ++), то в процентном соотношении SSA находит достаточно большое количество false positives по отношению к числу хорошей диагностики. И это нормально - в коде, в котором нет ошибок, статический анализатор и не должен ничего находить. Однако необходимо избавляться от false positives - это одна из главных трудностей работы с SSA (подробнее про это см. в главе "Особенности работы с SSA").
Наибольший интерес представлял анализ notepad ++. Это приложение считается достаточно стабильным, и многие пользователи используют именно его, чтобы оценить качество работы статических анализаторов.
Особенности работы с SSA
Для эффективной работы с SSA необходимо учитывать некоторые особенности его работы.
Первая – это обилие false positive.
Рассмотрим следующий пример:
struct S {
const char* name;
int id;
};
S namedArray[] = {
{"one", 1},
{"two", 2},
{"three", 3},
{"four", 4},
{"five", 5},
{"six", 6},
};
#define nrKeys sizeof(namedArray)/sizeof(S)
int _tmain(int argc, _TCHAR* argv[])
{
int i;
bool flag = false;
for (i = 0; i < nrKeys; i++) {
if (namedArray[i].id == 2)
{
flag = true;
break;
}
}
if (flag == true)
namedArray[i].id = 3;
return 0;
}
SSA диагностика:
example.cpp(26): error #12049: buffer overflow: array index of "namedArray" is possibly outside the bounds; array "namedArray" of size (0:5) can be indexed by value 6
Однако переменная i никогда не будет равна 6, т.к. namedArray[i].id = 3; (line 26) выполнится только если flag = true. А Flag может стать равным true только в цикле, т.е. I всегда <6.
Алгоритмы статического анализа не всегда способны корректно анализировать зависимость хода исполнения программы от значений различных переменных. Особую трудность вызывает работа с массивами, так как анализ области значений каждого элемента массива в отдельности приводит к огромной ресурсоемкости алгортимов. Поэтому анализ в некоторых ситуациях приходится упрощать.
Еще один пример:
int f(int n)
{
int j, k, arr[2];
for (k = 0; k < 2; k++)
arr[k] = 0;
if (n != 0)
{
j = n;
arr[k - 1] = 1;
}
if (arr[k - 1] != 0)
{
printf("%d\n", j);
}
return 0;
}
SSA диагностика:
example.cpp(12): error #12144: "j" is possibly uninitialized
Однако же видно, что переменная j всегда будет инициализирована.
Некоторые конкурирующие продукты в этом случае предпочитают не выдавать вообще никакой диагностики, что может привести к замалчиванию о серьезных дефектах в приложениях. SSA во многих случаях информирует разработчика о возможной проблеме. Именно с этим связан несколько повышенный объем false-positive диагностики.
Однако сравнивая SSA со статическими анализаторами, предлагаемыми другими компаниями, на различных тестах, можно сделать вывод, что продукт Intel®Static Security Analyzer возвращает большее количество сообщений, чем аналогичные продукты. Основная часть диагностики является корректными утверждениями о программе, исправление которых остается на усмотрение разработчика.
Вторая особенность – это build specification file
Для того, чтобы провести анализ приложения необходимо построить build specification file, отвечающий за порядок анализа файлов проекта. Для этого используются специальные утилиты, поставляемые вместе с SSA. Для создания build specification file достаточно выполнить стандартное построение приложения из-под прилагаемой утилиты.
Если вы модифицируете свой проект, добавляя или удаляя какой-то файл, или изменяя опции компиляции – необходимо создать новый файл спецификации, иначе анализ может быть неполным или неправильным.
И третья особенность – message suppression и filtering.
В SSA предусмотрена возможность выбора диагностики для анализа. Для этого в продукте предусмотрено два механизма. Фильтрация(filtering) сообщений и подавление сообщений (suppression). Пользовтель SSA имеет возможность отфильтровать интересующие его сообщения по следующим признакам:
- severity - уровень важности сообщения
- problem - тип проблемы
- source - месторасположение проблемы в исходном коде программы
- state - статус диагностики
- investigated - смотреть только исследованные или неисследованные проблемы
Механизм подавления сообщений реализован с помощью статусов диагностики:
- Confirmed - отложить
- Fixed - проблема была исследована и исправлена
- Not a problem - программист не считает данную диагностику проблемой и не собирается исправлять
- Not fixed - проблема не была исправлена в предыдущем построении приложения
- Regression - проблема была неправильно исправлена в предыдущем построении приложения.
В итоге, процесс исследования диагностики следуюший:
- Смотрим на описание диагностики и местоположение проблемы в коде, вызвавшим эту диагностику.
- Если проблема не нуждается в исправлении, устанавливаем статус "Not a problem".
- Если проблема нуждается в исправлении, то:
- Если мы хотим исправить ее сейчас, то идем в код, исправляем и переводим статус в "Fixed".
- Если хотим исправить ее позже, переводим статус в "Confirmed".
- После нового построения приложения:
- "New" становится "Not fixed"
- Если диагностика со статусом "Fixed" по прежнему присутсвует в результатах анализа, то ее статус изменяется на "Regression" Диагностики помеченные статусами "Not a problem", Confirmed не меняют своего статуса
- При этом:
- New, Not fixed, Regression являются uninvestigated
- Not a problem, Confirmed, Fixed are investigated
Результаты стажировки
В результате мы создали около 300 новых тестов для SSA. Мы постарались максимально улучшить качество SSA, не только анализируя эффективность его работы, но и пользовательский интерфейс.
В результате своей стажировки я написала статью на английском языке, которая включила в себя:
- Описание преимуществ статического анализа
- Краткий руководство по SSA
- Трудности работы с SSA
- Сравнение работы SSA c другими продуктами на рынке на конкретном примере
Я думаю, что задача выполнена на 100%.
Я получила огромный опыт работы с open-source проектами при их скачивании и компиляции (с помощью cmake, scons, Mozilla build).
Познакомилась с различными продуктами верификации программ, основанными на алгоримах статического анализа.
Стала опытным пользователем SSA и увеличила свои знания об интеловском компиляторе, частью которого SSA и является. Углубила свои знания языков C/C++ и приобрела навыки написания безопасных программ.
Я познакомилась с языком Perl, написав несколько скриптов для обработки диагностики.
Улучшила свой письменный и устный английский.
Работе помогала поддержка команды, подробные разъяснения ментора и кипучая деятельность нашего менеджера.
Впечатления от Летней Школы Intel
Два месяца летней школы были настолько необычными и интересными, что я могу с уверенностью сказать – они перевернули мою жизнь. Международная IT-компания – это мир, со своими законами и правилами. Здесь все прислушиваются друг к другу, и всюду царит уважение. Бесплатный кофе повышает настроение, а атмосфера офиса дарит ощущение того, что ты – часть чего-то очень важного и значительного. Все это захватывает тебя и несет на своих волнах в увлекательный мир исследований и технологий. Кроме корпоративной жизни нас ждала интереснейшая образовательная часть. В результате я очень многое узнала о продуктах Intel.
После летней стажировки я уяснила для себя одно важное правило:
Не нужно бояться сделать на шаг больше, чем нужно.
Я очень рада, что смогла попасть в Летнюю Школу. Я благодарна всем организаторам, а особенно Николаю Куртову, директору школы в Новосибирске.
Пожалуйста, обратитесь к странице Уведомление об оптимизации для более подробной информации относительно производительности и оптимизации в программных продуктах компании Intel.
Комментарии (14) 
| 05.10.2010 06:05
arina-nsk | SSA - часть компилятора. Intel compiler делает анализ, а Inspector XE предоставляет GUI интерфейс для отображения результатов. |
| 05.10.2010 13:44
Василий
| А написанная статья на английском была опубликована? |
| 05.10.2010 21:08
arina-nsk | Статья будет опубликована, как только последняя версия parallel studio выйдет в свет. |
| 06.10.2010 04:33
Alx |
Арина, а разве во втором примере инициализация переменной j не зависит от значения n? Ведь если n будет равно 0, переменная j не будет проинициализирована. |
| 06.10.2010 09:43
cypok
|
Очень тяжело читать тем, кто знает что SSA — это Static Single Sssignment. Арина, а реально получить этот анализатор (как я понял из предыдущего ответа, часть компилятора) студентам по какой-либо бесплатной лицензии, или если я буду пользоваться им для разработки open-source продукта. Или основная аудитория продукта — это крупные компании? |
| 06.10.2010 21:31
arina-nsk |
Насколько я знаю, есть специальная образовательная программа Intel по работе с университетами. При заключении этого договора университет получает несколько лицензий бесплатно, а несколько оплачивает. Кроме того, можно всегда скачать бесплатную версию parallel studio на месяц. Более подробную информацию можно увидеть здесь: http://software.intel.com/ru-ru/articles/intel-software-evaluation-center/ и здесь: http://software.intel.com/en-us/articles/intel-academic-developer -program/ |
| 07.10.2010 04:02
arina-nsk |
Спасибо за вопрос, Alx, я недостаточно полно пояснила этот пример. В случае, когда n!=0, переменная j проинициализированна (line 9). При этом arr[k - 1] = 1 (line 10); Дальнейшее использование переменной j зависит уже не от n, а от arr[k - 1]. Если n == 0, то и arr[k - 1] = 0 (line 6) и j остается неинициализированной, но и обращения к ней не произойдет, т.к. не выполнится условие arr[k - 1] != 0 (line 12) Да, можно считать, что j в этом случае неинициализированна, но она не используется, следовательно это не приведет ни к каким плачевным результатам. И задача статического анализа - уберечь пользователя от такого рода сообщений, давая возможность уделить внимание более серьезной диагностике. |
| 11.10.2010 03:53
Evgeniy Ryzhkov
|
Арина, спасибо за статью. Как заинтересованное лицо имею вопросы: 1. Легенда на графиках имеет четыре пункта. В статье - пять. Куда подевались сообщения "+!"? 2.По легенде опять же не понятно. Собственно стопроцентные ошибки – это что (каким символом обозначено)? 3. "Static Security Analyzer – инструмент статического анализа для языков программирования С/С++ и FORTRAN, поддерживающий технологии OpenMP и Cilk". В рамках исследования инструмента тестирование диагностики OpenMP не проводилось (судя по тестовым проектам). 4. " Однако сравнивая SSA со статическими анализаторами, предлагаемыми другими компаниями, на различных тестах, можно сделать вывод, что продукт Intel®Static Security Analyzer возвращает большее количество сообщений, чем аналогичные продукты." Много диагностических сообщений – это хорошо или плохо? 5. Хотя бы намекните, с какими инструментами сравнивались. |
| 11.10.2010 08:07
arina-nsk |
Evgeniy, спасибо за ваш интерес к моей статье. Отвечу на все ваши вопросы по порядку:, 1. На графике "++" и "+!" объединены в одну группу - "++", т.к. при анализе сообщений SSA было важно количество корректной диагностики в целом (а "++" и "+!" являются корректными). Исправления в легенде по этому поводу были сделаны практически сразу после публикации статьи, но обновления, к сожалению, не произошло. 2. 100 - процентные ошибки - это синий цвет. Стоит помнить, что в терминах статического анализа "ошибка" - это именно "уязвимость кода". Это слабое место в коде, которое при определенном стечении обстоятельств, может привести к непоправимым последствиям. 3. В рамках летней школы нам было предложено анализировать проекты, написанные на C/C++, которые представляют наибольший интерес для основных пользователей. OpenMP и Cilk являются более специализированными технологиями и не входили в нашу область задач. 4. Много диагностических сообщений, тем более правильных, что видно на диаграммах - это очень хорошо. Это означает, что SSA делает достаточно эффективный анализ и в ширину, и в глубину. Далее выбор стоит за разработчиком - учитывать и исправлять каждую значимую и не особо значимую ошибку или нет (все-таки утечка памяти куда более серьезная ошибка, чем неиспользуемая в коде переменная). Как раз для фильтрации сообщений "по серьезности" и предусмотрен вес сообщения и другие фильтры, про которые я писала в статье. 5. К сожалению, на ваш последний вопрос я не могу ответить. Могу только сказать, что это известные и общепризнанные инструменты статического анализа. |
| 12.10.2010 04:09
arina-nsk | На основании лицензионных сооглашений и в силу субъективности оценок я не могу публиковать результаты сравнений с конкретными продуктами. Поэтому я лично сделала собирательный вывод. Именно поэтому я не конкретизирую, хорошо это или плохо, когда продукт выдает большее количество сообщений. Это решение существенно зависит от отношения пользователя к результатам диагностики и качеству программ. Одни пользователи исправляют практически 90% из того, что выдает SSA, другие предпочитают увидеть 5% наиболее важных проблем. |
| 17.10.2010 04:35
Vitaly Slobodskoy (Intel)
| Пожалуй, не соглашусь с тем, что приведённые примеры являются false-positives. С точки зрения поддержки этого кода подобные "временно корректные" решения могут создать ощутимые проблемы в будущем, когда другой человек изменит код (а для этих примеров это очень легко сделать), при котором действительно появится возможность для buffer overflow в первом случае и обращение к неинициализированной переменной во втором. Если SSA генерирует false positives лишь такого рода, то хвала этому продукту и скорейшее обязательное его использование повсеместно. |
| 18.10.2010 03:37
arina-nsk |
Конечно, false positives, случаются разного рода. Но в том и сложность объективно оценить работу SSA и сравнить ее с работой конкурентов - оценка диагностических сообщений любого статического анализатора очень субъективна и зависит от восприятия разработчика. |
Обратная ссылка (2)
-
Twitter Trackbacks for
Анализ безопасности программ с помощью Intel® Static Security Analyzer - Intel® Software Network
[intel.com]
on Topsy.com
05.10.2010 02:23 - Немного о лете или Как студенты проводят лето с пользой и с Интел – Блоги Intel® Software Network
11.10.2010 01:07




Василий
789