/* * 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 "policy_timers.h" #include "policy_timers_v16.h" #include "policy_timers_v18.h" #include "wv_cdm_event_listener.h" using namespace wvcdm; using namespace video_widevine; class PolicyTimersFuzzer { public: PolicyTimersFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){}; void Process(); private: FuzzedDataProvider fdp_; License license_; void SetUp(); }; void PolicySetBool(std::function function, FuzzedDataProvider* fdp) { if (fdp->ConsumeBool()) { function(fdp->ConsumeBool()); } } void PolicySetInt64(std::function function, FuzzedDataProvider* fdp) { if (fdp->ConsumeBool()) { function(fdp->ConsumeIntegral()); } } void PolicyTimersFuzzer::SetUp() { License_Policy* policy = license_.mutable_policy(); PolicySetBool( std::bind(&License_Policy::set_can_renew, policy, std::placeholders::_1), &fdp_); PolicySetInt64(std::bind(&License_Policy::set_renewal_delay_seconds, policy, std::placeholders::_1), &fdp_); PolicySetBool(std::bind(&License_Policy::set_soft_enforce_playback_duration, policy, std::placeholders::_1), &fdp_); PolicySetInt64(std::bind(&License_Policy::set_renewal_retry_interval_seconds, policy, std::placeholders::_1), &fdp_); PolicySetInt64(std::bind(&License_Policy::set_license_duration_seconds, policy, std::placeholders::_1), &fdp_); if (fdp_.ConsumeBool()) { video_widevine::License::Policy::TimerDelayBase time_delay_base = (video_widevine::License::Policy::TimerDelayBase) fdp_.ConsumeIntegralInRange( License_Policy_TimerDelayBase_TIMER_DELAY_BASE_UNSPECIFIED, License_Policy_TimerDelayBase_FIRST_DECRYPT); policy->set_initial_renewal_delay_base(time_delay_base); } if (fdp_.ConsumeBool()) { policy->set_playback_duration_seconds(fdp_.ConsumeIntegral()); } if (fdp_.ConsumeBool()) { policy->set_rental_duration_seconds(fdp_.ConsumeIntegral()); } if (fdp_.ConsumeBool()) { policy->set_renewal_recovery_duration_seconds( fdp_.ConsumeIntegral()); } if (fdp_.ConsumeBool()) { policy->set_soft_enforce_rental_duration(fdp_.ConsumeBool()); } if (fdp_.ConsumeBool()) { policy->set_can_play(fdp_.ConsumeBool()); } license_.set_license_start_time(fdp_.ConsumeIntegral()); } void PolicyTimersFuzzer::Process() { std::unique_ptr policy_timers; if (fdp_.ConsumeBool()) { policy_timers = std::make_unique(); } else { policy_timers = std::make_unique(); } while (fdp_.remaining_bytes()) { auto invoke_policy_timers_API = fdp_.PickValueInArray>({ [&]() { SetUp(); }, [&]() { policy_timers->SetLicense(license_); }, [&]() { policy_timers->BeginDecryption( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->DecryptionEvent( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->RestorePlaybackTimes( fdp_.ConsumeIntegral() /*current_time*/, fdp_.ConsumeIntegral() /*playback_start_time*/, fdp_.ConsumeIntegral() /*last_playback_time*/, fdp_.ConsumeIntegral() /* grace_period_end_time */); }, [&]() { policy_timers->GetLicenseOrRentalOrPlaybackDurationRemaining( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->GetPlaybackDurationRemaining( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { int64_t seconds_since_last_played = fdp_.ConsumeIntegral(); policy_timers->GetSecondsSinceStarted( fdp_.ConsumeIntegral() /*current_time*/, fdp_.ConsumeBool() ? &seconds_since_last_played : nullptr); }, [&]() { int64_t seconds_since_last_played = fdp_.ConsumeIntegral(); policy_timers->GetSecondsSinceLastPlayed( fdp_.ConsumeIntegral() /*current_time*/, fdp_.ConsumeBool() ? &seconds_since_last_played : nullptr); }, [&]() { policy_timers->IsLicenseForFuture( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { int64_t expiry_time = fdp_.ConsumeIntegral(); policy_timers->UpdateExpirationTime( fdp_.ConsumeIntegral() /*current_time*/, fdp_.ConsumeBool() ? &expiry_time : nullptr); }, [&]() { policy_timers->HasRenewalRetryIntervalExpired( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->UpdateRenewalRequest( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->HasRenewalRecoveryDurationExpired( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->HasRenewalDelayExpired( fdp_.ConsumeIntegral() /*current_time*/); }, [&]() { policy_timers->UpdateLicense( fdp_.ConsumeIntegral() /*current_time*/, license_); }, }); invoke_policy_timers_API(); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { PolicyTimersFuzzer policy_timers_fuzzer(data, size); policy_timers_fuzzer.Process(); return 0; }