1 /*
2 * Copyright (c) 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 <cstddef>
17 #include <cstdint>
18 #include <string>
19 #include <vector>
20 #include "faultlogger.h"
21 #include "faultlog_manager.h"
22 #include "faultlogger_service_ohos.h"
23 #include "faultlogger_service_fuzzer.h"
24 #include "faultlogger_fuzzertest_common.h"
25 #include "hiview_global.h"
26 #include "hiview_platform.h"
27
28 using namespace OHOS::HiviewDFX;
29 namespace OHOS {
30 namespace {
31 constexpr int FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH = 50;
32 constexpr int32_t FAULTLOGTYPE_SIZE = 6;
33 }
34
35 class HiviewTestContext : public HiviewContext {
36 public:
GetHiViewDirectory(DirectoryType type __UNUSED)37 std::string GetHiViewDirectory(DirectoryType type __UNUSED)
38 {
39 return "/data/log/hiview/sys_event_test";
40 }
41 };
42
CreateFaultloggerInstance()43 std::shared_ptr<Faultlogger> CreateFaultloggerInstance()
44 {
45 static std::unique_ptr<HiviewPlatform> platform = std::make_unique<HiviewPlatform>();
46 auto plugin = std::make_shared<Faultlogger>();
47 plugin->SetName("Faultlogger");
48 plugin->SetHandle(nullptr);
49 plugin->SetHiviewContext(platform.get());
50 plugin->OnLoad();
51 return plugin;
52 }
53
FuzzServiceInterfaceDump(const uint8_t * data,size_t size)54 void FuzzServiceInterfaceDump(const uint8_t* data, size_t size)
55 {
56 constexpr int maxLen = 20;
57 int32_t fd;
58 if (size <= (sizeof(fd) + maxLen)) {
59 return;
60 }
61
62 auto service = CreateFaultloggerInstance();
63 FaultloggerServiceOhos serviceOhos;
64 FaultloggerServiceOhos::StartService(service.get());
65 if (FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr) != service.get()) {
66 printf("FaultloggerServiceOhos start service error.\n");
67 return;
68 }
69
70 STREAM_TO_VALUEINFO(data, fd);
71 std::vector<std::u16string> args;
72 char16_t arg[maxLen] = {0};
73 errno_t err = strncpy_s(reinterpret_cast<char*>(arg), sizeof(arg), reinterpret_cast<const char*>(data), maxLen);
74 if (err != EOK) {
75 std::cout << "strncpy_s arg failed" << std::endl;
76 return;
77 }
78 args.push_back(arg);
79
80 (void)serviceOhos.Dump(fd, args);
81 }
82
FuzzServiceInterfaceQuerySelfFaultLog(const uint8_t * data,size_t size)83 void FuzzServiceInterfaceQuerySelfFaultLog(const uint8_t* data, size_t size)
84 {
85 HiviewTestContext hiviewTestContext;
86 HiviewGlobal::CreateInstance(hiviewTestContext);
87
88 auto service = CreateFaultloggerInstance();
89 FaultloggerServiceOhos serviceOhos;
90 FaultloggerServiceOhos::StartService(service.get());
91 if (FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr) != service.get()) {
92 printf("FaultloggerServiceOhos start service error.\n");
93 return;
94 }
95 int32_t faultType;
96 int32_t maxNum;
97 int offsetTotalLength = sizeof(faultType) + sizeof(maxNum);
98 if (offsetTotalLength > size) {
99 return;
100 }
101
102 STREAM_TO_VALUEINFO(data, faultType);
103 STREAM_TO_VALUEINFO(data, maxNum);
104
105 auto remoteObject = serviceOhos.QuerySelfFaultLog(faultType, maxNum);
106 auto result = iface_cast<FaultLogQueryResultOhos>(remoteObject);
107 if (result != nullptr) {
108 while (result->HasNext()) {
109 result->GetNext();
110 }
111 }
112 }
113
FuzzServiceInterfaceCreateTempFaultLogFile(const uint8_t * data,size_t size)114 void FuzzServiceInterfaceCreateTempFaultLogFile(const uint8_t* data, size_t size)
115 {
116 auto faultLogManager = std::make_unique<FaultLogManager>(nullptr);
117 faultLogManager->Init();
118
119 int64_t time;
120 int32_t id;
121 int32_t faultType;
122 int offsetTotalLength = sizeof(time) + sizeof(id) + sizeof(faultType) + FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
123 if (offsetTotalLength > size) {
124 return;
125 }
126
127 STREAM_TO_VALUEINFO(data, time);
128 STREAM_TO_VALUEINFO(data, id);
129 STREAM_TO_VALUEINFO(data, faultType);
130
131 std::string module(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
132 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
133 faultLogManager->CreateTempFaultLogFile(time, id, faultType, module);
134 }
135
FuzzServiceInterfaceAddFaultLog(const uint8_t * data,size_t size)136 void FuzzServiceInterfaceAddFaultLog(const uint8_t* data, size_t size)
137 {
138 auto service = CreateFaultloggerInstance();
139 FaultloggerServiceOhos serviceOhos;
140 FaultloggerServiceOhos::StartService(service.get());
141 if (FaultloggerServiceOhos::GetOrSetFaultlogger(nullptr) != service.get()) {
142 printf("FaultloggerServiceOhos start service error.\n");
143 return;
144 }
145 FaultLogInfoOhos info;
146 int32_t faultLogType {0};
147 int offsetTotalLength = sizeof(info.time) + sizeof(info.pid) + sizeof(info.uid) + sizeof(faultLogType) +
148 (6 * FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH); // 6 : Offset by 6 string length
149 if (offsetTotalLength > size) {
150 return;
151 }
152
153 STREAM_TO_VALUEINFO(data, info.time);
154 STREAM_TO_VALUEINFO(data, info.pid);
155 STREAM_TO_VALUEINFO(data, info.uid);
156 STREAM_TO_VALUEINFO(data, faultLogType);
157 info.faultLogType = abs(faultLogType % 10); // 10 : get the absolute value of the last digit of the number
158
159 std::string module(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
160 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
161 info.module = module;
162 std::string reason(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
163 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
164 info.reason = reason;
165 std::string logPath(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
166 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
167 info.logPath = logPath;
168 std::string registers(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
169 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
170 info.registers = registers;
171 std::string hilog(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
172 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
173 info.sectionMaps["HILOG"] = hilog;
174 std::string keyLogFile(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
175 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
176 info.sectionMaps["KEYLOGFILE"] = keyLogFile;
177 serviceOhos.AddFaultLog(info);
178 serviceOhos.Destroy();
179 }
180
FuzzServiceInterfaceOnEvent(const uint8_t * data,size_t size)181 void FuzzServiceInterfaceOnEvent(const uint8_t* data, size_t size)
182 {
183 auto service = CreateFaultloggerInstance();
184
185 int32_t pid;
186 int32_t uid;
187 int32_t tid;
188 int offsetTotalLength = sizeof(pid) + sizeof(uid) + sizeof(tid) +
189 (7 * FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH); // 7 : Offset by 7 string length
190 if (offsetTotalLength > size) {
191 return;
192 }
193
194 STREAM_TO_VALUEINFO(data, pid);
195 STREAM_TO_VALUEINFO(data, uid);
196 STREAM_TO_VALUEINFO(data, tid);
197
198 std::string domain(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
199 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
200 std::string eventName(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
201 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
202 SysEventCreator sysEventCreator(domain, eventName, SysEventCreator::FAULT);
203 std::map<std::string, std::string> bundle;
204 std::string hilog(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
205 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
206 bundle["HILOG"] = hilog;
207 std::string keyLogFile(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
208 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
209 bundle["KEYLOGFILE"] = keyLogFile;
210
211 std::string summary(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
212 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
213 std::string packageName(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
214 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
215 sysEventCreator.SetKeyValue("name_", "JS_ERROR");
216 sysEventCreator.SetKeyValue("pid_", pid);
217 sysEventCreator.SetKeyValue("uid_", uid);
218 sysEventCreator.SetKeyValue("tid_", tid);
219 sysEventCreator.SetKeyValue("SUMMARY", summary);
220 sysEventCreator.SetKeyValue("PACKAGE_NAME", packageName);
221 sysEventCreator.SetKeyValue("bundle_", bundle);
222 std::string desc(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
223 data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
224 auto sysEvent = std::make_shared<SysEvent>(desc, nullptr, sysEventCreator);
225 auto event = std::dynamic_pointer_cast<Event>(sysEvent);
226 service->OnEvent(event);
227 }
228
FuzzFaultloggerServiceInterface(const uint8_t * data,size_t size)229 void FuzzFaultloggerServiceInterface(const uint8_t* data, size_t size)
230 {
231 FuzzServiceInterfaceDump(data, size);
232 FuzzServiceInterfaceQuerySelfFaultLog(data, size);
233 FuzzServiceInterfaceCreateTempFaultLogFile(data, size);
234 FuzzServiceInterfaceAddFaultLog(data, size);
235 FuzzServiceInterfaceOnEvent(data, size);
236 usleep(10000); // 10000 : pause for 10000 microseconds to avoid resource depletion
237 }
238 }
239
240 // Fuzzer entry point.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)241 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
242 {
243 if (data == nullptr || size == 0) {
244 return 0;
245 }
246 OHOS::FuzzFaultloggerServiceInterface(data, size);
247 return 0;
248 }
249