1 /*
2 * Copyright (c) 2022-2023 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
16 #include "ressched_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstdlib>
21 #include <securec.h>
22 #include <vector>
23
24 #include "iremote_stub.h"
25 #include "ires_sched_service.h"
26 #include "iservice_registry.h"
27 #include "plugin_mgr.h"
28 #include "res_sched_service.h"
29 #include "singleton.h"
30 #include "system_ability_definition.h"
31
32 #define private public
33 #define protected public
34
35 #ifndef errno_t
36 typedef int errno_t;
37 #endif
38
39 #ifndef EOK
40 #define EOK 0
41 #endif
42
43 namespace OHOS {
44 namespace ResourceSchedule {
45 constexpr int32_t MAX_CODE = 5;
46 constexpr int32_t MIN_LEN = 4;
47 std::mutex mutexLock;
48 sptr<IRemoteObject> remoteObj;
49 const uint8_t* g_data = nullptr;
50 size_t g_size = 0;
51 size_t g_pos;
52
53 /**
54 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
55 * tips: only support basic type
56 */
57 template<class T>
GetData()58 T GetData()
59 {
60 T object {};
61 size_t objectSize = sizeof(object);
62 if (g_data == nullptr || objectSize > g_size - g_pos) {
63 return object;
64 }
65 errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize);
66 if (ret != EOK) {
67 return {};
68 }
69 g_pos += objectSize;
70 return object;
71 }
72
DoInit()73 bool DoInit()
74 {
75 std::lock_guard<std::mutex> lock(mutexLock);
76 if (remoteObj) {
77 return true;
78 }
79 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
80 if (!samgr) {
81 return false;
82 }
83 remoteObj = samgr->GetSystemAbility(RES_SCHED_SYS_ABILITY_ID);
84 if (!remoteObj) {
85 return false;
86 }
87 return true;
88 }
89
onRemoteRequest(uint32_t code,MessageParcel & data)90 int32_t onRemoteRequest(uint32_t code, MessageParcel& data)
91 {
92 if (!DoInit()) {
93 return -1;
94 }
95 MessageParcel reply;
96 MessageOption option;
97 return remoteObj->SendRequest(code, data, reply, option);
98 }
99
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)100 bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
101 {
102 if (size <= MIN_LEN) {
103 return false;
104 }
105
106 MessageParcel dataMessageParcel;
107 if (!dataMessageParcel.WriteInterfaceToken(IRemoteStub<IResSchedService>::GetDescriptor())) {
108 return false;
109 }
110
111 uint32_t code = *(reinterpret_cast<const uint32_t*>(data));
112 size -= sizeof(uint32_t);
113
114 dataMessageParcel.WriteBuffer(data + sizeof(uint32_t), size);
115 dataMessageParcel.RewindRead(0);
116
117 onRemoteRequest(code, dataMessageParcel);
118 return true;
119 }
120
OnRemoteRequest(const uint8_t * data,size_t size)121 bool OnRemoteRequest(const uint8_t* data, size_t size)
122 {
123 if (data == nullptr) {
124 return false;
125 }
126
127 if (size <= MIN_LEN) {
128 return false;
129 }
130
131 // initialize
132 g_data = data;
133 g_size = size;
134 g_pos = 0;
135
136 // getdata
137 uint32_t fuzzCode = GetData<uint32_t>();
138 MessageParcel fuzzData;
139 fuzzData.WriteInterfaceToken(ResSchedServiceStub::GetDescriptor());
140 fuzzData.WriteBuffer(g_data + g_pos, g_size - g_pos);
141 fuzzData.RewindRead(0);
142 MessageParcel fuzzReply;
143 MessageOption fuzzOption;
144 DelayedSingleton<ResSchedService>::GetInstance()->OnRemoteRequest(fuzzCode % MAX_CODE,
145 fuzzData, fuzzReply, fuzzOption);
146 return true;
147 }
148 } // namespace ResourceSchedule
149 } // namespace OHOS
150
151 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)152 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
153 {
154 /* Run your code on data */
155 OHOS::ResourceSchedule::DoSomethingInterestingWithMyAPI(data, size);
156 OHOS::ResourceSchedule::OnRemoteRequest(data, size);
157 return 0;
158 }
159