Комментарии 50
Не развеяли ("раз оправдываются — значит, есть что скрывать") :-)
И не думаю, что те, кто вас в чём-то обвиняет — тролли. Скорей просто не осознают масштабов человеческого эгоцентризма: они сосредоточены на своих (или нравящихся им) проектах, вы — на своём анализаторе (поэтому лично я не верю в вашу предвзятость: вам должно быть не до того… некогда гнобить чужие проекты, надо совершенствовать свой и хвастаться им), и вам с ними трудно друг друга понять.
Поэтому я решил написать небольшую статью, чтобы иметь возможность отвечать одной ссылкой.
Безо всякого стеба — неплохое решение!
А стоило бы сделать упор вот на что:
— Поскольку код проектов открыт, а триальная версия анализатора доступна, то любой скептик может провести собственный аудит кода, что не требует от аудитора выдающихся способностей или уймы времени.
— Даже если анализатор нашел множество ошибок (а чем больше проект, тем их должно быть больше), это еще не значит, что код плохой. Предупреждение может быть или ложным срабатыванием (коих ожидается гораздо больше, чем настоящих ошибок), или быть несущественным (ошибочный код или не выполняется почти никогда, или нивелируется поведением корректного кода). И наоборот, просто плохой стиль кода может быть абсолютно корректным с точки зрения как статического анализатора, так и самого рантайма (скажем, обфускация кода не меняет количество предупреждений).
— Не только физически невозможно, но и неинтересно проверять всех конкурентов проверенной программы, а уж тем более проводить сравнение по выявленным огрехам. А тем более каждый аудит оформлять в виде пухлой статьи.
— Проекты с закрытым кодом не могут быть проверены либо из-за недоступности исходников, либо из-за отсутствия права публиковать фрагменты кода. Поэтому статьи только об оперсорс проектах.
— Вор громче всех кричит о том, что у него что-то украли: голословные утверждения непроверяемы в силу человеческого фактора. Если уж абсолютно случайная последовательность нулей и единиц может выдать достаточно длинную очередь только нулей или единиц, это ли основание обвинять случайность в предвзятости? Точно так же предвзято относится обвиняющий в предвзятости, при этом ему совершенно необязательно быть троллем.
— Наконец, статьи тоже пишутся людьми. Есть неинтересные проекты, есть неудачно подобранные для статьи предупреждения, да и все что угодно может показаться негативом. Впрочем, все это проверяемо, и каждый может прогнать повторно Студию по коду — возможно, у него статья получится интереснее.
Поскольку код проектов открыт, а триальная версия анализатора доступна, то любой скептик может провести собственный аудит кода, что не требует от аудитора выдающихся способностей или уймы времениРазработчики проекта оказались вменяемыми и расторопными, пофиксив критичные баги. Ворох комментов «Вывсёврёти, проверял буквально через два месяца — такого количества багов нет»
Если проект качественный, то мы пишем, что не смогли найти ошибокЗдесь содержится логическая ошибка. Вы предвзято связываете качество проекта с возможностью нахождения ошибок вашим инструментом, но это не так. Невозможность найти ошибки статическим анализатором слишком мало говорит о качестве и наоборот, что, естественно, не отменяет пользы от использования анализатора.
Какое качество вы имеете в виду?
Думаю речь шла именно о качестве с точки зрения статического анализатора. Это следует из контекста статьи и вообще всего направления деятельности автора и его компании.
1. статическими анализаторами как раз и пользуются для нахождения ошибок, опечаток и пр., имея целью повышения качества кода (иначе зачем таковые вообще нужны)
2. плохо написанный код по определению должен содержать места, которые выявит статический анализатор — ожидается, что чем их меньше, тем код лучше
3. и наоборот, чтобы написать очень плохой код так, чтобы статический анализатор ничего не заметил, это нужно постараться.
Однако, утверждение не может быть полностью правдивым по следующим причинам:
1. как бы хорош ни был анализатор, но он по своей природе не может выявить достаточно большой класс ошибок — как, например, логические ошибки
2. все еще грустнее в мире языков с динамической и\или слабой типизацией, например, таких, как PHP или JS — на то он и статический.
3. даже хороший статический анализатор будет выдавать ложные предупреждения в тех местах, где код корректен, но анализатору что-то там не понравилось; и это не плохо — не будет лишним как минимум обратить внимание на подозрительный код, а как максимум — переписать его (если это возможно) так, чтобы не было предупреждения, а вместе с тем и меньше недоумения у людей, которые будут этот код читать.
Учитывая эти (достаточно очевидные) моменты, что-то я очень сомневаюсь, что есть серьезные проекты, на которые не ругнулся бы С.А., даже лидер класса, такой, как PVS-Studio.
Впрочем, ТС это можно, свое дитя всегда самое красивое )
Но на практике ошибки во всех проектах весьма однородны. Например, вот этот вид опечатки живёт везде. И вот эта проблема с нулевым указателем повсеместно. Итого, в среднем в проектах одни и те-же ошибки. Используется один и тот-же анализатор. Вывод: где мы нашли меньше ошибок при написании статьи, там и код лучше :). Всё честно.
P.S. Да, можно сказать, что мы почти не ищем, например, ошибки синхронизации. А качество проекта зависит от этого сильно. Однако, на практике, там где путают free с delete и сравниваю на равенство переменные (a==b==c==d), то скорее всего там и с синхронизацией всё будет плохо.
Повторюсь, если статический анализ выявляет подозрительное место, пусть и правильное — но это же место может еще привести к другим ошибкам. Даже если все эти i+++++i понятны автору, то сторонний программист вполне вероятно тут споткнется.
Потому нужны и статические анализаторы, и код-ревью, и тестирование и однообразный стиль кода.
Вывод: где мы нашли меньше ошибок при написании статьи, там и код лучше :). Всё честно.Давайте как пример рассмотрим NGINX, который Вы привели как пример качественного проекта, свидетельством чему было невыявление ошибок стат. анализом в 2014.
В 2017 вышла новость об устранении в нём уязвимости.
Я обратил внимание на то, как уязвимость была устранена:
+ if (size > NGX_MAX_OFF_T_VALUE - (end - start)) {
+ return NGX_HTTP_RANGE_NOT_SATISFIABLE;
+ }
+
size += end - start;
Это было устранение возможного переполнения. Я решил проверить как выводятся start и end, ведь переполнения во время арифметических действий для проверки возможности переполнения других арифметических действий для меня не являются новостью.
Я увидел следующую картину:
while (*p >= '0' && *p <= '9') {
if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) {
return NGX_HTTP_RANGE_NOT_SATISFIABLE;
}
start = start * 10 + *p++ - '0';
}
Проверка с выходом из функции должна была предотвращать возможное переполнение целого со знаком start, но вместо такого сложения
start = start * 10 + (*p++ - '0');
было сделано такое start = (start * 10 + *p++) - '0';
Что приводит к возможности переполнения левой части, а учитывая знаковость start, это является неопределённым поведением, что не даёт гарантию компенсации последующим вычитанием '0'. Тогда я даже смог добиться некорректного поведения при компиляции похожего куска кода с помощью gcc с оптимизацией.Это всё ставило под удар конечное утверждение об исправлении уязвимости, так как эта цепочка при определённых обстоятельствах могла привести к некорректности проверки.
Я сообщил о своей находке и через некоторое проблема была исправлена. Это было отрадно, но сама заплатка снова дала повод задуматься. Подобный функционал был разбросан по множеству перегруженных кодом функций. Эти куски не могли быть обобщены в одну функцию, которая могла быть подвергнута тщательному осмотру и тестированию из-за обилия неструктурного кода, мешающего провести декомпозицию. При таком подходе к написанию кода остаётся только гадать, сколько похожего кода было не затронуто исправлением, так как его трудней выявить. Более того, я обнаружил ещё недостатки, но уже утратил желание в этом участвовать — это стало походить на бесконечную историю.
А теперь вопросы:
- Способен ли подобные ошибки находить анализатор?
- Насколько качественный код NGINX?
- Насколько верно утверждение про связь невыявления ошибок стат.анализом и качеством?
NGINX это качественный код? Да. И наш анализ это подтверждает.
Может в нём быть уязвимость? Да, может. И Ваш анализ это подтверждает.
Здесь нет противоречия. Всё дело в том, что NGINX это очень важный проект и его ОЧЕНЬ внимательно исследуют. И вполне естественно, что-то находят критические ошибки.
Однако, если подвернуть СТОЛЬ ЖЕ ТЩАТЕЛЬНОМУ анализу проект, который мы оценили невысоко, то там будет мрак и ужас с точки зрения безопасности. Просто такой анализ никто не будет делать, так как это не имеет практического смысла. Уязвимости в «калькуляторе» никому не интересны.
В большинстве проектов подобное даже править не будут, потому что настоящих, проявляющихся в реальном мире, ошибок полно.
Это практическая ошибка, проявляющаяся на gcc.Извините, но нет. Пока ошибки нет в бинарнике — это всё теория. «Похожий код», «если сменить настройки» — это всё теория.
Если ошибка есть в бинарнике — то это один уровень срочности, понятно, что нужно выпускать новую версию.
Если ошибка в исходнике, но в скомпилированном бинарнике её нет — то это принципиально другой уровень опасноcти.
И показатель качества — это только качество кода, а не реакция на уведомления.Показатель качество — это, в некотором смысле количество «сферических CVE» (количнество CVE при условии, что все ошибки, заслуживающие статуса CVE таковой получают)
Судя по вашему описанию проблема, которую вы нашли не породила (и, главное, не могла породить) ни одного CVE.
Реакция — это, всё же, о другомРеакция — это о том, есть ли у разработчиков ресурсы на то, чтобы реагировать не только на реальные CVE, но и на CWE и более слабые сигналы. Куда, увы и ах, относится и ваш пример…
Зачем вам вместо банального objdump'а потребовался «похожий кусок кода», если и на оригинальном всё воспроизводилось?
Тут Andrey2008 постоянно борется с таким пренебрежительным отношением к ошибкам, но оно, очевидно, неискоренимо даже в среде ценителей.
Может быть наоборот стоить тестировать игру а не ОС. Многие разрабатывают игры (больше потенциальных клиентов) но не многие разрабатывают ОС.
Конечно же, это не так. В «целом» ничего похожего на методологию не популяризуется, нет сравнений с другими решениями анализа. Вообще, про «методологию» не так много информации, чтобы можно было сравнить с другими методологиями.
В 99% показываете результат анализа, описание некоторых правил анализа, но полную методологию скрываете.
В этом ничего плохого, ноу-хай и все такое, но не стоит лукавить, что вы популяризируете методологию.
Методология статического анализа кода: запускаем регулярно какой-то статический анализатор, находим ошибки на ранних этапах, исправляем. Profit. Эту методологию мы и популяризуем.
Быть может Вы путаете методологию и реализацию? Вот в случаях обсуждения реализации можно говорить о сравнении с другими решениями и о отсутствии описания в наших статях деталей этой самой реализации.
(собираюсь один из этих языков изучить)
Для Раста уже есть анализатор (clippy), да и сам язык такой, что накосячить в разы сложнее, чем в С
apt install pvsstudio
E: Unable to locate package pvsstudio
Я понимаю, что у вас есть Глубокие Причины, почему вас нет в списке пакетов, но… всё равно неудобно.
Команда PVS-Studio непредвзята при написании статей