Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Unified Diff: tests/test_patching.cc

Issue 8605003: Add logic for patching calls to the x86-64 vsyscall page (Closed) Base URL: https://seccompsandbox.googlecode.com/svn/trunk
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « library.cc ('k') | tests/test_patching_input.S » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/test_patching.cc
diff --git a/tests/test_patching.cc b/tests/test_patching.cc
index bb1babbc65a2a22856953edee5ef307066853dbf..448bdac30f047c45bf6e2c2489ff277dded1fe87 100644
--- a/tests/test_patching.cc
+++ b/tests/test_patching.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/time.h>
#include "library.h"
#include "sandbox.h"
@@ -49,3 +51,82 @@ TEST(test_patching_syscall) {
StartSeccompSandbox();
CHECK(my_getpid() == pid);
}
+
+#if defined(__x86_64__)
+
+// These test cases test patching calls to the vsyscall page, which is
+// present on x86-64 only.
+
+// The timer tests below could fail on a heavily loaded machine, but
+// we make a generous allowance for this. They could also fail if the
+// clock is changed while the test is running.
+const int kMaxTime = 30; // Time in seconds
+
+extern "C" int my_vgettimeofday(struct timeval *tv, struct timezone *tz);
+extern char my_vgettimeofday_end[];
+
+extern "C" int my_vtime(time_t *time);
+extern char my_vtime_end[];
+
+extern "C" int my_vgetcpu(unsigned *cpu, unsigned *node, void *tcache);
+extern char my_vgetcpu_end[];
+
+void check_patching_vsyscall(char *func, char *func_end) {
+ patch_range(func, func_end);
+ CHECK(func[0] == '\x48'); // 48 83 ec 08 sub $8, %rsp (unmodified)
+ CHECK(func[1] == '\x83');
+ CHECK(func[2] == '\xec');
+ CHECK(func[3] == '\x08');
+ CHECK(func[4] == '\xe9'); // e9 XX XX XX XX jmp X
+ CHECK(func[9] == '\x90'); // 90 nop
+ CHECK(func[10] == '\x90'); // 90 nop
+ CHECK(func[11] == '\x90'); // 90 nop
+ CHECK(func[12] == '\x90'); // 90 nop
+ CHECK(func[13] == '\x48'); // 48 83 c4 08 add $8, %rsp (unmodified)
+ CHECK(func[14] == '\x83');
+ CHECK(func[15] == '\xc4');
+ CHECK(func[16] == '\x08');
+ CHECK(func[17] == '\xc3'); // c3 ret (unmodified)
+}
+
+TEST(test_patching_vsyscall_gettimeofday) {
+ struct timeval time1;
+ struct timeval time2;
+ CHECK_SUCCEEDS(gettimeofday(&time1, NULL) == 0);
+ CHECK(my_vgettimeofday(&time2, NULL) == 0);
+ CHECK(time1.tv_sec <= time2.tv_sec && time2.tv_sec < time1.tv_sec + kMaxTime);
+
+ check_patching_vsyscall((char *) my_vgettimeofday, my_vgettimeofday_end);
+
+ StartSeccompSandbox();
+ CHECK(my_vgettimeofday(&time2, NULL) == 0);
+ CHECK(time1.tv_sec <= time2.tv_sec && time2.tv_sec < time1.tv_sec + kMaxTime);
+}
+
+TEST(test_patching_vsyscall_time) {
+ time_t time1;
+ time_t time2;
+ CHECK_SUCCEEDS((time1 = time(NULL)) != -1);
+ time2 = time(NULL);
+ CHECK(time1 <= time2 && time2 < time1 + kMaxTime);
+
+ check_patching_vsyscall((char *) my_vtime, my_vtime_end);
+
+ StartSeccompSandbox();
+ time2 = time(NULL);
+ CHECK(time1 <= time2 && time2 < time1 + kMaxTime);
+}
+
+TEST(test_patching_vsyscall_getcpu) {
+ CHECK(my_vgetcpu(NULL, NULL, NULL) == 0);
+
+ check_patching_vsyscall((char *) my_vgetcpu, my_vgetcpu_end);
+
+ StartSeccompSandbox();
+ // glibc's sched_getcpu() could still succeed if it goes via the
+ // vdso and just reads memory, but my_vgetcpu() is always redirected
+ // through the sandbox's handler and is rejected.
+ CHECK(my_vgetcpu(NULL, NULL, NULL) == -ENOSYS);
+}
+
+#endif
« no previous file with comments | « library.cc ('k') | tests/test_patching_input.S » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698