Merge cherrypicks of [9428056, 9428057, 9428058, 9428059, 9427659, 9428140, 9428141, 9427864, 9428122, 9428123, 9428124, 9428180, 9428181, 9427966, 9427967, 9427968, 9427969, 9427970, 9427971, 9427972, 9427973, 9428182, 9428183, 9428184, 9428104, 9427370, 9428126, 9427923, 9427974, 9427975, 9428127, 9428185] into sparse-5831595-L25200000368072328 Change-Id: Ie38581bb72a0d416a6016600cfc1862c77da3afe
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp index 23a35e5..f164f28 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -62,10 +62,8 @@ secure, keyId, iv, mode, pattern, subSamples, source, offset, destination, [&](Status_V1_2 hStatus, uint32_t hBytesWritten, hidl_string hDetailedError) { status = toStatus_1_0(hStatus); - if (status == Status::OK) { - bytesWritten = hBytesWritten; - detailedError = hDetailedError; - } + bytesWritten = hBytesWritten; + detailedError = hDetailedError; } ); @@ -109,6 +107,10 @@ "destination decrypt buffer base not set"); return Void(); } + } else { + _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, + "destination type not supported"); + return Void(); } sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId]; @@ -126,38 +128,45 @@ (static_cast<void *>(sourceBase->getPointer())); uint8_t* srcPtr = static_cast<uint8_t *>(base + source.offset + offset); void* destPtr = NULL; - if (destination.type == BufferType::SHARED_MEMORY) { - const SharedBuffer& destBuffer = destination.nonsecureMemory; - sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId]; - if (destBase == nullptr) { - _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); - return Void(); - } - - if (destBuffer.offset + destBuffer.size > destBase->getSize()) { - _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size"); - return Void(); - } - destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset); - } else if (destination.type == BufferType::NATIVE_HANDLE) { - native_handle_t *handle = const_cast<native_handle_t *>( - destination.secureMemory.getNativeHandle()); - destPtr = static_cast<void *>(handle); + // destination.type == BufferType::SHARED_MEMORY + const SharedBuffer& destBuffer = destination.nonsecureMemory; + sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId]; + if (destBase == nullptr) { + _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); + return Void(); } + if (destBuffer.offset + destBuffer.size > destBase->getSize()) { + _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size"); + return Void(); + } + destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset); + + // Calculate the output buffer size and determine if any subsamples are // encrypted. size_t destSize = 0; bool haveEncryptedSubsamples = false; for (size_t i = 0; i < subSamples.size(); i++) { const SubSample &subSample = subSamples[i]; - destSize += subSample.numBytesOfClearData; - destSize += subSample.numBytesOfEncryptedData; + if (__builtin_add_overflow(destSize, subSample.numBytesOfClearData, &destSize)) { + _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample clear size overflow"); + return Void(); + } + if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize)) { + _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample encrypted size overflow"); + return Void(); + } if (subSample.numBytesOfEncryptedData > 0) { haveEncryptedSubsamples = true; } } + if (destSize > destBuffer.size) { + _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "subsample sum too large"); + return Void(); + } + if (mode == Mode::UNENCRYPTED) { if (haveEncryptedSubsamples) { _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,