Merge branch 'main' into cwe497

This commit is contained in:
Geoffrey White
2022-03-01 11:58:24 +00:00
1354 changed files with 128014 additions and 70864 deletions

View File

@@ -1,2 +1,3 @@
| hiding.cpp:6:17:6:17 | i | Variable i hides another variable of the same name (on $@). | hiding.cpp:4:13:4:13 | i | line 4 |
| hiding.cpp:18:15:18:15 | k | Variable k hides another variable of the same name (on $@). | hiding.cpp:15:11:15:11 | k | line 15 |
| hiding.cpp:38:11:38:11 | x | Variable x hides another variable of the same name (on $@). | hiding.cpp:36:9:36:9 | x | line 36 |

View File

@@ -35,7 +35,7 @@ void structuredBinding() {
int xs[1] = {1};
auto [x] = xs;
{
auto [x] = xs; // BAD [NOT DETECTED]
auto [x] = xs; // BAD
auto [y] = xs; // GOOD
}
}

View File

@@ -0,0 +1,24 @@
| test.cpp:15:16:15:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:9:7:9:7 | x | x | test.cpp:10:3:10:13 | Store: ... = ... | here |
| test.cpp:58:16:58:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:51:36:51:36 | y | y | test.cpp:52:3:52:13 | Store: ... = ... | here |
| test.cpp:73:16:73:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:62:7:62:7 | x | x | test.cpp:68:3:68:13 | Store: ... = ... | here |
| test.cpp:98:15:98:15 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:92:8:92:8 | s | s | test.cpp:93:3:93:15 | Store: ... = ... | here |
| test.cpp:111:16:111:16 | Load: p | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:102:7:102:7 | x | x | test.cpp:106:3:106:14 | Store: ... = ... | here |
| test.cpp:161:16:161:17 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:132:7:132:8 | b1 | b1 | test.cpp:136:3:136:12 | Store: ... = ... | here |
| test.cpp:162:16:162:17 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:132:7:132:8 | b1 | b1 | test.cpp:137:3:137:16 | Store: ... = ... | here |
| test.cpp:164:16:164:17 | Load: p2 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:139:3:139:12 | Store: ... = ... | here |
| test.cpp:165:16:165:17 | Load: p2 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:139:3:139:12 | Store: ... = ... | here |
| test.cpp:166:17:166:18 | Load: p2 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:140:3:140:16 | Store: ... = ... | here |
| test.cpp:167:16:167:17 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:141:3:141:15 | Store: ... = ... | here |
| test.cpp:168:17:168:18 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:142:3:142:19 | Store: ... = ... | here |
| test.cpp:170:16:170:17 | Load: p3 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:144:3:144:12 | Store: ... = ... | here |
| test.cpp:171:17:171:18 | Load: p3 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:145:3:145:16 | Store: ... = ... | here |
| test.cpp:172:18:172:19 | Load: p2 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:146:3:146:15 | Store: ... = ... | here |
| test.cpp:173:18:173:19 | Load: p2 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:147:3:147:19 | Store: ... = ... | here |
| test.cpp:174:18:174:19 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:142:3:142:19 | Store: ... = ... | here |
| test.cpp:175:16:175:17 | Load: p1 | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:148:3:148:18 | Store: ... = ... | here |
| test.cpp:177:14:177:21 | Load: access to array | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:132:7:132:8 | b1 | b1 | test.cpp:151:3:151:15 | Store: ... = ... | here |
| test.cpp:178:14:178:21 | Load: access to array | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:132:7:132:8 | b1 | b1 | test.cpp:152:3:152:19 | Store: ... = ... | here |
| test.cpp:179:14:179:21 | Load: access to array | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:153:3:153:18 | Store: ... = ... | here |
| test.cpp:180:14:180:19 | Load: * ... | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:133:7:133:8 | b2 | b2 | test.cpp:154:3:154:22 | Store: ... = ... | here |
| test.cpp:181:13:181:20 | Load: access to array | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:155:3:155:21 | Store: ... = ... | here |
| test.cpp:182:14:182:19 | Load: * ... | Stack variable $@ escapes $@ and is used after it has expired. | test.cpp:134:7:134:8 | b3 | b3 | test.cpp:156:3:156:25 | Store: ... = ... | here |

View File

@@ -0,0 +1 @@
Likely Bugs/Memory Management/UsingExpiredStackAddress.ql

View File

