Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64ccc9d9 authored by Kris Alder's avatar Kris Alder Committed by Android (Google) Code Review
Browse files

Merge "Added metadataretriever_fuzzer"

parents af8fd30b 077f8191
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -63,3 +63,20 @@ cc_fuzz {
        "libmediametrics",
    ],
}

cc_fuzz {
    name: "metadataretriever_fuzzer",
    srcs: [
        "metadataretriever_fuzzer.cpp",
    ],
    defaults: [
        "libmediaplayerserviceFuzzer_defaults",
    ],
    static_libs: [
        "libplayerservice_datasource",
    ],
    shared_libs: [
        "libdatasource",
        "libdrmframework",
    ],
}
+25 −0
Original line number Diff line number Diff line
# Fuzzer for libmediaplayerservice
## Table of contents
+ [StagefrightMediaRecorder](#StagefrightMediaRecorder)
+ [StagefrightMetadataRetriever](#StagefrightMetadataRetriever)

# <a name="StagefrightMediaRecorder"></a> Fuzzer for StagefrightMediaRecorder

@@ -24,3 +25,27 @@ You can find the possible values in the fuzzer's source code.
  $ adb sync data
  $ adb shell /data/fuzz/arm64/mediarecorder_fuzzer/mediarecorder_fuzzer
```

# <a name="StagefrightMetadataRetriever"></a> Fuzzer for StagefrightMetadataRetriever

StagefrightMetadataRetriever supports the following data sources:
1. Url (parameter name: `url`)
2. File descriptor (parameter name: `fd`)
3. DataSource (parameter name: `source`)

| Parameter| Valid Values| Configured Value|
|------------- |-------------| ----- |
| `url` | Url of data source | Value obtained from FuzzedDataProvider |
| `fd` | File descriptor value of input file | Value obtained from FuzzedDataProvider |
| `source` | DataSource object | Data obtained from FuzzedDataProvider |

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) metadataretriever_fuzzer
```
2. To run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/metadataretriever_fuzzer/metadataretriever_fuzzer
```
+156 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 *
 */

#include <StagefrightMetadataRetriever.h>
#include <binder/ProcessState.h>
#include <datasource/FileSource.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/foundation/base64.h>

#include <fuzzer/FuzzedDataProvider.h>

using namespace std;
using namespace android;

const char *kMimeTypes[] = {MEDIA_MIMETYPE_IMAGE_JPEG,         MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC,
                            MEDIA_MIMETYPE_VIDEO_VP8,          MEDIA_MIMETYPE_VIDEO_VP9,
                            MEDIA_MIMETYPE_VIDEO_AV1,          MEDIA_MIMETYPE_VIDEO_AVC,
                            MEDIA_MIMETYPE_VIDEO_HEVC,         MEDIA_MIMETYPE_VIDEO_MPEG4,
                            MEDIA_MIMETYPE_VIDEO_H263,         MEDIA_MIMETYPE_VIDEO_MPEG2,
                            MEDIA_MIMETYPE_VIDEO_RAW,          MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
                            MEDIA_MIMETYPE_VIDEO_SCRAMBLED,    MEDIA_MIMETYPE_VIDEO_DIVX,
                            MEDIA_MIMETYPE_VIDEO_DIVX3,        MEDIA_MIMETYPE_VIDEO_XVID,
                            MEDIA_MIMETYPE_VIDEO_MJPEG,        MEDIA_MIMETYPE_AUDIO_AMR_NB,
                            MEDIA_MIMETYPE_AUDIO_AMR_WB,       MEDIA_MIMETYPE_AUDIO_MPEG,
                            MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
                            MEDIA_MIMETYPE_AUDIO_MIDI,         MEDIA_MIMETYPE_AUDIO_AAC,
                            MEDIA_MIMETYPE_AUDIO_QCELP,        MEDIA_MIMETYPE_AUDIO_VORBIS,
                            MEDIA_MIMETYPE_AUDIO_OPUS,         MEDIA_MIMETYPE_AUDIO_G711_ALAW,
                            MEDIA_MIMETYPE_AUDIO_G711_MLAW,    MEDIA_MIMETYPE_AUDIO_RAW,
                            MEDIA_MIMETYPE_AUDIO_FLAC,         MEDIA_MIMETYPE_AUDIO_AAC_ADTS,
                            MEDIA_MIMETYPE_AUDIO_MSGSM,        MEDIA_MIMETYPE_AUDIO_AC3,
                            MEDIA_MIMETYPE_AUDIO_EAC3,         MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
                            MEDIA_MIMETYPE_AUDIO_AC4,          MEDIA_MIMETYPE_AUDIO_SCRAMBLED,
                            MEDIA_MIMETYPE_AUDIO_ALAC,         MEDIA_MIMETYPE_AUDIO_WMA,
                            MEDIA_MIMETYPE_AUDIO_MS_ADPCM,     MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM,
                            MEDIA_MIMETYPE_CONTAINER_MPEG4,    MEDIA_MIMETYPE_CONTAINER_WAV,
                            MEDIA_MIMETYPE_CONTAINER_OGG,      MEDIA_MIMETYPE_CONTAINER_MATROSKA,
                            MEDIA_MIMETYPE_CONTAINER_MPEG2TS,  MEDIA_MIMETYPE_CONTAINER_AVI,
                            MEDIA_MIMETYPE_CONTAINER_MPEG2PS,  MEDIA_MIMETYPE_CONTAINER_HEIF,
                            MEDIA_MIMETYPE_TEXT_3GPP,          MEDIA_MIMETYPE_TEXT_SUBRIP,
                            MEDIA_MIMETYPE_TEXT_VTT,           MEDIA_MIMETYPE_TEXT_CEA_608,
                            MEDIA_MIMETYPE_TEXT_CEA_708,       MEDIA_MIMETYPE_DATA_TIMED_ID3};

class MetadataRetrieverFuzzer {
   public:
    MetadataRetrieverFuzzer(const uint8_t *data, size_t size)
        : mFdp(data, size),
          mMdRetriever(new StagefrightMetadataRetriever()),
          mDataSourceFd(memfd_create("InputFile", MFD_ALLOW_SEALING)) {}
    ~MetadataRetrieverFuzzer() { close(mDataSourceFd); }
    bool setDataSource(const uint8_t *data, size_t size);
    void getData();

   private:
    FuzzedDataProvider mFdp;
    sp<StagefrightMetadataRetriever> mMdRetriever = nullptr;
    const int32_t mDataSourceFd;
};

void MetadataRetrieverFuzzer::getData() {
    int64_t timeUs = mFdp.ConsumeIntegral<int64_t>();
    int32_t option = mFdp.ConsumeIntegral<int32_t>();
    int32_t colorFormat = mFdp.ConsumeIntegral<int32_t>();
    bool metaOnly = mFdp.ConsumeBool();
    mMdRetriever->getFrameAtTime(timeUs, option, colorFormat, metaOnly);

    int32_t index = mFdp.ConsumeIntegral<int32_t>();
    colorFormat = mFdp.ConsumeIntegral<int32_t>();
    metaOnly = mFdp.ConsumeBool();
    bool thumbnail = mFdp.ConsumeBool();
    mMdRetriever->getImageAtIndex(index, colorFormat, metaOnly, thumbnail);

    index = mFdp.ConsumeIntegral<int32_t>();
    colorFormat = mFdp.ConsumeIntegral<int32_t>();
    int32_t left = mFdp.ConsumeIntegral<int32_t>();
    int32_t top = mFdp.ConsumeIntegral<int32_t>();
    int32_t right = mFdp.ConsumeIntegral<int32_t>();
    int32_t bottom = mFdp.ConsumeIntegral<int32_t>();
    mMdRetriever->getImageRectAtIndex(index, colorFormat, left, top, right, bottom);

    index = mFdp.ConsumeIntegral<int32_t>();
    colorFormat = mFdp.ConsumeIntegral<int32_t>();
    metaOnly = mFdp.ConsumeBool();
    mMdRetriever->getFrameAtIndex(index, colorFormat, metaOnly);

    mMdRetriever->extractAlbumArt();

    int32_t keyCode = mFdp.ConsumeIntegral<int32_t>();
    mMdRetriever->extractMetadata(keyCode);
}

bool MetadataRetrieverFuzzer::setDataSource(const uint8_t *data, size_t size) {
    status_t status = -1;

    enum DataSourceChoice {FromHttp, FromFd, FromFileSource, kMaxValue = FromFileSource};
    switch (mFdp.ConsumeEnum<DataSourceChoice>()) {
        case FromHttp: {
            KeyedVector<String8, String8> mHeaders;
            mHeaders.add(String8(mFdp.ConsumeRandomLengthString().c_str()),
                         String8(mFdp.ConsumeRandomLengthString().c_str()));

            uint32_t dataBlobSize = mFdp.ConsumeIntegralInRange<uint16_t>(0, size);
            vector<uint8_t> uriSuffix = mFdp.ConsumeBytes<uint8_t>(dataBlobSize);

            string uri("data:");
            uri += ";base64,";
            AString out;
            encodeBase64(uriSuffix.data(), uriSuffix.size(), &out);
            uri += out.c_str();
            status = mMdRetriever->setDataSource(nullptr /*httpService*/, uri.c_str(), &mHeaders);
            break;
        }
        case FromFd: {
            write(mDataSourceFd, data, size);

            status = mMdRetriever->setDataSource(mDataSourceFd, 0, size);
            break;
        }
        case FromFileSource: {
            write(mDataSourceFd, data, size);

            sp<DataSource> dataSource = new FileSource(dup(mDataSourceFd), 0, size);
            status = mMdRetriever->setDataSource(dataSource, mFdp.PickValueInArray(kMimeTypes));
            break;
        }
    }

    if (status != 0) {
        return false;
    }
    return true;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    MetadataRetrieverFuzzer mrtFuzzer(data, size);
    ProcessState::self()->startThreadPool();
    if (mrtFuzzer.setDataSource(data, size)) {
        mrtFuzzer.getData();
    }
    return 0;
}