• 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 "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