@@ -0,0 +1,199 @@
struct S100 {
int i;
int* p;
};
static struct S100 s101;
void escape1() {
int x;
s101.p = &x;
}
int simple_field_bad() {
escape1();
return *s101.p; // BAD
}
int simple_field_good() {
escape1();
return s101.i; // GOOD
}
int deref_p() {
return *s101.p;
}
int field_indirect_bad() {
escape1();
return deref_p(); // BAD [NOT DETECTED]
}
int deref_i() {
return s101.i;
}
int field_indirect_good() {
escape1();
return deref_i(); // GOOD
}
void store_argument(int *p) {
s101.p = p;
}
int store_argument_value() {
int x;
store_argument(&x);
return *s101.p; // GOOD
}
void store_address_of_argument(int y) {
s101.p = &y;
}
int store_argument_address() {
int x;
store_address_of_argument(x);
return *s101.p; // BAD
}
void address_escapes_through_pointer_arith() {
int x[2];
int* p0 = x;
int* p1 = p0 + 1;
int* p2 = p1 - 1;
int* p3 = 1 + p2;
p3++;
s101.p = p3;
}
int test_pointer_arith_bad() {
address_escapes_through_pointer_arith();
return *s101.p; // BAD
}
int test_pointer_arith_good_1() {
int x;
address_escapes_through_pointer_arith();
s101.p = &x;
return *s101.p; // GOOD
}
int test_pointer_arith_good_2(bool b) {
int x;
if(b) {
address_escapes_through_pointer_arith();
}
return *s101.p; // GOOD (we can't say for sure that this is a local address)
}
void field_address_escapes() {
S100 s;
s101.p = &s.i;
}
int test_field_address_escapes() {
field_address_escapes();
return s101.p[0]; // BAD
}
void escape_through_reference() {
int x = 0;
int& r0 = x;
int& r1 = r0;
r1++;
s101.p = &r1;
}
int test_escapes_through_reference() {
escape_through_reference();
return *s101.p; // BAD
}
struct S300 {
int a1[15];
int a2[14][15];
int a3[13][14][15];
int *p1;
int (*p2)[15];
int (*p3)[14][15];
int** pp;
};
S300 s1;
S300 s2;
S300 s3;
S300 s4;
S300 s5;
S300 s6;
void escape_through_arrays() {
int b1[15];
int b2[14][15];
int b3[13][14][15];
s1.p1 = b1;
s2.p1 = &b1[1];
s1.p2 = b2;
s2.p2 = &b2[1];
s3.p1 = b2[1];
s4.p1 = &b2[1][2];
s1.p3 = b3;
s2.p3 = &b3[1];
s3.p2 = b3[1];
s4.p2 = &b3[1][2];
s5.p1 = b3[1][2];
s6.p1 = &b3[1][2][3];
s1.pp[0] = b1;
s2.pp[0] = &b1[1];
s3.pp[0] = b2[1];
s4.pp[0] = &b2[1][2];
s5.pp[0] = b3[1][2];
s6.pp[0] = &b3[1][2][3];
}
void test_escape_through_arrays() {
escape_through_arrays();
int x1 = *s1.p1; // BAD
int x2 = *s2.p1; // BAD
int* x3 = s1.p2[1]; // BAD
int x4 = *s1.p2[1]; // BAD
int* x5 = *s2.p2; // BAD
int* x6 = s3.p1; // BAD
int x7 = *&s4.p1[1]; // BAD
int x8 = *s1.p3[1][2]; // BAD
int x9 = (*s2.p3[0])[0]; // BAD
int x10 = **s3.p2; // BAD
int x11 = **s4.p2; // BAD
int x12 = (*s4.p1); // BAD
int x13 = s5.p1[1]; // BAD
int* x14 = s1.pp[0]; // BAD
int x15 = *s2.pp[0]; // BAD
int x16 = *s3.pp[0]; // BAD
int x17 = **s4.pp; // BAD
int x18 = s5.pp[0][0]; // BAD
int x19 = (*s6.pp)[0]; // BAD
}
void not_escape_through_arrays() {
int x;
s1.a1[0] = x;
s1.a2[0][1] = s1.a1[0];
**s1.a3[0] = 42;
}
void test_not_escape_through_array() {
not_escape_through_arrays();
int x20 = s1.a1[0]; // GOOD
int x21 = s1.a2[0][1]; // GOOD
int* x22 = s1.a3[5][2]; // GOOD
}

View File

@@ -7,6 +7,8 @@ edges
| test.cpp:40:11:40:17 | access to array | test.cpp:11:26:11:28 | url |
| test.cpp:46:18:46:26 | http:// | test.cpp:49:11:49:16 | buffer |
| test.cpp:49:11:49:16 | buffer | test.cpp:11:26:11:28 | url |
| test.cpp:110:21:110:40 | http://example.com | test.cpp:121:11:121:13 | ptr |
| test.cpp:121:11:121:13 | ptr | test.cpp:11:26:11:28 | url |
nodes
| test.cpp:11:26:11:28 | url | semmle.label | url |
| test.cpp:15:30:15:32 | url | semmle.label | url |
@@ -17,9 +19,12 @@ nodes
| test.cpp:40:11:40:17 | access to array | semmle.label | access to array |
| test.cpp:46:18:46:26 | http:// | semmle.label | http:// |
| test.cpp:49:11:49:16 | buffer | semmle.label | buffer |
| test.cpp:110:21:110:40 | http://example.com | semmle.label | http://example.com |
| test.cpp:121:11:121:13 | ptr | semmle.label | ptr |
subpaths
#select
| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |

View File

@@ -58,3 +58,66 @@ void test()
openUrl(buffer);
}
}
typedef unsigned long size_t;
int strncmp(const char *s1, const char *s2, size_t n);
char* strstr(char* s1, const char* s2);
void test2(const char *url)
{
if (strncmp(url, "http://", 7)) // GOOD (or at least dubious; we are not constructing the URL)
{
openUrl(url);
}
}
void test3(char *url)
{
char *ptr;
ptr = strstr(url, "https://"); // GOOD (https)
if (!ptr)
{
ptr = strstr(url, "http://"); // GOOD (we are not constructing the URL)
}
if (ptr)
{
openUrl(ptr);
}
}
void test4(char *url)
{
const char *https_string = "https://"; // GOOD (https)
const char *http_string = "http://"; // GOOD (we are not constructing the URL)
char *ptr;
ptr = strstr(url, https_string);
if (!ptr)
{
ptr = strstr(url, http_string);
}
if (ptr)
{
openUrl(ptr);
}
}
void test5()
{
char *url_string = "http://example.com"; // BAD
char *ptr;
ptr = strstr(url_string, "https://"); // GOOD (https)
if (!ptr)
{
ptr = strstr(url_string, "http://"); // GOOD (we are not constructing the URL here)
}
if (ptr)
{
openUrl(ptr);
}
}

View File

@@ -99,19 +99,19 @@ void positiveTestCases()
void* h = 0;
wchar_t* lpApplicationName = NULL;
// CreatePorcessA
// CreateProcessA
CreateProcessA( //BUG
NULL,
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcessW
// CreateProcessW
CreateProcessW( //BUG
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess
// CreateProcess
CreateProcess( //BUG
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
@@ -162,7 +162,7 @@ void positiveTestCases()
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess with a hardcoded variable for application Name (NULL)
// CreateProcess with a hardcoded variable for application Name (NULL)
// Variation: tab instead of space
CreateProcess( //BUG
lpApplicationName,
@@ -276,19 +276,19 @@ void negativeTestCases_quotedCommandLine()
void* h = 0;
wchar_t* lpApplicationName = NULL;
// CreatePorcessA
// CreateProcessA
CreateProcessA(
NULL,
(char*)"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcessW
// CreateProcessW
CreateProcessW(
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess
// CreateProcess
CreateProcess(
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
@@ -339,7 +339,7 @@ void negativeTestCases_quotedCommandLine()
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess with a hardcoded variable for application Name (NULL)
// CreateProcess with a hardcoded variable for application Name (NULL)
CreateProcess(
lpApplicationName,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
@@ -359,19 +359,19 @@ void negativeTestCases_AppNameSet()
void* h = 0;
const wchar_t* lpApplicationName = (const wchar_t*)L"MyApp.exe";
// CreatePorcessA
// CreateProcessA
CreateProcessA(
(char*)"MyApp.exe",
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcessW
// CreateProcessW
CreateProcessW(
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess
// CreateProcess
CreateProcess(
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
@@ -422,7 +422,7 @@ void negativeTestCases_AppNameSet()
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreatePorcess with a hardcoded variable for application Name (NULL)
// CreateProcess with a hardcoded variable for application Name (NULL)
CreateProcess(
(wchar_t*)lpApplicationName,
(wchar_t*)L"C:\\Program Files\\MyApp",