Skip to content

Commit 05c8610

Browse files
author
Robert Marsh
committed
C++: tests for alias analysis of malloc
1 parent 3c8aeb9 commit 05c8610

File tree

9 files changed

+217
-0
lines changed

9 files changed

+217
-0
lines changed

cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,18 @@
5252
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | |
5353
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | |
5454
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | |
55+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | |
56+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | |
57+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
58+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | |
59+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | |
60+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | |
61+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | |
62+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | |
63+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | |
64+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | |
65+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | |
66+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | |
67+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | |
68+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | |
69+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | |

cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,12 @@
88
| test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | AST only |
99
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | AST only |
1010
| test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only |
11+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
12+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |
13+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | AST only |
14+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | AST only |
15+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | AST only |
16+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | AST only |
17+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | AST only |
18+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | AST only |
19+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | AST only |

cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@
4040
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | |
4141
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | |
4242
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | |
43+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
44+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | |
45+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | |
46+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | |
47+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | |
48+
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | |

cpp/ql/test/library-tests/dataflow/security-taint/test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,16 @@ void guard() {
7676
if (len > 1000) return;
7777
char **node = (char **) malloc(len * sizeof(char *));
7878
}
79+
80+
const char *alias_global;
81+
82+
void mallocBuffer() {
83+
const char *userName = getenv("USER_NAME");
84+
char *alias = (char*)malloc(4096);
85+
char *copy = (char*)malloc(4096);
86+
strcpy(copy, userName);
87+
alias_global = alias; // to force a Chi node on all aliased memory
88+
if (!strcmp(copy, "admin")) { // copy should be tainted
89+
isAdmin = true;
90+
}
91+
}

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,3 +1240,46 @@ ssa.cpp:
12401240
# 254| v254_10(void) = UnmodeledUse : mu*
12411241
# 254| v254_11(void) = AliasedUse : ~m262_1
12421242
# 254| v254_12(void) = ExitFunction :
1243+
1244+
# 268| void* MallocAliasing(void*, int)
1245+
# 268| Block 0
1246+
# 268| v268_1(void) = EnterFunction :
1247+
# 268| m268_2(unknown) = AliasedDefinition :
1248+
# 268| m268_3(unknown) = InitializeNonLocal :
1249+
# 268| m268_4(unknown) = Chi : total:m268_2, partial:m268_3
1250+
# 268| mu268_5(unknown) = UnmodeledDefinition :
1251+
# 268| r268_6(glval<void *>) = VariableAddress[s] :
1252+
# 268| m268_7(void *) = InitializeParameter[s] : &:r268_6
1253+
# 268| r268_8(void *) = Load : &:r268_6, m268_7
1254+
# 268| m268_9(unknown) = InitializeIndirection[s] : &:r268_8
1255+
# 268| r268_10(glval<int>) = VariableAddress[size] :
1256+
# 268| m268_11(int) = InitializeParameter[size] : &:r268_10
1257+
# 269| r269_1(glval<void *>) = VariableAddress[buf] :
1258+
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
1259+
# 269| r269_3(glval<int>) = VariableAddress[size] :
1260+
# 269| r269_4(int) = Load : &:r269_3, m268_11
1261+
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
1262+
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_9
1263+
# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6
1264+
# 269| m269_8(void *) = Store : &:r269_1, r269_5
1265+
# 270| r270_1(glval<unknown>) = FunctionAddress[memcpy] :
1266+
# 270| r270_2(glval<void *>) = VariableAddress[buf] :
1267+
# 270| r270_3(void *) = Load : &:r270_2, m269_8
1268+
# 270| r270_4(glval<void *>) = VariableAddress[s] :
1269+
# 270| r270_5(void *) = Load : &:r270_4, m268_7
1270+
# 270| r270_6(glval<int>) = VariableAddress[size] :
1271+
# 270| r270_7(int) = Load : &:r270_6, m268_11
1272+
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
1273+
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7
1274+
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
1275+
# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10
1276+
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
1277+
# 271| r271_2(glval<void *>) = VariableAddress[buf] :
1278+
# 271| r271_3(void *) = Load : &:r271_2, m269_8
1279+
# 271| m271_4(void *) = Store : &:r271_1, r271_3
1280+
# 268| v268_12(void) = ReturnIndirection : &:r268_8, ~m270_11
1281+
# 268| r268_13(glval<void *>) = VariableAddress[#return] :
1282+
# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4
1283+
# 268| v268_15(void) = UnmodeledUse : mu*
1284+
# 268| v268_16(void) = AliasedUse : ~m270_11
1285+
# 268| v268_17(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,3 +1235,46 @@ ssa.cpp:
12351235
# 254| v254_10(void) = UnmodeledUse : mu*
12361236
# 254| v254_11(void) = AliasedUse : ~m262_1
12371237
# 254| v254_12(void) = ExitFunction :
1238+
1239+
# 268| void* MallocAliasing(void*, int)
1240+
# 268| Block 0
1241+
# 268| v268_1(void) = EnterFunction :
1242+
# 268| m268_2(unknown) = AliasedDefinition :
1243+
# 268| m268_3(unknown) = InitializeNonLocal :
1244+
# 268| m268_4(unknown) = Chi : total:m268_2, partial:m268_3
1245+
# 268| mu268_5(unknown) = UnmodeledDefinition :
1246+
# 268| r268_6(glval<void *>) = VariableAddress[s] :
1247+
# 268| m268_7(void *) = InitializeParameter[s] : &:r268_6
1248+
# 268| r268_8(void *) = Load : &:r268_6, m268_7
1249+
# 268| m268_9(unknown) = InitializeIndirection[s] : &:r268_8
1250+
# 268| r268_10(glval<int>) = VariableAddress[size] :
1251+
# 268| m268_11(int) = InitializeParameter[size] : &:r268_10
1252+
# 269| r269_1(glval<void *>) = VariableAddress[buf] :
1253+
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
1254+
# 269| r269_3(glval<int>) = VariableAddress[size] :
1255+
# 269| r269_4(int) = Load : &:r269_3, m268_11
1256+
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
1257+
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_4
1258+
# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6
1259+
# 269| m269_8(void *) = Store : &:r269_1, r269_5
1260+
# 270| r270_1(glval<unknown>) = FunctionAddress[memcpy] :
1261+
# 270| r270_2(glval<void *>) = VariableAddress[buf] :
1262+
# 270| r270_3(void *) = Load : &:r270_2, m269_8
1263+
# 270| r270_4(glval<void *>) = VariableAddress[s] :
1264+
# 270| r270_5(void *) = Load : &:r270_4, m268_7
1265+
# 270| r270_6(glval<int>) = VariableAddress[size] :
1266+
# 270| r270_7(int) = Load : &:r270_6, m268_11
1267+
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
1268+
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_9
1269+
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
1270+
# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10
1271+
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
1272+
# 271| r271_2(glval<void *>) = VariableAddress[buf] :
1273+
# 271| r271_3(void *) = Load : &:r271_2, m269_8
1274+
# 271| m271_4(void *) = Store : &:r271_1, r271_3
1275+
# 268| v268_12(void) = ReturnIndirection : &:r268_8, m268_9
1276+
# 268| r268_13(glval<void *>) = VariableAddress[#return] :
1277+
# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4
1278+
# 268| v268_15(void) = UnmodeledUse : mu*
1279+
# 268| v268_16(void) = AliasedUse : ~m270_11
1280+
# 268| v268_17(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/ssa.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,11 @@ char StringLiteralAliasing2(bool b) {
262262
const char* s = "Literal";
263263
return s[2];
264264
}
265+
266+
void *malloc(int size);
267+
268+
void *MallocAliasing(void *s, int size) {
269+
void *buf = malloc(size);
270+
memcpy(buf, s, size);
271+
return buf;
272+
}

cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,3 +1149,43 @@ ssa.cpp:
11491149
# 254| v254_9(void) = UnmodeledUse : mu*
11501150
# 254| v254_10(void) = AliasedUse : ~mu254_4
11511151
# 254| v254_11(void) = ExitFunction :
1152+
1153+
# 268| void* MallocAliasing(void*, int)
1154+
# 268| Block 0
1155+
# 268| v268_1(void) = EnterFunction :
1156+
# 268| mu268_2(unknown) = AliasedDefinition :
1157+
# 268| mu268_3(unknown) = InitializeNonLocal :
1158+
# 268| mu268_4(unknown) = UnmodeledDefinition :
1159+
# 268| r268_5(glval<void *>) = VariableAddress[s] :
1160+
# 268| m268_6(void *) = InitializeParameter[s] : &:r268_5
1161+
# 268| r268_7(void *) = Load : &:r268_5, m268_6
1162+
# 268| mu268_8(unknown) = InitializeIndirection[s] : &:r268_7
1163+
# 268| r268_9(glval<int>) = VariableAddress[size] :
1164+
# 268| m268_10(int) = InitializeParameter[size] : &:r268_9
1165+
# 269| r269_1(glval<void *>) = VariableAddress[buf] :
1166+
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
1167+
# 269| r269_3(glval<int>) = VariableAddress[size] :
1168+
# 269| r269_4(int) = Load : &:r269_3, m268_10
1169+
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
1170+
# 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4
1171+
# 269| m269_7(void *) = Store : &:r269_1, r269_5
1172+
# 270| r270_1(glval<unknown>) = FunctionAddress[memcpy] :
1173+
# 270| r270_2(glval<void *>) = VariableAddress[buf] :
1174+
# 270| r270_3(void *) = Load : &:r270_2, m269_7
1175+
# 270| r270_4(glval<void *>) = VariableAddress[s] :
1176+
# 270| r270_5(void *) = Load : &:r270_4, m268_6
1177+
# 270| r270_6(glval<int>) = VariableAddress[size] :
1178+
# 270| r270_7(int) = Load : &:r270_6, m268_10
1179+
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
1180+
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~mu268_4
1181+
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
1182+
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
1183+
# 271| r271_2(glval<void *>) = VariableAddress[buf] :
1184+
# 271| r271_3(void *) = Load : &:r271_2, m269_7
1185+
# 271| m271_4(void *) = Store : &:r271_1, r271_3
1186+
# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4
1187+
# 268| r268_12(glval<void *>) = VariableAddress[#return] :
1188+
# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4
1189+
# 268| v268_14(void) = UnmodeledUse : mu*
1190+
# 268| v268_15(void) = AliasedUse : ~mu268_4
1191+
# 268| v268_16(void) = ExitFunction :

cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,3 +1149,43 @@ ssa.cpp:
11491149
# 254| v254_9(void) = UnmodeledUse : mu*
11501150
# 254| v254_10(void) = AliasedUse : ~mu254_4
11511151
# 254| v254_11(void) = ExitFunction :
1152+
1153+
# 268| void* MallocAliasing(void*, int)
1154+
# 268| Block 0
1155+
# 268| v268_1(void) = EnterFunction :
1156+
# 268| mu268_2(unknown) = AliasedDefinition :
1157+
# 268| mu268_3(unknown) = InitializeNonLocal :
1158+
# 268| mu268_4(unknown) = UnmodeledDefinition :
1159+
# 268| r268_5(glval<void *>) = VariableAddress[s] :
1160+
# 268| m268_6(void *) = InitializeParameter[s] : &:r268_5
1161+
# 268| r268_7(void *) = Load : &:r268_5, m268_6
1162+
# 268| mu268_8(unknown) = InitializeIndirection[s] : &:r268_7
1163+
# 268| r268_9(glval<int>) = VariableAddress[size] :
1164+
# 268| m268_10(int) = InitializeParameter[size] : &:r268_9
1165+
# 269| r269_1(glval<void *>) = VariableAddress[buf] :
1166+
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
1167+
# 269| r269_3(glval<int>) = VariableAddress[size] :
1168+
# 269| r269_4(int) = Load : &:r269_3, m268_10
1169+
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
1170+
# 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4
1171+
# 269| m269_7(void *) = Store : &:r269_1, r269_5
1172+
# 270| r270_1(glval<unknown>) = FunctionAddress[memcpy] :
1173+
# 270| r270_2(glval<void *>) = VariableAddress[buf] :
1174+
# 270| r270_3(void *) = Load : &:r270_2, m269_7
1175+
# 270| r270_4(glval<void *>) = VariableAddress[s] :
1176+
# 270| r270_5(void *) = Load : &:r270_4, m268_6
1177+
# 270| r270_6(glval<int>) = VariableAddress[size] :
1178+
# 270| r270_7(int) = Load : &:r270_6, m268_10
1179+
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
1180+
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~mu268_4
1181+
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
1182+
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
1183+
# 271| r271_2(glval<void *>) = VariableAddress[buf] :
1184+
# 271| r271_3(void *) = Load : &:r271_2, m269_7
1185+
# 271| m271_4(void *) = Store : &:r271_1, r271_3
1186+
# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4
1187+
# 268| r268_12(glval<void *>) = VariableAddress[#return] :
1188+
# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4
1189+
# 268| v268_14(void) = UnmodeledUse : mu*
1190+
# 268| v268_15(void) = AliasedUse : ~mu268_4
1191+
# 268| v268_16(void) = ExitFunction :

0 commit comments

Comments
 (0)