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 "playerdatasrc_fuzzer.h"
17 #include <iostream>
18 #include <unistd.h>
19 #include "stub_common.h"
20 #include "media_server.h"
21 #include "media_parcel.h"
22 #include "i_standard_player_service.h"
23 #include <fcntl.h>
24 #include "i_standard_player_listener.h"
25 #include "player.h"
26 #include "meta/media_types.h"
27 #include "common/media_core.h"
28 #include "media_data_source_stub.h"
29 #include "fuzzer/FuzzedDataProvider.h"
30
31 using namespace std;
32 using namespace OHOS;
33 using namespace OHOS::Media;
34
35 namespace OHOS {
36 namespace Media {
37 const char *DATA_PATH = "/data/test/fuzz_create.mp4";
38 const int32_t SYSTEM_ABILITY_ID = 3002;
39 const bool RUN_ON_CREATE = false;
40 const int32_t PLAY_TIME_1_SEC = 1;
41 int32_t g_duration = 0;
42
PlayerDataSrcFuzzer(int32_t fd,size_t size)43 PlayerDataSrcFuzzer::PlayerDataSrcFuzzer(int32_t fd, size_t size) : fd_(fd), size_(size) {}
44
~PlayerDataSrcFuzzer()45 PlayerDataSrcFuzzer::~PlayerDataSrcFuzzer() {}
46
ReadAt(int64_t pos,uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)47 int32_t PlayerDataSrcFuzzer::ReadAt(int64_t pos, uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
48 {
49 if (mem == nullptr) {
50 return 0;
51 }
52 if (pos + static_cast<int64_t>(length) >= static_cast<int64_t>(size_)) {
53 return -1;
54 }
55 if (pos > 0) {
56 lseek(fd_, pos, SEEK_SET);
57 }
58 int32_t ans = read(fd_, mem->GetBase(), length);
59 return ans;
60 }
61
ReadAt(uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)62 int32_t PlayerDataSrcFuzzer::ReadAt(uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
63 {
64 if (mem == nullptr) {
65 return 0;
66 }
67 if (static_cast<int64_t>(length) >= static_cast<int64_t>(size_)) {
68 return -1;
69 }
70 int ans = read(fd_, mem->GetBase(), length);
71 return ans;
72 }
73
ReadAt(const std::shared_ptr<AVSharedMemory> & mem,uint32_t length,int64_t pos=-1)74 int32_t PlayerDataSrcFuzzer::ReadAt(const std::shared_ptr<AVSharedMemory> &mem, uint32_t length, int64_t pos = -1)
75 {
76 int ans = ReadAt(pos, length, mem);
77 return ans;
78 }
79
GetSize(int64_t & size)80 int32_t PlayerDataSrcFuzzer::GetSize(int64_t &size)
81 {
82 size = static_cast<int32_t>(size_);
83 return 0;
84 }
85
SetDataSrcSource(sptr<IRemoteStub<IStandardPlayerService>> & playerStub)86 void PlayerDataSrcFuzzer::SetDataSrcSource(sptr<IRemoteStub<IStandardPlayerService>> &playerStub)
87 {
88 int32_t fileDes = open(DATA_PATH, O_RDONLY);
89 if (fileDes < 0) {
90 return;
91 }
92 struct stat64 st;
93 fstat(fileDes, &st);
94 const std::shared_ptr<IMediaDataSource> src = std::make_shared<PlayerDataSrcFuzzer>(fileDes, st.st_size);
95 sptr<MediaDataSourceStub> dataSrcStub_ = new(std::nothrow) MediaDataSourceStub(src);
96 sptr<IRemoteObject> object = dataSrcStub_->AsObject();
97 playerStub->SetSource(object);
98 return;
99 }
100
GetPlayStub()101 sptr<IRemoteStub<IStandardPlayerService>> PlayerDataSrcFuzzer::GetPlayStub()
102 {
103 std::shared_ptr<MediaServer> mediaServer =
104 std::make_shared<MediaServer>(SYSTEM_ABILITY_ID, RUN_ON_CREATE);
105 sptr<IRemoteObject> listener = new(std::nothrow) MediaListenerStubFuzzer();
106 sptr<IRemoteObject> player = mediaServer->GetSubSystemAbility(
107 IStandardMediaService::MediaSystemAbility::MEDIA_PLAYER, listener);
108 if (player == nullptr) {
109 return nullptr;
110 }
111 sptr<IRemoteStub<IStandardPlayerService>> playerStub = iface_cast<IRemoteStub<IStandardPlayerService>>(player);
112 return playerStub;
113 }
114
SelectTrack(sptr<IRemoteStub<IStandardPlayerService>> & playerStub)115 void PlayerDataSrcFuzzer::SelectTrack(sptr<IRemoteStub<IStandardPlayerService>> &playerStub)
116 {
117 std::vector<Format> audioTrack;
118 std::vector<int32_t> audioTrackIds;
119 int32_t currentAudioTrackIndex = -1;
120 playerStub->GetAudioTrackInfo(audioTrack);
121 playerStub->GetCurrentTrack(MediaType::MEDIA_TYPE_AUD, currentAudioTrackIndex);
122 for (Format audioTrackFormat: audioTrack) {
123 int32_t trackIndex = -1;
124 audioTrackFormat.GetIntValue("track_index", trackIndex);
125 audioTrackIds.push_back(trackIndex);
126 }
127 for (int32_t trackIndex: audioTrackIds) {
128 if (trackIndex != currentAudioTrackIndex) {
129 playerStub->SelectTrack(trackIndex, PlayerSwitchMode::SWITCH_SMOOTH);
130 playerStub->GetCurrentTrack(MediaType::MEDIA_TYPE_AUD, currentAudioTrackIndex);
131 sleep(PLAY_TIME_1_SEC);
132 playerStub->DeselectTrack(currentAudioTrackIndex);
133 playerStub->GetCurrentTrack(MediaType::MEDIA_TYPE_AUD, currentAudioTrackIndex);
134 sleep(PLAY_TIME_1_SEC);
135 }
136 }
137 return;
138 }
139
RunFuzz(uint8_t * data,size_t size)140 bool PlayerDataSrcFuzzer::RunFuzz(uint8_t *data, size_t size)
141 {
142 int32_t fd = open(DATA_PATH, O_RDONLY);
143 sptr<IRemoteStub<IStandardPlayerService>> playerStub = GetPlayStub();
144 if (playerStub == nullptr) {
145 return false;
146 }
147 SetDataSrcSource(playerStub);
148 sleep(PLAY_TIME_1_SEC);
149 playerStub->SetRenderFirstFrame(false);
150 sleep(PLAY_TIME_1_SEC);
151 AVPlayStrategy playbackStrategy = {.mutedMediaType = OHOS::Media::MediaType::MEDIA_TYPE_AUD};
152 playerStub->SetPlaybackStrategy(playbackStrategy);
153 sleep(PLAY_TIME_1_SEC);
154 playerStub->Prepare();
155 sleep(PLAY_TIME_1_SEC);
156 playerStub->SelectBitRate(0);
157 sleep(PLAY_TIME_1_SEC);
158 playerStub->SetVolume(1, 1);
159 sleep(PLAY_TIME_1_SEC);
160 playerStub->SetPlaybackSpeed(SPEED_FORWARD_0_50_X);
161 sleep(PLAY_TIME_1_SEC);
162 playerStub->GetDuration(g_duration);
163 if (g_duration == 0) {
164 playerStub->Release();
165 sleep(PLAY_TIME_1_SEC);
166 return false;
167 }
168 playerStub->SetPlayRange(0, g_duration);
169 sleep(PLAY_TIME_1_SEC);
170 playerStub->SetMediaMuted(OHOS::Media::MediaType::MEDIA_TYPE_AUD, true);
171 sleep(PLAY_TIME_1_SEC);
172 SelectTrack(playerStub);
173 FuzzedDataProvider fdp(data, size);
174 int seekTime = abs(fdp.ConsumeIntegral<int32_t>())%g_duration;
175 playerStub->Seek(seekTime, SEEK_NEXT_SYNC);
176 sleep(PLAY_TIME_1_SEC);
177 playerStub->Play();
178 sleep(PLAY_TIME_1_SEC);
179 playerStub->Pause();
180 sleep(PLAY_TIME_1_SEC);
181 playerStub->SetLooping(true);
182 sleep(PLAY_TIME_1_SEC);
183 playerStub->Stop();
184 sleep(PLAY_TIME_1_SEC);
185 playerStub->Release();
186 sleep(PLAY_TIME_1_SEC);
187 close(fd);
188 return true;
189 }
190 }
191 }
192
193 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)194 extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size)
195 {
196 if (size < sizeof(int64_t)) {
197 return false;
198 }
199 int32_t fd = open(DATA_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
200 if (fd < 0) {
201 return false;
202 }
203 int len = write(fd, data, size);
204 if (len <= 0) {
205 close(fd);
206 return false;
207 }
208 close(fd);
209 PlayerDataSrcFuzzer player(0, 0);
210 player.RunFuzz(data, size);
211 unlink(DATA_PATH);
212 return 0;
213 }
214
215