1 /*
2 * Copyright (c) 2024 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 "video_post_processor_fuzzer.h"
17 #include "buffer_info.h"
18 #include "foundation/multimedia/camera_framework/common/utils/camera_log.h"
19 #include "ipc_file_descriptor.h"
20 #include "securec.h"
21
22 using namespace std;
23
24 namespace OHOS {
25 namespace CameraStandard {
26 using namespace DeferredProcessing;
27 using DeferredVideoJobPtr = std::shared_ptr<DeferredVideoJob>;
28 std::shared_ptr<VideoPostProcessor> VideoPostProcessorFuzzer::processor_{nullptr};
29 std::shared_ptr<DeferredVideoWork> VideoPostProcessorFuzzer::work_{nullptr};
30 static constexpr int32_t MAX_CODE_LEN = 512;
31 static constexpr int32_t MIN_SIZE_NUM = 4;
32 static constexpr int NUM_1 = 1;
33 static const uint8_t* RAW_DATA = nullptr;
34 const size_t THRESHOLD = 10;
35 static size_t g_dataSize = 0;
36 static size_t g_pos;
37
38 /*
39 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
40 * tips: only support basic type
41 */
42 template<class T>
GetData()43 T GetData()
44 {
45 T object {};
46 size_t objectSize = sizeof(object);
47 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
48 return object;
49 }
50 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
51 if (ret != EOK) {
52 return {};
53 }
54 g_pos += objectSize;
55 return object;
56 }
57
58 template<class T>
GetArrLength(T & arr)59 uint32_t GetArrLength(T& arr)
60 {
61 if (arr == nullptr) {
62 MEDIA_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
63 return 0;
64 }
65 return sizeof(arr) / sizeof(arr[0]);
66 }
67
VideoPostProcessorFuzzTest1()68 void VideoPostProcessorFuzzer::VideoPostProcessorFuzzTest1()
69 {
70 constexpr int32_t executionModeCount1 = static_cast<int32_t>(ExecutionMode::DUMMY) + 1;
71 ExecutionMode selectedExecutionMode = static_cast<ExecutionMode>(GetData<uint8_t>() % executionModeCount1);
72 processor_->SetExecutionMode(selectedExecutionMode);
73 processor_->SetDefaultExecutionMode();
74 uint8_t randomNum = GetData<uint8_t>();
75 std::vector<std::string> testStrings = {"test1", "test2"};
76 std::string videoId(testStrings[randomNum % testStrings.size()]);
77 auto srcFd = NUM_1;
78 auto dstFd = NUM_1;
79 processor_->copyFileByFd(srcFd, dstFd);
80 auto isAutoSuspend = GetData<bool>();
81 std::string videoId_(testStrings[randomNum % testStrings.size()]);
82 sptr<IPCFileDescriptor> srcFd_ = sptr<IPCFileDescriptor>::MakeSptr(GetData<int>());
83 sptr<IPCFileDescriptor> dstFd_ = sptr<IPCFileDescriptor>::MakeSptr(GetData<int>());
84 DeferredVideoJobPtr jobPtr = std::make_shared<DeferredVideoJob>(videoId_, srcFd_, dstFd_);
85 std::shared_ptr<DeferredVideoWork> work_ =
86 make_shared<DeferredVideoWork>(jobPtr, selectedExecutionMode, isAutoSuspend);
87 processor_->StartTimer(videoId, work_);
88 processor_->StopTimer(work_);
89 processor_->ProcessRequest(work_);
90 processor_->RemoveRequest(videoId);
91 constexpr int32_t executionModeCount2 = static_cast<int32_t>(ScheduleType::NORMAL_TIME_STATE) + 2;
92 ScheduleType selectedScheduleType = static_cast<ScheduleType>(GetData<uint8_t>() % executionModeCount2);
93 constexpr int32_t executionModeCount3 = static_cast<int32_t>(DpsError::DPS_ERROR_VIDEO_PROC_INTERRUPTED) + 2;
94 DpsError selectedDpsError = static_cast<DpsError>(GetData<uint8_t>() % executionModeCount3);
95 constexpr int32_t executionModeCount4 = static_cast<int32_t>(MediaResult::PAUSE) + 2;
96 MediaResult selectedMediaResult = static_cast<MediaResult>(GetData<uint8_t>() % executionModeCount4);
97 constexpr int32_t executionModeCount5 = static_cast<int32_t>(HdiStatus::HDI_NOT_READY_TEMPORARILY) + 1;
98 HdiStatus selectedHdiStatus = static_cast<HdiStatus>(GetData<uint8_t>() % executionModeCount5);
99 processor_->PauseRequest(videoId, selectedScheduleType);
100 sptr<IPCFileDescriptor> inputFd_ = nullptr;
101 processor_->StartMpeg(videoId, inputFd_);
102 processor_->StopMpeg(selectedMediaResult, work_);
103 processor_->OnSessionDied();
104 processor_->OnProcessDone(videoId);
105 processor_->OnError(videoId, selectedDpsError);
106 processor_->OnStateChanged(selectedHdiStatus);
107 processor_->OnTimerOut(videoId);
108 }
109
VideoPostProcessorFuzzTest2()110 void VideoPostProcessorFuzzer::VideoPostProcessorFuzzTest2()
111 {
112 std::vector<std::string> pendingVideos;
113 processor_->GetPendingVideos(pendingVideos);
114 uint8_t randomNum = GetData<uint8_t>();
115 std::vector<std::string> testStrings = {"test1", "test2"};
116 std::string videoId(testStrings[randomNum % testStrings.size()]);
117 auto inputFd = GetData<int>();
118 processor_->PrepareStreams(videoId, inputFd);
119 StreamDescription stream;
120 sptr<BufferProducerSequenceable> producer;
121 processor_->SetStreamInfo(stream, producer);
122 processor_->GetRunningWork(videoId);
123 }
124
Test()125 void Test()
126 {
127 auto videoPostProcessor = std::make_unique<VideoPostProcessorFuzzer>();
128 if (videoPostProcessor == nullptr) {
129 MEDIA_INFO_LOG("videoPostProcessor is null");
130 return;
131 }
132 if ((RAW_DATA == nullptr) || (g_dataSize > MAX_CODE_LEN) || (g_dataSize < MIN_SIZE_NUM)) {
133 return;
134 }
135 int32_t userId = GetData<int32_t>();
136 VideoPostProcessorFuzzer::processor_ = std::make_shared<VideoPostProcessor>(userId);
137 if (VideoPostProcessorFuzzer::processor_ == nullptr) {
138 return;
139 }
140 videoPostProcessor->VideoPostProcessorFuzzTest1();
141 videoPostProcessor->VideoPostProcessorFuzzTest2();
142 }
143
144 typedef void (*TestFuncs[1])();
145
146 TestFuncs g_testFuncs = {
147 Test,
148 };
149
FuzzTest(const uint8_t * rawData,size_t size)150 bool FuzzTest(const uint8_t* rawData, size_t size)
151 {
152 // initialize data
153 RAW_DATA = rawData;
154 g_dataSize = size;
155 g_pos = 0;
156
157 uint32_t code = GetData<uint32_t>();
158 uint32_t len = GetArrLength(g_testFuncs);
159 if (len > 0) {
160 g_testFuncs[code % len]();
161 } else {
162 MEDIA_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
163 }
164
165 return true;
166 }
167 } // namespace CameraStandard
168 } // namespace OHOS
169
170 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)171 extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size)
172 {
173 if (size < OHOS::CameraStandard::THRESHOLD) {
174 return 0;
175 }
176
177 OHOS::CameraStandard::FuzzTest(data, size);
178 return 0;
179 }