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 #define TLOG_TAG "crasher"
18 
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <trusty_log.h>
23 #include <uapi/err.h>
24 
25 #include <lib/tipc/tipc.h>
26 #include <lib/tipc/tipc_srv.h>
27 
28 #include <crasher.h>
29 #include <crasher_consts.h>
30 #include <crasher_funcs.h>
31 
32 static struct tipc_port_acl crasher_port_acl = {
33         .flags = IPC_PORT_ALLOW_TA_CONNECT,
34         .uuid_num = 0,
35         .uuids = NULL,
36         .extra_data = NULL,
37 };
38 
39 static struct tipc_port crasher_port = {
40         .name = CRASHER_PORT,
41         .msg_max_size = sizeof(struct crasher_msg),
42         .msg_queue_len = 1,
43         .acl = &crasher_port_acl,
44         .priv = NULL,
45 };
46 
47 static int __attribute__((no_sanitize("undefined")))
crasher_on_message(const struct tipc_port * port,handle_t chan,void * ctx)48 crasher_on_message(const struct tipc_port* port, handle_t chan, void* ctx) {
49     assert(port == &crasher_port);
50     assert(ctx == NULL);
51     struct crasher_msg msg;
52 
53     int ret = tipc_recv1(chan, sizeof(msg), &msg, sizeof(msg));
54     if (ret < 0 || ret != sizeof(msg)) {
55         TLOGE("Failed to receive message (%d)\n", ret);
56         return ret;
57     }
58 
59     TLOGD("cmd %d\n", msg.cmd);
60 
61     switch (msg.cmd) {
62     case CRASHER_NOP:
63         TLOGI("nop\n");
64         break;
65     case CRASHER_EXIT_SUCCESS:
66         TLOGI("exit success\n");
67         exit(EXIT_SUCCESS);
68         break;
69     case CRASHER_EXIT_FAILURE:
70         TLOGI("exit failure\n");
71         exit(EXIT_FAILURE);
72         break;
73     case CRASHER_READ_NULL_PTR:
74         TLOGI("read null\n");
75         READ_ONCE(*(uint8_t*)NULL);
76         break;
77     case CRASHER_READ_BAD_PTR:
78         TLOGI("read bad ptr\n");
79         READ_ONCE(*(uint8_t*)1);
80         break;
81     case CRASHER_WRITE_BAD_PTR:
82         TLOGI("write bad ptr\n");
83         WRITE_ONCE(*(uint8_t*)1, 0);
84         break;
85     case CRASHER_WRITE_RO_PTR:
86         TLOGI("write ro ptr\n");
87         WRITE_ONCE(*(uint8_t*)crasher_rodata_func, 0);
88         break;
89     case CRASHER_EXEC_RODATA:
90         TLOGI("call crasher_rodata_func\n");
91         crasher_rodata_func();
92         break;
93     case CRASHER_EXEC_DATA:
94         TLOGI("call crasher_data_func\n");
95         crasher_data_func();
96         break;
97 #ifdef __aarch64__
98     case CRASHER_BRK:
99         TLOGI("BRK instruction\n");
100         __asm__("brk #42");
101         break;
102 #endif
103     default:
104         TLOGE("Bad command: %d\n", msg.cmd);
105         return -1;
106     }
107 
108     ret = tipc_send1(chan, &msg, sizeof(msg));
109     if (ret < 0 || ret != sizeof(msg)) {
110         TLOGE("Failed to send message (%d)\n", ret);
111         return ret < 0 ? ret : ERR_IO;
112     }
113     TLOGD("cmd %d done\n", msg.cmd);
114 
115     return 0;
116 }
117 
118 static struct tipc_srv_ops crasher_ops = {
119         .on_message = crasher_on_message,
120 };
121 
main(void)122 int main(void) {
123     struct tipc_hset* hset = tipc_hset_create();
124     if (!hset) {
125         return -1;
126     }
127 
128     int rc = tipc_add_service(hset, &crasher_port, 1, 1, &crasher_ops);
129     if (rc < 0) {
130         return rc;
131     }
132 
133     rc = tipc_run_event_loop(hset);
134     TLOGE("crasher going down: (%d)\n", rc);
135     return rc;
136 }
137