| diff --git a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c |
| index 3c238e6..7481dd2 100644 |
| --- a/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c |
| +++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c |
| @@ -19,7 +19,6 @@ |
| #include <linux/prctl.h> |
| #include <linux/ptrace.h> |
| #include <linux/seccomp.h> |
| -#include <poll.h> |
| #include <pthread.h> |
| #include <semaphore.h> |
| #include <signal.h> |
| @@ -28,6 +27,7 @@ |
| #include <string.h> |
| #include <linux/elf.h> |
| #include <sys/uio.h> |
| +#include <sys/utsname.h> |
| #include <fcntl.h> // ANDROID |
| #include <sys/mman.h> |
| #include <sys/times.h> |
| @@ -1798,7 +1798,8 @@ TEST_F(TSYNC, two_siblings_not_under_filter) { |
| } |
| |
| /* Make sure restarted syscalls are seen directly as "restart_syscall". */ |
| -TEST(syscall_restart) { |
| +TEST(syscall_restart) |
| +{ |
| long ret; |
| unsigned long msg; |
| pid_t child_pid; |
| @@ -1815,20 +1816,25 @@ TEST(syscall_restart) { |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0), |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0), |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0), |
| - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_poll, 4, 0), |
| + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0), |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0), |
| |
| /* Allow __NR_write for easy logging. */ |
| BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_write, 0, 1), |
| BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), |
| BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), |
| - BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), /* poll */ |
| - BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), /* restart */ |
| + /* The nanosleep jump target. */ |
| + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x100), |
| + /* The restart_syscall jump target. */ |
| + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE|0x200), |
| }; |
| struct sock_fprog prog = { |
| - .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), |
| + .len = (unsigned short) (sizeof(filter)/sizeof(filter[0])), |
| .filter = filter, |
| }; |
| +#if defined(__arm__) |
| + struct utsname utsbuf; |
| +#endif |
| |
| ASSERT_EQ(0, pipe(pipefd)); |
| |
| @@ -1837,10 +1843,7 @@ TEST(syscall_restart) { |
| if (child_pid == 0) { |
| /* Child uses EXPECT not ASSERT to deliver status correctly. */ |
| char buf = ' '; |
| - struct pollfd fds = { |
| - .fd = pipefd[0], |
| - .events = POLLIN, |
| - }; |
| + struct timespec timeout = { }; |
| |
| /* Attach parent as tracer and stop. */ |
| EXPECT_EQ(0, ptrace(PTRACE_TRACEME)); |
| @@ -1864,10 +1867,11 @@ TEST(syscall_restart) { |
| TH_LOG("Failed to get sync data from read()"); |
| } |
| |
| - /* Start poll to be interrupted. */ |
| + /* Start nanosleep to be interrupted. */ |
| + timeout.tv_sec = 1; |
| errno = 0; |
| - EXPECT_EQ(1, poll(&fds, 1, -1)) { |
| - TH_LOG("Call to poll() failed (errno %d)", errno); |
| + EXPECT_EQ(0, nanosleep(&timeout, NULL)) { |
| + TH_LOG("Call to nanosleep() failed (errno %d)", errno); |
| } |
| |
| /* Read final sync from parent. */ |
| @@ -1892,14 +1896,14 @@ TEST(syscall_restart) { |
| ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); |
| ASSERT_EQ(1, write(pipefd[1], ".", 1)); |
| |
| - /* Wait for poll() to start. */ |
| + /* Wait for nanosleep() to start. */ |
| ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); |
| ASSERT_EQ(true, WIFSTOPPED(status)); |
| ASSERT_EQ(SIGTRAP, WSTOPSIG(status)); |
| ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16)); |
| ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg)); |
| ASSERT_EQ(0x100, msg); |
| - EXPECT_EQ(__NR_poll, get_syscall(_metadata, child_pid)); |
| + EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid)); |
| |
| /* Might as well check siginfo for sanity while we're here. */ |
| ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info)); |
| @@ -1910,7 +1914,7 @@ TEST(syscall_restart) { |
| /* Verify signal delivery came from child (seccomp-triggered). */ |
| EXPECT_EQ(child_pid, info.si_pid); |
| |
| - /* Interrupt poll with SIGSTOP (which we'll need to handle). */ |
| + /* Interrupt nanosleep with SIGSTOP (which we'll need to handle). */ |
| ASSERT_EQ(0, kill(child_pid, SIGSTOP)); |
| ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); |
| ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); |
| @@ -1920,7 +1924,7 @@ TEST(syscall_restart) { |
| ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info)); |
| EXPECT_EQ(getpid(), info.si_pid); |
| |
| - /* Restart poll with SIGCONT, which triggers restart_syscall. */ |
| + /* Restart nanosleep with SIGCONT, which triggers restart_syscall. */ |
| ASSERT_EQ(0, kill(child_pid, SIGCONT)); |
| ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); |
| ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0)); |
| @@ -1934,16 +1938,25 @@ TEST(syscall_restart) { |
| ASSERT_EQ(SIGTRAP, WSTOPSIG(status)); |
| ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16)); |
| ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg)); |
| + |
| ASSERT_EQ(0x200, msg); |
| ret = get_syscall(_metadata, child_pid); |
| #if defined(__arm__) |
| - /* FIXME: ARM does not expose true syscall in registers. */ |
| - EXPECT_EQ(__NR_poll, ret); |
| -#else |
| - EXPECT_EQ(__NR_restart_syscall, ret); |
| + /* |
| + * FIXME: |
| + * - native ARM registers do NOT expose true syscall. |
| + * - compat ARM registers on ARM64 DO expose true syscall. |
| + */ |
| + ASSERT_EQ(0, uname(&utsbuf)); |
| + if (strncmp(utsbuf.machine, "arm", 3) == 0) { |
| + EXPECT_EQ(__NR_nanosleep, ret); |
| + } else |
| #endif |
| + { |
| + EXPECT_EQ(__NR_restart_syscall, ret); |
| + } |
| |
| - /* Write again to end poll. */ |
| + /* Write again to end test. */ |
| ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0)); |
| ASSERT_EQ(1, write(pipefd[1], "!", 1)); |
| EXPECT_EQ(0, close(pipefd[1])); |