1 /*
2 * Copyright 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 // Authors: corbin.souffrant@leviathansecurity.com
17 // brian.balling@leviathansecurity.com
18
19 #include <fuzzer/FuzzedDataProvider.h>
20 #include <helpers.h>
21 #include <pdx/client_channel.h>
22 #include <pdx/service.h>
23 #include <pdx/service_dispatcher.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <sys/eventfd.h>
27 #include <thread>
28
29 using namespace android::pdx;
30
31 // Fuzzer for Message object functions.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)32 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
33 FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
34
35 FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
36 std::shared_ptr<Service> service(
37 new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
38 std::shared_ptr<Channel> channel(nullptr);
39
40 // Generate a random Message object to call functions in.
41 MessageInfo info;
42 info.pid = fdp.ConsumeIntegral<int>();
43 info.tid = fdp.ConsumeIntegral<int>();
44 info.cid = fdp.ConsumeIntegral<int>();
45 info.mid = fdp.ConsumeIntegral<int>();
46 info.euid = fdp.ConsumeIntegral<int>();
47 info.egid = fdp.ConsumeIntegral<int>();
48 info.op = fdp.ConsumeIntegral<int32_t>();
49 info.flags = fdp.ConsumeIntegral<uint32_t>();
50 info.service = service.get();
51 info.channel = channel.get();
52 info.send_len = fdp.ConsumeIntegral<size_t>();
53 info.recv_len = fdp.ConsumeIntegral<size_t>();
54 info.fd_count = fdp.ConsumeIntegral<size_t>();
55 if (fdp.remaining_bytes() >= 32) {
56 std::vector<uint8_t> impulse_vec = fdp.ConsumeBytes<uint8_t>(32);
57 memcpy(info.impulse, impulse_vec.data(), 32);
58 }
59
60 Message message = Message(info);
61
62 // A bunch of getters that probably won't do much, but might as well
63 // get coverage, while we are here.
64 message.GetProcessId();
65 message.GetThreadId();
66 message.GetEffectiveUserId();
67 message.GetEffectiveGroupId();
68 message.GetChannelId();
69 message.GetMessageId();
70 message.GetOp();
71 message.GetFlags();
72 message.GetSendLength();
73 message.GetReceiveLength();
74 message.GetFileDescriptorCount();
75 message.ImpulseEnd();
76 message.replied();
77 message.IsChannelExpired();
78 message.IsServiceExpired();
79 message.GetState();
80 message.GetState();
81
82 // Some misc. functions.
83 unsigned int fd = fdp.ConsumeIntegral<unsigned int>();
84 int clear_mask = fdp.ConsumeIntegral<int>();
85 int set_mask = fdp.ConsumeIntegral<int>();
86 Status<void> status = {};
87 message.ModifyChannelEvents(clear_mask, set_mask);
88
89 // Fuzz the handle functions.
90 LocalHandle l_handle = {};
91 BorrowedHandle b_handle = {};
92 RemoteHandle r_handle = {};
93 LocalChannelHandle lc_handle = {};
94 BorrowedChannelHandle bc_handle = {};
95 RemoteChannelHandle rc_handle = {};
96 FileReference f_ref = fdp.ConsumeIntegral<int32_t>();
97 ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>();
98
99 // These don't actually modify any state in the Message or params.
100 // They can be called in any order.
101 message.PushFileHandle(b_handle);
102 message.PushFileHandle(r_handle);
103 message.PushChannelHandle(lc_handle);
104 message.PushChannelHandle(bc_handle);
105 message.PushChannelHandle(rc_handle);
106 message.GetFileHandle(f_ref, &l_handle);
107 message.GetChannelHandle(c_ref, &lc_handle);
108
109 // Can only reply once, pick at random.
110 switch (fdp.ConsumeIntegral<uint8_t>()) {
111 case 0:
112 message.ReplyFileDescriptor(fd);
113 break;
114 case 1:
115 message.Reply(status);
116 break;
117 case 2:
118 message.Reply(l_handle);
119 break;
120 case 3:
121 message.Reply(b_handle);
122 break;
123 case 4:
124 message.Reply(r_handle);
125 break;
126 case 5:
127 message.Reply(lc_handle);
128 break;
129 case 6:
130 message.Reply(bc_handle);
131 break;
132 case 7:
133 message.Reply(rc_handle);
134 }
135
136 // Fuzz the channel functions.
137 int flags = fdp.ConsumeIntegral<int>();
138 int channel_id = 0;
139 message.PushChannel(flags, channel, &channel_id);
140 message.CheckChannel(service.get(), c_ref, &channel);
141 message.CheckChannel(c_ref, &channel);
142 message.PushChannel(service.get(), flags, channel, &channel_id);
143 size_t iovec_size = sizeof(iovec);
144 struct iovec* iovecs = nullptr;
145
146 // Fuzz the read/write functions. Needs at least one iovec, plus one byte.
147 if (fdp.remaining_bytes() >= iovec_size + 1) {
148 std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size);
149 struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data());
150 std::vector<uint8_t> tmp_buf =
151 fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
152 void* buf = reinterpret_cast<void*>(tmp_buf.data());
153 size_t buf_size = fdp.ConsumeIntegral<size_t>();
154
155 // Capping num_vecs to 1024 so it doesn't allocate too much memory.
156 size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
157
158 if (num_vecs > 0)
159 iovecs = new struct iovec[num_vecs];
160 for (size_t i = 0; i < num_vecs; i++) {
161 iovecs[i] = *vector;
162 }
163
164 message.ReadAll(vector, buf_size);
165 message.WriteAll(buf, buf_size);
166 message.ReadVectorAll(vector, num_vecs);
167 message.WriteVectorAll(vector, num_vecs);
168 message.ReadVector(vector, buf_size);
169 message.WriteVector(vector, buf_size);
170 }
171
172 if (iovecs != nullptr)
173 delete[] iovecs;
174 return 0;
175 }
176