SlideShare a Scribd company logo
1 of 49
Выявление ошибок и
потенциальных уязвимостей
в C и C++ коде с помощью
анализатора PVS-Studio
Андрей Карпов, CTO
www.viva64.com
karpov@viva64.com
Для разминки несколько интересных
ошибок, которые сложно найти
2
Ошибка в проекте StarEngine
PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header,
uintptr_t header_mask, int value)
{
char buf[128];
sprintf(buf, "%d", value);
return set_value_buffer(dest, header, header_mask, buf);
}
3
PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362
Ошибка в проекте StarEngine
#define sfstream std::fstream
#define schar char
#define suchar unsigned schar
#define sprintf std::printf
#define satof atof
#define satoi atoi
PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header,
uintptr_t header_mask, int value)
{
char buf[128];
sprintf(buf, "%d", value);
return set_value_buffer(dest, header, header_mask, buf);
}
PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362
4
Ошибка в проекте
Multi-threaded Dynamic Queue
5
COleDataSource* CGridCtrl::CopyTextFromGrid()
{
....
for (int row = Selection.GetMinRow();
row <= Selection.GetMaxRow(); row++)
{
....
sf.Write(T2A(str.GetBuffer(1)), str.GetLength());
....
}
....
}
6
#define W2A(lpw) (
((_lpw = lpw) == NULL) ? NULL : (
(_convert = (static_cast<int>(wcslen(_lpw))+1), 
(_convert>INT_MAX/2) ? NULL : 
ATLW2AHELPER((LPSTR) alloca(_convert*sizeof(WCHAR)), 
_lpw, _convert*sizeof(WCHAR), _acp))))
#define T2A W2A
Ошибка в проекте
Multi-threaded Dynamic Queue
PVS-Studio: V505 The 'alloca' function is used
inside the loop. This can quickly overflow
stack. GridCtrl gridctrl.cpp 2332
7
COleDataSource* CGridCtrl::CopyTextFromGrid()
{
....
for (int row = Selection.GetMinRow();
row <= Selection.GetMaxRow(); row++)
{
....
sf.Write(T2A(str.GetBuffer(1)), str.GetLength());
....
}
....
}
Ошибка в проекте
Network Security Services (NSS)
8
SECStatus
SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
SHA512Context ctx;
unsigned int outLen;
SHA384_Begin(&ctx);
SHA512_Update(&ctx, src, src_length);
SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
memset(&ctx, 0, sizeof ctx);
return SECSuccess;
}
Ошибка в проекте
Network Security Services (NSS)
9
SECStatus
SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
SHA512Context ctx;
unsigned int outLen;
SHA384_Begin(&ctx);
SHA512_Update(&ctx, src, src_length);
SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
memset(&ctx, 0, sizeof ctx);
return SECSuccess;
} PVS-Studio: V597 CWE-14 The compiler could delete the
'memset' function call, which is used to flush 'ctx' object.
The RtlSecureZeroMemory() function should be used to
erase the private data. sha512.c 1423
char c;
printf("%s is already in *.base_fs format, just copying ....);
rewind(blk_alloc_file);
while ((c = fgetc(blk_alloc_file)) != EOF) {
fputc(c, base_fs_file);
}
10
Ошибка в проекте Android
char c;
printf("%s is already in *.base_fs format, just copying ....);
rewind(blk_alloc_file);
while ((c = fgetc(blk_alloc_file)) != EOF) {
fputc(c, base_fs_file);
}
PVS-Studio: V739 CWE-20 EOF should not be compared with a value of the 'char' type. The
'(c = fgetc(blk_alloc_file))' should be of the 'int' type. blk_alloc_to_base_fs.c 61
11
Ошибка в проекте Android
Обзоры кода – это замечательно, но их
стало недостаточно
• MS DOS 1.0 : 4 000 строк кода
• Ядро Linux 1.0.0 : 176 250 строк кода
• Ядро Linux 4.11.7 в 100 раз больше: 18 373 471 строк
кода
• Photoshop 1.0 : 128 000 строк кода
• Photoshop CS 6 : 10 000 000 строк кода
12
У статических анализаторов в прошлом
подпорчена репутация
• RATS, Cppcheck
• MISRA C, MISRA C++
13
Заглянем внутрь PVS-Studio
14
Вывод типов (type inference)
• Информации о типах нужна для реализации большинства
диагностик
• Нужно уметь выводить типы из цепочки typedef
• Нужно уметь подставлять типы (и константы) для анализа
шаблонов
typedef
15
Вывод типов (type inference)
template<class T, size_t N> struct X
{
T A[N];
void Foo()
{
memset(A, 0, sizeof(T) * 10);
}
};
16
Вывод типов (type inference)
template<class T, size_t N> struct X
{
T A[N];
void Foo()
{
memset(A, 0, sizeof(T) * 10);
}
};
void Do()
{
X<int, 5> a;
a.Foo();
}
PVS-Studio: V512 CWE-119 Instantiate X < int, 5 >: A call of
the 'memset' function will lead to overflow of the buffer
'A'. test.cpp 127
17
Анализ потока данных (data-flow analysis)
int cache_lookup_path(...., vnode_t dp, ....)
{
....
if (dp && (dp->v_flag & VISHARDLINK)) {
break;
}
if ((dp->v_flag & VROOT) ||
dp == ndp->ni_rootdir ||
dp->v_parent == NULLVP)
break;
....
}
Ошибка в проекте
XNU kernel
PVS-Studio: V522 CWE-690 There might be dereferencing of a
potential null pointer 'dp'. vfs_cache.c 1449
18
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
} 19
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
} 20
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
} 21
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
} time.day
Ошибка в проекте
protobuf
(Chromium)
22
Анализ потока данных (data-flow analysis)
• CoreHard Spring 2018. Павел Беликов. Как работает анализ Data
Flow в статическом анализаторе кода
https://youtu.be/nrQUpGM9vYQ
23
Символьное выполнение (symbolic execution)
void F(int X)
{
int A = X;
int B = X + 10;
int Q[5];
Q[B - A] = 1;
}
PVS-Studio: V557 CWE-787 Array overrun is possible. The 'B - A' index is pointing
beyond array bound. test.cpp 126
24
Символьное выполнение (symbolic execution)
PVS-Studio: V547 CWE-571 Expression 'A < C' is always true. test.cpp 137
void F(int A, int B, int C)
{
if (A < B)
if (B < C)
if (A < C)
foo();
}
25
Сопоставление с шаблоном
(pattern-based analysis)
Ошибка в Linux Kernel
static ssize_t lp8788_show_eoc_time(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lp8788_charger *pchg = dev_get_drvdata(dev);
char *stime[] = { "400ms", "5min", "10min", "15min",
"20min", "25min", "30min" "No timeout" };
....
}
PVS-Studio: V653 A suspicious string consisting of two parts is used for
array initialization. It is possible that a comma is missing. Consider
inspecting this literal: "30min" "No timeout". lp8788-charger.c 657
26
Сопоставление с шаблоном
(pattern-based analysis)
Ошибка в проекте
WebRTC
void AsyncSocksProxySocket::SendAuth() {
....
char * sensitive = new char[len];
pass_.CopyTo(sensitive, true);
request.WriteString(sensitive); // Password
memset(sensitive, 0, len);
delete [] sensitive;
DirectSend(request.Data(), request.Length());
state_ = SS_AUTH;
}
PVS-Studio: V597 CWE-14 The compiler could delete the 'memset' function
call, which is used to flush 'sensitive' object. The RtlSecureZeroMemory()
function should be used to erase the private data. socketadapters.cc 677 27
Аннотирование методов (method annotations)
Любая достаточно развитая технология
неотличима от магии.
(c) Артур Кларк
28
Аннотирование методов (method annotations)
• Статический анализ – это не магия, а большая работа
• Например, в PVS-Studio размечено 7140 функций (C и C++)
29
Аннотирование методов (method annotations)
• WinAPI
• стандартная библиотека C
• стандартная библиотека шаблонов (STL)
• glibc (GNU C Library)
• Qt
• MFC
• zlib
• libpng
• OpenSSL
• и так далее
30
31
Пример аннотирования функции fread
C_"size_t fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);"
C_"size_t std::fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);"
ADD(HAVE_STATE | RET_SKIP | F_MODIFY_PTR_1, nullptr, nullptr, "fread",
POINTER_1, BYTE_COUNT, COUNT, POINTER_2).
Add_Read(from_2_3, to_return, buf_1).Add_DataSafetyStatusRelations(0, 3);
ADD(HAVE_STATE | RET_SKIP | F_MODIFY_PTR_1, "std", nullptr, "fread",
POINTER_1, BYTE_COUNT, COUNT, POINTER_2).
Add_Read(from_2_3, to_return, buf_1).Add_DataSafetyStatusRelations(0, 3);
32
Пример аннотирования функции fread
define MAX_AVISYNTH_SCRIPT_LENGTH 16384
void TavisynthPage::onLoad(void)
{
....
char script[MAX_AVISYNTH_SCRIPT_LENGTH];
size_t len = fread(script, 1, MAX_AVISYNTH_SCRIPT_LENGTH, f);
fclose(f);
script[len] = '0';
....
}
Ошибка в проекте
ffdshow
33
Пример аннотирования функции fread
define MAX_AVISYNTH_SCRIPT_LENGTH 16384
void TavisynthPage::onLoad(void)
{
....
char script[MAX_AVISYNTH_SCRIPT_LENGTH];
size_t len = fread(script, 1, MAX_AVISYNTH_SCRIPT_LENGTH, f);
fclose(f);
script[len] = '0';
....
}
Ошибка в проекте
ffdshow
PVS-Studio: V557 Array overrun is possible. The value of 'len' index
could reach 16384. cavisynth.cpp 129
34
Автоматическое аннотирование функций
inline uint32_t bswap32(uint32_t pData) {
return
(((pData & 0xFF000000) >> 24) | ((pData & 0x00FF0000) >> 8) |
((pData & 0x0000FF00) << 8) | ((pData & 0x000000FF) << 24));
}
Ошибка в проекте Android
35
Автоматическое аннотирование функций
Ошибка в проекте Android
bool ELFAttribute::merge(....) {
....
uint32_t subsection_length =
*reinterpret_cast<const uint32_t*>(subsection_data);
if (llvm::sys::IsLittleEndianHost !=
m_Config.targets().isLittleEndian())
bswap32(subsection_length);
....
}
PVS-Studio: V530 CWE-252 The return value of function 'bswap32' is required to be
utilized. ELFAttribute.cpp 84
36
Смесь технологий
int Div(int X)
{
return 10 / X;
}
void Foo()
{
for (int i = 0; i < 5; ++i)
Div(i);
}
PVS-Studio: V609 CWE-628 Divide by zero. Denominator 'X' == 0.
The 'Div' function processes value '[0..4]'. Inspect the first
argument. Check lines: 106, 110. test.cpp 106
Автоматическое аннотирование
+
Анализ потока управления
37
Время поговорить про уязвимости
38
Ошибка Уязвимость
Термин SAST
• SAST
• Static Application Security Testing
• Статическое тестирование защищённости приложений
39
Две разновидности SAST
• Поиск известных CVE
• Профилактика новых CVE
40
Common Weakness Enumeration (CWE)
41
Поиск потенциальных уязвимостей
• Классические диагностики
• V1010 - Диагностика поможет выявлять потенциальные
уязвимости, которые можно классифицировать как CWE-20:
Improper Input Validation
42
43
CVE-2014-1266static OSStatus
SSLVerifySignedServerKeyExchange(.....)
{
OSStatus err;
....
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
....
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
44
CVE-2014-1266static OSStatus
SSLVerifySignedServerKeyExchange(.....)
{
OSStatus err;
....
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
....
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
• V640 / CWE-483 The code's operational logic does not
correspond with its formatting. The statement is
indented to the right, but it is always executed. It is
possible that curly brackets are missing.
• V779 / CWE-561 Unreachable code detected. It is
possible that an error is present
45
CVE-2012-2122
typedef char my_bool;
my_bool
check_scramble(const char *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
....
return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}
46
CVE-2012-2122
V642 Saving the 'memcmp' function result inside the 'char' type variable is inappropriate.
The significant bits could be lost breaking the program's logic. password.c
typedef char my_bool;
my_bool
check_scramble(const char *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
....
return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}
47
Заключение
• Анализаторы сейчас и 10 лет назад – это две большие разницы
• Внедрение статического анализа неизбежно из-за роста размеров
и сложности проектов
• Анализаторы помогут выявить многие потенциальные
уязвимости и ошибки на самом раннем этапе
• Попробуйте PVS-Studio
48
Приглашаю к обсуждению
Андрей Карпов, CTO
E-Mail: karpov@viva64.com
49

More Related Content

What's hot

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Mikhail Matrosov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работуcorehard_by
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2Eugeniy Tyumentcev
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...solit
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в DjangoMoscowDjango
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2PyNSK
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка DjangoVladimir Rudnyh
 
Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1PyNSK
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о BoostSergey Platonov
 
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»Yandex
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...Ontico
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияcorehard_by
 

What's hot (20)

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работу
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
 
Progr labrab-4-2013-c++
Progr labrab-4-2013-c++Progr labrab-4-2013-c++
Progr labrab-4-2013-c++
 
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2Нейронные сети и Keras. Часть 2
Нейронные сети и Keras. Часть 2
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка Django
 
Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1Нейронные сети и Keras. Часть 1
Нейронные сети и Keras. Часть 1
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Coroutines
CoroutinesCoroutines
Coroutines
 
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюдения
 

Similar to Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализатора PVS-Studio

Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Andrey Karpov
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутAndrey Karpov
 
Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?Andrey Karpov
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Tatyanazaxarova
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Googleyaevents
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteTatyanazaxarova
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеAndrey Karpov
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья СтусьПолный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья СтусьMail.ru Group
 
Статический анализ как ответ на вопрос о повышении качества кода
Статический анализ как ответ на вопрос о повышении качества кодаСтатический анализ как ответ на вопрос о повышении качества кода
Статический анализ как ответ на вопрос о повышении качества кодаAndrey Karpov
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаAndrey Karpov
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Mikhail Kurnosov
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времениTatyanazaxarova
 
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)Ontico
 

Similar to Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализатора PVS-Studio (20)

Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минут
 
Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?Статический анализ: ищем ошибки... и уязвимости?
Статический анализ: ищем ошибки... и уязвимости?
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в коде
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья СтусьПолный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
 
Статический анализ как ответ на вопрос о повышении качества кода
Статический анализ как ответ на вопрос о повышении качества кодаСтатический анализ как ответ на вопрос о повышении качества кода
Статический анализ как ответ на вопрос о повышении качества кода
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программиста
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 
Вечный вопрос измерения времени
Вечный вопрос измерения времениВечный вопрос измерения времени
Вечный вопрос измерения времени
 
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
 

More from Andrey Karpov

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программистаAndrey Karpov
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developerAndrey Karpov
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Andrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewAndrey Karpov
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Andrey Karpov
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?Andrey Karpov
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaAndrey Karpov
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)Andrey Karpov
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Andrey Karpov
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareAndrey Karpov
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineAndrey Karpov
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsAndrey Karpov
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++Andrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youAndrey Karpov
 

