From f572d60633f196d4c9a1bcfd59bff0f5bb14225a Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Sun, 2 Sep 2018 13:24:11 -0700 Subject: [PATCH] Restrict usage table size in mod mock Merge from Widevine repo of http://go/wvgerrit/58820 This adds an option to the oemcrypto mod mock so that it will limit the usage table to the specified size. It returns the resource limit error code when the maximum size is reached. bug: 111260263 test: unit tests Change-Id: I166b06855fba77ae8ddd13a922fe05be93f2c8f6 --- .../oemcrypto/ref/src/oemcrypto_engine_ref.h | 4 ++++ .../ref/src/oemcrypto_usage_table_ref.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index dd5a5311..ecf816a9 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -152,6 +152,10 @@ class CryptoEngine { // Rate limit for nonce generation. Default to 20 nonce/second. virtual int nonce_flood_count() { return 20; } + // Limit for size of usage table. If this is zero, then the + // size is unlimited -- or limited only by memory size. + virtual size_t max_usage_table_size() { return 0; } + // Set destination pointer based on the output destination description. OEMCryptoResult SetDestination(OEMCrypto_DestBufferDesc* out_description, size_t data_length, uint8_t subsample_flags); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp index 5373d5da..b91ed78b 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp @@ -380,6 +380,11 @@ OEMCryptoResult UsageTable::CreateNewUsageEntry(SessionContext* session, if (!entry) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!usage_entry_number) return OEMCrypto_ERROR_UNKNOWN_FAILURE; uint32_t index = generation_numbers_.size(); + size_t max = ce_->max_usage_table_size(); + if (max > 0 && index >= max) { + LOGE("Too many usage entries: %d/%d", index, max); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } UsageTableEntry* new_entry = MakeEntry(index); generation_numbers_.push_back(master_generation_number_); sessions_.push_back(session); @@ -404,6 +409,11 @@ OEMCryptoResult UsageTable::LoadUsageEntry(SessionContext* session, LOGE("LoadUsageEntry: index %d used by other session.", index); return OEMCrypto_ERROR_INVALID_SESSION; } + size_t max = ce_->max_usage_table_size(); + if (max > 0 && index >= max) { + LOGE("Too many usage entries: %d/%d", index, max); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } UsageTableEntry* new_entry = MakeEntry(index); OEMCryptoResult status = new_entry->LoadData(ce_, index, buffer); @@ -512,6 +522,12 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader( if (!LoadGenerationNumber(false)) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (buffer.size() < SignedHeaderSize(0)) return OEMCrypto_ERROR_SHORT_BUFFER; + size_t max = ce_->max_usage_table_size(); + if (max > 0 && buffer.size() > SignedHeaderSize(max)) { + LOGE("Header too big: %zd bytes/%zd bytes", + buffer.size(), SignedHeaderSize(max)); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } std::vector clear_buffer(buffer.size()); SignedHeaderBlock* clear = reinterpret_cast(&clear_buffer[0]);