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 <stdio.h> 6#include <stdlib.h> 7 8#include <zircon/process.h> 9#include <zircon/syscalls.h> 10#include <zircon/syscalls/object.h> 11#include <unittest/unittest.h> 12 13static bool handle_replace_test(void) { 14 BEGIN_TEST; 15 16 zx_handle_t event = ZX_HANDLE_INVALID; 17 ASSERT_EQ(ZX_OK, zx_event_create(0u, &event), ""); 18 19 zx_handle_t replaced = ZX_HANDLE_INVALID; 20 ASSERT_EQ(ZX_OK, zx_handle_replace(event, ZX_RIGHTS_BASIC, &replaced), ""); 21 ASSERT_EQ(ZX_ERR_BAD_HANDLE, zx_handle_close(event), ""); 22 23 zx_handle_t failed = ZX_HANDLE_INVALID; 24 ASSERT_EQ(ZX_ERR_INVALID_ARGS, zx_handle_replace(replaced, ZX_RIGHT_SIGNAL, &failed), ""); 25 ASSERT_EQ(ZX_ERR_BAD_HANDLE, zx_handle_close(replaced), ""); 26 ASSERT_EQ(ZX_HANDLE_INVALID, failed, ""); 27 28 END_TEST; 29} 30 31static bool handle_info_test(void) { 32 BEGIN_TEST; 33 34 zx_handle_t event; 35 ASSERT_EQ(zx_event_create(0u, &event), 0, ""); 36 zx_handle_t duped; 37 zx_status_t status = zx_handle_duplicate(event, ZX_RIGHT_SAME_RIGHTS, &duped); 38 ASSERT_EQ(status, ZX_OK, ""); 39 40 ASSERT_EQ(zx_object_get_info(event, ZX_INFO_HANDLE_VALID, NULL, 0u, NULL, NULL), ZX_OK, 41 "handle should be valid"); 42 ASSERT_EQ(zx_handle_close(event), ZX_OK, "failed to close the handle"); 43 ASSERT_EQ(zx_object_get_info(event, ZX_INFO_HANDLE_VALID, NULL, 0u, NULL, NULL), ZX_ERR_BAD_HANDLE, 44 "handle should be valid"); 45 46 zx_info_handle_basic_t info = {}; 47 ASSERT_EQ(zx_object_get_info(duped, ZX_INFO_HANDLE_BASIC, &info, 4u, NULL, NULL), 48 ZX_ERR_BUFFER_TOO_SMALL, "bad struct size validation"); 49 50 status = zx_object_get_info(duped, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), NULL, NULL); 51 ASSERT_EQ(status, ZX_OK, "handle should be valid"); 52 53 const zx_rights_t evr = ZX_RIGHTS_BASIC | 54 ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL; 55 56 EXPECT_GT(info.koid, 0ULL, "object id should be positive"); 57 EXPECT_EQ(info.type, (uint32_t)ZX_OBJ_TYPE_EVENT, "handle should be an event"); 58 EXPECT_EQ(info.rights, evr, "wrong set of rights"); 59 EXPECT_EQ(info.props, (uint32_t)ZX_OBJ_PROP_WAITABLE, ""); 60 EXPECT_EQ(info.related_koid, 0ULL, "events don't have associated koid"); 61 62 zx_handle_close(event); 63 zx_handle_close(duped); 64 65 END_TEST; 66} 67 68static bool handle_related_koid_test(void) { 69 BEGIN_TEST; 70 71 zx_info_handle_basic_t info0 = {}; 72 zx_info_handle_basic_t info1 = {}; 73 74 zx_status_t status = zx_object_get_info( 75 zx_job_default(), ZX_INFO_HANDLE_BASIC, &info0, sizeof(info0), NULL, NULL); 76 ASSERT_EQ(status, ZX_OK, ""); 77 78 status = zx_object_get_info( 79 zx_process_self(), ZX_INFO_HANDLE_BASIC, &info1, sizeof(info1), NULL, NULL); 80 ASSERT_EQ(status, ZX_OK, ""); 81 82 EXPECT_EQ(info0.type, (uint32_t)ZX_OBJ_TYPE_JOB, ""); 83 EXPECT_EQ(info1.type, (uint32_t)ZX_OBJ_TYPE_PROCESS, ""); 84 85 zx_handle_t thread; 86 status = zx_thread_create(zx_process_self(), "hitr", 4, 0u, &thread); 87 ASSERT_EQ(status, ZX_OK, ""); 88 89 zx_info_handle_basic_t info2 = {}; 90 91 status = zx_object_get_info( 92 thread, ZX_INFO_HANDLE_BASIC, &info2, sizeof(info2), NULL, NULL); 93 ASSERT_EQ(status, ZX_OK, ""); 94 95 EXPECT_EQ(info2.type, (uint32_t)ZX_OBJ_TYPE_THREAD, ""); 96 97 // The related koid of a process is its job and this test assumes that the 98 // default job is in fact the parent job of this test. Equivalently, a thread's 99 // associated koid is the process koid. 100 EXPECT_EQ(info1.related_koid, info0.koid, ""); 101 EXPECT_EQ(info2.related_koid, info1.koid, ""); 102 103 zx_handle_close(thread); 104 105 zx_handle_t sock0, sock1; 106 status = zx_socket_create(0u, &sock0, &sock1); 107 ASSERT_EQ(status, ZX_OK, ""); 108 109 status = zx_object_get_info( 110 sock0, ZX_INFO_HANDLE_BASIC, &info0, sizeof(info0), NULL, NULL); 111 ASSERT_EQ(status, ZX_OK, ""); 112 113 status = zx_object_get_info( 114 sock1, ZX_INFO_HANDLE_BASIC, &info1, sizeof(info1), NULL, NULL); 115 ASSERT_EQ(status, ZX_OK, ""); 116 117 EXPECT_EQ(info0.type, (uint32_t)ZX_OBJ_TYPE_SOCKET, ""); 118 EXPECT_EQ(info1.type, (uint32_t)ZX_OBJ_TYPE_SOCKET, ""); 119 120 // The related koid of a socket pair are each other koids. 121 EXPECT_EQ(info0.related_koid, info1.koid, ""); 122 EXPECT_EQ(info1.related_koid, info0.koid, ""); 123 124 zx_handle_close(sock0); 125 zx_handle_close(sock1); 126 END_TEST; 127} 128 129static bool handle_rights_test(void) { 130 BEGIN_TEST; 131 132 zx_handle_t event; 133 ASSERT_EQ(zx_event_create(0u, &event), 0, ""); 134 zx_handle_t duped_ro, duped_ro2; 135 ASSERT_EQ(zx_handle_duplicate(event, ZX_RIGHT_READ, &duped_ro), ZX_OK, ""); 136 ASSERT_EQ(zx_handle_duplicate(event, ZX_RIGHT_READ, &duped_ro2), ZX_OK, ""); 137 138 zx_info_handle_basic_t info = {}; 139 zx_status_t status = zx_object_get_info(duped_ro, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), NULL, NULL); 140 ASSERT_EQ(status, ZX_OK, "handle should be valid"); 141 142 ASSERT_EQ(info.rights, ZX_RIGHT_READ, "wrong set of rights"); 143 144 zx_handle_t h; 145 status = zx_handle_duplicate(duped_ro, ZX_RIGHT_SAME_RIGHTS, &h); 146 ASSERT_EQ(status, ZX_ERR_ACCESS_DENIED, "should fail rights check"); 147 148 status = zx_handle_duplicate(event, ZX_RIGHT_EXECUTE | ZX_RIGHT_READ, &h); 149 ASSERT_EQ(status, ZX_ERR_INVALID_ARGS, "cannot upgrade rights"); 150 151 ASSERT_EQ(zx_handle_replace(duped_ro, ZX_RIGHT_EXECUTE | ZX_RIGHT_READ, &h), ZX_ERR_INVALID_ARGS, 152 "cannot upgrade rights"); 153 // duped_ro1 should now be invalid. 154 ASSERT_EQ(zx_handle_close(duped_ro), ZX_ERR_BAD_HANDLE, "replaced handle should be invalid on failure"); 155 156 status = zx_handle_replace(duped_ro2, ZX_RIGHT_SAME_RIGHTS, &h); 157 ASSERT_EQ(status, ZX_OK, "should be able to replace handle"); 158 // duped_ro2 should now be invalid. 159 160 ASSERT_EQ(zx_handle_close(event), ZX_OK, "failed to close original handle"); 161 ASSERT_EQ(zx_handle_close(duped_ro2), ZX_ERR_BAD_HANDLE, "replaced handle should be invalid on success"); 162 ASSERT_EQ(zx_handle_close(h), ZX_OK, "failed to close replacement handle"); 163 164 END_TEST; 165} 166 167BEGIN_TEST_CASE(handle_info_tests) 168RUN_TEST(handle_replace_test) 169RUN_TEST(handle_info_test) 170RUN_TEST(handle_related_koid_test) 171RUN_TEST(handle_rights_test) 172END_TEST_CASE(handle_info_tests) 173 174#ifndef BUILD_COMBINED_TESTS 175int main(int argc, char** argv) { 176 return unittest_run_all_tests(argc, argv) ? 0 : -1; 177} 178#endif 179