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:51:28 -0700 |
| commit | 5dd7590c6c6fcedd77ac5ec2dd97c8badfb9eb36 (patch) | |
| tree | aa39cb7ba612c2ca194b66e8d8d84dbb7fa46cbe /drm | |
| parent | 874ec86ebc323baa7e6a6ab784dc4550444d6aa6 (diff) | |
| download | frameworks_av-5dd7590c6c6fcedd77ac5ec2dd97c8badfb9eb36.tar.gz frameworks_av-5dd7590c6c6fcedd77ac5ec2dd97c8badfb9eb36.tar.bz2 frameworks_av-5dd7590c6c6fcedd77ac5ec2dd97c8badfb9eb36.zip | |
[RESTRICT AUTOMERGE] clearkey hidl CryptoPlugin: security fixes
* 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 | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp index f33f94e711..198e0997d0 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp @@ -77,6 +77,10 @@ Return<void> CryptoPlugin::decrypt( "destination decrypt buffer base not set"); return Void(); } + } else { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, + "destination type not supported"); + return Void(); } sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId]; @@ -94,24 +98,19 @@ Return<void> CryptoPlugin::decrypt( (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::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::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); + return Void(); + } - if (destBuffer.offset + destBuffer.size > destBase->getSize()) { - _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 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::ERROR_DRM_CANNOT_HANDLE, 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. @@ -119,13 +118,24 @@ Return<void> CryptoPlugin::decrypt( 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::BAD_VALUE, 0, "subsample clear size overflow"); + return Void(); + } + if (__builtin_add_overflow(destSize, subSample.numBytesOfEncryptedData, &destSize)) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow"); + return Void(); + } if (subSample.numBytesOfEncryptedData > 0) { haveEncryptedSubsamples = true; } } + if (destSize > destBuffer.size) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large"); + return Void(); + } + if (mode == Mode::UNENCRYPTED) { if (haveEncryptedSubsamples) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, |
