1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <inttypes.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #include <zircon/zx-syscall-numbers.h>
10 #include <zircon/syscalls.h>
11 #include <unittest/unittest.h>
12
13 extern zx_status_t bad_syscall(uint64_t num);
14
bad_access_test(void)15 bool bad_access_test(void) {
16 BEGIN_TEST;
17 void* unmapped_addr = (void*)4096;
18 zx_handle_t h[2];
19 EXPECT_EQ(zx_channel_create(0, h, h + 1),
20 0, "Error: channel create failed");
21 EXPECT_LT(zx_channel_write(0, h[0], unmapped_addr, 1, NULL, 0),
22 0, "Error: reading unmapped addr");
23 EXPECT_LT(zx_channel_write(h[0], 0, (void*)KERNEL_ASPACE_BASE - 1, 5, NULL, 0),
24 0, "Error: read crossing kernel boundary");
25 EXPECT_LT(zx_channel_write(h[0], 0, (void*)KERNEL_ASPACE_BASE, 1, NULL, 0),
26 0, "Error: read into kernel space");
27 EXPECT_EQ(zx_channel_write(h[0], 0, (void*)&unmapped_addr, sizeof(void*), NULL, 0),
28 0, "Good syscall failed");
29 END_TEST;
30 }
31
try_bad_syscall(void * arg)32 static void try_bad_syscall(void* arg) {
33 uint64_t num = (uintptr_t)arg;
34 zx_status_t status = bad_syscall(num);
35 UNITTEST_FAIL_TRACEF("bad syscall %#" PRIx64 " returned %d", num, status);
36 }
37
38 #define TRY_BAD_SYSCALL(num) \
39 ASSERT_DEATH(try_bad_syscall, (void*)(uintptr_t)(num), \
40 "bad syscall did not crash")
41
bad_syscall_num_test(void)42 bool bad_syscall_num_test(void) {
43 BEGIN_TEST;
44 TRY_BAD_SYSCALL(ZX_SYS_COUNT);
45 TRY_BAD_SYSCALL(0x80000000ull);
46 TRY_BAD_SYSCALL(0xff00ff0000000000ull);
47 TRY_BAD_SYSCALL(0xff00ff0000000010ull);
48 END_TEST;
49 }
50
51 BEGIN_TEST_CASE(bad_syscall_tests)
RUN_TEST(bad_access_test)52 RUN_TEST(bad_access_test)
53 RUN_TEST(bad_syscall_num_test)
54 END_TEST_CASE(bad_syscall_tests)
55
56 #ifndef BUILD_COMBINED_TESTS
57 int main(int argc, char** argv) {
58 return unittest_run_all_tests(argc, argv) ? 0 : -1;
59 }
60 #endif
61