• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }