diff options
| author | Edwin Wong <edwinwong@google.com> | 2019-09-24 07:31:40 -0700 |
|---|---|---|
| committer | Sterling Huber <hubers@google.com> | 2019-12-19 22:10:47 +0000 |
| commit | 0ec6f56ea142285856dec8ac0ea35f3988621abc (patch) | |
| tree | 39064cf00995a7a1b3777887c2000e923ab24aa5 /drm | |
| parent | 3ae43b0ae940eb860fe03a4db6a17fefa155807a (diff) | |
| download | frameworks_av-0ec6f56ea142285856dec8ac0ea35f3988621abc.tar.gz frameworks_av-0ec6f56ea142285856dec8ac0ea35f3988621abc.tar.bz2 frameworks_av-0ec6f56ea142285856dec8ac0ea35f3988621abc.zip | |
RESTRICT AUTOMERGE
Harden Clearkey releaseSecureStops implementation.
Perform more checking for invalid input.
Test: CTS tests
android.media.cts.MediaDrmClearkeyTest#testSecureStop
android.media.cts.MediaDrmClearkeyTest
Test: run drmpoc
no signal 6 on clearkey service after the fix
Test: adb shell ps | grep clearkey
pid ID does not change after running drmpoc
bug: 137284652
Change-Id: I971bb33eec6d37ef86fa1a53501c1e6bda50fa3b
Diffstat (limited to 'drm')
| -rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp index 0c74a6ccad..71bb2185bd 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp @@ -797,38 +797,55 @@ Return<void> DrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) { } Return<Status> DrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) { - // minimum opaqueData contains the uint32_t count, see comment below - if (ssRelease.opaqueData.size() < sizeof(uint32_t)) { + // OpaqueData starts with 4 byte decimal integer string + const size_t kFourBytesOffset = 4; + if (ssRelease.opaqueData.size() < kFourBytesOffset) { + ALOGE("Invalid secureStopRelease length"); return Status::BAD_VALUE; } Status status = Status::OK; std::vector<uint8_t> input = toVector(ssRelease.opaqueData); + if (input.size() < kSecureStopIdSize + kFourBytesOffset) { + // The minimum size of SecureStopRelease has to contain + // a 4 bytes count and one secureStop id + ALOGE("Total size of secureStops is too short"); + return Status::BAD_VALUE; + } + // The format of opaqueData is shared between the server // and the drm service. The clearkey implementation consists of: // count - number of secure stops // list of fixed length secure stops - size_t countBufferSize = sizeof(uint32_t); uint32_t count = 0; sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count); // Avoid divide by 0 below. if (count == 0) { + ALOGE("Invalid 0 secureStop count"); return Status::BAD_VALUE; } - size_t secureStopSize = (input.size() - countBufferSize) / count; - uint8_t buffer[secureStopSize]; - size_t offset = countBufferSize; // skip the count + // Computes the fixed length secureStop size + size_t secureStopSize = (input.size() - kFourBytesOffset) / count; + if (secureStopSize < kSecureStopIdSize) { + // A valid secureStop contains the id plus data + ALOGE("Invalid secureStop size"); + return Status::BAD_VALUE; + } + uint8_t* buffer = new uint8_t[secureStopSize]; + size_t offset = kFourBytesOffset; // skip the count for (size_t i = 0; i < count; ++i, offset += secureStopSize) { memcpy(buffer, input.data() + offset, secureStopSize); - std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize); + // A secureStop contains id+data, we only use the id for removal + std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize); status = removeSecureStop(toHidlVec(id)); if (Status::OK != status) break; } + delete[] buffer; return status; } |
