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

Commit adec76d0 authored by Glenn Kasten's avatar Glenn Kasten Committed by Gerrit Code Review
Browse files

Merge "Adding fuzzers for libstagefright."

parents 949694cf ae47117b
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
cc_defaults {
    name: "libstagefright_fuzzer_defaults",
    cflags: [
        "-Wno-multichar",
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wall",
    ],
    shared_libs: [
        "libstagefright",
	"libstagefright_codecbase",
        "libutils",
        "libstagefright_foundation",
        "libmedia",
        "libaudioclient",
        "libmedia_omx",
        "libgui",
        "libbinder",
        "libcutils",
    ],
}

cc_fuzz {
    name: "libstagefright_mediaclock_fuzzer",
    srcs: [
        "MediaClockFuzzer.cpp",
    ],
    defaults: ["libstagefright_fuzzer_defaults"],
}

cc_fuzz {
    name: "libstagefright_mediascanner_fuzzer",
    srcs: [
        "StagefrightMediaScannerFuzzer.cpp",
    ],
    defaults: ["libstagefright_fuzzer_defaults"],
}

cc_fuzz {
    name: "libstagefright_skipcutbuffer_fuzzer",
    srcs: [
        "SkipCutBufferFuzzer.cpp",
    ],
    defaults: ["libstagefright_fuzzer_defaults"],
}