More from Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализатора PVS-Studio

  • 1. Выявление ошибок и потенциальных уязвимостей в C и C++ коде с помощью анализатора PVS-Studio Андрей Карпов, CTO www.viva64.com karpov@viva64.com
  • 2. Для разминки несколько интересных ошибок, которые сложно найти 2
  • 3. Ошибка в проекте StarEngine PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; sprintf(buf, "%d", value); return set_value_buffer(dest, header, header_mask, buf); } 3 PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362
  • 4. Ошибка в проекте StarEngine #define sfstream std::fstream #define schar char #define suchar unsigned schar #define sprintf std::printf #define satof atof #define satoi atoi PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; sprintf(buf, "%d", value); return set_value_buffer(dest, header, header_mask, buf); } PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362 4
  • 5. Ошибка в проекте Multi-threaded Dynamic Queue 5 COleDataSource* CGridCtrl::CopyTextFromGrid() { .... for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++) { .... sf.Write(T2A(str.GetBuffer(1)), str.GetLength()); .... } .... }
  • 6. 6 #define W2A(lpw) ( ((_lpw = lpw) == NULL) ? NULL : ( (_convert = (static_cast<int>(wcslen(_lpw))+1), (_convert>INT_MAX/2) ? NULL : ATLW2AHELPER((LPSTR) alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp)))) #define T2A W2A
  • 7. Ошибка в проекте Multi-threaded Dynamic Queue PVS-Studio: V505 The 'alloca' function is used inside the loop. This can quickly overflow stack. GridCtrl gridctrl.cpp 2332 7 COleDataSource* CGridCtrl::CopyTextFromGrid() { .... for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++) { .... sf.Write(T2A(str.GetBuffer(1)), str.GetLength()); .... } .... }
  • 8. Ошибка в проекте Network Security Services (NSS) 8 SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) { SHA512Context ctx; unsigned int outLen; SHA384_Begin(&ctx); SHA512_Update(&ctx, src, src_length); SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); memset(&ctx, 0, sizeof ctx); return SECSuccess; }
  • 9. Ошибка в проекте Network Security Services (NSS) 9 SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) { SHA512Context ctx; unsigned int outLen; SHA384_Begin(&ctx); SHA512_Update(&ctx, src, src_length); SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); memset(&ctx, 0, sizeof ctx); return SECSuccess; } PVS-Studio: V597 CWE-14 The compiler could delete the 'memset' function call, which is used to flush 'ctx' object. The RtlSecureZeroMemory() function should be used to erase the private data. sha512.c 1423
  • 10. char c; printf("%s is already in *.base_fs format, just copying ....); rewind(blk_alloc_file); while ((c = fgetc(blk_alloc_file)) != EOF) { fputc(c, base_fs_file); } 10 Ошибка в проекте Android
  • 11. char c; printf("%s is already in *.base_fs format, just copying ....); rewind(blk_alloc_file); while ((c = fgetc(blk_alloc_file)) != EOF) { fputc(c, base_fs_file); } PVS-Studio: V739 CWE-20 EOF should not be compared with a value of the 'char' type. The '(c = fgetc(blk_alloc_file))' should be of the 'int' type. blk_alloc_to_base_fs.c 61 11 Ошибка в проекте Android
  • 12. Обзоры кода – это замечательно, но их стало недостаточно • MS DOS 1.0 : 4 000 строк кода • Ядро Linux 1.0.0 : 176 250 строк кода • Ядро Linux 4.11.7 в 100 раз больше: 18 373 471 строк кода • Photoshop 1.0 : 128 000 строк кода • Photoshop CS 6 : 10 000 000 строк кода 12
  • 13. У статических анализаторов в прошлом подпорчена репутация • RATS, Cppcheck • MISRA C, MISRA C++ 13
  • 15. Вывод типов (type inference) • Информации о типах нужна для реализации большинства диагностик • Нужно уметь выводить типы из цепочки typedef • Нужно уметь подставлять типы (и константы) для анализа шаблонов typedef 15
  • 16. Вывод типов (type inference) template<class T, size_t N> struct X { T A[N]; void Foo() { memset(A, 0, sizeof(T) * 10); } }; 16
  • 17. Вывод типов (type inference) template<class T, size_t N> struct X { T A[N]; void Foo() { memset(A, 0, sizeof(T) * 10); } }; void Do() { X<int, 5> a; a.Foo(); } PVS-Studio: V512 CWE-119 Instantiate X < int, 5 >: A call of the 'memset' function will lead to overflow of the buffer 'A'. test.cpp 127 17
  • 18. Анализ потока данных (data-flow analysis) int cache_lookup_path(...., vnode_t dp, ....) { .... if (dp && (dp->v_flag & VISHARDLINK)) { break; } if ((dp->v_flag & VROOT) || dp == ndp->ni_rootdir || dp->v_parent == NULLVP) break; .... } Ошибка в проекте XNU kernel PVS-Studio: V522 CWE-690 There might be dereferencing of a potential null pointer 'dp'. vfs_cache.c 1449 18
  • 19. static const int kDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } } 19
  • 20. static const int kDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } } 20
  • 21. static const int kDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } } 21
  • 22. static const int kDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } } time.day Ошибка в проекте protobuf (Chromium) 22
  • 23. Анализ потока данных (data-flow analysis) • CoreHard Spring 2018. Павел Беликов. Как работает анализ Data Flow в статическом анализаторе кода https://youtu.be/nrQUpGM9vYQ 23
  • 24. Символьное выполнение (symbolic execution) void F(int X) { int A = X; int B = X + 10; int Q[5]; Q[B - A] = 1; } PVS-Studio: V557 CWE-787 Array overrun is possible. The 'B - A' index is pointing beyond array bound. test.cpp 126 24
  • 25. Символьное выполнение (symbolic execution) PVS-Studio: V547 CWE-571 Expression 'A < C' is always true. test.cpp 137 void F(int A, int B, int C) { if (A < B) if (B < C) if (A < C) foo(); } 25
  • 26. Сопоставление с шаблоном (pattern-based analysis) Ошибка в Linux Kernel static ssize_t lp8788_show_eoc_time(struct device *dev, struct device_attribute *attr, char *buf) { struct lp8788_charger *pchg = dev_get_drvdata(dev); char *stime[] = { "400ms", "5min", "10min", "15min", "20min", "25min", "30min" "No timeout" }; .... } PVS-Studio: V653 A suspicious string consisting of two parts is used for array initialization. It is possible that a comma is missing. Consider inspecting this literal: "30min" "No timeout". lp8788-charger.c 657 26
  • 27. Сопоставление с шаблоном (pattern-based analysis) Ошибка в проекте WebRTC void AsyncSocksProxySocket::SendAuth() { .... char * sensitive = new char[len]; pass_.CopyTo(sensitive, true); request.WriteString(sensitive); // Password memset(sensitive, 0, len); delete [] sensitive; DirectSend(request.Data(), request.Length()); state_ = SS_AUTH; } PVS-Studio: V597 CWE-14 The compiler could delete the 'memset' function call, which is used to flush 'sensitive' object. The RtlSecureZeroMemory() function should be used to erase the private data. socketadapters.cc 677 27
  • 28. Аннотирование методов (method annotations) Любая достаточно развитая технология неотличима от магии. (c) Артур Кларк 28
  • 29. Аннотирование методов (method annotations) • Статический анализ – это не магия, а большая работа • Например, в PVS-Studio размечено 7140 функций (C и C++) 29
  • 30. Аннотирование методов (method annotations) • WinAPI • стандартная библиотека C • стандартная библиотека шаблонов (STL) • glibc (GNU C Library) • Qt • MFC • zlib • libpng • OpenSSL • и так далее 30
  • 31. 31
  • 32. Пример аннотирования функции fread C_"size_t fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);" C_"size_t std::fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);" ADD(HAVE_STATE | RET_SKIP | F_MODIFY_PTR_1, nullptr, nullptr, "fread", POINTER_1, BYTE_COUNT, COUNT, POINTER_2). Add_Read(from_2_3, to_return, buf_1).Add_DataSafetyStatusRelations(0, 3); ADD(HAVE_STATE | RET_SKIP | F_MODIFY_PTR_1, "std", nullptr, "fread", POINTER_1, BYTE_COUNT, COUNT, POINTER_2). Add_Read(from_2_3, to_return, buf_1).Add_DataSafetyStatusRelations(0, 3); 32
  • 33. Пример аннотирования функции fread define MAX_AVISYNTH_SCRIPT_LENGTH 16384 void TavisynthPage::onLoad(void) { .... char script[MAX_AVISYNTH_SCRIPT_LENGTH]; size_t len = fread(script, 1, MAX_AVISYNTH_SCRIPT_LENGTH, f); fclose(f); script[len] = '0'; .... } Ошибка в проекте ffdshow 33
  • 34. Пример аннотирования функции fread define MAX_AVISYNTH_SCRIPT_LENGTH 16384 void TavisynthPage::onLoad(void) { .... char script[MAX_AVISYNTH_SCRIPT_LENGTH]; size_t len = fread(script, 1, MAX_AVISYNTH_SCRIPT_LENGTH, f); fclose(f); script[len] = '0'; .... } Ошибка в проекте ffdshow PVS-Studio: V557 Array overrun is possible. The value of 'len' index could reach 16384. cavisynth.cpp 129 34
  • 35. Автоматическое аннотирование функций inline uint32_t bswap32(uint32_t pData) { return (((pData & 0xFF000000) >> 24) | ((pData & 0x00FF0000) >> 8) | ((pData & 0x0000FF00) << 8) | ((pData & 0x000000FF) << 24)); } Ошибка в проекте Android 35
  • 36. Автоматическое аннотирование функций Ошибка в проекте Android bool ELFAttribute::merge(....) { .... uint32_t subsection_length = *reinterpret_cast<const uint32_t*>(subsection_data); if (llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) bswap32(subsection_length); .... } PVS-Studio: V530 CWE-252 The return value of function 'bswap32' is required to be utilized. ELFAttribute.cpp 84 36
  • 37. Смесь технологий int Div(int X) { return 10 / X; } void Foo() { for (int i = 0; i < 5; ++i) Div(i); } PVS-Studio: V609 CWE-628 Divide by zero. Denominator 'X' == 0. The 'Div' function processes value '[0..4]'. Inspect the first argument. Check lines: 106, 110. test.cpp 106 Автоматическое аннотирование + Анализ потока управления 37
  • 38. Время поговорить про уязвимости 38 Ошибка Уязвимость
  • 39. Термин SAST • SAST • Static Application Security Testing • Статическое тестирование защищённости приложений 39
  • 40. Две разновидности SAST • Поиск известных CVE • Профилактика новых CVE 40
  • 42. Поиск потенциальных уязвимостей • Классические диагностики • V1010 - Диагностика поможет выявлять потенциальные уязвимости, которые можно классифицировать как CWE-20: Improper Input Validation 42
  • 43. 43
  • 44. CVE-2014-1266static OSStatus SSLVerifySignedServerKeyExchange(.....) { OSStatus err; .... if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; .... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; } 44
  • 45. CVE-2014-1266static OSStatus SSLVerifySignedServerKeyExchange(.....) { OSStatus err; .... if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; .... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; } • V640 / CWE-483 The code's operational logic does not correspond with its formatting. The statement is indented to the right, but it is always executed. It is possible that curly brackets are missing. • V779 / CWE-561 Unreachable code detected. It is possible that an error is present 45
  • 46. CVE-2012-2122 typedef char my_bool; my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { .... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); } 46
  • 47. CVE-2012-2122 V642 Saving the 'memcmp' function result inside the 'char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. password.c typedef char my_bool; my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { .... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); } 47
  • 48. Заключение • Анализаторы сейчас и 10 лет назад – это две большие разницы • Внедрение статического анализа неизбежно из-за роста размеров и сложности проектов • Анализаторы помогут выявить многие потенциальные уязвимости и ошибки на самом раннем этапе • Попробуйте PVS-Studio 48
  • 49. Приглашаю к обсуждению Андрей Карпов, CTO E-Mail: karpov@viva64.com 49