From 4528a2899daf521edbd9e93ff3630fde3b4a1533 Mon Sep 17 00:00:00 2001 From: Akshata Kadam Date: Wed, 27 Sep 2023 09:52:40 +0000 Subject: [PATCH] Added device_files_fuzzer exec/s: 150 Test: ./device_files_fuzzer Bug: 265234582 Change-Id: I55b65929e3b741df8d5ff114f6d7eb63888e7913 --- fuzzer/Android.bp | 6 + fuzzer/README.md | 21 ++ fuzzer/device_files_fuzzer.cpp | 508 +++++++++++++++++++++++++++++++++ 3 files changed, 535 insertions(+) create mode 100644 fuzzer/device_files_fuzzer.cpp diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index a44a711e..81231400 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -128,3 +128,9 @@ cc_fuzz { srcs: ["certificate_provisioning_fuzzer.cpp"], defaults: ["libcdm_fuzzer_defaults"], } + +cc_fuzz { + name: "device_files_fuzzer", + srcs: ["device_files_fuzzer.cpp"], + defaults: ["libcdm_fuzzer_defaults"], +} diff --git a/fuzzer/README.md b/fuzzer/README.md index 9ab1e445..d313f2f0 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -12,6 +12,7 @@ + [buffer_reader_fuzzer](#BufferReader) + [cdm_engine_fuzzer](#CdmEngine) + [certificate_provisioning_fuzzer](#CertificateProvisioning) ++ [device_files_fuzzer](#DeviceFile) # Fuzzer for PolicyEngine @@ -283,3 +284,23 @@ CertificateProvisioning supports the following parameters: $ adb sync data $ adb shell /data/fuzz/arm64/certificate_provisioning_fuzzer/vendor/certificate_provisioning_fuzzer ``` + +# Fuzzer for DeviceFile + +DeviceFile supports the following parameters: +1. AtscModeEnabled (parameter name: "atsc_mode_enabled") + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +|`AtscModeEnabled`| `Bool` |Value obtained from FuzzedDataProvider| + +#### Steps to run +1. Build the fuzzer +``` + $ mm -j$(nproc) device_files_fuzzer +``` +2. Run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/device_files_fuzzer/vendor/device_files_fuzzer +``` diff --git a/fuzzer/device_files_fuzzer.cpp b/fuzzer/device_files_fuzzer.cpp new file mode 100644 index 00000000..d511bc47 --- /dev/null +++ b/fuzzer/device_files_fuzzer.cpp @@ -0,0 +1,508 @@ +/* + * 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 +#include +#include +#include +#include + +using namespace wvcdm; +using namespace wvutil; +using namespace video_widevine; + +static constexpr uint16_t kMaxByte = 256; +static constexpr uint16_t kMaxVectorSize = 1000; +static constexpr uint8_t kMinVectorSize = 0; +static constexpr uint8_t kMinKeySetId = 0; +static constexpr uint8_t kMaxKeySetId = 100; + +class DeviceFilesFuzzer { +public: + DeviceFilesFuzzer(const uint8_t *data, size_t size) : mFdp(data, size){}; + void process(); + +private: + FuzzedDataProvider mFdp; +}; + +void createLicenseData(DeviceFiles::CdmLicenseData &licenseData, + FuzzedDataProvider &mFdp) { + std::map appParameters; + appParameters[mFdp.ConsumeBytesAsString(kMaxByte)] = + mFdp.ConsumeBytesAsString(kMaxByte); + + licenseData.key_set_id = std::to_string( + mFdp.ConsumeIntegralInRange(kMinKeySetId, kMaxKeySetId)); + 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::Type::kUninitialized, CryptoWrappedKey::Type::kEcc), + mFdp.ConsumeRandomLengthString(kMaxByte)); +} + +void createUsageData(DeviceFiles::CdmUsageData &usageData, + FuzzedDataProvider &mFdp) { + usageData.provider_session_token = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.license_request = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.license = mFdp.ConsumeRandomLengthString(kMaxByte); + usageData.key_set_id = std::to_string( + mFdp.ConsumeIntegralInRange(kMinKeySetId, kMaxKeySetId)); + 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::Type::kUninitialized, CryptoWrappedKey::Type::kEcc), + mFdp.ConsumeRandomLengthString(kMaxByte)); +} + +void createCertificateAndKey(std::string &certificate, CryptoWrappedKey &key, + FuzzedDataProvider &mFdp) { + DrmCertificate drmCertificate; + drmCertificate.set_type( + (DrmCertificate_Type)mFdp.ConsumeIntegralInRange( + DrmCertificate_Type::DrmCertificate_Type_ROOT, + DrmCertificate_Type::DrmCertificate_Type_PROVISIONER)); + drmCertificate.set_serial_number( + std::to_string(mFdp.ConsumeIntegral())); + drmCertificate.set_system_id(mFdp.ConsumeIntegral()); + drmCertificate.set_creation_time_seconds(mFdp.ConsumeIntegral()); + drmCertificate.set_expiration_time_seconds(mFdp.ConsumeIntegral()); + std::string setDrmCertificate; + drmCertificate.SerializeToString(&setDrmCertificate); + + SignedDrmCertificate signedDrmCertificate; + if (mFdp.ConsumeBool()) { + signedDrmCertificate.set_drm_certificate(setDrmCertificate); + } + + signedDrmCertificate.SerializeToString(&certificate); + + key = CryptoWrappedKey( + (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange( + CryptoWrappedKey::Type::kUninitialized, CryptoWrappedKey::Type::kEcc), + mFdp.ConsumeBytesAsString(kMaxByte)); +} + +void DeviceFilesFuzzer::process() { + FileSystem fileSystem; + DeviceFiles deviceFiles(mFdp.ConsumeBool() ? &fileSystem : nullptr); + deviceFiles.Reset((CdmSecurityLevel)mFdp.ConsumeIntegralInRange( + kSecurityLevelUninitialized, kSecurityLevelUnknown)); + + while (mFdp.remaining_bytes()) { + auto invokeDeviceFilesAPI = mFdp.PickValueInArray< + const std::function>( + {[&]() { + std::string certificate; + CryptoWrappedKey wrappedPrivateKey; + createCertificateAndKey(certificate, wrappedPrivateKey, mFdp); + deviceFiles.StoreCertificate(mFdp.ConsumeBool() ? certificate : "", + wrappedPrivateKey); + }, + + [&]() { + bool AtscModeEnabled = mFdp.ConsumeBool(); + std::string certificate; + CryptoWrappedKey privateKey; + std::string serialNumber; + uint32_t systemId; + + deviceFiles.RetrieveCertificate( + AtscModeEnabled, mFdp.ConsumeBool() ? &certificate : nullptr, + &privateKey, mFdp.ConsumeBool() ? &serialNumber : nullptr, + mFdp.ConsumeBool() ? &systemId : nullptr); + }, + + [&]() { + std::string certificate; + CryptoWrappedKey privateKey; + std::string serialNumber; + uint32_t systemId; + + deviceFiles.RetrieveLegacyCertificate(&certificate, &privateKey, + &serialNumber, &systemId); + }, + + [&]() { deviceFiles.RemoveCertificate(); }, + + [&]() { + std::string certificate; + CryptoWrappedKey wrappedPrivateKey; + createCertificateAndKey(certificate, wrappedPrivateKey, mFdp); + + deviceFiles.StoreOemCertificate( + mFdp.ConsumeBool() ? certificate : "", wrappedPrivateKey); + }, + + [&]() { + std::string certificate; + CryptoWrappedKey privateKey; + + deviceFiles.RetrieveOemCertificate(&certificate, &privateKey); + }, + + [&]() { deviceFiles.HasOemCertificate(); }, + + [&]() { deviceFiles.RemoveOemCertificate(); }, + + [&]() { + DeviceFiles::CdmLicenseData licenseData; + createLicenseData(licenseData, mFdp); + DeviceFiles::ResponseType result; + deviceFiles.StoreLicense(licenseData, + mFdp.ConsumeBool() ? &result : nullptr); + }, + + [&]() { + DeviceFiles::CdmLicenseData licenseData; + DeviceFiles::ResponseType result; + + deviceFiles.RetrieveLicense( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + mFdp.ConsumeBool() ? &licenseData : nullptr, + mFdp.ConsumeBool() ? &result : nullptr); + }, + + [&]() { + deviceFiles.StoreAtscLicense( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + mFdp.ConsumeRandomLengthString( + kMaxByte) /* serialized_license_data */ + ); + }, + + [&]() { + deviceFiles.DeleteLicense( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + std::vector keySetIds; + + deviceFiles.ListLicenses(&keySetIds); + }, + + [&]() { deviceFiles.DeleteAllFiles(); }, + + [&]() { deviceFiles.DeleteAllLicenses(); }, + + [&]() { + deviceFiles.LicenseExists( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + deviceFiles.ReserveLicenseId( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + deviceFiles.UnreserveLicenseId( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + deviceFiles.StoreUsageInfo( + mFdp.ConsumeRandomLengthString( + kMaxByte), /* provider_session_token */ + mFdp.ConsumeRandomLengthString(kMaxByte), /* key_request */ + mFdp.ConsumeRandomLengthString(kMaxByte), /* key_response */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + mFdp.ConsumeRandomLengthString(kMaxByte), /* usage_entry */ + mFdp.ConsumeIntegral(), /* usage_entry_index */ + mFdp.ConsumeRandomLengthString(kMaxByte), /* drm_certificate */ + CryptoWrappedKey( + (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange( + CryptoWrappedKey::Type::kUninitialized, + CryptoWrappedKey::Type::kEcc), /* type */ + mFdp.ConsumeRandomLengthString(kMaxByte) /* key */ + ) /* wrapped_private_key */ + ); + }, + + [&]() { + std::vector keySetIds; + std::vector providerSessionTokens; + + deviceFiles.ListUsageIds( + mFdp.ConsumeRandomLengthString(kMaxByte), /* app_id */ + mFdp.ConsumeBool() ? &keySetIds : nullptr, + mFdp.ConsumeBool() ? &providerSessionTokens : nullptr); + }, + + [&]() { + std::string providerSessionToken; + + deviceFiles.GetProviderSessionToken( + mFdp.ConsumeRandomLengthString(kMaxByte), /* app_id */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + &providerSessionToken); + }, + + [&]() { + deviceFiles.DeleteUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + uint32_t keySetIdsSize = mFdp.ConsumeIntegralInRange( + kMinVectorSize, kMaxVectorSize); + std::vector keySetIds; + for (int i = 0; i < keySetIdsSize; ++i) + keySetIds.push_back( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + + deviceFiles.DeleteMultipleUsageInfoByKeySetIds( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + keySetIds); + }, + + [&]() { + std::vector providerSessionTokens; + + deviceFiles.DeleteAllUsageInfoForApp( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + &providerSessionTokens); + }, + + [&]() { deviceFiles.DeleteAllUsageInfo(); }, + + [&]() { + CdmKeyMessage licenseRequest; + CdmKeyResponse license; + UsageEntry usageEntry; + UsageEntryIndex usageEntryIndex; + std::string drmCertificate; + CryptoWrappedKey wrappedPrivateKey; + + deviceFiles.RetrieveUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* provider_session_token */ + &licenseRequest, &license, &usageEntry, &usageEntryIndex, + &drmCertificate, &wrappedPrivateKey); + }, + + [&]() { + std::string providerSessionToken; + CdmKeyMessage licenseRequest; + CdmKeyResponse license; + UsageEntry usageEntry; + UsageEntryIndex usageEntryIndex; + std::string drmCertificate; + CryptoWrappedKey wrappedPrivateKey; + + deviceFiles.RetrieveUsageInfoByKeySetId( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + &providerSessionToken, &licenseRequest, &license, &usageEntry, + &usageEntryIndex, &drmCertificate, &wrappedPrivateKey); + }, + + [&]() { + std::vector usageInfoFileNames; + + deviceFiles.ListUsageInfoFiles(&usageInfoFileNames); + }, + + [&]() { + std::vector usageData; + + deviceFiles.RetrieveUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + &usageData); + }, + + [&]() { + std::string providerSessionToken = + mFdp.ConsumeRandomLengthString(kMaxByte); + DeviceFiles::CdmUsageData usageData; + + deviceFiles.RetrieveUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + providerSessionToken, &usageData); + }, + + [&]() { + uint32_t usageDataSize = mFdp.ConsumeIntegralInRange( + kMinVectorSize, kMaxVectorSize); + std::vector usageData; + for (int i = 0; i < usageDataSize; ++i) { + DeviceFiles::CdmUsageData unit; + createUsageData(unit, mFdp); + usageData.push_back(unit); + } + + deviceFiles.StoreUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + usageData); + }, + + [&]() { + DeviceFiles::CdmUsageData usageData; + createUsageData(usageData, mFdp); + deviceFiles.UpdateUsageInfo( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* usage_info_file_name */ + usageData); + }, + + [&]() { + uint32_t mediaSegmentIvSize = mFdp.ConsumeIntegralInRange( + kMinVectorSize, kMaxVectorSize); + std::vector mediaSegmentIv; + for (int i = 0; i < mediaSegmentIvSize; ++i) + mediaSegmentIv.push_back(mFdp.ConsumeIntegral()); + + deviceFiles.StoreHlsAttributes( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + (CdmHlsMethod)mFdp.ConsumeIntegralInRange( + kHlsMethodNone, kHlsMethodSampleAes), /* method */ + mediaSegmentIv); + }, + + [&]() { + CdmHlsMethod method; + std::vector mediaSegmentIv; + + deviceFiles.RetrieveHlsAttributes( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)), /* key_set_id */ + &method, &mediaSegmentIv); + }, + + [&]() { + deviceFiles.DeleteHlsAttributes( + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)) /* key_set_id */ + ); + }, + + [&]() { + uint32_t usageEntryInfoListSize = + mFdp.ConsumeIntegralInRange(kMinVectorSize, + kMaxVectorSize); + std::vector usageEntryInfoList; + for (int i = 0; i < usageEntryInfoListSize; ++i) { + CdmUsageEntryInfo unit; + + unit.storage_type = + (CdmUsageEntryStorageType)mFdp.ConsumeIntegralInRange( + kStorageLicense, kStorageTypeUnknown); + unit.key_set_id = mFdp.ConsumeRandomLengthString(kMaxByte); + unit.usage_info_file_name = + std::to_string(mFdp.ConsumeIntegralInRange( + kMinKeySetId, kMaxKeySetId)); + unit.last_use_time = mFdp.ConsumeIntegral(); + unit.offline_license_expiry_time = mFdp.ConsumeIntegral(); + usageEntryInfoList.push_back(unit); + } + + deviceFiles.StoreUsageTableInfo( + mFdp.ConsumeRandomLengthString( + kMaxByte), /* usage_table_header */ + usageEntryInfoList); + }, + + [&]() { + UsageTableHeader usageTableHeader; + std::vector usageEntryInfoList; + bool lruUpgrade; + + deviceFiles.RetrieveUsageTableInfo(&usageTableHeader, + &usageEntryInfoList, &lruUpgrade); + }, + + [&]() { deviceFiles.DeleteUsageTableInfo(); }, + + [&]() { + okp::SystemFallbackInfo info; + info.SetState((okp::SystemState)mFdp.ConsumeIntegralInRange( + (int)okp::SystemState::kUnknown, + (int)okp::SystemState::kProvisioned)); + info.SetFirstCheckedTime(mFdp.ConsumeIntegral()); + info.SetBackoffStartTime(mFdp.ConsumeIntegral()); + info.SetBackoffDuration(mFdp.ConsumeIntegral()); + info.SetProvisioningTime(mFdp.ConsumeIntegral()); + + deviceFiles.StoreOkpInfo(info); + }, + + [&]() { + okp::SystemFallbackInfo info; + + deviceFiles.RetrieveOkpInfo(&info); + }, + + [&]() { deviceFiles.DeleteOkpInfo(); }}); + + invokeDeviceFilesAPI(); + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + DeviceFilesFuzzer deviceFilesFuzzer(data, size); + deviceFilesFuzzer.process(); + return 0; +}