diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql b/cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql index 7eb823201d4..d715be46bd2 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql @@ -22,15 +22,18 @@ import semmle.code.cpp.dataflow.DataFlow */ class SystemCallFunction extends Function { SystemCallFunction() { - this.getName().matches("SYSC\\_%") + exists(MacroInvocation m | + m.getMacro().getName().matches("SYSCALL\\_DEFINE%") and + this = m.getEnclosingFunction() + ) } } /** * A value that comes from a Linux system call (sources). */ -class SystemParameterSource extends DataFlow::Node { - SystemParameterSource() { +class SystemCallSource extends DataFlow::Node { + SystemCallSource() { exists(FunctionCall fc | fc.getTarget() instanceof SystemCallFunction and ( @@ -72,7 +75,7 @@ class UnSafePutUserMacro extends Macro { } } -class ExploitableUserModePtrParam extends SystemParameterSource { +class ExploitableUserModePtrParam extends SystemCallSource { ExploitableUserModePtrParam() { exists(UnSafePutUserMacro unsafePutUser | DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr())) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/NoCheckBeforeUnsafePutUser.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/NoCheckBeforeUnsafePutUser.expected index 6212a583c3b..c81cfd254df 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/NoCheckBeforeUnsafePutUser.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/NoCheckBeforeUnsafePutUser.expected @@ -1,3 +1,3 @@ -| test.cpp:16:22:16:23 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:16:22:16:23 | ref arg & ... | ref arg & ... | -| test.cpp:37:22:37:23 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:37:22:37:23 | ref arg & ... | ref arg & ... | -| test.cpp:65:22:65:28 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:65:22:65:28 | ref arg & ... | ref arg & ... | +| test.cpp:20:21:20:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:20:21:20:22 | ref arg & ... | ref arg & ... | +| test.cpp:41:21:41:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:41:21:41:22 | ref arg & ... | ref arg & ... | +| test.cpp:69:21:69:27 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:69:21:69:27 | ref arg & ... | ref arg & ... | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp index cac53a779ca..277b9a545e2 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser/test.cpp @@ -1,7 +1,11 @@ typedef unsigned long size_t; -void SYSC_SOMESYSTEMCALL(void *param); +#define SYSCALL_DEFINE(name, ...) \ + void do_sys_##name(); \ + void sys_##name(...) { do_sys_##name(); } \ + void do_sys_##name() +SYSCALL_DEFINE(somesystemcall, void *param) {}; bool user_access_begin_impl(const void *where, size_t sz); void user_access_end_impl(); @@ -13,14 +17,14 @@ void unsafe_put_user_impl(int what, const void *where, size_t sz); void test1(int p) { - SYSC_SOMESYSTEMCALL(&p); + sys_somesystemcall(&p); unsafe_put_user(123, &p); // BAD } void test2(int p) { - SYSC_SOMESYSTEMCALL(&p); + sys_somesystemcall(&p); if (user_access_begin(&p, sizeof(p))) { @@ -34,7 +38,7 @@ void test3() { int v; - SYSC_SOMESYSTEMCALL(&v); + sys_somesystemcall(&v); unsafe_put_user(123, &v); // BAD } @@ -43,7 +47,7 @@ void test4() { int v; - SYSC_SOMESYSTEMCALL(&v); + sys_somesystemcall(&v); if (user_access_begin(&v, sizeof(v))) { @@ -62,7 +66,7 @@ void test5() { data myData; - SYSC_SOMESYSTEMCALL(&myData); + sys_somesystemcall(&myData); unsafe_put_user(123, &(myData.x)); // BAD } @@ -71,7 +75,7 @@ void test6() { data myData; - SYSC_SOMESYSTEMCALL(&myData); + sys_somesystemcall(&myData); if (user_access_begin(&myData, sizeof(myData))) {