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 "transcoderstub_fuzzer.h"
17 #include <cmath>
18 #include <iostream>
19 #include "string_ex.h"
20 #include "directory_ex.h"
21 #include <unistd.h>
22 #include <numeric>
23 #include "fuzzer/FuzzedDataProvider.h"
24 #include "media_server.h"
25 #include "media_parcel.h"
26 #include "i_standard_transcoder_service.h"
27 #include "stub_common.h"
28 #include "media_log.h"
29
30 using namespace std;
31 using namespace OHOS;
32 using namespace Media;
33
34 namespace {
35 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "TranscoderStubFuzzTest" };
36 constexpr char INPUT_VIDEO_PATH[] = "/data/local/tmp/input.mp4";
37 constexpr char OUTPUT_VIDEO_PATH[] = "/data/local/tmp/output.mp4";
38 constexpr int32_t SYSTEM_ABILITY_ID = 3002;
39 constexpr bool RUN_ON_CREATE = false;
40 constexpr uint32_t SECOND_TWO = 2;
41 } // namespace
42
43 namespace OHOS {
44 namespace Media {
CreateFuzzTranscoder()45 sptr<IRemoteStub<IStandardTransCoderService>> CreateFuzzTranscoder()
46 {
47 std::shared_ptr<MediaServer> mediaServer = std::make_shared<MediaServer>(SYSTEM_ABILITY_ID, RUN_ON_CREATE);
48 sptr<IRemoteObject> listener = new (std::nothrow) MediaListenerStubFuzzer();
49 sptr<IRemoteObject> transcoder =
50 mediaServer->GetSubSystemAbility(IStandardMediaService::MediaSystemAbility::MEDIA_TRANSCODER, listener);
51 return iface_cast<IRemoteStub<IStandardTransCoderService>>(transcoder);
52 }
53
FuzzTranscoderSetVideoEncoder(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t encoderType)54 void FuzzTranscoderSetVideoEncoder(sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t encoderType)
55 {
56 MessageParcel data;
57 MessageParcel reply;
58 MessageOption option;
59
60 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
61 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
62
63 int32_t encoderArr[] = { VideoCodecFormat::VIDEO_DEFAULT, VideoCodecFormat::H264, VideoCodecFormat::MPEG4,
64 VideoCodecFormat::H265, VideoCodecFormat::VIDEO_CODEC_FORMAT_BUTT };
65 int32_t index = encoderType % std::size(encoderArr);
66 int32_t value = encoderArr[std::abs(index)];
67 data.WriteInt32(value);
68 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_ENCODER, data, reply, option);
69 }
70
FuzzTranscoderSetVideoSize(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t width,int32_t height)71 void FuzzTranscoderSetVideoSize(sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t width, int32_t height)
72 {
73 MessageParcel data;
74 MessageParcel reply;
75 MessageOption option;
76
77 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
78 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
79 data.WriteInt32(width);
80 data.WriteInt32(height);
81 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_SIZE, data, reply, option);
82 }
83
FuzzTranscoderSetVideoEncodingBitRate(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t rate)84 void FuzzTranscoderSetVideoEncodingBitRate(sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t rate)
85 {
86 MessageParcel data;
87 MessageParcel reply;
88 MessageOption option;
89
90 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
91 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
92 data.WriteInt32(rate);
93 transcoder->OnRemoteRequest(
94 IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_ENCODING_BIT_RATE, data, reply, option);
95 }
96
FuzzTranscoderSetAudioEncoder(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t audioEncoderType)97 void FuzzTranscoderSetAudioEncoder(sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t audioEncoderType)
98 {
99 MessageParcel data;
100 MessageParcel reply;
101 MessageOption option;
102
103 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
104 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
105
106 int32_t encoderArr[] = { AudioCodecFormat::AUDIO_DEFAULT, AudioCodecFormat::AAC_LC, AudioCodecFormat::AUDIO_MPEG,
107 AudioCodecFormat::AUDIO_G711MU, AudioCodecFormat::AUDIO_CODEC_FORMAT_BUTT };
108 int32_t index = audioEncoderType % std::size(encoderArr);
109 int32_t value = encoderArr[std::abs(index)];
110 data.WriteInt32(value);
111 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_ENCODER, data, reply, option);
112 }
113
FuzzTranscoderSetAudioEncodingBitRate(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t audioBitrate)114 void FuzzTranscoderSetAudioEncodingBitRate(
115 sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t audioBitrate)
116 {
117 MessageParcel data;
118 MessageParcel reply;
119 MessageOption option;
120
121 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
122 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
123 data.WriteInt32(audioBitrate);
124 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_ENCODER, data, reply, option);
125 }
126
FuzzTranscoderSetOutputFormat(sptr<IRemoteStub<IStandardTransCoderService>> transcoder,int32_t outputFormat)127 void FuzzTranscoderSetOutputFormat(sptr<IRemoteStub<IStandardTransCoderService>> transcoder, int32_t outputFormat)
128 {
129 MessageParcel data;
130 MessageParcel reply;
131 MessageOption option;
132
133 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
134 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
135
136 int32_t outputFormatArr[] = { OutputFormatType::FORMAT_DEFAULT, OutputFormatType::FORMAT_MPEG_4,
137 OutputFormatType::FORMAT_M4A, OutputFormatType::FORMAT_MP3, OutputFormatType::FORMAT_WAV,
138 OutputFormatType::FORMAT_BUTT };
139 int32_t index = outputFormat % std::size(outputFormatArr);
140 int32_t value = outputFormatArr[std::abs(index)];
141 data.WriteInt32(value);
142 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_VIDEO_ENCODER, data, reply, option);
143 }
144
FuzzTranscoderSetInputFile(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)145 void FuzzTranscoderSetInputFile(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
146 {
147 MessageParcel data;
148 MessageParcel reply;
149 MessageOption option;
150
151 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
152 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
153
154 int fdInput = open(INPUT_VIDEO_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
155 if (fdInput < 0) {
156 return;
157 }
158 data.WriteFileDescriptor(fdInput);
159 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_INPUT_FILE_FD, data, reply, option);
160 close(fdInput);
161 }
162
FuzzTranscoderSetOutputFile(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)163 void FuzzTranscoderSetOutputFile(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
164 {
165 MessageParcel data;
166 MessageParcel reply;
167 MessageOption option;
168
169 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
170 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
171
172 int fdOutput = open(OUTPUT_VIDEO_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
173 if (fdOutput < 0) {
174 return;
175 }
176 data.WriteFileDescriptor(fdOutput);
177 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::SET_OUTPUT_FILE, data, reply, option);
178 close(fdOutput);
179 }
180
FuzzTranscoderPrepare(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)181 void FuzzTranscoderPrepare(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
182 {
183 MessageParcel data;
184 MessageParcel reply;
185 MessageOption option;
186
187 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
188 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
189 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::PREPARE, data, reply, option);
190 }
191
FuzzTranscoderStart(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)192 void FuzzTranscoderStart(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
193 {
194 MessageParcel data;
195 MessageParcel reply;
196 MessageOption option;
197
198 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
199 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
200 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::START, data, reply, option);
201 }
202
FuzzTranscoderPause(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)203 void FuzzTranscoderPause(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
204 {
205 MessageParcel data;
206 MessageParcel reply;
207 MessageOption option;
208
209 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
210 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
211 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::PAUSE, data, reply, option);
212 }
213
FuzzTranscoderResume(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)214 void FuzzTranscoderResume(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
215 {
216 MessageParcel data;
217 MessageParcel reply;
218 MessageOption option;
219
220 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
221 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
222 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::RESUME, data, reply, option);
223 }
224
FuzzTranscoderCancel(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)225 void FuzzTranscoderCancel(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
226 {
227 MessageParcel data;
228 MessageParcel reply;
229 MessageOption option;
230
231 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
232 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
233 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::CANCEL, data, reply, option);
234 }
235
FuzzTranscoderRelease(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)236 void FuzzTranscoderRelease(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
237 {
238 MessageParcel data;
239 MessageParcel reply;
240 MessageOption option;
241
242 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
243 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
244 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::RELEASE, data, reply, option);
245 }
246
FuzzTranscoderDestroyStub(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)247 void FuzzTranscoderDestroyStub(sptr<IRemoteStub<IStandardTransCoderService>> transcoder)
248 {
249 MessageParcel data;
250 MessageParcel reply;
251 MessageOption option;
252
253 bool token = data.WriteInterfaceToken(transcoder->GetDescriptor());
254 CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!");
255 transcoder->OnRemoteRequest(IStandardTransCoderService::RecorderServiceMsg::DESTROY, data, reply, option);
256 }
257 } // namespace Media
258 } // namespace OHOS
259
260 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)261 extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
262 {
263 /* Run your code on data */
264 int fdInput = open(INPUT_VIDEO_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
265 if (fdInput < 0) {
266 return 0;
267 }
268 if (write(fdInput, data, size) <= 0) {
269 close(fdInput);
270 return 0;
271 }
272 close(fdInput);
273
274 FuzzedDataProvider fdp(data, size);
275 auto transcoder = OHOS::Media::CreateFuzzTranscoder();
276 OHOS::Media::FuzzTranscoderSetVideoEncoder(transcoder, fdp.ConsumeIntegral<int32_t>());
277 OHOS::Media::FuzzTranscoderSetVideoSize(transcoder, fdp.ConsumeIntegral<int32_t>(), fdp.ConsumeIntegral<int32_t>());
278 OHOS::Media::FuzzTranscoderSetVideoEncodingBitRate(transcoder, fdp.ConsumeIntegral<int32_t>());
279 OHOS::Media::FuzzTranscoderSetAudioEncoder(transcoder, fdp.ConsumeIntegral<int32_t>());
280 OHOS::Media::FuzzTranscoderSetAudioEncodingBitRate(transcoder, fdp.ConsumeIntegral<int32_t>());
281 OHOS::Media::FuzzTranscoderSetOutputFormat(transcoder, fdp.ConsumeIntegral<int32_t>());
282 OHOS::Media::FuzzTranscoderSetInputFile(transcoder);
283 OHOS::Media::FuzzTranscoderSetOutputFile(transcoder);
284 OHOS::Media::FuzzTranscoderPrepare(transcoder);
285 sleep(SECOND_TWO);
286 OHOS::Media::FuzzTranscoderStart(transcoder);
287 sleep(SECOND_TWO);
288 OHOS::Media::FuzzTranscoderPause(transcoder);
289 sleep(SECOND_TWO);
290 OHOS::Media::FuzzTranscoderResume(transcoder);
291 sleep(SECOND_TWO);
292 OHOS::Media::FuzzTranscoderCancel(transcoder);
293 OHOS::Media::FuzzTranscoderRelease(transcoder);
294 OHOS::Media::FuzzTranscoderDestroyStub(transcoder);
295
296 unlink(INPUT_VIDEO_PATH);
297 unlink(OUTPUT_VIDEO_PATH);
298
299 return 0;
300 }