Understand syscalls better.

This commit is contained in:
Geoffrey White
2022-05-26 13:50:48 +01:00
parent e3ea7751d1
commit 2bcf7e17c8
3 changed files with 21 additions and 14 deletions

View File

@@ -22,15 +22,18 @@ import semmle.code.cpp.dataflow.DataFlow
*/ */
class SystemCallFunction extends Function { class SystemCallFunction extends Function {
SystemCallFunction() { 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). * A value that comes from a Linux system call (sources).
*/ */
class SystemParameterSource extends DataFlow::Node { class SystemCallSource extends DataFlow::Node {
SystemParameterSource() { SystemCallSource() {
exists(FunctionCall fc | exists(FunctionCall fc |
fc.getTarget() instanceof SystemCallFunction and fc.getTarget() instanceof SystemCallFunction and
( (
@@ -72,7 +75,7 @@ class UnSafePutUserMacro extends Macro {
} }
} }
class ExploitableUserModePtrParam extends SystemParameterSource { class ExploitableUserModePtrParam extends SystemCallSource {
ExploitableUserModePtrParam() { ExploitableUserModePtrParam() {
exists(UnSafePutUserMacro unsafePutUser | exists(UnSafePutUserMacro unsafePutUser |
DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr())) DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr()))

View File

@@ -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: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: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: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: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: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 & ... |

View File

@@ -1,7 +1,11 @@
typedef unsigned long size_t; 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); bool user_access_begin_impl(const void *where, size_t sz);
void user_access_end_impl(); 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) void test1(int p)
{ {
SYSC_SOMESYSTEMCALL(&p); sys_somesystemcall(&p);
unsafe_put_user(123, &p); // BAD unsafe_put_user(123, &p); // BAD
} }
void test2(int p) void test2(int p)
{ {
SYSC_SOMESYSTEMCALL(&p); sys_somesystemcall(&p);
if (user_access_begin(&p, sizeof(p))) if (user_access_begin(&p, sizeof(p)))
{ {
@@ -34,7 +38,7 @@ void test3()
{ {
int v; int v;
SYSC_SOMESYSTEMCALL(&v); sys_somesystemcall(&v);
unsafe_put_user(123, &v); // BAD unsafe_put_user(123, &v); // BAD
} }
@@ -43,7 +47,7 @@ void test4()
{ {
int v; int v;
SYSC_SOMESYSTEMCALL(&v); sys_somesystemcall(&v);
if (user_access_begin(&v, sizeof(v))) if (user_access_begin(&v, sizeof(v)))
{ {
@@ -62,7 +66,7 @@ void test5()
{ {
data myData; data myData;
SYSC_SOMESYSTEMCALL(&myData); sys_somesystemcall(&myData);
unsafe_put_user(123, &(myData.x)); // BAD unsafe_put_user(123, &(myData.x)); // BAD
} }
@@ -71,7 +75,7 @@ void test6()
{ {
data myData; data myData;
SYSC_SOMESYSTEMCALL(&myData); sys_somesystemcall(&myData);
if (user_access_begin(&myData, sizeof(myData))) if (user_access_begin(&myData, sizeof(myData)))
{ {