From b89903da4b6fb52863e0bd0f09971981ebafb1ae Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Fri, 24 May 2019 17:03:56 -0700 Subject: [PATCH] [LibOS] Test syscall arguments during parsing (in inline-debug mode) --- LibOS/shim/src/shim_parser.c | 58 +++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/LibOS/shim/src/shim_parser.c b/LibOS/shim/src/shim_parser.c index 446a79b1..1ffc265b 100644 --- a/LibOS/shim/src/shim_parser.c +++ b/LibOS/shim/src/shim_parser.c @@ -433,7 +433,16 @@ static inline int is_pointer (const char * type) static inline void parse_string_arg (va_list * ap) { - VPRINTF("\"%s\"", ap); + va_list ap_test_arg; + va_copy(ap_test_arg, *ap); + const char* test_arg = va_arg(ap_test_arg, const char*); + if (!test_user_string(test_arg)) { + VPRINTF("\"%s\"", ap); + } else { + /* invalid memory region, print arg as ptr not string */ + VPRINTF("\"(invalid-addr %p)\"", ap); + } + va_end(ap_test_arg); } static inline void parse_pointer_arg (va_list * ap) @@ -732,7 +741,17 @@ static void parse_exec_args (const char * type, va_list * ap) PUTS("["); - for (; *args ; args++) { + for (; ; args++) { + if (test_user_memory(args, sizeof(*args), false)) { + PRINTF("(invalid-argv %p)", args); + break; + } + if (*args == NULL) + break; + if (test_user_string(*args)) { + PRINTF("(invalid-addr %p),", *args); + continue; + } PUTS(*args); PUTS(","); } @@ -749,15 +768,23 @@ static void parse_exec_envp (const char * type, va_list * ap) return; } - int cnt = 0; - PUTS("["); - for (; *envp ; envp++) - if (cnt++ < 2) { - PUTS(*envp); - PUTS(","); + int cnt = 0; + for (; cnt < 2; cnt++, envp++) { + if (test_user_memory(envp, sizeof(*envp), false)) { + PRINTF("(invalid-envp %p)", envp); + break; } + if (*envp == NULL) + break; + if (test_user_string(*envp)) { + PRINTF("(invalid-addr %p),", *envp); + continue; + } + PUTS(*envp); + PUTS(","); + } if (cnt > 2) PRINTF("(%d more)", cnt); @@ -830,6 +857,11 @@ static void parse_sigmask (const char * type, va_list * ap) return; } + if (test_user_memory(sigset, sizeof(*sigset), false)) { + PRINTF("(invalid-addr %p)", sigset); + return; + } + PUTS("["); for (int signum = 1 ; signum <= sizeof(sigset) * 8 ; signum++) @@ -870,6 +902,11 @@ static void parse_timespec (const char * type, va_list * ap) return; } + if (test_user_memory((void*)tv, sizeof(*tv), false)) { + PRINTF("(invalid-addr %p)", tv); + return; + } + PRINTF("[%ld,%ld]", tv->tv_sec, tv->tv_nsec); } @@ -882,6 +919,11 @@ static void parse_sockaddr (const char * type, va_list *ap) return; } + if (test_user_memory((void*)addr, sizeof(*addr), false)) { + PRINTF("(invalid-addr %p)", addr); + return; + } + switch (addr->sa_family) { case AF_INET: { struct sockaddr_in * a = (void *) addr;