From b408fa26c782c57272f11b46a235cca8c9ccb9be Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Tue, 28 Apr 2015 16:42:20 -0700 Subject: Harden drmserver process against fuzzing attacks bug: 19572107 Change-Id: I5ba0a434b016e8dc376f7d0eef5cf76b99ab50fd --- drm/common/IDrmManagerService.cpp | 56 ++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index 3f62ed7..b90da1b 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -34,6 +34,7 @@ #include "IDrmManagerService.h" #define INVALID_BUFFER_LENGTH -1 +#define MAX_BINDER_TRANSACTION_SIZE ((1*1024*1024)-(4096*2)) using namespace android; @@ -933,7 +934,12 @@ status_t BnDrmManagerService::onTransact( //Filling DRM info const int infoType = data.readInt32(); - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + + if (bufferSize > data.dataAvail()) { + return BAD_VALUE; + } + char* buffer = NULL; if (0 < bufferSize) { buffer = (char *)data.readInplace(bufferSize); @@ -986,6 +992,9 @@ status_t BnDrmManagerService::onTransact( const int size = data.readInt32(); for (int index = 0; index < size; ++index) { + if (!data.dataAvail()) { + break; + } const String8 key(data.readString8()); if (key == String8("FileDescriptorKey")) { char buffer[16]; @@ -1035,7 +1044,12 @@ status_t BnDrmManagerService::onTransact( const int uniqueId = data.readInt32(); //Filling DRM Rights - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + reply->writeInt32(BAD_VALUE); + return DRM_NO_ERROR; + } + const DrmBuffer drmBuffer((char *)data.readInplace(bufferSize), bufferSize); const String8 mimeType(data.readString8()); @@ -1206,10 +1220,13 @@ status_t BnDrmManagerService::onTransact( const int convertId = data.readInt32(); //Filling input data - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + return BAD_VALUE; + } DrmBuffer* inputData = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize); - DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData); + DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData); if (NULL != drmConvertedStatus) { //Filling Drm Converted Ststus @@ -1393,7 +1410,12 @@ status_t BnDrmManagerService::onTransact( const int decryptUnitId = data.readInt32(); //Filling Header info - const int bufferSize = data.readInt32(); + const uint32_t bufferSize = data.readInt32(); + if (bufferSize > data.dataAvail()) { + reply->writeInt32(BAD_VALUE); + clearDecryptHandle(&handle); + return DRM_NO_ERROR; + } DrmBuffer* headerInfo = NULL; headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize); @@ -1417,9 +1439,17 @@ status_t BnDrmManagerService::onTransact( readDecryptHandleFromParcelData(&handle, data); const int decryptUnitId = data.readInt32(); - const int decBufferSize = data.readInt32(); + const uint32_t decBufferSize = data.readInt32(); + const uint32_t encBufferSize = data.readInt32(); + + if (encBufferSize > data.dataAvail() || + decBufferSize > MAX_BINDER_TRANSACTION_SIZE) { + reply->writeInt32(BAD_VALUE); + reply->writeInt32(0); + clearDecryptHandle(&handle); + return DRM_NO_ERROR; + } - const int encBufferSize = data.readInt32(); DrmBuffer* encBuffer = new DrmBuffer((char *)data.readInplace(encBufferSize), encBufferSize); @@ -1429,8 +1459,10 @@ status_t BnDrmManagerService::onTransact( DrmBuffer* IV = NULL; if (0 != data.dataAvail()) { - const int ivBufferlength = data.readInt32(); - IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength); + const uint32_t ivBufferlength = data.readInt32(); + if (ivBufferlength <= data.dataAvail()) { + IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength); + } } const status_t status @@ -1477,7 +1509,11 @@ status_t BnDrmManagerService::onTransact( DecryptHandle handle; readDecryptHandleFromParcelData(&handle, data); - const int numBytes = data.readInt32(); + const uint32_t numBytes = data.readInt32(); + if (numBytes > MAX_BINDER_TRANSACTION_SIZE) { + reply->writeInt32(BAD_VALUE); + return DRM_NO_ERROR; + } char* buffer = new char[numBytes]; const off64_t offset = data.readInt64(); -- cgit v1.1