diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index 81231400..1ad4e09f 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -134,3 +134,9 @@ cc_fuzz { srcs: ["device_files_fuzzer.cpp"], defaults: ["libcdm_fuzzer_defaults"], } + +cc_fuzz{ + name: "cdm_session_fuzzer", + srcs: ["cdm_session_fuzzer.cpp"], + defaults: ["libcdm_fuzzer_defaults"] +} diff --git a/fuzzer/README.md b/fuzzer/README.md index d313f2f0..33cbe1df 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -13,6 +13,7 @@ + [cdm_engine_fuzzer](#CdmEngine) + [certificate_provisioning_fuzzer](#CertificateProvisioning) + [device_files_fuzzer](#DeviceFile) ++ [cdm_session_fuzzer](#CdmSession) # Fuzzer for PolicyEngine @@ -304,3 +305,27 @@ DeviceFile supports the following parameters: $ adb sync data $ adb shell /data/fuzz/arm64/device_files_fuzzer/vendor/device_files_fuzzer ``` + +# Fuzzer for CdmSession + +CdmSession supports the following parameters: +1. CdmKeyResponse (parameter name: "key_response") +2. CdmSessionId (parameter name: "forced_session_id") +3. KeyId (parameter name:"key_id") + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +|`key_response`| `String` |Value obtained from FuzzedDataProvider| +|`forced_session_id`| `String` |Value obtained from FuzzedDataProvider| +|`key_id`| `String` |Value obtained from FuzzedDataProvider| + +#### Steps to run +1. Build the fuzzer +``` + $ mm -j$(nproc) cdm_session_fuzzer +``` +2. Run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/cdm_session_fuzzer/vendor/cdm_session_fuzzer +``` diff --git a/fuzzer/cdm_session_fuzzer.cpp b/fuzzer/cdm_session_fuzzer.cpp new file mode 100644 index 00000000..38905589 --- /dev/null +++ b/fuzzer/cdm_session_fuzzer.cpp @@ -0,0 +1,569 @@ +/* + * 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 "cdm_client_property_set.h" +#include "cdm_random.h" +#include "cdm_session.h" +#include "cdm_session_map.h" +#include "device_files.h" +#include "license.h" +#include "metrics_collections.h" +#include "timer_metric.h" +#include "vendor_widevine_fuzz_helper.h" +#include "wv_cdm_event_listener.h" +#include "wv_cdm_types.h" +#include + +using namespace wvcdm; +using namespace wvcdm::metrics; +using namespace wvutil; + +static constexpr int32_t kMinByte = 0; +static constexpr int32_t kMaxByte = 256; +static constexpr int32_t kMaxId = 100; +static constexpr int32_t kMinId = 0; +static constexpr int8_t kMaxSize = 16; +static std::string kSessionId = "sid"; +static std::string kKeyId = "k" + kSessionId; + +std::string kInitType[] = {ISO_BMFF_VIDEO_MIME_TYPE, ISO_BMFF_AUDIO_MIME_TYPE, + WEBM_VIDEO_MIME_TYPE, WEBM_AUDIO_MIME_TYPE, + CENC_INIT_DATA_FORMAT, HLS_INIT_DATA_FORMAT, + WEBM_INIT_DATA_FORMAT}; + +class FuzzEventListener : public WvCdmEventListener { + void OnSessionRenewalNeeded(const CdmSessionId & /*session_id*/) {} + void OnSessionKeysChange(const CdmSessionId & /*session_id*/, + const CdmKeyStatusMap & /*keys_status*/, + bool /*has_new_usable_key*/) {} + void OnExpirationUpdate(const CdmSessionId & /*session_id*/, + int64_t /*new_expiry_time_seconds*/) {} +}; + +class CdmSessionFuzzer { +public: + CdmSessionFuzzer(const uint8_t *data, size_t size) : mFdp(data, size){}; + void process(); + +private: + FuzzedDataProvider mFdp; + void invokeCdmSessionAPIs(CdmSession *cdmSession); + void invokeCdmSessionMapAPIs(); + CdmResponseType + initCdmSession(CdmSession *cdmSession, + FuzzCdmClientPropertySet *fuzzCdmClientPropertySet, + CdmSessionId forcedsessionId, + FuzzEventListener *fuzzeventListener, bool forcedLevel); + void createResponse(CdmKeyResponse *response); + void setLicenseMsg(std::string *msg); + void storeLicense(DeviceFiles::CdmLicenseData licenseData); +}; + +class FuzzFile : public File { +public: + FuzzFile(FuzzedDataProvider *fdp) : mFdp(fdp) {} + + ssize_t Read(char *buffer, size_t bytes) { + std::vector initData = mFdp->ConsumeBytes( + mFdp->ConsumeIntegralInRange(kMinByte, bytes)); + buffer = initData.data(); + return initData.size(); + }; + + ssize_t Write(const char * /* buffer*/, size_t bytes) { + return mFdp->ConsumeIntegralInRange(kMinByte, bytes); + }; + +private: + FuzzedDataProvider *mFdp; +}; + +class FuzzFileSystem : public FileSystem { +public: + FuzzFileSystem(FuzzedDataProvider *fdp) : mFdp(fdp) {} + + std::unique_ptr Open(const std::string &, int) { + return std::unique_ptr(new FuzzFile(mFdp)); + } + + bool Exists(const std::string &) { return mFdp->ConsumeBool(); } + + bool Remove(const std::string &) { return mFdp->ConsumeBool(); } + + ssize_t FileSize(const std::string &) { + return mFdp->ConsumeIntegralInRange(kMinByte, kMaxByte); + } + + bool List(const std::string &, std::vector *) { + return mFdp->ConsumeBool(); + } + +private: + FuzzedDataProvider *mFdp; +}; + +void policySetBool(std::function function, + FuzzedDataProvider *fdp) { + if (fdp->ConsumeBool()) { + function(fdp->ConsumeBool()); + } +} + +void CdmSessionFuzzer::setLicenseMsg(std::string *msg) { + video_widevine::License license; + + if (mFdp.ConsumeBool()) { + std::string provider_client_token = + mFdp.ConsumeRandomLengthString(kMaxByte); + license.set_provider_client_token(provider_client_token); + } + if (mFdp.ConsumeBool()) { + uint32_t scheme = mFdp.ConsumeIntegral(); + license.set_protection_scheme(scheme); + } + + video_widevine::License::KeyContainer *container = license.add_key(); + + if (mFdp.ConsumeBool()) { + uint32_t keyType = mFdp.ConsumeIntegralInRange( + video_widevine::License::KeyContainer::SIGNING, + video_widevine::License::KeyContainer::ENTITLEMENT); + container->set_type((video_widevine::License_KeyContainer_KeyType)keyType); + } + + if (mFdp.ConsumeBool()) { + container->mutable_iv(); + } + + if (mFdp.ConsumeBool()) { + std::string keyString = mFdp.ConsumeRandomLengthString(kMaxByte); + container->set_key(keyString); + } + + if (mFdp.ConsumeBool()) { + container->mutable_id(); + } + + if (mFdp.ConsumeBool()) { + container->mutable_track_label(); + } + + video_widevine::License_KeyContainer_KeyControl *keyControl = + container->mutable_key_control(); + if (mFdp.ConsumeBool()) { + keyControl->mutable_key_control_block(); + } + + if (mFdp.ConsumeBool()) { + keyControl->mutable_iv(); + } + + if (mFdp.ConsumeBool()) { + video_widevine::License_Policy *policy = license.mutable_policy(); + policySetBool(std::bind(&video_widevine::License_Policy::set_can_persist, + policy, std::placeholders::_1), + &mFdp); + if (mFdp.ConsumeBool()) { + std::string server_url = mFdp.ConsumeRandomLengthString(kMaxByte); + policy->set_renewal_server_url(server_url); + } + policySetBool( + std::bind(&video_widevine::License_Policy::set_always_include_client_id, + policy, std::placeholders::_1), + &mFdp); + } + + LicenseIdentification *id = license.mutable_id(); + if (mFdp.ConsumeBool()) { + id->set_type(mFdp.ConsumeBool() ? video_widevine::STREAMING + : video_widevine::OFFLINE); + } + if (mFdp.ConsumeBool()) { + std::string provider_session_token = + mFdp.ConsumeRandomLengthString(kMaxByte); + id->set_provider_session_token(provider_session_token); + } + license.SerializeToString(msg); +} + +void CdmSessionFuzzer::createResponse(CdmKeyResponse *response) { + video_widevine::SignedMessage signed_message; + video_widevine::SignedMessage type; + signed_message.set_type(video_widevine::SignedMessage::LICENSE); + signed_message.mutable_service_version_info(); + std::string sign = mFdp.ConsumeRandomLengthString(kMaxByte); + sign.resize(kMaxId, '0'); + signed_message.set_signature(sign); + std::string key = mFdp.ConsumeRandomLengthString(kMaxByte); + key.resize(kMaxId, '0'); + signed_message.set_session_key(key); + std::string message = mFdp.ConsumeRandomLengthString(kMaxByte); + message.resize(kMaxId, '0'); + signed_message.set_oemcrypto_core_message(message); + signed_message.set_using_secondary_key(mFdp.ConsumeBool()); + std::string setMsg = mFdp.ConsumeRandomLengthString(kMaxByte); + signed_message.set_msg(setMsg); + signed_message.SerializeToString(response); +} + +CdmResponseType CdmSessionFuzzer::initCdmSession( + CdmSession *cdmSession, FuzzCdmClientPropertySet *fuzzCdmClientPropertySet, + CdmSessionId forcedsessionId, FuzzEventListener *fuzzeventListener, + bool forcedLevel) { + CdmResponseType result; + if (mFdp.ConsumeBool()) { + result = + cdmSession->Init(fuzzCdmClientPropertySet /*cdm_client_property_set*/, + &forcedsessionId /*forced_session_id*/, + fuzzeventListener /*event_listener*/, forcedLevel); + } else { + result = + cdmSession->Init(fuzzCdmClientPropertySet /*cdm_client_property_set*/); + } + return result; +} + +void CdmSessionFuzzer::storeLicense(DeviceFiles::CdmLicenseData licenseData) { + FuzzFileSystem fileSystemdev(&mFdp); + DeviceFiles deviceFiles(mFdp.ConsumeBool() ? &fileSystemdev : nullptr); + deviceFiles.Init((CdmSecurityLevel)mFdp.ConsumeIntegralInRange( + kSecurityLevelL1, kSecurityLevelL3)); + std::map appParameters; + + appParameters[mFdp.ConsumeBytesAsString(kMaxByte)] = + mFdp.ConsumeBytesAsString(kMaxByte); + licenseData.key_set_id = + std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + licenseData.state = + (CdmOfflineLicenseState)mFdp.ConsumeIntegralInRange( + kLicenseStateActive, kLicenseStateUnknown); + licenseData.pssh_data = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.license_request = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.license = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.license_renewal_request = + mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.license_renewal = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.release_server_url = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.playback_start_time = mFdp.ConsumeIntegral(); + licenseData.last_playback_time = mFdp.ConsumeIntegral(); + licenseData.grace_period_end_time = mFdp.ConsumeIntegral(); + licenseData.app_parameters = appParameters; + licenseData.usage_entry = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.usage_entry_index = mFdp.ConsumeIntegral(); + licenseData.drm_certificate = mFdp.ConsumeRandomLengthString(kMaxByte); + licenseData.wrapped_private_key = CryptoWrappedKey( + (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange( + CryptoWrappedKey::kUninitialized, CryptoWrappedKey::kEcc), + mFdp.ConsumeRandomLengthString(kMaxByte)); + + DeviceFiles::ResponseType result; + deviceFiles.StoreLicense(licenseData, &result); +} + +void CdmSessionFuzzer::invokeCdmSessionAPIs(CdmSession *cdmSession) { + CdmKeyResponse response; + createResponse(&response); + CdmKeyRequest keyRequest; + CdmKeyMessage signedRequest; + keyRequest.message = signedRequest; + keyRequest.type = (CdmKeyRequestType)mFdp.ConsumeIntegralInRange( + kKeyRequestTypeUnknown, kKeyRequestTypeRelease); + std::string url; + keyRequest.url = url; + while (mFdp.remaining_bytes()) { + auto invokeCdmSessionAPI = mFdp.PickValueInArray< + const std::function>( + {[&]() { cdmSession->AddKey(response /*key_response*/); }, + [&]() { + FuzzCdmClientPropertySet propertyset(&mFdp); + propertyset.enable_privacy_mode(); + propertyset.set_service_certificate(kTestSignedCertificate); + PropertiesTestPeer::ForceReinit(); + PropertiesTestPeer::AddSessionPropertySet( + mFdp.ConsumeBool() ? kTestSessionId1 + : mFdp.ConsumeRandomLengthString(kMaxByte), + &propertyset); + std::string rawServiceCertificate; + PropertiesTestPeer::GetServiceCertificate( + mFdp.ConsumeBool() ? kTestSessionId1 + : mFdp.ConsumeRandomLengthString(kMaxByte), + &rawServiceCertificate); + cdmSession->SetServiceCertificate( + rawServiceCertificate /*service_certificate*/); + }, + [&]() { + CdmQueryMap queryResponse; + cdmSession->QueryKeyStatus(&queryResponse /*query_response*/); + }, + [&]() { + const std::string oecVersion = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + std::string dataType = mFdp.PickValueInArray(kInitType); + std::unique_ptr initData(new InitializationData( + dataType, a2bs_hex(mFdp.ConsumeRandomLengthString(kMaxByte)), + oecVersion)); + CdmLicenseType licenseType = + (CdmLicenseType)mFdp.ConsumeIntegralInRange( + kLicenseTypeOffline, kLicenseTypeEmbeddedKeyData); + CdmAppParameterMap appParameters; + cdmSession->GenerateKeyRequest( + *initData /*init_data*/, licenseType /*license_type*/, + appParameters /*app_parameters*/, &keyRequest /*key_request*/); + }, + [&]() { + CdmQueryMap queryResponse; + cdmSession->QueryStatus(&queryResponse /*query_response*/); + }, + [&]() { + DeviceFiles::CdmLicenseData licenseData; + storeLicense(licenseData); + std::string randomData = mFdp.ConsumeRandomLengthString(kMaxByte); + const CdmKeySetId keySetId = + mFdp.ConsumeBool() + ? (kKeyId + wvutil::b2a_hex(randomData)) + : std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + CdmLicenseType licenseType = + (CdmLicenseType)mFdp.ConsumeIntegralInRange( + kLicenseTypeOffline, kLicenseTypeEmbeddedKeyData); + int errorDetail = mFdp.ConsumeIntegral(); + cdmSession->RestoreOfflineSession(keySetId /*key_set_id*/, + licenseType /*license_type*/, + &errorDetail /*error_detail*/); + }, + [&]() { + DeviceFiles::CdmUsageData usageData; + usageData.provider_session_token = + mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.license_request = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.license = mFdp.ConsumeRandomLengthString(kMaxByte); + std::string randomData = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.key_set_id = + mFdp.ConsumeBool() + ? (kKeyId + wvutil::b2a_hex(randomData)) + : std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + usageData.usage_entry = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.usage_entry_index = mFdp.ConsumeIntegral(); + usageData.drm_certificate = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.wrapped_private_key = CryptoWrappedKey( + (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange( + CryptoWrappedKey::kUninitialized, CryptoWrappedKey::kEcc), + mFdp.ConsumeRandomLengthString(kMaxByte)); + int errorDetail = mFdp.ConsumeIntegral(); + cdmSession->RestoreUsageSession(usageData /*usage_data*/, + &errorDetail /*error_detail*/); + }, + [&]() { + const std::string keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + CdmKeyAllowedUsage keyUsage; + cdmSession->QueryKeyAllowedUsage(keyId /*key_id*/, + &keyUsage /*key_usage*/); + }, + [&]() { + CdmQueryMap queryResponse; + cdmSession->QueryOemCryptoSessionId( + &queryResponse /*query_response*/); + }, + [&]() { + const KeyId keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + CdmDecryptionParametersV16 params(keyId); + const uint8_t encryptBufferParam = mFdp.ConsumeIntegral(); + void *decryptBufferParam; + size_t decryptbufferOffsetParam = mFdp.ConsumeIntegral(); + size_t length = mFdp.ConsumeIntegral(); + const std::vector iv = mFdp.ConsumeBytes(kMaxSize); + CdmDecryptionSample sample(&encryptBufferParam, decryptBufferParam, + decryptbufferOffsetParam, length, iv); + CdmDecryptionSubsample subsample(mFdp.ConsumeIntegral(), + mFdp.ConsumeIntegral()); + sample.subsamples.push_back(subsample); + params.samples.push_back(sample); + cdmSession->Decrypt(params /*parameters*/); + }, + [&]() { + cdmSession->GenerateRenewalRequest(&keyRequest /*key_request*/); + }, + [&]() { cdmSession->RenewKey(response /*key_response*/); }, + [&]() { + const KeyId keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + cdmSession->IsKeyLoaded(keyId /*key_id*/); + }, + [&]() { cdmSession->GetDurationRemaining(); }, + [&]() { + cdmSession->NotifyResolution( + mFdp.ConsumeIntegral() /*width*/, + mFdp.ConsumeIntegral() /*height*/); + }, + [&]() { + cdmSession->OnTimerEvent(mFdp.ConsumeBool() /*update_usage*/); + }, + [&]() { + const CdmKeySetId keySetId = + kKeyId + mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->OnKeyReleaseEvent(keySetId /*key_set_id*/); + }, + [&]() { + std::string appId = + kSessionId + + std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + cdmSession->GetApplicationId(&appId /*app_id*/); + }, + [&]() { cdmSession->UpdateUsageEntryInformation(); }, + [&]() { cdmSession->GenerateSessionId(); }, + [&]() { + const std::string inBuffer = + mFdp.ConsumeRandomLengthString(kMaxByte); + const std::string keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + const std::string iv = mFdp.ConsumeRandomLengthString(kMaxByte); + CdmEncryptionAlgorithm algorithm = + mFdp.ConsumeBool() + ? CdmEncryptionAlgorithm::kEncryptionAlgorithmAesCbc128 + : CdmEncryptionAlgorithm::kEncryptionAlgorithmUnknown; + std::string outBuffer = mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->GenericEncrypt(inBuffer /*in_buffer*/, keyId /*key_id*/, + iv, algorithm, &outBuffer /*out_buffer*/); + }, + [&]() { + const std::string inBuffer = + mFdp.ConsumeRandomLengthString(kMaxByte); + const std::string keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + const std::string iv = mFdp.ConsumeRandomLengthString(kMaxByte); + CdmEncryptionAlgorithm algorithm = + mFdp.ConsumeBool() + ? CdmEncryptionAlgorithm::kEncryptionAlgorithmAesCbc128 + : CdmEncryptionAlgorithm::kEncryptionAlgorithmUnknown; + std::string outBuffer = mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->GenericDecrypt(inBuffer /*in_buffer*/, keyId /*key_id*/, + iv, algorithm, &outBuffer /*out_buffer*/); + }, + [&]() { + const std::string message = mFdp.ConsumeRandomLengthString(kMaxByte); + const std::string keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + CdmSigningAlgorithm algorithm = + mFdp.ConsumeBool() + ? CdmSigningAlgorithm::kSigningAlgorithmHmacSha256 + : CdmSigningAlgorithm::kSigningAlgorithmUnknown; + std::string signature = mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->GenericSign(message, keyId /*key_id*/, algorithm, + &signature); + }, + [&]() { + const std::string message = mFdp.ConsumeRandomLengthString(kMaxByte); + const std::string keyId = std::to_string( + mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + CdmSigningAlgorithm algorithm = + mFdp.ConsumeBool() + ? CdmSigningAlgorithm::kSigningAlgorithmHmacSha256 + : CdmSigningAlgorithm::kSigningAlgorithmUnknown; + const std::string signature = + mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->GenericVerify(message, keyId /*key_id*/, algorithm, + signature); + }, + [&]() { + uint32_t frameNumber = mFdp.ConsumeIntegral(); + const std::string hash = mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->SetDecryptHash(frameNumber /*frame_number*/, hash); + }, + [&]() { + std::string hashErrorString = + mFdp.ConsumeRandomLengthString(kMaxByte); + cdmSession->GetDecryptHashError( + &hashErrorString /*hash_error_string*/); + }, + [&]() { cdmSession->ReleaseKey(response /*key_response*/); }, + [&]() { + cdmSession->GenerateReleaseRequest(&keyRequest /*key_request*/); + }}); + invokeCdmSessionAPI(); + } + UsageEntryIndex entryIndex = mFdp.ConsumeIntegral(); + cdmSession->DeleteUsageEntry(entryIndex /*usage_entry_index*/); + cdmSession->DeleteLicenseFile(); + cdmSession->RemoveKeys(); + cdmSession->RemoveLicense(); +} + +void CdmSessionFuzzer::invokeCdmSessionMapAPIs() { + FuzzFileSystem fileSystemMap(&mFdp); + CdmSessionMap cdmsessionMap; + std::shared_ptr CdmMetricsMap( + new metrics::SessionMetrics); + CdmSession *session = new CdmSession(&fileSystemMap, CdmMetricsMap); + const CdmSessionId forcedSessionId = + kSessionId + + std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + cdmsessionMap.Add(forcedSessionId /*id*/, session /*session*/); + while (mFdp.remaining_bytes()) { + auto invokeCdmSessionMapAPI = + mFdp.PickValueInArray>({ + [&]() { cdmsessionMap.Exists(forcedSessionId /*id*/); }, + [&]() { cdmsessionMap.Size(); }, + [&]() { + std::shared_ptr cdmsessionShared = + std::make_shared(&fileSystemMap, CdmMetricsMap); + cdmsessionMap.FindSession(forcedSessionId /*id*/, + &cdmsessionShared /*session*/); + }, + [&]() { + CdmSessionList sessions; + cdmsessionMap.GetSessionList(sessions); + }, + }); + invokeCdmSessionMapAPI(); + cdmsessionMap.CloseSession(forcedSessionId); + } +} + +void CdmSessionFuzzer::process() { + if (mFdp.ConsumeBool()) { + FuzzFileSystem fileSystem(&mFdp); + FuzzEventListener fuzzeventListener; + std::shared_ptr metrics = + std::make_shared(); + std::unique_ptr cdmSession = + std::make_unique(&fileSystem, metrics); + std::unique_ptr fuzzCdmClientPropertySet( + new FuzzCdmClientPropertySet(&mFdp)); + const CdmSessionId forcedSessionId = + kSessionId + + std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId)); + bool forcedLevel = mFdp.ConsumeBool(); + CdmResponseType result = + initCdmSession(cdmSession.get(), fuzzCdmClientPropertySet.get(), + forcedSessionId, &fuzzeventListener, forcedLevel); + if (result == NO_ERROR) { + invokeCdmSessionAPIs(cdmSession.get()); + } + } else { + invokeCdmSessionMapAPIs(); + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + CdmSessionFuzzer cdmSessionFuzzer(data, size); + cdmSessionFuzzer.process(); + return 0; +}