diff options
| author | Robert Shih <robertshih@google.com> | 2019-08-26 17:03:13 -0700 |
|---|---|---|
| committer | Robert Shih <robertshih@google.com> | 2019-08-26 17:53:27 -0700 |
| commit | d23bd2a2a80f6bfc8c827bf21e53ad4500582d56 (patch) | |
| tree | 4eb3b480f0b476e914ba619c77f15b71b4ffc587 /drm | |
| parent | f08d61d30e9ed041d7426c0168e2ee092eaf36ac (diff) | |
| download | frameworks_av-d23bd2a2a80f6bfc8c827bf21e53ad4500582d56.tar.gz frameworks_av-d23bd2a2a80f6bfc8c827bf21e53ad4500582d56.tar.bz2 frameworks_av-d23bd2a2a80f6bfc8c827bf21e53ad4500582d56.zip | |
clearkey hidl CryptoPlugin: misc & security fixes
* propagate decrypt error message
* reject native handle output
* validate subsample sizes
Bug: 137283376
Test: cryptopoc
Change-Id: Ic4267fdc0e391bdecc1caab3b8fd4aa34ad76541
Diffstat (limited to 'drm')
| -rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp index 23a35e5bdb..f164f2859b 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp @@ -62,10 +62,8 @@ Return<void> CryptoPlugin::decrypt( 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 @@ Return<void> CryptoPlugin::decrypt_1_2( "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,24 +128,20 @@ Return<void> CryptoPlugin::decrypt_1_2( (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(); - } + // 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); + 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. @@ -151,13 +149,24 @@ Return<void> CryptoPlugin::decrypt_1_2( 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, |
