C语言标准未定义负数左移操作
CVE-2016-9840 CVE-2016-9841 CVE-2016-9843C语言标准未定义指针减法导致越界的情况
验证代码#include输出#include #include #include // c标准未定义负数左移操作 void test_CVE_2016_9842() { int nag = -10; unsigned pos = 10; int ret_nag = nag << 5; int ret_nag2 = (int)((unsigned)nag << 5); int ret_pos = -(pos << 5); if (ret_nag != ret_nag2 || ret_nag != ret_pos) { printf("CVE_2016_9842 recurrencen"); } else { printf("CVE_2016_9842 no recurrencen"); } } // c标准未定义指针减法导致越界的情况 void test_CVE_2016_9840_9841_9843() { srand(time(NULL)); // 1.数组 char arr[100] = {0}; for (size_t i = 0; i < 100; ++i) { arr[i] = rand() % 256; } char* point_arr = arr; point_arr--; bool flag = false; for (size_t i = 0; i < 100; ++i) { if (*++point_arr != arr[i]) { flag = true; break; } } if (flag) { printf("CVE_2016_9840_9841_9843 array recurrencen"); } else { printf("CVE_2016_9840_9841_9843 array no recurrencen"); } // 2.指针 size_t len = 10000; char* p = (char*)malloc(len); for (size_t i = 0; i < len; ++i) { p[i] = rand() % 256; } // 测试指针减法导致越界情况 char* q = p; char* start = p; p--; flag = false; for (size_t i = 0; i < len; ++i) { if (*++p != *q++) { flag = true; break; } } if (flag) { printf("CVE_2016_9840_9841_9843 point recurrencen"); } else { printf("CVE_2016_9840_9841_9843 point no recurrencen"); } // 测试预增指针后再访问是否效率更高 char c; char* p1 = start; p1--; char* p2 = start; int count = 1000000; char* p11; char* p22; time_t t1 = time(NULL); for (size_t i = 0; i < count; ++i) { p22 = p2; for (size_t j = 0; j < len; ++j) { c = *p22++; } } time_t t2 = time(NULL); for (size_t i = 0; i < count; ++i) { p11 = p1; for (size_t j = 0; j < len; ++j) { c = *++p11; } } time_t t3 = time(NULL); printf("post-increment time: %ldn", t2-t1); printf("pre-increment time: %ldn", t3-t2); free(start); } int main(void) { test_CVE_2016_9842(); test_CVE_2016_9840_9841_9843(); return 0; }
gcc 7.5.0
CVE_2016_9842 no recurrence
CVE_2016_9840_9841_9843 array no recurrence
CVE_2016_9840_9841_9843 point no recurrence
post-increment time: 24
pre-increment time: 20
- 未验证成功两个C语言未定义的行为
- 验证成功*++p比*p++速度更快



