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