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