cas: validate shared buffer size before using -- DO NOT MERGE
bug: 67962232
test:
cts MediaCasTest
Change-Id: I6bafa324fe6bca5c6a172cc4f9f724ba9f44b7ba
diff --git a/drm/libmediadrm/DescramblerImpl.cpp b/drm/libmediadrm/DescramblerImpl.cpp
index 94e09e2..5764669 100644
--- a/drm/libmediadrm/DescramblerImpl.cpp
+++ b/drm/libmediadrm/DescramblerImpl.cpp
@@ -20,8 +20,9 @@
#include <media/cas/DescramblerAPI.h>
#include <media/DescramblerImpl.h>
#include <media/SharedLibrary.h>
-#include <utils/Log.h>
+#include <media/stagefright/foundation/AUtils.h>
#include <binder/IMemory.h>
+#include <utils/Log.h>
namespace android {
@@ -74,10 +75,57 @@
return getBinderStatus(OK);
}
+static inline bool validateRangeForSize(
+ uint64_t offset, uint64_t length, uint64_t size) {
+ return isInRange<uint64_t, uint64_t>(0, size, offset, length);
+}
+
Status DescramblerImpl::descramble(
const DescrambleInfo& info, int32_t *result) {
ALOGV("descramble");
+ if (info.srcMem == NULL || info.srcMem->pointer() == NULL) {
+ ALOGE("srcMem is invalid");
+ return getBinderStatus(BAD_VALUE);
+ }
+
+ // use 64-bit here to catch bad subsample size that might be overflowing.
+ uint64_t totalBytesInSubSamples = 0;
+ for (size_t i = 0; i < info.numSubSamples; i++) {
+ totalBytesInSubSamples += (uint64_t)info.subSamples[i].mNumBytesOfClearData +
+ info.subSamples[i].mNumBytesOfEncryptedData;
+ }
+ // validate if the specified srcOffset and requested total subsample size
+ // is consistent with the source shared buffer size.
+ if (!validateRangeForSize(info.srcOffset, totalBytesInSubSamples, info.srcMem->size())) {
+ ALOGE("Invalid srcOffset and subsample size: "
+ "srcOffset %llu, totalBytesInSubSamples %llu, srcMem size %llu",
+ (unsigned long long) info.srcOffset,
+ (unsigned long long) totalBytesInSubSamples,
+ (unsigned long long) info.srcMem->size());
+ android_errorWriteLog(0x534e4554, "67962232");
+ return getBinderStatus(BAD_VALUE);
+ }
+ void *dstPtr = NULL;
+ if (info.dstType == DescrambleInfo::kDestinationTypeVmPointer) {
+ // When using shared memory, src buffer is also used as dst
+ dstPtr = info.srcMem->pointer();
+
+ // In this case the dst and src would be the same buffer, need to validate
+ // dstOffset against the buffer size too.
+ if (!validateRangeForSize(info.dstOffset, totalBytesInSubSamples, info.srcMem->size())) {
+ ALOGE("Invalid dstOffset and subsample size: "
+ "dstOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu",
+ (unsigned long long) info.dstOffset,
+ (unsigned long long) totalBytesInSubSamples,
+ (unsigned long long) info.srcMem->size());
+ android_errorWriteLog(0x534e4554, "67962232");
+ return getBinderStatus(BAD_VALUE);
+ }
+ } else {
+ dstPtr = info.dstPtr;
+ }
+
*result = mPlugin->descramble(
info.dstType != DescrambleInfo::kDestinationTypeVmPointer,
info.scramblingControl,
@@ -85,8 +133,7 @@
info.subSamples,
info.srcMem->pointer(),
info.srcOffset,
- info.dstType == DescrambleInfo::kDestinationTypeVmPointer ?
- info.srcMem->pointer() : info.dstPtr,
+ dstPtr,
info.dstOffset,
NULL);