From b305d99d3b04496883c69b2a8666efafc370b0db Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Wed, 23 May 2018 15:57:01 -0700 Subject: [PATCH] Make Defensive Copies in CopyBufferInChunks (This is a merge of http://go/wvgerrit/51084) Nominally, OEMCrypto probably shouldn't modify the buffer descriptor we pass into OEMCrypto_DecryptCENC(), but in practice, we know some platforms do this, so we make defensive copies in CryptoSession::DecryptInChunks() just in case. Turns out, some devices also behave like this in OEMCrypto_CopyBuffer(), so we should also be doing defensive copies in CryptoSession::CopyBufferInChunks(). Bug: 79779554 Test: ExoPlayer Demo App, played "Secure Subsample UHD (WebM, VP9)" Test: build_and_run_all_unit_tests.sh Change-Id: Ib46043a6cc0aa42d1d1cc85f5adb477c566363e9 --- .../cdm/core/src/crypto_session.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index cc844504..c382e18a 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -2358,7 +2358,7 @@ size_t CryptoSession::GenericEncryptionBlockSize( OEMCryptoResult CryptoSession::CopyBufferInChunks( const CdmDecryptionParameters& params, - OEMCrypto_DestBufferDesc buffer_descriptor) { + OEMCrypto_DestBufferDesc full_buffer_descriptor) { size_t remaining_encrypt_length = params.encrypt_length; uint8_t subsample_flags = OEMCrypto_FirstSubsample; @@ -2374,19 +2374,18 @@ OEMCryptoResult CryptoSession::CopyBufferInChunks( // calculating the new values. remaining_encrypt_length -= chunk_size; - // Update the destination buffer with the new offset. + // Update the destination buffer with the new offset. Because OEMCrypto + // can modify the OEMCrypto_DestBufferDesc during the call to + // OEMCrypto_CopyBuffer, (and is known to do so on some platforms) a new + // OEMCrypto_DestBufferDesc must be allocated for each call. + OEMCrypto_DestBufferDesc buffer_descriptor = full_buffer_descriptor; switch (buffer_descriptor.type) { case OEMCrypto_BufferType_Clear: - buffer_descriptor.buffer.clear.address = - static_cast(params.decrypt_buffer) + - params.decrypt_buffer_offset + additional_offset; - buffer_descriptor.buffer.clear.max_length = - params.decrypt_buffer_length - - (params.decrypt_buffer_offset + additional_offset); + buffer_descriptor.buffer.clear.address += additional_offset; + buffer_descriptor.buffer.clear.max_length -= additional_offset; break; case OEMCrypto_BufferType_Secure: - buffer_descriptor.buffer.secure.offset = - params.decrypt_buffer_offset + additional_offset; + buffer_descriptor.buffer.secure.offset += additional_offset; break; case OEMCrypto_BufferType_Direct: // OEMCrypto_BufferType_Direct does not need modification.