Forráskód Böngészése

[LibOS] Return EFAULT on null file in execve()

Previously, execve(NULL, ...) failed with segfault. This commit adds
memory checks that all arguments of execve() are valid memory regions.
Also adds LibOS regression test on execve(bad-file, bad-args, bad-env).
Dmitrii Kuvaiskii 5 éve
szülő
commit
880d70a259

+ 20 - 1
LibOS/shim/src/sys/shim_exec.c

@@ -262,11 +262,30 @@ int shim_do_execve (const char * file, const char ** argv,
     struct shim_dentry * dent = NULL;
     int ret = 0, argc = 0;
 
-    for (const char ** a = argv ; *a ; a++, argc++);
+    if (test_user_string(file))
+        return -EFAULT;
+
+    for (const char** a = argv; /* no condition*/; a++, argc++) {
+        if (test_user_memory(a, sizeof(*a), false))
+            return -EFAULT;
+        if (*a == NULL)
+            break;
+        if (test_user_string(*a))
+            return -EFAULT;
+    }
 
     if (!envp)
         envp = initial_envp;
 
+    for (const char** e = envp; /* no condition*/; e++) {
+        if (test_user_memory(e, sizeof(*e), false))
+            return -EFAULT;
+        if (*e == NULL)
+            break;
+        if (test_user_string(*e))
+            return -EFAULT;
+    }
+
     BEGIN_PROFILE_INTERVAL();
 
 

+ 13 - 0
LibOS/shim/test/regression/00_bootstrap.py

@@ -32,6 +32,19 @@ regression.add_check(name="2 page child binary",
 rv = regression.run_checks()
 if rv: sys.exit(rv)
 
+# Running execve with invalid pointers in arguments
+regression = Regression(loader, "exec_invalid_args")
+
+regression.add_check(name="Execve with invalid pointers in arguments",
+    check=lambda res: "execve(invalid-path) correctly returned error" in res[0].out and \
+                      "execve(invalid-argv-ptr) correctly returned error" in res[0].out and \
+                      "execve(invalid-envp-ptr) correctly returned error" in res[0].out and \
+                      "execve(invalid-argv) correctly returned error" in res[0].out and \
+                      "execve(invalid-envp) correctly returned error" in res[0].out)
+
+rv = regression.run_checks()
+if rv: sys.exit(rv)
+
 # Shared Object Test
 regression = Regression(loader, "shared_object")
 

+ 37 - 0
LibOS/shim/test/regression/exec_invalid_args.c

@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+int main(int argc, const char** argv, const char** envp) {
+    int r;
+    char* badptr = (char*) -1;
+
+    char* bad_argv[]  = { badptr,  NULL };
+    char* good_argv[] = { "DUMMY", NULL };
+
+    char* bad_envp[]  = { badptr,  NULL };
+    char* good_envp[] = { "DUMMY", NULL };
+
+    r = execve(badptr, good_argv, good_envp);
+    if (r == -1 && errno == EFAULT)
+        printf("execve(invalid-path) correctly returned error\n");
+
+    r = execve(argv[0], badptr, good_envp);
+    if (r == -1 && errno == EFAULT)
+        printf("execve(invalid-argv-ptr) correctly returned error\n");
+
+    r = execve(argv[0], good_argv, badptr);
+    if (r == -1 && errno == EFAULT)
+        printf("execve(invalid-envp-ptr) correctly returned error\n");
+
+    r = execve(argv[0], bad_argv, good_envp);
+    if (r == -1 && errno == EFAULT)
+        printf("execve(invalid-argv) correctly returned error\n");
+
+    r = execve(argv[0], good_argv, bad_envp);
+    if (r == -1 && errno == EFAULT)
+        printf("execve(invalid-envp) correctly returned error\n");
+
+    return 0;
+}