1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "storagedaemon_fuzzer.h"
16
17 #include <cstddef>
18 #include <cstdint>
19 #include <cstring>
20
21 #include "accesstoken_kit.h"
22 #include "message_parcel.h"
23 #include "nativetoken_kit.h"
24 #include "securec.h"
25 #include "storage_daemon.h"
26 #include "storage_daemon_ipc_interface_code.h"
27 #include "storage_daemon_stub.h"
28 #include "token_setproc.h"
29 #include "user_manager.h"
30
31 using namespace OHOS::StorageDaemon;
32
33 namespace OHOS {
34 constexpr uint8_t MAX_CALL_TRANSACTION = 32;
35 constexpr size_t U32_AT_SIZE = 4;
36 constexpr size_t FOO_MAX_LEN = 1024;
37
38 std::shared_ptr<StorageDaemon::StorageDaemon> storageDaemon = std::make_shared<StorageDaemon::StorageDaemon>();
39 std::shared_ptr<StorageDaemon::UserManager> userManager = StorageDaemon::UserManager::GetInstance();
GetU32Data(const char * ptr)40 uint32_t GetU32Data(const char *ptr)
41 {
42 // 将第0个数字左移24位,将第1个数字左移16位,将第2个数字左移8位,第3个数字不左移
43 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
44 }
45
46 enum {
47 TOKEN_INDEX_ONE = 0,
48 TOKEN_INDEX_TWO,
49 TOKEN_INDEX_THREE,
50 };
51
SetNativeToken()52 void SetNativeToken()
53 {
54 uint64_t tokenId;
55 const char **perms = new const char *[3];
56 perms[TOKEN_INDEX_ONE] = "ohos.permission.STORAGE_MANAGER";
57 perms[TOKEN_INDEX_TWO] = "ohos.permission.MOUNT_UNMOUNT_MANAGER";
58 perms[TOKEN_INDEX_THREE] = "ohos.permission.MOUNT_FORMAT_MANAGER";
59 NativeTokenInfoParams infoInstance = {
60 .dcapsNum = 0,
61 .permsNum = 1,
62 .aclsNum = 0,
63 .dcaps = nullptr,
64 .perms = perms,
65 .acls = nullptr,
66 .aplStr = "system_core",
67 };
68
69 infoInstance.processName = "StorageDaemonFuzzTest";
70 tokenId = GetAccessTokenId(&infoInstance);
71 const uint64_t systemAppMask = (static_cast<uint64_t>(1) << 32);
72 tokenId |= systemAppMask;
73 SetSelfTokenID(tokenId);
74 OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
75 delete[] perms;
76 }
77
StorageDaemonFuzzTest(std::unique_ptr<char[]> data,size_t size)78 bool StorageDaemonFuzzTest(std::unique_ptr<char[]> data, size_t size)
79 {
80 SetNativeToken();
81 uint32_t code = GetU32Data(data.get());
82 if (code == 0 ||
83 code % MAX_CALL_TRANSACTION == static_cast<int32_t>(StorageDaemonInterfaceCode::CREATE_SHARE_FILE) ||
84 code % MAX_CALL_TRANSACTION == static_cast<int32_t>(StorageDaemonInterfaceCode::DELETE_SHARE_FILE)) {
85 return true;
86 }
87 MessageParcel datas;
88 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
89 datas.WriteBuffer(data.get(), size);
90 datas.RewindRead(0);
91 MessageParcel reply;
92 MessageOption option;
93 storageDaemon->OnRemoteRequest(code % MAX_CALL_TRANSACTION, datas, reply, option);
94
95 return true;
96 }
97
HandleStartUserFuzzTest(const uint8_t * data,size_t size)98 bool HandleStartUserFuzzTest(const uint8_t *data, size_t size)
99 {
100 MessageParcel datas;
101 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
102 datas.WriteBuffer(data, size);
103 datas.RewindRead(0);
104 MessageParcel reply;
105
106 storageDaemon->HandleStartUser(datas, reply);
107 return true;
108 }
109
HandleStopUserFuzzTest(const uint8_t * data,size_t size)110 bool HandleStopUserFuzzTest(const uint8_t *data, size_t size)
111 {
112 MessageParcel datas;
113 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
114 datas.WriteBuffer(data, size);
115 datas.RewindRead(0);
116 MessageParcel reply;
117
118 storageDaemon->HandleStopUser(datas, reply);
119 return true;
120 }
121
HandlePrepareUserDirsFuzzTest(const uint8_t * data,size_t size)122 bool HandlePrepareUserDirsFuzzTest(const uint8_t *data, size_t size)
123 {
124 MessageParcel datas;
125 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
126 datas.WriteBuffer(data, size);
127 datas.RewindRead(0);
128 MessageParcel reply;
129
130 storageDaemon->HandlePrepareUserDirs(datas, reply);
131 return true;
132 }
133
HandleDestroyUserDirsFuzzTest(const uint8_t * data,size_t size)134 bool HandleDestroyUserDirsFuzzTest(const uint8_t *data, size_t size)
135 {
136 MessageParcel datas;
137 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
138 datas.WriteBuffer(data, size);
139 datas.RewindRead(0);
140 MessageParcel reply;
141
142 storageDaemon->HandleDestroyUserDirs(datas, reply);
143 return true;
144 }
145
HandleMountFuzzTest(const uint8_t * data,size_t size)146 bool HandleMountFuzzTest(const uint8_t *data, size_t size)
147 {
148 MessageParcel datas;
149 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
150 datas.WriteBuffer(data, size);
151 datas.RewindRead(0);
152 MessageParcel reply;
153
154 storageDaemon->HandleMount(datas, reply);
155 return true;
156 }
157
HandleUMountFuzzTest(const uint8_t * data,size_t size)158 bool HandleUMountFuzzTest(const uint8_t *data, size_t size)
159 {
160 MessageParcel datas;
161 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
162 datas.WriteBuffer(data, size);
163 datas.RewindRead(0);
164 MessageParcel reply;
165
166 storageDaemon->HandleUMount(datas, reply);
167 return true;
168 }
169
HandlePartitionFuzzTest(const uint8_t * data,size_t size)170 bool HandlePartitionFuzzTest(const uint8_t *data, size_t size)
171 {
172 MessageParcel datas;
173 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
174 datas.WriteBuffer(data, size);
175 datas.RewindRead(0);
176 MessageParcel reply;
177
178 storageDaemon->HandlePartition(datas, reply);
179 return true;
180 }
181
HandleCheckFuzzTest(const uint8_t * data,size_t size)182 bool HandleCheckFuzzTest(const uint8_t *data, size_t size)
183 {
184 MessageParcel datas;
185 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
186 datas.WriteBuffer(data, size);
187 datas.RewindRead(0);
188 MessageParcel reply;
189
190 storageDaemon->HandleCheck(datas, reply);
191 return true;
192 }
193
HandleSetVolDescFuzzTest(const uint8_t * data,size_t size)194 bool HandleSetVolDescFuzzTest(const uint8_t *data, size_t size)
195 {
196 MessageParcel datas;
197 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
198 datas.WriteBuffer(data, size);
199 datas.RewindRead(0);
200 MessageParcel reply;
201
202 storageDaemon->HandleSetVolDesc(datas, reply);
203 return true;
204 }
205
HandleFormatFuzzTest(const uint8_t * data,size_t size)206 bool HandleFormatFuzzTest(const uint8_t *data, size_t size)
207 {
208 MessageParcel datas;
209 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
210 datas.WriteBuffer(data, size);
211 datas.RewindRead(0);
212 MessageParcel reply;
213
214 storageDaemon->HandleFormat(datas, reply);
215 return true;
216 }
217
HandleSetBundleQuotaFuzzTest(const uint8_t * data,size_t size)218 bool HandleSetBundleQuotaFuzzTest(const uint8_t *data, size_t size)
219 {
220 MessageParcel datas;
221 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
222 datas.WriteBuffer(data, size);
223 datas.RewindRead(0);
224 MessageParcel reply;
225
226 storageDaemon->HandleSetBundleQuota(datas, reply);
227 return true;
228 }
229
HandleGenerateUserKeysFuzzTest(const uint8_t * data,size_t size)230 bool HandleGenerateUserKeysFuzzTest(const uint8_t *data, size_t size)
231 {
232 MessageParcel datas;
233 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
234 datas.WriteBuffer(data, size);
235 datas.RewindRead(0);
236 MessageParcel reply;
237
238 storageDaemon->HandleGenerateUserKeys(datas, reply);
239 return true;
240 }
241
HandleDeleteUserKeysFuzzTest(const uint8_t * data,size_t size)242 bool HandleDeleteUserKeysFuzzTest(const uint8_t *data, size_t size)
243 {
244 MessageParcel datas;
245 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
246 datas.WriteBuffer(data, size);
247 datas.RewindRead(0);
248 MessageParcel reply;
249
250 storageDaemon->HandleDeleteUserKeys(datas, reply);
251 return true;
252 }
253
HandleUpdateUserAuthFuzzTest(const uint8_t * data,size_t size)254 bool HandleUpdateUserAuthFuzzTest(const uint8_t *data, size_t size)
255 {
256 MessageParcel datas;
257 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
258 datas.WriteBuffer(data, size);
259 datas.RewindRead(0);
260 MessageParcel reply;
261
262 storageDaemon->HandleUpdateUserAuth(datas, reply);
263 return true;
264 }
265
HandleActiveUserKeyFuzzTest(const uint8_t * data,size_t size)266 bool HandleActiveUserKeyFuzzTest(const uint8_t *data, size_t size)
267 {
268 MessageParcel datas;
269 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
270 datas.WriteBuffer(data, size);
271 datas.RewindRead(0);
272 MessageParcel reply;
273
274 storageDaemon->HandleActiveUserKey(datas, reply);
275 return true;
276 }
277
HandleInactiveUserKeyFuzzTest(const uint8_t * data,size_t size)278 bool HandleInactiveUserKeyFuzzTest(const uint8_t *data, size_t size)
279 {
280 MessageParcel datas;
281 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
282 datas.WriteBuffer(data, size);
283 datas.RewindRead(0);
284 MessageParcel reply;
285
286 storageDaemon->HandleInactiveUserKey(datas, reply);
287 return true;
288 }
289
HandleUpdateKeyContextFuzzTest(const uint8_t * data,size_t size)290 bool HandleUpdateKeyContextFuzzTest(const uint8_t *data, size_t size)
291 {
292 MessageParcel datas;
293 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
294 datas.WriteBuffer(data, size);
295 datas.RewindRead(0);
296 MessageParcel reply;
297
298 storageDaemon->HandleUpdateKeyContext(datas, reply);
299 return true;
300 }
301
HandleDeleteAppkeyFuzzTest(const uint8_t * data,size_t size)302 bool HandleDeleteAppkeyFuzzTest(const uint8_t *data, size_t size)
303 {
304 MessageParcel datas;
305 datas.WriteInterfaceToken(StorageDaemonStub::GetDescriptor());
306 datas.WriteBuffer(data, size);
307 datas.RewindRead(0);
308 MessageParcel reply;
309
310 storageDaemon->HandleDeleteAppkey(datas, reply);
311 return true;
312 }
313
UserManagerFuzzTest(const uint8_t * data,size_t size)314 bool UserManagerFuzzTest(const uint8_t *data, size_t size)
315 {
316 if ((data == nullptr) || (size < sizeof(int32_t))) {
317 return false;
318 }
319
320 int32_t userId = *(reinterpret_cast<const int32_t *>(data));
321 uint32_t flag = *(reinterpret_cast<const uint32_t *>(data));
322 userManager->PrepareUserDirs(userId, flag);
323 userManager->DestroyUserDirs(userId, flag);
324 userManager->StartUser(userId);
325 userManager->StopUser(userId);
326 userManager->CreateBundleDataDir(flag);
327
328 return true;
329 }
330 } // namespace OHOS
331
332 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)333 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
334 {
335 /* Run your code on data */
336 if (data == nullptr) {
337 return 0;
338 }
339
340 /* Validate the length of size */
341 if (size < OHOS::U32_AT_SIZE || size > OHOS::FOO_MAX_LEN) {
342 return 0;
343 }
344
345 auto str = std::make_unique<char[]>(size + 1);
346 (void)memset_s(str.get(), size + 1, 0x00, size + 1);
347 if (memcpy_s(str.get(), size, data, size) != EOK) {
348 return 0;
349 }
350 OHOS::StorageDaemonFuzzTest(move(str), size);
351 OHOS::UserManagerFuzzTest(data, size);
352 OHOS::HandleStartUserFuzzTest(data, size);
353 OHOS::HandleStopUserFuzzTest(data, size);
354 OHOS::HandlePrepareUserDirsFuzzTest(data, size);
355 OHOS::HandleDestroyUserDirsFuzzTest(data, size);
356 OHOS::HandleMountFuzzTest(data, size);
357 OHOS::HandleUMountFuzzTest(data, size);
358 OHOS::HandlePartitionFuzzTest(data, size);
359 OHOS::HandleCheckFuzzTest(data, size);
360 OHOS::HandleSetVolDescFuzzTest(data, size);
361 OHOS::HandleFormatFuzzTest(data, size);
362 OHOS::HandleSetBundleQuotaFuzzTest(data, size);
363 OHOS::HandleGenerateUserKeysFuzzTest(data, size);
364 OHOS::HandleDeleteUserKeysFuzzTest(data, size);
365 OHOS::HandleUpdateUserAuthFuzzTest(data, size);
366 OHOS::HandleActiveUserKeyFuzzTest(data, size);
367 OHOS::HandleInactiveUserKeyFuzzTest(data, size);
368 OHOS::HandleUpdateKeyContextFuzzTest(data, size);
369 OHOS::HandleDeleteAppkeyFuzzTest(data, size);
370 return 0;
371 }
372