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