From 8059d69bbd754b7d26e93cfc109254e680e03b98 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 6 Apr 2020 14:24:16 +0100 Subject: [PATCH] C++: Model calls to operator new / delete for NewFreeMismatch.ql. --- cpp/ql/src/Critical/NewDelete.qll | 33 +++++++++++++++---- .../Critical/NewFree/NewFreeMismatch.expected | 2 ++ .../query-tests/Critical/NewFree/test2.cpp | 4 +-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/Critical/NewDelete.qll b/cpp/ql/src/Critical/NewDelete.qll index 7650af2f053..93d4ca0973c 100644 --- a/cpp/ql/src/Critical/NewDelete.qll +++ b/cpp/ql/src/Critical/NewDelete.qll @@ -16,9 +16,19 @@ predicate allocExpr(Expr alloc, string kind) { isAllocationExpr(alloc) and not alloc.isFromUninstantiatedTemplate(_) and ( - alloc instanceof FunctionCall and - not alloc.(FunctionCall).getTarget() instanceof OperatorNewAllocationFunction and - kind = "malloc" + exists(Function target | + alloc.(FunctionCall).getTarget() = target and + ( + target.getName() = "operator new" and + kind = "new" + or + target.getName() = "operator new[]" and + kind = "new[]" + or + not target instanceof OperatorNewAllocationFunction and + kind = "malloc" + ) + ) or alloc instanceof NewExpr and kind = "new" and @@ -113,9 +123,20 @@ predicate allocReaches(Expr e, Expr alloc, string kind) { * describing the type of that free or delete. */ predicate freeExpr(Expr free, Expr freed, string kind) { - freeCall(free, freed) and - not free.(FunctionCall).getTarget() instanceof OperatorDeleteDeallocationFunction and - kind = "free" + exists(Function target | + freeCall(free, freed) and + free.(FunctionCall).getTarget() = target and + ( + target.getName() = "operator delete" and + kind = "delete" + or + target.getName() = "operator delete[]" and + kind = "delete[]" + or + not target instanceof OperatorDeleteDeallocationFunction and + kind = "free" + ) + ) or free.(DeleteExpr).getExpr() = freed and kind = "delete" diff --git a/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected b/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected index 8bcb9efa587..45f88d426c9 100644 --- a/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected +++ b/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected @@ -1,7 +1,9 @@ | test2.cpp:19:3:19:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:18:12:18:18 | new | new | | test2.cpp:26:3:26:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:25:7:25:13 | new | new | | test2.cpp:51:2:51:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:45:18:45:24 | new | new | +| test2.cpp:55:2:55:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:46:20:46:33 | call to operator new | new | | test2.cpp:57:2:57:18 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test2.cpp:47:21:47:26 | call to malloc | malloc | +| test2.cpp:58:2:58:18 | call to operator delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test2.cpp:47:21:47:26 | call to malloc | malloc | | test.cpp:36:2:36:17 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:27:18:27:23 | call to malloc | malloc | | test.cpp:41:2:41:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:26:7:26:17 | new | new | | test.cpp:68:3:68:11 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:64:28:64:33 | call to malloc | malloc | diff --git a/cpp/ql/test/query-tests/Critical/NewFree/test2.cpp b/cpp/ql/test/query-tests/Critical/NewFree/test2.cpp index d5abd62ab71..43a286f6f97 100644 --- a/cpp/ql/test/query-tests/Critical/NewFree/test2.cpp +++ b/cpp/ql/test/query-tests/Critical/NewFree/test2.cpp @@ -52,9 +52,9 @@ void test_operator_new() delete ptr_opnew; // GOOD ::operator delete(ptr_opnew); // GOOD - free(ptr_opnew); // BAD [NOT DETECTED] + free(ptr_opnew); // BAD delete ptr_malloc; // BAD - ::operator delete(ptr_malloc); // BAD [NOT DETECTED] + ::operator delete(ptr_malloc); // BAD free(ptr_malloc); // GOOD }