From 05c8610bbc641f780fcd6a8e758634b91c48fb93 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 7 Feb 2020 16:22:09 -0800 Subject: [PATCH 1/8] C++: tests for alias analysis of malloc --- .../dataflow/security-taint/tainted.expected | 15 +++++++ .../security-taint/tainted_diff.expected | 9 ++++ .../security-taint/tainted_ir.expected | 6 +++ .../dataflow/security-taint/test.cpp | 13 ++++++ .../ir/ssa/aliased_ssa_ir.expected | 43 +++++++++++++++++++ .../ir/ssa/aliased_ssa_ir_unsound.expected | 43 +++++++++++++++++++ cpp/ql/test/library-tests/ir/ssa/ssa.cpp | 8 ++++ .../ir/ssa/unaliased_ssa_ir.expected | 40 +++++++++++++++++ .../ir/ssa/unaliased_ssa_ir_unsound.expected | 40 +++++++++++++++++ 9 files changed, 217 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected index 7359b068d8ea..a62b9b3e2043 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted.expected @@ -52,3 +52,18 @@ | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected index ed954b5444a7..c33772a39cc1 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected @@ -8,3 +8,12 @@ | test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected index 114c213ff54f..1b828c3cf1bf 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected @@ -40,3 +40,9 @@ | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/test.cpp b/cpp/ql/test/library-tests/dataflow/security-taint/test.cpp index 5eb7ee79b46b..9d28f9680ca2 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/security-taint/test.cpp @@ -76,3 +76,16 @@ void guard() { if (len > 1000) return; char **node = (char **) malloc(len * sizeof(char *)); } + +const char *alias_global; + +void mallocBuffer() { + const char *userName = getenv("USER_NAME"); + char *alias = (char*)malloc(4096); + char *copy = (char*)malloc(4096); + strcpy(copy, userName); + alias_global = alias; // to force a Chi node on all aliased memory + if (!strcmp(copy, "admin")) { // copy should be tainted + isAdmin = true; + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 5c12a3d21738..a1a2e4a04520 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1240,3 +1240,46 @@ ssa.cpp: # 254| v254_10(void) = UnmodeledUse : mu* # 254| v254_11(void) = AliasedUse : ~m262_1 # 254| v254_12(void) = ExitFunction : + +# 268| void* MallocAliasing(void*, int) +# 268| Block 0 +# 268| v268_1(void) = EnterFunction : +# 268| m268_2(unknown) = AliasedDefinition : +# 268| m268_3(unknown) = InitializeNonLocal : +# 268| m268_4(unknown) = Chi : total:m268_2, partial:m268_3 +# 268| mu268_5(unknown) = UnmodeledDefinition : +# 268| r268_6(glval) = VariableAddress[s] : +# 268| m268_7(void *) = InitializeParameter[s] : &:r268_6 +# 268| r268_8(void *) = Load : &:r268_6, m268_7 +# 268| m268_9(unknown) = InitializeIndirection[s] : &:r268_8 +# 268| r268_10(glval) = VariableAddress[size] : +# 268| m268_11(int) = InitializeParameter[size] : &:r268_10 +# 269| r269_1(glval) = VariableAddress[buf] : +# 269| r269_2(glval) = FunctionAddress[malloc] : +# 269| r269_3(glval) = VariableAddress[size] : +# 269| r269_4(int) = Load : &:r269_3, m268_11 +# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 +# 269| m269_6(unknown) = ^CallSideEffect : ~m268_9 +# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6 +# 269| m269_8(void *) = Store : &:r269_1, r269_5 +# 270| r270_1(glval) = FunctionAddress[memcpy] : +# 270| r270_2(glval) = VariableAddress[buf] : +# 270| r270_3(void *) = Load : &:r270_2, m269_8 +# 270| r270_4(glval) = VariableAddress[s] : +# 270| r270_5(void *) = Load : &:r270_4, m268_7 +# 270| r270_6(glval) = VariableAddress[size] : +# 270| r270_7(int) = Load : &:r270_6, m268_11 +# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7 +# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 +# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10 +# 271| r271_1(glval) = VariableAddress[#return] : +# 271| r271_2(glval) = VariableAddress[buf] : +# 271| r271_3(void *) = Load : &:r271_2, m269_8 +# 271| m271_4(void *) = Store : &:r271_1, r271_3 +# 268| v268_12(void) = ReturnIndirection : &:r268_8, ~m270_11 +# 268| r268_13(glval) = VariableAddress[#return] : +# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4 +# 268| v268_15(void) = UnmodeledUse : mu* +# 268| v268_16(void) = AliasedUse : ~m270_11 +# 268| v268_17(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index 2a012447a689..2bfb941ab3b1 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1235,3 +1235,46 @@ ssa.cpp: # 254| v254_10(void) = UnmodeledUse : mu* # 254| v254_11(void) = AliasedUse : ~m262_1 # 254| v254_12(void) = ExitFunction : + +# 268| void* MallocAliasing(void*, int) +# 268| Block 0 +# 268| v268_1(void) = EnterFunction : +# 268| m268_2(unknown) = AliasedDefinition : +# 268| m268_3(unknown) = InitializeNonLocal : +# 268| m268_4(unknown) = Chi : total:m268_2, partial:m268_3 +# 268| mu268_5(unknown) = UnmodeledDefinition : +# 268| r268_6(glval) = VariableAddress[s] : +# 268| m268_7(void *) = InitializeParameter[s] : &:r268_6 +# 268| r268_8(void *) = Load : &:r268_6, m268_7 +# 268| m268_9(unknown) = InitializeIndirection[s] : &:r268_8 +# 268| r268_10(glval) = VariableAddress[size] : +# 268| m268_11(int) = InitializeParameter[size] : &:r268_10 +# 269| r269_1(glval) = VariableAddress[buf] : +# 269| r269_2(glval) = FunctionAddress[malloc] : +# 269| r269_3(glval) = VariableAddress[size] : +# 269| r269_4(int) = Load : &:r269_3, m268_11 +# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 +# 269| m269_6(unknown) = ^CallSideEffect : ~m268_4 +# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6 +# 269| m269_8(void *) = Store : &:r269_1, r269_5 +# 270| r270_1(glval) = FunctionAddress[memcpy] : +# 270| r270_2(glval) = VariableAddress[buf] : +# 270| r270_3(void *) = Load : &:r270_2, m269_8 +# 270| r270_4(glval) = VariableAddress[s] : +# 270| r270_5(void *) = Load : &:r270_4, m268_7 +# 270| r270_6(glval) = VariableAddress[size] : +# 270| r270_7(int) = Load : &:r270_6, m268_11 +# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_9 +# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 +# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10 +# 271| r271_1(glval) = VariableAddress[#return] : +# 271| r271_2(glval) = VariableAddress[buf] : +# 271| r271_3(void *) = Load : &:r271_2, m269_8 +# 271| m271_4(void *) = Store : &:r271_1, r271_3 +# 268| v268_12(void) = ReturnIndirection : &:r268_8, m268_9 +# 268| r268_13(glval) = VariableAddress[#return] : +# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4 +# 268| v268_15(void) = UnmodeledUse : mu* +# 268| v268_16(void) = AliasedUse : ~m270_11 +# 268| v268_17(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp index 5bdfd254e8f8..ee75a2f28e46 100644 --- a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp @@ -262,3 +262,11 @@ char StringLiteralAliasing2(bool b) { const char* s = "Literal"; return s[2]; } + +void *malloc(int size); + +void *MallocAliasing(void *s, int size) { + void *buf = malloc(size); + memcpy(buf, s, size); + return buf; +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 4319cb865874..545dd6f611ca 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -1149,3 +1149,43 @@ ssa.cpp: # 254| v254_9(void) = UnmodeledUse : mu* # 254| v254_10(void) = AliasedUse : ~mu254_4 # 254| v254_11(void) = ExitFunction : + +# 268| void* MallocAliasing(void*, int) +# 268| Block 0 +# 268| v268_1(void) = EnterFunction : +# 268| mu268_2(unknown) = AliasedDefinition : +# 268| mu268_3(unknown) = InitializeNonLocal : +# 268| mu268_4(unknown) = UnmodeledDefinition : +# 268| r268_5(glval) = VariableAddress[s] : +# 268| m268_6(void *) = InitializeParameter[s] : &:r268_5 +# 268| r268_7(void *) = Load : &:r268_5, m268_6 +# 268| mu268_8(unknown) = InitializeIndirection[s] : &:r268_7 +# 268| r268_9(glval) = VariableAddress[size] : +# 268| m268_10(int) = InitializeParameter[size] : &:r268_9 +# 269| r269_1(glval) = VariableAddress[buf] : +# 269| r269_2(glval) = FunctionAddress[malloc] : +# 269| r269_3(glval) = VariableAddress[size] : +# 269| r269_4(int) = Load : &:r269_3, m268_10 +# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 +# 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4 +# 269| m269_7(void *) = Store : &:r269_1, r269_5 +# 270| r270_1(glval) = FunctionAddress[memcpy] : +# 270| r270_2(glval) = VariableAddress[buf] : +# 270| r270_3(void *) = Load : &:r270_2, m269_7 +# 270| r270_4(glval) = VariableAddress[s] : +# 270| r270_5(void *) = Load : &:r270_4, m268_6 +# 270| r270_6(glval) = VariableAddress[size] : +# 270| r270_7(int) = Load : &:r270_6, m268_10 +# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~mu268_4 +# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 +# 271| r271_1(glval) = VariableAddress[#return] : +# 271| r271_2(glval) = VariableAddress[buf] : +# 271| r271_3(void *) = Load : &:r271_2, m269_7 +# 271| m271_4(void *) = Store : &:r271_1, r271_3 +# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 +# 268| r268_12(glval) = VariableAddress[#return] : +# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4 +# 268| v268_14(void) = UnmodeledUse : mu* +# 268| v268_15(void) = AliasedUse : ~mu268_4 +# 268| v268_16(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 4319cb865874..545dd6f611ca 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -1149,3 +1149,43 @@ ssa.cpp: # 254| v254_9(void) = UnmodeledUse : mu* # 254| v254_10(void) = AliasedUse : ~mu254_4 # 254| v254_11(void) = ExitFunction : + +# 268| void* MallocAliasing(void*, int) +# 268| Block 0 +# 268| v268_1(void) = EnterFunction : +# 268| mu268_2(unknown) = AliasedDefinition : +# 268| mu268_3(unknown) = InitializeNonLocal : +# 268| mu268_4(unknown) = UnmodeledDefinition : +# 268| r268_5(glval) = VariableAddress[s] : +# 268| m268_6(void *) = InitializeParameter[s] : &:r268_5 +# 268| r268_7(void *) = Load : &:r268_5, m268_6 +# 268| mu268_8(unknown) = InitializeIndirection[s] : &:r268_7 +# 268| r268_9(glval) = VariableAddress[size] : +# 268| m268_10(int) = InitializeParameter[size] : &:r268_9 +# 269| r269_1(glval) = VariableAddress[buf] : +# 269| r269_2(glval) = FunctionAddress[malloc] : +# 269| r269_3(glval) = VariableAddress[size] : +# 269| r269_4(int) = Load : &:r269_3, m268_10 +# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 +# 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4 +# 269| m269_7(void *) = Store : &:r269_1, r269_5 +# 270| r270_1(glval) = FunctionAddress[memcpy] : +# 270| r270_2(glval) = VariableAddress[buf] : +# 270| r270_3(void *) = Load : &:r270_2, m269_7 +# 270| r270_4(glval) = VariableAddress[s] : +# 270| r270_5(void *) = Load : &:r270_4, m268_6 +# 270| r270_6(glval) = VariableAddress[size] : +# 270| r270_7(int) = Load : &:r270_6, m268_10 +# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~mu268_4 +# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 +# 271| r271_1(glval) = VariableAddress[#return] : +# 271| r271_2(glval) = VariableAddress[buf] : +# 271| r271_3(void *) = Load : &:r271_2, m269_7 +# 271| m271_4(void *) = Store : &:r271_1, r271_3 +# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 +# 268| r268_12(glval) = VariableAddress[#return] : +# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4 +# 268| v268_14(void) = UnmodeledUse : mu* +# 268| v268_15(void) = AliasedUse : ~mu268_4 +# 268| v268_16(void) = ExitFunction : From 7f69cdfb5672d976bd10975311e5c3da8c263932 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 7 Feb 2020 15:02:12 -0800 Subject: [PATCH 2/8] C++: Dynamic allocations in IR alias analysis --- .../code/cpp/ir/implementation/Opcode.qll | 5 +++ .../aliased_ssa/Instruction.qll | 14 +++++++++ .../internal/AliasConfiguration.qll | 31 +++++++++++++++++++ .../aliased_ssa/internal/AliasedSSA.qll | 8 +++-- .../cpp/ir/implementation/raw/Instruction.qll | 14 +++++++++ .../raw/internal/TranslatedCall.qll | 29 ++++++++++++----- .../raw/internal/TranslatedElement.qll | 4 ++- .../unaliased_ssa/Instruction.qll | 14 +++++++++ .../security-taint/tainted_diff.expected | 6 ---- .../security-taint/tainted_ir.expected | 6 ++++ .../ir/ssa/aliased_ssa_ir.expected | 11 ++++--- .../ir/ssa/aliased_ssa_ir_unsound.expected | 11 ++++--- .../ir/ssa/unaliased_ssa_ir.expected | 7 +++-- .../ir/ssa/unaliased_ssa_ir_unsound.expected | 7 +++-- 14 files changed, 135 insertions(+), 32 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll index 886183c32ba6..987f6ae3c36b 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll @@ -82,6 +82,7 @@ private newtype TOpcode = TSizedBufferReadSideEffect() or TSizedBufferMustWriteSideEffect() or TSizedBufferMayWriteSideEffect() or + TInitializeDynamicAllocation() or TChi() or TInlineAsm() or TUnreached() or @@ -695,6 +696,10 @@ module Opcode { final override string toString() { result = "SizedBufferMayWriteSideEffect" } } + class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, TInitializeDynamicAllocation { + final override string toString() { result = "InitializeDynamicAllocation" } + } + class Chi extends Opcode, TChi { final override string toString() { result = "Chi" } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 4b993849046f..432608372cf7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -1340,6 +1340,20 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() } } +/** + * + */ +class InitializeDynamicAllocationInstruction extends SideEffectInstruction { + InitializeDynamicAllocationInstruction() { + getOpcode() instanceof Opcode::InitializeDynamicAllocation + } + + final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + + final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } + +} + /** * An instruction representing a GNU or MSVC inline assembly statement. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll index d9937294d701..82aec427a808 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll @@ -7,6 +7,9 @@ private newtype TAllocation = TVariableAllocation(IRVariable var) or TIndirectParameterAllocation(IRAutomaticUserVariable var) { exists(InitializeIndirectionInstruction instr | instr.getIRVariable() = var) + } or + TDynamicAllocation(CallInstruction call) { + exists(InitializeDynamicAllocationInstruction instr | instr.getPrimaryInstruction() = call) } /** @@ -95,3 +98,31 @@ class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocati final override predicate alwaysEscapes() { none() } } + +class DynamicAllocation extends Allocation, TDynamicAllocation { + CallInstruction call; + + DynamicAllocation() { this = TDynamicAllocation(call) } + + final override string toString() { + result = call.toString() + " at " + call.getLocation() // TODO: make this both short and unique + } + + final override CallInstruction getABaseInstruction() { result = call } + + final override IRFunction getEnclosingIRFunction() { result = call.getEnclosingIRFunction() } + + final override Language::Location getLocation() { result = call.getLocation() } + + final override string getUniqueId() { result = call.getUniqueId() } + + final override IRType getIRType() { + result instanceof IRUnknownType // TODO: look at casts and sizes? + } + + final override predicate isReadOnly() { none() } + + final override predicate isAlwaysAllocatedOnStack() { none() } + + final override predicate alwaysEscapes() { none() } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll index 7f7a62acda33..078ff65b76a6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll @@ -68,8 +68,12 @@ private newtype TMemoryLocation = ) and languageType = type.getCanonicalLanguageType() } or - TEntireAllocationMemoryLocation(IndirectParameterAllocation var, boolean isMayAccess) { - isMayAccess = false or isMayAccess = true + TEntireAllocationMemoryLocation(Allocation var, boolean isMayAccess) { + ( + var instanceof IndirectParameterAllocation or + var instanceof DynamicAllocation + ) and + (isMayAccess = false or isMayAccess = true) } or TUnknownMemoryLocation(IRFunction irFunc, boolean isMayAccess) { isMayAccess = false or isMayAccess = true diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 4b993849046f..432608372cf7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -1340,6 +1340,20 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() } } +/** + * + */ +class InitializeDynamicAllocationInstruction extends SideEffectInstruction { + InitializeDynamicAllocationInstruction() { + getOpcode() instanceof Opcode::InitializeDynamicAllocation + } + + final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + + final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } + +} + /** * An instruction representing a GNU or MSVC inline assembly statement. */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 93e5c43bf3b0..ca2353c0a800 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -341,16 +341,31 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects { ) } - override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { none() } - - override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() } + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { + expr.getTarget() instanceof AllocationFunction and + opcode instanceof Opcode::InitializeDynamicAllocation and + tag = OnlyInstructionTag() and + type = getUnknownType() // TODO: precise type + } - override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } + override Instruction getFirstInstruction() { + if expr.getTarget() instanceof AllocationFunction + then result = getInstruction(OnlyInstructionTag()) + else result = getChild(0).getFirstInstruction() + } - override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) { none() } + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + tag = OnlyInstructionTag() and + kind = gotoEdge() and + if exists(getChild(0)) + then result = getChild(0).getFirstInstruction() + else result = getParent().getChildSuccessor(this) + } - override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) { - none() + override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) { + tag = OnlyInstructionTag() and + operandTag = addressOperand() and + result = getPrimaryInstructionForSideEffect(OnlyInstructionTag()) } override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 64dc7e869c25..81abc58495da 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -411,7 +411,9 @@ newtype TTranslatedElement = TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or // The side effects of a `Call` TTranslatedSideEffects(Call expr) { - exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or expr instanceof ConstructorCall + exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or + expr instanceof ConstructorCall or + expr.getTarget() instanceof AllocationFunction } or // A precise side effect of an argument to a `Call` TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) { ( diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 4b993849046f..432608372cf7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1340,6 +1340,20 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() } } +/** + * + */ +class InitializeDynamicAllocationInstruction extends SideEffectInstruction { + InitializeDynamicAllocationInstruction() { + getOpcode() instanceof Opcode::InitializeDynamicAllocation + } + + final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + + final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } + +} + /** * An instruction representing a GNU or MSVC inline assembly statement. */ diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected index c33772a39cc1..ca905d718239 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected @@ -8,12 +8,6 @@ | test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | AST only | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected index 1b828c3cf1bf..1a7027d399cf 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected @@ -40,9 +40,15 @@ | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | | | test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | | | test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | | diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index a1a2e4a04520..263212209363 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1261,21 +1261,22 @@ ssa.cpp: # 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 # 269| m269_6(unknown) = ^CallSideEffect : ~m268_9 # 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6 -# 269| m269_8(void *) = Store : &:r269_1, r269_5 +# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5 +# 269| m269_9(void *) = Store : &:r269_1, r269_5 # 270| r270_1(glval) = FunctionAddress[memcpy] : # 270| r270_2(glval) = VariableAddress[buf] : -# 270| r270_3(void *) = Load : &:r270_2, m269_8 +# 270| r270_3(void *) = Load : &:r270_2, m269_9 # 270| r270_4(glval) = VariableAddress[s] : # 270| r270_5(void *) = Load : &:r270_4, m268_7 # 270| r270_6(glval) = VariableAddress[size] : # 270| r270_7(int) = Load : &:r270_6, m268_11 # 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 -# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_8 # 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 -# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10 +# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10 # 271| r271_1(glval) = VariableAddress[#return] : # 271| r271_2(glval) = VariableAddress[buf] : -# 271| r271_3(void *) = Load : &:r271_2, m269_8 +# 271| r271_3(void *) = Load : &:r271_2, m269_9 # 271| m271_4(void *) = Store : &:r271_1, r271_3 # 268| v268_12(void) = ReturnIndirection : &:r268_8, ~m270_11 # 268| r268_13(glval) = VariableAddress[#return] : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index 2bfb941ab3b1..e886e9073821 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1256,10 +1256,11 @@ ssa.cpp: # 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 # 269| m269_6(unknown) = ^CallSideEffect : ~m268_4 # 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6 -# 269| m269_8(void *) = Store : &:r269_1, r269_5 +# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5 +# 269| m269_9(void *) = Store : &:r269_1, r269_5 # 270| r270_1(glval) = FunctionAddress[memcpy] : # 270| r270_2(glval) = VariableAddress[buf] : -# 270| r270_3(void *) = Load : &:r270_2, m269_8 +# 270| r270_3(void *) = Load : &:r270_2, m269_9 # 270| r270_4(glval) = VariableAddress[s] : # 270| r270_5(void *) = Load : &:r270_4, m268_7 # 270| r270_6(glval) = VariableAddress[size] : @@ -1267,14 +1268,14 @@ ssa.cpp: # 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 # 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_9 # 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 -# 270| m270_11(unknown) = Chi : total:m269_7, partial:m270_10 +# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10 # 271| r271_1(glval) = VariableAddress[#return] : # 271| r271_2(glval) = VariableAddress[buf] : -# 271| r271_3(void *) = Load : &:r271_2, m269_8 +# 271| r271_3(void *) = Load : &:r271_2, m269_9 # 271| m271_4(void *) = Store : &:r271_1, r271_3 # 268| v268_12(void) = ReturnIndirection : &:r268_8, m268_9 # 268| r268_13(glval) = VariableAddress[#return] : # 268| v268_14(void) = ReturnValue : &:r268_13, m271_4 # 268| v268_15(void) = UnmodeledUse : mu* -# 268| v268_16(void) = AliasedUse : ~m270_11 +# 268| v268_16(void) = AliasedUse : ~m269_7 # 268| v268_17(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 545dd6f611ca..8f5f1db2aa75 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -1168,10 +1168,11 @@ ssa.cpp: # 269| r269_4(int) = Load : &:r269_3, m268_10 # 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 # 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4 -# 269| m269_7(void *) = Store : &:r269_1, r269_5 +# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5 +# 269| m269_8(void *) = Store : &:r269_1, r269_5 # 270| r270_1(glval) = FunctionAddress[memcpy] : # 270| r270_2(glval) = VariableAddress[buf] : -# 270| r270_3(void *) = Load : &:r270_2, m269_7 +# 270| r270_3(void *) = Load : &:r270_2, m269_8 # 270| r270_4(glval) = VariableAddress[s] : # 270| r270_5(void *) = Load : &:r270_4, m268_6 # 270| r270_6(glval) = VariableAddress[size] : @@ -1181,7 +1182,7 @@ ssa.cpp: # 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 271| r271_1(glval) = VariableAddress[#return] : # 271| r271_2(glval) = VariableAddress[buf] : -# 271| r271_3(void *) = Load : &:r271_2, m269_7 +# 271| r271_3(void *) = Load : &:r271_2, m269_8 # 271| m271_4(void *) = Store : &:r271_1, r271_3 # 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 # 268| r268_12(glval) = VariableAddress[#return] : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 545dd6f611ca..8f5f1db2aa75 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -1168,10 +1168,11 @@ ssa.cpp: # 269| r269_4(int) = Load : &:r269_3, m268_10 # 269| r269_5(void *) = Call : func:r269_2, 0:r269_4 # 269| mu269_6(unknown) = ^CallSideEffect : ~mu268_4 -# 269| m269_7(void *) = Store : &:r269_1, r269_5 +# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5 +# 269| m269_8(void *) = Store : &:r269_1, r269_5 # 270| r270_1(glval) = FunctionAddress[memcpy] : # 270| r270_2(glval) = VariableAddress[buf] : -# 270| r270_3(void *) = Load : &:r270_2, m269_7 +# 270| r270_3(void *) = Load : &:r270_2, m269_8 # 270| r270_4(glval) = VariableAddress[s] : # 270| r270_5(void *) = Load : &:r270_4, m268_6 # 270| r270_6(glval) = VariableAddress[size] : @@ -1181,7 +1182,7 @@ ssa.cpp: # 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 271| r271_1(glval) = VariableAddress[#return] : # 271| r271_2(glval) = VariableAddress[buf] : -# 271| r271_3(void *) = Load : &:r271_2, m269_7 +# 271| r271_3(void *) = Load : &:r271_2, m269_8 # 271| m271_4(void *) = Store : &:r271_1, r271_3 # 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 # 268| r268_12(glval) = VariableAddress[#return] : From 3ea351967468ec66ab1c91a488c33dac8525ac4e Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 7 Feb 2020 15:52:58 -0800 Subject: [PATCH 3/8] C++/C#: sync changes --- .../code/csharp/ir/implementation/Opcode.qll | 5 +++++ .../csharp/ir/implementation/raw/Instruction.qll | 14 ++++++++++++++ .../implementation/unaliased_ssa/Instruction.qll | 14 ++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll index 886183c32ba6..987f6ae3c36b 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll @@ -82,6 +82,7 @@ private newtype TOpcode = TSizedBufferReadSideEffect() or TSizedBufferMustWriteSideEffect() or TSizedBufferMayWriteSideEffect() or + TInitializeDynamicAllocation() or TChi() or TInlineAsm() or TUnreached() or @@ -695,6 +696,10 @@ module Opcode { final override string toString() { result = "SizedBufferMayWriteSideEffect" } } + class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, TInitializeDynamicAllocation { + final override string toString() { result = "InitializeDynamicAllocation" } + } + class Chi extends Opcode, TChi { final override string toString() { result = "Chi" } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index 4b993849046f..432608372cf7 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -1340,6 +1340,20 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() } } +/** + * + */ +class InitializeDynamicAllocationInstruction extends SideEffectInstruction { + InitializeDynamicAllocationInstruction() { + getOpcode() instanceof Opcode::InitializeDynamicAllocation + } + + final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + + final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } + +} + /** * An instruction representing a GNU or MSVC inline assembly statement. */ diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index 4b993849046f..432608372cf7 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1340,6 +1340,20 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() } } +/** + * + */ +class InitializeDynamicAllocationInstruction extends SideEffectInstruction { + InitializeDynamicAllocationInstruction() { + getOpcode() instanceof Opcode::InitializeDynamicAllocation + } + + final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + + final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } + +} + /** * An instruction representing a GNU or MSVC inline assembly statement. */ From 3266a8902376203ca95d44ba18affceaa1910dea Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 7 Feb 2020 16:56:57 -0800 Subject: [PATCH 4/8] C++: document DynamicAllocationInstruction --- .../ir/implementation/aliased_ssa/Instruction.qll | 12 +++++++++--- .../code/cpp/ir/implementation/raw/Instruction.qll | 12 +++++++++--- .../ir/implementation/unaliased_ssa/Instruction.qll | 12 +++++++++--- .../csharp/ir/implementation/raw/Instruction.qll | 12 +++++++++--- .../ir/implementation/unaliased_ssa/Instruction.qll | 12 +++++++++--- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 432608372cf7..f63f349e415d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -1341,17 +1341,23 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio } /** - * + * An instruction representing the initial value of newly allocated memory, e.g. the result of a + * call to `malloc` */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { getOpcode() instanceof Opcode::InitializeDynamicAllocation } - + + /** + * Gets the address of the allocation this instruction is initializing. + */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + /** + * Gets the operand for the allocation this instruction is initializing. + */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } - } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 432608372cf7..f63f349e415d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -1341,17 +1341,23 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio } /** - * + * An instruction representing the initial value of newly allocated memory, e.g. the result of a + * call to `malloc` */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { getOpcode() instanceof Opcode::InitializeDynamicAllocation } - + + /** + * Gets the address of the allocation this instruction is initializing. + */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + /** + * Gets the operand for the allocation this instruction is initializing. + */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } - } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 432608372cf7..f63f349e415d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1341,17 +1341,23 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio } /** - * + * An instruction representing the initial value of newly allocated memory, e.g. the result of a + * call to `malloc` */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { getOpcode() instanceof Opcode::InitializeDynamicAllocation } - + + /** + * Gets the address of the allocation this instruction is initializing. + */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + /** + * Gets the operand for the allocation this instruction is initializing. + */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } - } /** diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index 432608372cf7..f63f349e415d 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -1341,17 +1341,23 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio } /** - * + * An instruction representing the initial value of newly allocated memory, e.g. the result of a + * call to `malloc` */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { getOpcode() instanceof Opcode::InitializeDynamicAllocation } - + + /** + * Gets the address of the allocation this instruction is initializing. + */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + /** + * Gets the operand for the allocation this instruction is initializing. + */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } - } /** diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index 432608372cf7..f63f349e415d 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1341,17 +1341,23 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio } /** - * + * An instruction representing the initial value of newly allocated memory, e.g. the result of a + * call to `malloc` */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { getOpcode() instanceof Opcode::InitializeDynamicAllocation } - + + /** + * Gets the address of the allocation this instruction is initializing. + */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } + /** + * Gets the operand for the allocation this instruction is initializing. + */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } - } /** From f467260815313a2f7c35a4a37347aa959e97c73a Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 11 Feb 2020 12:17:46 -0800 Subject: [PATCH 5/8] C++: respond to PR comments. --- .../code/cpp/ir/implementation/aliased_ssa/Instruction.qll | 2 +- .../aliased_ssa/internal/AliasConfiguration.qll | 6 ++---- .../semmle/code/cpp/ir/implementation/raw/Instruction.qll | 2 +- .../cpp/ir/implementation/raw/internal/TranslatedCall.qll | 3 ++- .../cpp/ir/implementation/unaliased_ssa/Instruction.qll | 2 +- cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll | 2 +- .../code/csharp/ir/implementation/raw/Instruction.qll | 2 +- .../csharp/ir/implementation/unaliased_ssa/Instruction.qll | 2 +- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index f63f349e415d..981aa52bdab2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -1342,7 +1342,7 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio /** * An instruction representing the initial value of newly allocated memory, e.g. the result of a - * call to `malloc` + * call to `malloc`. */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll index 82aec427a808..fa0c625be9ee 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll @@ -105,7 +105,7 @@ class DynamicAllocation extends Allocation, TDynamicAllocation { DynamicAllocation() { this = TDynamicAllocation(call) } final override string toString() { - result = call.toString() + " at " + call.getLocation() // TODO: make this both short and unique + result = call.toString() + " at " + call.getLocation() // This isn't performant, but it's only used in test/dump code right not } final override CallInstruction getABaseInstruction() { result = call } @@ -116,9 +116,7 @@ class DynamicAllocation extends Allocation, TDynamicAllocation { final override string getUniqueId() { result = call.getUniqueId() } - final override IRType getIRType() { - result instanceof IRUnknownType // TODO: look at casts and sizes? - } + final override IRType getIRType() { result instanceof IRUnknownType } final override predicate isReadOnly() { none() } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index f63f349e415d..981aa52bdab2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -1342,7 +1342,7 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio /** * An instruction representing the initial value of newly allocated memory, e.g. the result of a - * call to `malloc` + * call to `malloc`. */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index ca2353c0a800..ba763a4c03cb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -345,7 +345,7 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects { expr.getTarget() instanceof AllocationFunction and opcode instanceof Opcode::InitializeDynamicAllocation and tag = OnlyInstructionTag() and - type = getUnknownType() // TODO: precise type + type = getUnknownType() } override Instruction getFirstInstruction() { @@ -357,6 +357,7 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { tag = OnlyInstructionTag() and kind = gotoEdge() and + expr.getTarget() instanceof AllocationFunction and if exists(getChild(0)) then result = getChild(0).getFirstInstruction() else result = getParent().getChildSuccessor(this) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index f63f349e415d..981aa52bdab2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1342,7 +1342,7 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio /** * An instruction representing the initial value of newly allocated memory, e.g. the result of a - * call to `malloc` + * call to `malloc`. */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { diff --git a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll index 27870fb3671a..e20dfd83efde 100644 --- a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll @@ -2,4 +2,4 @@ * Support for tracking tainted data through the program. */ -import TaintTrackingImpl +import semmle.code.cpp.ir.dataflow.DefaultTaintTracking diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index f63f349e415d..981aa52bdab2 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -1342,7 +1342,7 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio /** * An instruction representing the initial value of newly allocated memory, e.g. the result of a - * call to `malloc` + * call to `malloc`. */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index f63f349e415d..981aa52bdab2 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1342,7 +1342,7 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio /** * An instruction representing the initial value of newly allocated memory, e.g. the result of a - * call to `malloc` + * call to `malloc`. */ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { InitializeDynamicAllocationInstruction() { From 837fe84cec576c80da94649889e0e140eefd4d80 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 11 Feb 2020 12:18:45 -0800 Subject: [PATCH 6/8] C++/C#: autoformat Opcode.qll --- cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll | 3 ++- csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll index 987f6ae3c36b..33bb0895d8c3 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll @@ -696,7 +696,8 @@ module Opcode { final override string toString() { result = "SizedBufferMayWriteSideEffect" } } - class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, TInitializeDynamicAllocation { + class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, + TInitializeDynamicAllocation { final override string toString() { result = "InitializeDynamicAllocation" } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll index 987f6ae3c36b..33bb0895d8c3 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll @@ -696,7 +696,8 @@ module Opcode { final override string toString() { result = "SizedBufferMayWriteSideEffect" } } - class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, TInitializeDynamicAllocation { + class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode, + TInitializeDynamicAllocation { final override string toString() { result = "InitializeDynamicAllocation" } } From 52b164434d488ffc440dee7bf4fbf89bf299cdf5 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 12 Feb 2020 15:23:30 -0800 Subject: [PATCH 7/8] C++: remove accidental commit --- cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll index e20dfd83efde..27870fb3671a 100644 --- a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll @@ -2,4 +2,4 @@ * Support for tracking tainted data through the program. */ -import semmle.code.cpp.ir.dataflow.DefaultTaintTracking +import TaintTrackingImpl From 9e1ea01be82d29ed32a33ff53c8a9673ff21abc9 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Thu, 13 Feb 2020 13:01:09 -0700 Subject: [PATCH 8/8] Fix typo --- .../implementation/aliased_ssa/internal/AliasConfiguration.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll index fa0c625be9ee..e95086c89fc9 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasConfiguration.qll @@ -105,7 +105,7 @@ class DynamicAllocation extends Allocation, TDynamicAllocation { DynamicAllocation() { this = TDynamicAllocation(call) } final override string toString() { - result = call.toString() + " at " + call.getLocation() // This isn't performant, but it's only used in test/dump code right not + result = call.toString() + " at " + call.getLocation() // This isn't performant, but it's only used in test/dump code right now. } final override CallInstruction getABaseInstruction() { result = call }