blob: 70d73c8c52bb53f84227934541b6ec7a52b56a33 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Authors: corbin.souffrant@leviathansecurity.com
// dylan.katz@leviathansecurity.com
#include <MediaMuxerFuzzer.h>
#include <cutils/ashmem.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <media/stagefright/MediaMuxer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
namespace android {
// Can't seem to get setBuffer or setString working. It always segfaults on a
// null pointer read or memleaks. So that functionality is missing.
void createMessage(AMessage *msg, FuzzedDataProvider *fdp) {
size_t count = fdp->ConsumeIntegralInRange<size_t>(0, 32);
while (fdp->remaining_bytes() > 0 && count > 0) {
uint8_t function_id =
fdp->ConsumeIntegralInRange<uint8_t>(0, amessage_setvals.size() - 1);
amessage_setvals[function_id](msg, fdp);
count--;
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
size_t data_size = fdp.ConsumeIntegralInRange<size_t>(0, size);
int fd = ashmem_create_region("mediamuxer_fuzz_region", data_size);
if (fd < 0)
return 0;
uint8_t *sh_data = static_cast<uint8_t *>(
mmap(NULL, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
if (sh_data == MAP_FAILED)
return 0;
MediaMuxer::OutputFormat format =
(MediaMuxer::OutputFormat)fdp.ConsumeIntegralInRange<int32_t>(0, 4);
sp<MediaMuxer> mMuxer = MediaMuxer::create(fd, format);
if (mMuxer == nullptr) {
return 0;
}
while (fdp.remaining_bytes() > 1) {
switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 4)) {
case 0: {
// For some reason it only likes mp4s here...
if (format == 1 || format == 4)
break;
sp<AMessage> a_format(new AMessage);
createMessage(a_format.get(), &fdp);
mMuxer->addTrack(a_format);
break;
}
case 1: {
mMuxer->start();
break;
}
case 2: {
int degrees = fdp.ConsumeIntegral<int>();
mMuxer->setOrientationHint(degrees);
break;
}
case 3: {
int latitude = fdp.ConsumeIntegral<int>();
int longitude = fdp.ConsumeIntegral<int>();
mMuxer->setLocation(latitude, longitude);
break;
}
case 4: {
size_t buf_size = fdp.ConsumeIntegralInRange<size_t>(0, data_size);
sp<ABuffer> a_buffer(new ABuffer(buf_size));
size_t trackIndex = fdp.ConsumeIntegral<size_t>();
int64_t timeUs = fdp.ConsumeIntegral<int64_t>();
uint32_t flags = fdp.ConsumeIntegral<uint32_t>();
mMuxer->writeSampleData(a_buffer, trackIndex, timeUs, flags);
}
}
}
if (fdp.ConsumeBool())
mMuxer->stop();
munmap(sh_data, data_size);
close(fd);
return 0;
}
} // namespace android