• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <uapi/err.h>
18 
19 #include <lib/tipc/tipc.h>
20 #include <lib/unittest/unittest.h>
21 
22 #include <trusty/time.h>
23 #include <trusty_unittest.h>
24 
25 #include <crasher.h>
26 #include <crasher_consts.h>
27 
28 #define TLOG_TAG "crash-test"
29 
30 #define US2NS(us) ((us) * (1000LL))
31 #define MS2NS(ms) (US2NS(ms) * 1000LL)
32 #define S2NS(s) (MS2NS(s) * 1000LL)
33 
crasher_connect(handle_t * chan)34 static int crasher_connect(handle_t* chan) {
35     return tipc_connect(chan, CRASHER_PORT);
36 }
37 
crasher_command(handle_t chan,enum crasher_command cmd)38 static int crasher_command(handle_t chan, enum crasher_command cmd) {
39     int ret;
40     struct uevent evt;
41     struct crasher_msg msg = {
42             .cmd = cmd,
43     };
44 
45     ret = tipc_send1(chan, &msg, sizeof(msg));
46     ASSERT_GE(ret, 0);
47     ASSERT_EQ(ret, sizeof(msg));
48 
49     ret = wait(chan, &evt, INFINITE_TIME);
50     if (ret) {
51         EXPECT_EQ(ret, ERR_CHANNEL_CLOSED);
52         return ret;
53     }
54     if (!(evt.event & IPC_HANDLE_POLL_MSG)) {
55         EXPECT_EQ(evt.event, IPC_HANDLE_POLL_HUP);
56         if (evt.event & IPC_HANDLE_POLL_HUP) {
57             return ERR_CHANNEL_CLOSED;
58         }
59         return ERR_IO;
60     }
61 
62     ret = tipc_recv1(chan, sizeof(msg), &msg, sizeof(msg));
63     if (ret < 0) {
64         EXPECT_EQ(ret, ERR_CHANNEL_CLOSED);
65         return ret;
66     }
67     ASSERT_EQ(ret, sizeof(msg));
68 
69     return 0;
70 
71 test_abort:
72     return ret < 0 ? ret : ERR_IO;
73 }
74 
TEST(crash,connect)75 TEST(crash, connect) {
76     handle_t chan = INVALID_IPC_HANDLE;
77     ASSERT_EQ(crasher_connect(&chan), 0);
78     ASSERT_EQ(crasher_command(chan, CRASHER_NOP), 0);
79 
80 test_abort:
81     close(chan);
82 }
83 
TEST(crash,exit_success)84 TEST(crash, exit_success) {
85     handle_t chan1 = INVALID_IPC_HANDLE;
86     handle_t chan2 = INVALID_IPC_HANDLE;
87     int64_t t1, t2;
88 
89     ASSERT_EQ(crasher_connect(&chan1), 0);
90     trusty_gettime(0, &t1);
91     ASSERT_EQ(crasher_command(chan1, CRASHER_EXIT_SUCCESS), ERR_CHANNEL_CLOSED);
92     ASSERT_EQ(crasher_connect(&chan2), 0);
93     trusty_gettime(0, &t2);
94     ASSERT_EQ(crasher_command(chan2, CRASHER_EXIT_SUCCESS), ERR_CHANNEL_CLOSED);
95     ASSERT_LT(t2 - t1, S2NS(1));
96 
97 test_abort:
98     close(chan1);
99     close(chan2);
100 }
101 
TEST(crash,exit_failure)102 TEST(crash, exit_failure) {
103     handle_t chan1 = INVALID_IPC_HANDLE;
104     handle_t chan2 = INVALID_IPC_HANDLE;
105     int64_t t1, t2;
106 
107     ASSERT_EQ(crasher_connect(&chan1), 0);
108     trusty_gettime(0, &t1);
109     ASSERT_EQ(crasher_command(chan1, CRASHER_EXIT_FAILURE), ERR_CHANNEL_CLOSED);
110     ASSERT_EQ(crasher_connect(&chan2), 0);
111     trusty_gettime(0, &t2);
112     ASSERT_EQ(crasher_command(chan2, CRASHER_EXIT_FAILURE), ERR_CHANNEL_CLOSED);
113     ASSERT_GT(t2 - t1, S2NS(1));
114 
115 test_abort:
116     close(chan1);
117     close(chan2);
118 }
119 
TEST(crash,read_null_ptr)120 TEST(crash, read_null_ptr) {
121     handle_t chan = INVALID_IPC_HANDLE;
122     ASSERT_EQ(crasher_connect(&chan), 0);
123     ASSERT_EQ(crasher_command(chan, CRASHER_READ_NULL_PTR), ERR_CHANNEL_CLOSED);
124 
125 test_abort:
126     close(chan);
127 }
128 
129 #if __aarch64__
TEST(crash,brk_instruction)130 TEST(crash, brk_instruction) {
131     handle_t chan = INVALID_IPC_HANDLE;
132     ASSERT_EQ(crasher_connect(&chan), 0);
133     ASSERT_EQ(crasher_command(chan, CRASHER_BRK), ERR_CHANNEL_CLOSED);
134 
135 test_abort:
136     close(chan);
137 }
138 #endif
139 
TEST(crash,read_bad_ptr)140 TEST(crash, read_bad_ptr) {
141     handle_t chan = INVALID_IPC_HANDLE;
142     ASSERT_EQ(crasher_connect(&chan), 0);
143     ASSERT_EQ(crasher_command(chan, CRASHER_READ_BAD_PTR), ERR_CHANNEL_CLOSED);
144 
145 test_abort:
146     close(chan);
147 }
148 
TEST(crash,write_bad_ptr)149 TEST(crash, write_bad_ptr) {
150     handle_t chan = INVALID_IPC_HANDLE;
151     ASSERT_EQ(crasher_connect(&chan), 0);
152     ASSERT_EQ(crasher_command(chan, CRASHER_WRITE_BAD_PTR), ERR_CHANNEL_CLOSED);
153 
154 test_abort:
155     close(chan);
156 }
157 
TEST(crash,write_ro_ptr)158 TEST(crash, write_ro_ptr) {
159     handle_t chan = INVALID_IPC_HANDLE;
160     ASSERT_EQ(crasher_connect(&chan), 0);
161     ASSERT_EQ(crasher_command(chan, CRASHER_WRITE_RO_PTR), ERR_CHANNEL_CLOSED);
162 
163 test_abort:
164     close(chan);
165 }
166 
TEST(crash,exec_rodata)167 TEST(crash, exec_rodata) {
168     handle_t chan = INVALID_IPC_HANDLE;
169     ASSERT_EQ(crasher_connect(&chan), 0);
170     ASSERT_EQ(crasher_command(chan, CRASHER_EXEC_RODATA), ERR_CHANNEL_CLOSED);
171 
172 test_abort:
173     close(chan);
174 }
175 
TEST(crash,exec_data)176 TEST(crash, exec_data) {
177     handle_t chan = INVALID_IPC_HANDLE;
178     ASSERT_EQ(crasher_connect(&chan), 0);
179     ASSERT_EQ(crasher_command(chan, CRASHER_EXEC_DATA), ERR_CHANNEL_CLOSED);
180 
181 test_abort:
182     close(chan);
183 }
184 
185 PORT_TEST(crash, "com.android.trusty.crashtest")
186