diff options
author | Wonsik Kim <wonsik@google.com> | 2020-01-24 11:45:37 -0800 |
---|---|---|
committer | Wonsik Kim <wonsik@google.com> | 2020-01-24 11:45:37 -0800 |
commit | 1cac425df9ae7cbfc8f0926f3e78b10a068d85ee (patch) | |
tree | 76407875287b8e4040c7d0656d7be3ee09e03873 | |
parent | 12ce8338cc178e7683386c026709a74f2733abb7 (diff) |
Partial revert of commit ccb7ac6b6552c0692cf002364cdaaba676d47350
Revert android_media_MediaCodec_queueSecureInputBuffer only.
Bug: 148192445
Test: Play Movies
Change-Id: I95350bb16f49faa557e26ecd87cc6c223aa187a1
-rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 140 |
1 files changed, 134 insertions, 6 deletions
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index ab6966d5d1c3..9b37f955fa17 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -1750,22 +1750,150 @@ static void android_media_MediaCodec_queueSecureInputBuffer( return; } - NativeCryptoInfo cryptoInfo{env, cryptoInfoObj}; + jint numSubSamples = + env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); + + jintArray numBytesOfClearDataObj = + (jintArray)env->GetObjectField( + cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); + + jintArray numBytesOfEncryptedDataObj = + (jintArray)env->GetObjectField( + cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); + + jbyteArray keyObj = + (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); + + jbyteArray ivObj = + (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); + + jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); + enum CryptoPlugin::Mode mode; + if (jmode == gCryptoModes.Unencrypted) { + mode = CryptoPlugin::kMode_Unencrypted; + } else if (jmode == gCryptoModes.AesCtr) { + mode = CryptoPlugin::kMode_AES_CTR; + } else if (jmode == gCryptoModes.AesCbc) { + mode = CryptoPlugin::kMode_AES_CBC; + } else { + throwExceptionAsNecessary(env, INVALID_OPERATION); + return; + } + + jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID); + + CryptoPlugin::Pattern pattern; + if (patternObj == NULL) { + pattern.mEncryptBlocks = 0; + pattern.mSkipBlocks = 0; + } else { + pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID); + pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID); + } + + status_t err = OK; + + CryptoPlugin::SubSample *subSamples = NULL; + jbyte *key = NULL; + jbyte *iv = NULL; + + if (numSubSamples <= 0) { + err = -EINVAL; + } else if (numBytesOfClearDataObj == NULL + && numBytesOfEncryptedDataObj == NULL) { + err = -EINVAL; + } else if (numBytesOfEncryptedDataObj != NULL + && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { + err = -ERANGE; + } else if (numBytesOfClearDataObj != NULL + && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { + err = -ERANGE; + // subSamples array may silently overflow if number of samples are too large. Use + // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms + } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) { + err = -EINVAL; + } else { + jboolean isCopy; + + jint *numBytesOfClearData = + (numBytesOfClearDataObj == NULL) + ? NULL + : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); + + jint *numBytesOfEncryptedData = + (numBytesOfEncryptedDataObj == NULL) + ? NULL + : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); + + subSamples = new CryptoPlugin::SubSample[numSubSamples]; + + for (jint i = 0; i < numSubSamples; ++i) { + subSamples[i].mNumBytesOfClearData = + (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; + + subSamples[i].mNumBytesOfEncryptedData = + (numBytesOfEncryptedData == NULL) + ? 0 : numBytesOfEncryptedData[i]; + } + + if (numBytesOfEncryptedData != NULL) { + env->ReleaseIntArrayElements( + numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); + numBytesOfEncryptedData = NULL; + } + + if (numBytesOfClearData != NULL) { + env->ReleaseIntArrayElements( + numBytesOfClearDataObj, numBytesOfClearData, 0); + numBytesOfClearData = NULL; + } + } + + if (err == OK && keyObj != NULL) { + if (env->GetArrayLength(keyObj) != 16) { + err = -EINVAL; + } else { + jboolean isCopy; + key = env->GetByteArrayElements(keyObj, &isCopy); + } + } + + if (err == OK && ivObj != NULL) { + if (env->GetArrayLength(ivObj) != 16) { + err = -EINVAL; + } else { + jboolean isCopy; + iv = env->GetByteArrayElements(ivObj, &isCopy); + } + } + AString errorDetailMsg; - status_t err = cryptoInfo.mErr; if (err == OK) { err = codec->queueSecureInputBuffer( index, offset, - cryptoInfo.mSubSamples, cryptoInfo.mNumSubSamples, - (const uint8_t *)cryptoInfo.mKey, (const uint8_t *)cryptoInfo.mIv, - cryptoInfo.mMode, - cryptoInfo.mPattern, + subSamples, numSubSamples, + (const uint8_t *)key, (const uint8_t *)iv, + mode, + pattern, timestampUs, flags, &errorDetailMsg); } + if (iv != NULL) { + env->ReleaseByteArrayElements(ivObj, iv, 0); + iv = NULL; + } + + if (key != NULL) { + env->ReleaseByteArrayElements(keyObj, key, 0); + key = NULL; + } + + delete[] subSamples; + subSamples = NULL; + throwExceptionAsNecessary( env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); } |