cc_fuzz {
    name: "libstagefright_mediamuxer_fuzzer",
    srcs: [
        "MediaMuxerFuzzer.cpp",
    ],
    defaults: ["libstagefright_fuzzer_defaults"],
}
+68 −0
Original line number Diff line number Diff line
/*
 * 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 <fuzzer/FuzzedDataProvider.h>
#include <media/stagefright/MediaClock.h>
#include <media/stagefright/foundation/AMessage.h>

namespace android {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
  sp<MediaClock> mClock(new MediaClock);

  bool registered = false;
  while (fdp.remaining_bytes() > 0) {
    switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 5)) {
    case 0: {
      if (registered == false) {
        mClock->init();
        registered = true;
      }
      break;
    }
    case 1: {
      int64_t startingTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
      mClock->setStartingTimeMedia(startingTimeMediaUs);
      break;
    }
    case 2: {
      mClock->clearAnchor();
      break;
    }
    case 3: {
      int64_t anchorTimeRealUs = fdp.ConsumeIntegral<int64_t>();
      int64_t anchorTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
      int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
      mClock->updateAnchor(anchorTimeMediaUs, anchorTimeRealUs, maxTimeMediaUs);
      break;
    }
    case 4: {
      int64_t maxTimeMediaUs = fdp.ConsumeIntegral<int64_t>();
      mClock->updateMaxTimeMedia(maxTimeMediaUs);
      break;
    }
    case 5: {
      wp<AMessage> msg(new AMessage);
      mClock->setNotificationMessage(msg.promote());
    }
    }
  }

  return 0;
}
} // namespace android
+103 −0
Original line number Diff line number Diff line
/*
 * 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(new MediaMuxer(fd, format));

  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
+109 −0
Original line number Diff line number Diff line
/*
 * 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

#pragma once

#include <fuzzer/FuzzedDataProvider.h>
#include <media/stagefright/foundation/AMessage.h>

namespace android {

// Mappings vectors are the list of attributes that the MediaMuxer
// class looks for in the message.
static std::vector<const char *> floatMappings{
    "capture-rate",
    "time-lapse-fps",
    "frame-rate",
};

static std::vector<const char *> int64Mappings{
    "exif-offset",    "exif-size", "target-time",
    "thumbnail-time", "timeUs",    "durationUs",
};

static std::vector<const char *> int32Mappings{"loop",
                                               "time-scale",
                                               "crypto-mode",
                                               "crypto-default-iv-size",
                                               "crypto-encrypted-byte-block",
                                               "crypto-skip-byte-block",
                                               "frame-count",
                                               "max-bitrate",
                                               "pcm-big-endian",
                                               "temporal-layer-count",
                                               "temporal-layer-id",
                                               "thumbnail-width",
                                               "thumbnail-height",
                                               "track-id",
                                               "valid-samples",
                                               "color-format",
                                               "ca-system-id",
                                               "is-sync-frame",
                                               "bitrate",
                                               "max-bitrate",
                                               "width",
                                               "height",
                                               "sar-width",
                                               "sar-height",
                                               "display-width",
                                               "display-height",
                                               "is-default",
                                               "tile-width",
                                               "tile-height",
                                               "grid-rows",
                                               "grid-cols",
                                               "rotation-degrees",
                                               "channel-count",
                                               "sample-rate",
                                               "bits-per-sample",
                                               "channel-mask",
                                               "encoder-delay",
                                               "encoder-padding",
                                               "is-adts",
                                               "frame-rate",
                                               "max-height",
                                               "max-width",
                                               "max-input-size",
                                               "haptic-channel-count",
                                               "pcm-encoding",
                                               "aac-profile"};

static const std::vector<std::function<void(AMessage *, FuzzedDataProvider *)>>
    amessage_setvals = {
        [](AMessage *msg, FuzzedDataProvider *fdp) -> void {
          msg->setRect("crop", fdp->ConsumeIntegral<int32_t>(),
                       fdp->ConsumeIntegral<int32_t>(),
                       fdp->ConsumeIntegral<int32_t>(),
                       fdp->ConsumeIntegral<int32_t>());
        },
        [](AMessage *msg, FuzzedDataProvider *fdp) -> void {
          msg->setFloat(floatMappings[fdp->ConsumeIntegralInRange<size_t>(
                            0, floatMappings.size() - 1)],
                        fdp->ConsumeFloatingPoint<float>());
        },
        [](AMessage *msg, FuzzedDataProvider *fdp) -> void {
          msg->setInt64(int64Mappings[fdp->ConsumeIntegralInRange<size_t>(
                            0, int64Mappings.size() - 1)],
                        fdp->ConsumeIntegral<int64_t>());
        },
        [](AMessage *msg, FuzzedDataProvider *fdp) -> void {
          msg->setInt32(int32Mappings[fdp->ConsumeIntegralInRange<size_t>(
                            0, int32Mappings.size() - 1)],
                        fdp->ConsumeIntegral<int32_t>());
        }};
} // namespace android
+73 −0
Original line number Diff line number Diff line
/*
 * 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 <fuzzer/FuzzedDataProvider.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/SkipCutBuffer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>

namespace android {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
  size_t skip = fdp.ConsumeIntegral<size_t>();
  size_t cut = fdp.ConsumeIntegral<size_t>();
  size_t num16Channels = fdp.ConsumeIntegral<size_t>();
  sp<SkipCutBuffer> sBuffer(new SkipCutBuffer(skip, cut, num16Channels));

  while (fdp.remaining_bytes() > 0) {
    // Cap size to 1024 to limit max amount allocated.
    size_t buf_size = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
    size_t range = fdp.ConsumeIntegralInRange<size_t>(0, buf_size);
    size_t length = fdp.ConsumeIntegralInRange<size_t>(0, buf_size - range);

    switch (fdp.ConsumeIntegralInRange<uint8_t>(0, 4)) {
    case 0: {
      sp<ABuffer> a_buffer(new ABuffer(buf_size));
      sp<AMessage> format(new AMessage);
      sp<MediaCodecBuffer> s_buffer(new MediaCodecBuffer(format, a_buffer));
      s_buffer->setRange(range, length);
      sBuffer->submit(s_buffer);
      break;
    }
    case 1: {
      std::unique_ptr<MediaBufferBase> m_buffer(new MediaBuffer(buf_size));
      m_buffer->set_range(range, length);
      sBuffer->submit(reinterpret_cast<MediaBuffer *>(m_buffer.get()));
      break;
    }
    case 2: {
      sp<ABuffer> a_buffer(new ABuffer(buf_size));
      sp<AMessage> format(new AMessage);
      sp<MediaCodecBuffer> s_buffer(new MediaCodecBuffer(format, a_buffer));
      a_buffer->setRange(range, length);
      sBuffer->submit(a_buffer);
      break;
    }
    case 3: {
      sBuffer->clear();
      break;
    }
    case 4: {
      sBuffer->size();
    }
    }
  }
  return 0;
}
} // namespace android
Loading