|
@@ -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;
|