Files
android/fuzzer/buffer_reader_fuzzer.cpp
Onkar Shinde 363447d00c Updated buffer_reader_fuzzer
Implemented google c++ code style changes for buffer_reader_fuzzer

exec/s: 3649
Test: ./buffer_reader_fuzzer
Bug: 312374669

Change-Id: I53bd247f6c95202d7a5e86115aa060c61821d49c
2023-12-08 10:26:48 +00:00

292 lines
10 KiB
C++

/*
* Copyright (C) 2023 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 <buffer_reader.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <initialization_data.h>
#include <string_conversions.h>
#include <wv_cdm_constants.h>
using namespace wvcdm;
using namespace video_widevine;
using namespace wvutil;
static constexpr int32_t kMaxByte = 20;
static constexpr int32_t kMinSize = 0;
static constexpr int32_t kMaxSize = 1000;
const std::string kInitDataTypes[] = {
HLS_INIT_DATA_FORMAT, ISO_BMFF_VIDEO_MIME_TYPE, ISO_BMFF_AUDIO_MIME_TYPE,
CENC_INIT_DATA_FORMAT, WEBM_VIDEO_MIME_TYPE, WEBM_AUDIO_MIME_TYPE,
WEBM_INIT_DATA_FORMAT,
};
const std::string kHlsMethod[] = {HLS_METHOD_AES_128, HLS_METHOD_NONE,
HLS_METHOD_SAMPLE_AES};
const std::string kOemCryptoWithoutEntitlements = "13";
const std::string kOemCryptoWithEntitlements = "14";
const std::string kInitDataVersions[] = {
kOemCryptoWithoutEntitlements,
kOemCryptoWithEntitlements,
};
const std::string kMultipleWidevinePsshBox = wvutil::a2bs_hex(
// first PSSH box, Widevine with single keys
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031"
// second PSSH box, Widevine with entitled keys
"000001fb" // atom size
"70737368" // atom type="pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"000001db" // data size
// data:
"220b47726f7570563254657374381448"
"e3dc959b065002580272580a10668093"
"381a8c5be48a0168ce372726ac1210c8"
"326486bb5d5c4a958f00b1111afc811a"
"20082cd9d3aed3ebe6239d30fbcf0b22"
"1d28cbb0360ea1295c2363973346ec00"
"512210914781334e864c8eb7f768cf26"
"49073872580a10f872d11d5b1052f2bd"
"a94e60a0e383021210450897c987a85c"
"2e9579f968554a12991a2097e603ceea"
"f35ed8cef1029eae7a0a54701e3d6db6"
"80e7da1de3b22a8db347fb2210b41c34"
"29b7bb96972bbaf6587bc0ddf172580a"
"10bac58b9fce9e5929a42a180e529f19"
"4712103f11f22988d25659b145ce4854"
"3e6b141a20416e22768e5a57b08d155e"
"5210d00658056947ff06d626668bceb3"
"5eb01c6b57221081fb2ff3fef79d332f"
"f98be46233596972580a101261c8036d"
"ae5c8caa968858aa0ca9cc12106d583c"
"b37c1456519843a81cf49912221a20c2"
"1116bb54a226e8d879a4cd41d8879920"
"2ae85b80d83b1b4447e5d7fcad6f6a22"
"100b27a4c3f44771d2b0c7c34c66af35"
"b572580a10ab1c8c259c6b5967991389"
"65bff5ac0c1210b5b4473658565d3786"
"efaf4b85d8e6e21a203ce6a9085285c2"
"ece0b650dc83dd7aa8ac849611a8e3f8"
"3c8f389223c0f3621522101946f0c2a3"
"d543101cc842bbec2d0b30");
const std::string kHlsData =
"EXT-X-KEY: METHOD=SAMPLE-AES, "
"URI=”data:text/plain;base64,eyANCiAgICJwcm92aWRlciI6Im1sYmFtaGJvIiwNCiAg"
"ICJjb250ZW50X2lkIjoiMjAxNV9UZWFycyIsDQogICAia2V5X2lkcyI6DQogICBbDQo"
"gICAgICAiMzcxZTEzNWUxYTk4NWQ3NWQxOThhN2Y0MTAyMGRjMjMiDQogICBdDQp9DQ"
"o=, "
"IV=0x6df49213a781e338628d0e9c812d328e, "
"KEYFORMAT=”com.widevine”, "
"KEYFORMATVERSIONS=”1”";
const std::string kHlsMethodParse = "EXT-X-KEY: METHOD=";
const std::string KUriParse = "\"URI=\"data:text/plain;base64,";
const std::string kIvParse = "\"IV=";
const std::string kKeyFormatParse = "\"KEYFORMAT=\"";
const std::string kKeyFormatVersionParse = "\"KEYFORMATVERSIONS=\"";
class BufferReaderFuzzer {
public:
BufferReaderFuzzer(const uint8_t *data, size_t size) : fdp_(data, size){};
void Process();
std::string SetPartialRandomHlsData();
std::string SetRandomHlsData();
private:
FuzzedDataProvider fdp_;
};
std::string BufferReaderFuzzer::SetPartialRandomHlsData() {
std::string hls_method =
kHlsMethodParse +
(fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxByte)
: fdp_.PickValueInArray(kHlsMethod)) +
", \"";
std::string uri = KUriParse +
(fdp_.ConsumeBool()
? fdp_.ConsumeRandomLengthString(kMaxByte)
: "eyANCiAgICJwcm92aWRlciI6Im1sYmFtaGJvIiwNCiAg\" \
\"ICJjb250ZW50X2lkIjoiMjAxNV9UZWFycyIsDQogICAia2V5X2lkcyI6DQogICBbDQo\" \
\"gICAgICAiMzcxZTEzNWUxYTk4NWQ3NWQxOThhN2Y0MTAyMGRjMjMiDQogICBdDQp9DQ\" \
\"o=") + ", \"";
std::string iv =
kIvParse +
((fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxByte)
: "0x6df49213a781e338628d0e9c812d328e,")) +
"\"";
std::string key_format =
kKeyFormatParse +
(fdp_.ConsumeBool()
? ("\"" + fdp_.ConsumeRandomLengthString(kMaxByte) + "\"")
: "com.widevine\", \"");
std::string key_format_version =
kKeyFormatVersionParse +
(fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxByte) : "\"1\"");
std::string result = hls_method + uri + iv + key_format + key_format_version;
return result;
}
std::string BufferReaderFuzzer::SetRandomHlsData() {
std::string hls_method;
if (fdp_.ConsumeBool()) {
hls_method = kHlsMethodParse;
}
hls_method += fdp_.ConsumeRandomLengthString(kMaxByte) + ", \"";
std::string uri;
if (fdp_.ConsumeBool()) {
uri = KUriParse;
}
uri += fdp_.ConsumeRandomLengthString(kMaxByte) + ", \"";
std::string iv;
if (fdp_.ConsumeBool()) {
iv = kIvParse;
}
iv += fdp_.ConsumeRandomLengthString(kMaxByte) + "\"";
std::string key_format;
if (fdp_.ConsumeBool()) {
key_format = kKeyFormatParse;
}
key_format += fdp_.ConsumeRandomLengthString(kMaxByte) + "\"";
std::string key_format_version;
if (fdp_.ConsumeBool()) {
key_format_version = kKeyFormatVersionParse;
}
key_format_version += fdp_.ConsumeRandomLengthString(kMaxByte);
std::string result = hls_method + uri + iv + key_format + key_format_version;
return result;
}
void BufferReaderFuzzer::Process() {
std::vector<uint8_t> raw_data =
fdp_.ConsumeBytes<uint8_t>(fdp_.ConsumeIntegral<size_t>());
BufferReader reader(raw_data.data(), raw_data.size());
std::string type = fdp_.PickValueInArray(kInitDataTypes);
std::string data;
if (type == ISO_BMFF_VIDEO_MIME_TYPE || type == ISO_BMFF_AUDIO_MIME_TYPE ||
type == CENC_INIT_DATA_FORMAT) {
data = fdp_.ConsumeBool()
? wvutil::a2bs_hex(fdp_.ConsumeRandomLengthString(kMaxByte))
: kMultipleWidevinePsshBox;
} else if (type == HLS_INIT_DATA_FORMAT) {
data = fdp_.PickValueInArray(
{kHlsData, SetPartialRandomHlsData(), SetRandomHlsData()});
} else {
data = fdp_.ConsumeRandomLengthString(kMaxByte);
}
std::string init_data_type =
fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxByte) : type;
std::string version =
fdp_.ConsumeBool() ? fdp_.PickValueInArray(kInitDataVersions) : "";
InitializationData init_data(init_data_type, data, version);
while (fdp_.remaining_bytes()) {
auto invoke_buffer_reader_API =
fdp_.PickValueInArray<const std::function<void()>>({
[&]() {
uint8_t place_holder;
fdp_.ConsumeBool() ? reader.Read1(&place_holder)
: reader.Read1(nullptr);
},
[&]() {
uint16_t place_holder;
fdp_.ConsumeBool() ? reader.Read2(&place_holder)
: reader.Read2(nullptr);
},
[&]() {
int16_t place_holder;
fdp_.ConsumeBool() ? reader.Read2s(&place_holder)
: reader.Read2s(nullptr);
},
[&]() {
int64_t place_holder;
fdp_.ConsumeBool() ? reader.Read8s(&place_holder)
: reader.Read8s(nullptr);
},
[&]() {
uint64_t place_holder;
fdp_.ConsumeBool() ? reader.Read8(&place_holder)
: reader.Read8(nullptr);
},
[&]() {
int64_t place_holder;
fdp_.ConsumeBool() ? reader.Read4sInto8s(&place_holder)
: reader.Read4sInto8s(nullptr);
},
[&]() {
std::string place_holder;
fdp_.ConsumeBool()
? reader.ReadString(
&place_holder,
fdp_.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize))
: reader.ReadString(
nullptr, fdp_.ConsumeIntegralInRange<size_t>(kMinSize,
kMaxSize));
},
[&]() {
std::vector<uint8_t> place_holder;
fdp_.ConsumeBool()
? reader.ReadVec(
&place_holder,
fdp_.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize))
: reader.ReadVec(nullptr, fdp_.ConsumeIntegralInRange<size_t>(
kMinSize, kMaxSize));
},
[&]() { init_data.ExtractWrappedKeys(); },
[&]() { init_data.DumpToLogs(); },
[&]() { init_data.WidevineSystemID(); },
});
invoke_buffer_reader_API();
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
BufferReaderFuzzer buffer_reader_fuzzer(data, size);
buffer_reader_fuzzer.Process();
return 0;
}