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