Remove extractor-defaults_no-sanitizer am: 5641c5a31f
Change-Id: I4ae63336b865f6d60b2db100a203cc18fe637157
diff --git a/camera/aidl/android/hardware/ICameraServiceListener.aidl b/camera/aidl/android/hardware/ICameraServiceListener.aidl
index e9dcbdb..47580f8 100644
--- a/camera/aidl/android/hardware/ICameraServiceListener.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceListener.aidl
@@ -83,4 +83,12 @@
* can retry after receiving this callback.
*/
oneway void onCameraAccessPrioritiesChanged();
+
+ /**
+ * Notify registered clients about cameras being opened/closed.
+ * Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission
+ * will receive such callbacks.
+ */
+ oneway void onCameraOpened(String cameraId, String clientPackageId);
+ oneway void onCameraClosed(String cameraId);
}
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index e945ba0..cba6c73 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -92,6 +92,12 @@
}
virtual binder::Status onCameraAccessPrioritiesChanged();
+ virtual binder::Status onCameraOpened(const String16&, const String16&) {
+ return binder::Status::ok();
+ }
+ virtual binder::Status onCameraClosed(const String16&) {
+ return binder::Status::ok();
+ }
private:
const wp<CameraManagerGlobal> mCameraManager;
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 8fe029a..dc5afc5 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -95,6 +95,17 @@
return binder::Status::ok();
}
+ virtual binder::Status onCameraOpened(const String16& /*cameraId*/,
+ const String16& /*clientPackageName*/) {
+ // No op
+ return binder::Status::ok();
+ }
+
+ virtual binder::Status onCameraClosed(const String16& /*cameraId*/) {
+ // No op
+ return binder::Status::ok();
+ }
+
bool waitForNumCameras(size_t num) const {
Mutex::Autolock l(mLock);
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 51274d1..c2cc429 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -1071,6 +1071,7 @@
Vector<uint8_t> keySetId;
readVector(data, keySetId);
DrmPlugin::OfflineLicenseState state;
+ state = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
status_t result = getOfflineLicenseState(keySetId, &state);
reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
reply->writeInt32(result);
diff --git a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
index caff393..121a4e2 100644
--- a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
@@ -76,10 +76,21 @@
android::status_t InitDataParser::parsePssh(const Vector<uint8_t>& initData,
Vector<const uint8_t*>* keyIds) {
+ // Description of PSSH format:
+ // https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
size_t readPosition = 0;
- // Validate size field
uint32_t expectedSize = initData.size();
+ const char psshIdentifier[4] = {'p', 's', 's', 'h'};
+ const uint8_t psshVersion1[4] = {1, 0, 0, 0};
+ uint32_t keyIdCount = 0;
+ size_t headerSize = sizeof(expectedSize) + sizeof(psshIdentifier) +
+ sizeof(psshVersion1) + kSystemIdSize + sizeof(keyIdCount);
+ if (initData.size() < headerSize) {
+ return android::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ // Validate size field
expectedSize = htonl(expectedSize);
if (memcmp(&initData[readPosition], &expectedSize,
sizeof(expectedSize)) != 0) {
@@ -88,7 +99,6 @@
readPosition += sizeof(expectedSize);
// Validate PSSH box identifier
- const char psshIdentifier[4] = {'p', 's', 's', 'h'};
if (memcmp(&initData[readPosition], psshIdentifier,
sizeof(psshIdentifier)) != 0) {
return android::ERROR_DRM_CANNOT_HANDLE;
@@ -96,7 +106,6 @@
readPosition += sizeof(psshIdentifier);
// Validate EME version number
- const uint8_t psshVersion1[4] = {1, 0, 0, 0};
if (memcmp(&initData[readPosition], psshVersion1,
sizeof(psshVersion1)) != 0) {
return android::ERROR_DRM_CANNOT_HANDLE;
@@ -110,12 +119,14 @@
readPosition += kSystemIdSize;
// Read key ID count
- uint32_t keyIdCount;
memcpy(&keyIdCount, &initData[readPosition], sizeof(keyIdCount));
keyIdCount = ntohl(keyIdCount);
readPosition += sizeof(keyIdCount);
- if (readPosition + ((uint64_t)keyIdCount * kKeyIdSize) !=
- initData.size() - sizeof(uint32_t)) {
+
+ uint64_t psshSize = 0;
+ if (__builtin_mul_overflow(keyIdCount, kKeyIdSize, &psshSize) ||
+ __builtin_add_overflow(readPosition, psshSize, &psshSize) ||
+ psshSize != initData.size() - sizeof(uint32_t) /* DataSize(0) */) {
return android::ERROR_DRM_CANNOT_HANDLE;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index 3ecf6d5..f164f28 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -136,8 +136,6 @@
return Void();
}
- base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
-
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 7cb5a38..d74bc53 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -809,11 +809,6 @@
// count - number of secure stops
// list of fixed length secure stops
size_t countBufferSize = sizeof(uint32_t);
- if (input.size() < countBufferSize) {
- // SafetyNet logging
- android_errorWriteLog(0x534e4554, "144766455");
- return Status::BAD_VALUE;
- }
uint32_t count = 0;
sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
index 95eb909..7b6f21a 100644
--- a/media/codec2/components/raw/C2SoftRawDec.cpp
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -58,7 +58,7 @@
addParameter(
DefineParam(mSampleRate, C2_PARAMKEY_SAMPLE_RATE)
.withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).inRange(8000, 384000)})
+ .withFields({C2F(mSampleRate, value).greaterThan(0)})
.withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
.build());
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index 78d221e..c7588e9 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -62,7 +62,7 @@
android::base::unique_fd &&fd0,
android::base::unique_fd &&fd1) {
Mutexed<Jobs>::Locked jobs(mJobs);
- auto it = jobs->queues.try_emplace(comp, comp, systemTime()).first;
+ auto it = jobs->queues.try_emplace(comp, comp).first;
it->second.workList.emplace_back(
std::move(work), fenceFd, std::move(fd0), std::move(fd1));
jobs->cond.broadcast();
@@ -79,7 +79,8 @@
for (auto it = jobs->queues.begin(); it != jobs->queues.end(); ) {
Queue &queue = it->second;
if (queue.workList.empty()
- || nowNs - queue.lastQueuedTimestampNs < kIntervalNs) {
+ || (queue.lastQueuedTimestampNs != 0 &&
+ nowNs - queue.lastQueuedTimestampNs < kIntervalNs)) {
++it;
continue;
}
@@ -104,6 +105,7 @@
sp<Fence> fence(new Fence(fenceFd));
fence->waitForever(LOG_TAG);
}
+ queue.lastQueuedTimestampNs = nowNs;
comp->queue(&items);
for (android::base::unique_fd &ufd : uniqueFds) {
(void)ufd.release();
@@ -143,8 +145,8 @@
android::base::unique_fd fd1;
};
struct Queue {
- Queue(const std::shared_ptr<Codec2Client::Component> &comp, nsecs_t timestamp)
- : component(comp), lastQueuedTimestampNs(timestamp) {}
+ Queue(const std::shared_ptr<Codec2Client::Component> &comp)
+ : component(comp), lastQueuedTimestampNs(0) {}
Queue(const Queue &) = delete;
Queue &operator =(const Queue &) = delete;
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 9d183d4..5d00d94 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -132,6 +132,7 @@
AACExtractor::AACExtractor(
DataSourceHelper *source, off64_t offset)
: mDataSource(source),
+ mMeta(nullptr),
mInitCheck(NO_INIT),
mFrameDurationUs(0) {
@@ -180,7 +181,9 @@
}
AACExtractor::~AACExtractor() {
- AMediaFormat_delete(mMeta);
+ if (mMeta != nullptr) {
+ AMediaFormat_delete(mMeta);
+ }
}
media_status_t AACExtractor::getMetaData(AMediaFormat *meta) {
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
index 7097b48..818e466 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/extractors/fuzzers/Android.bp
@@ -36,13 +36,13 @@
static_libs: [
"liblog",
"libstagefright_foundation",
- "libmedia",
+ "libmediandk_format",
+ "libmedia_ndkformatpriv",
],
shared_libs: [
"libutils",
"libbinder",
- "libmediandk",
],
/* GETEXTRACTORDEF is not defined as extractor library is not linked in the
@@ -50,6 +50,14 @@
* generated.
*/
allow_undefined_symbols: true,
+
+ host_supported: true,
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_fuzz {
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
index 291e020..1be8466 100644
--- a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -187,3 +187,15 @@
cTrack->stop(track);
free(cTrack);
}
+
+void ExtractorFuzzerBase::processData(const uint8_t* data, size_t size) {
+ if (setDataSource(data, size)) {
+ if (createExtractor()) {
+ getExtractorDef();
+ getMetadata();
+ extractTracks();
+ getTracksMetadata();
+ seekAndExtractTracks();
+ }
+ }
+}
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
index 93665f0..98a6cc9 100644
--- a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
AacExtractor* extractor = new AacExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
index b2f9261..6c9e1a5 100644
--- a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
AmrExtractor* extractor = new AmrExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
index 61e41cf..8734d45 100644
--- a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
FlacExtractor* extractor = new FlacExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
index 86c70fc..6a2a1c1 100644
--- a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -70,6 +70,8 @@
void seekAndExtractTracks();
+ void processData(const uint8_t* data, size_t size);
+
protected:
class BufferSource : public DataSource {
public:
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
index 14274b7..eceb93f 100644
--- a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
MKVExtractor* extractor = new MKVExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
index 71c154b..9a47c18 100644
--- a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
Mp3Extractor* extractor = new Mp3Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
index d2cc133..3903519 100644
--- a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -48,17 +48,9 @@
return 0;
}
MP4Extractor* extractor = new MP4Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
index c34ffa0..240ef66 100644
--- a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
@@ -54,17 +54,9 @@
return 0;
}
MPEG2Extractor* extractor = new MPEG2Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->extractTracks();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
index 033c50b..bd2fcc5 100644
--- a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
OGGExtractor* extractor = new OGGExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
index 1397122..cb11ebd 100644
--- a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
wavExtractor* extractor = new wavExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 572bd5f..2d92f75 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1062,6 +1062,8 @@
// drop it now to reduce our footprint
free(mLastTrack->mTx3gBuffer);
mLastTrack->mTx3gBuffer = NULL;
+ mLastTrack->mTx3gFilled = 0;
+ mLastTrack->mTx3gSize = 0;
}
} else if (chunk_type == FOURCC("moov")) {
@@ -2644,6 +2646,10 @@
// if those apps are compensating for it, we'd break them with such a change
//
+ if (mLastTrack->mTx3gBuffer == NULL) {
+ mLastTrack->mTx3gSize = 0;
+ mLastTrack->mTx3gFilled = 0;
+ }
if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
size_t growth = kTx3gGrowth;
if (growth < chunk_size) {
@@ -5030,8 +5036,11 @@
}
status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
- off64_t offset, off64_t /* size */) {
+ off64_t offset, off64_t size) {
ALOGV("parseSampleAuxiliaryInformationSizes");
+ if (size < 9) {
+ return -EINVAL;
+ }
// 14496-12 8.7.12
uint8_t version;
if (mDataSource->readAt(
@@ -5044,25 +5053,32 @@
return ERROR_UNSUPPORTED;
}
offset++;
+ size--;
uint32_t flags;
if (!mDataSource->getUInt24(offset, &flags)) {
return ERROR_IO;
}
offset += 3;
+ size -= 3;
if (flags & 1) {
+ if (size < 13) {
+ return -EINVAL;
+ }
uint32_t tmp;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_MALFORMED;
}
mCurrentAuxInfoType = tmp;
offset += 4;
+ size -= 4;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_MALFORMED;
}
mCurrentAuxInfoTypeParameter = tmp;
offset += 4;
+ size -= 4;
}
uint8_t defsize;
@@ -5071,6 +5087,7 @@
}
mCurrentDefaultSampleInfoSize = defsize;
offset++;
+ size--;
uint32_t smplcnt;
if (!mDataSource->getUInt32(offset, &smplcnt)) {
@@ -5078,11 +5095,16 @@
}
mCurrentSampleInfoCount = smplcnt;
offset += 4;
-
+ size -= 4;
if (mCurrentDefaultSampleInfoSize != 0) {
ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
return OK;
}
+ if(smplcnt > size) {
+ ALOGW("b/124525515 - smplcnt(%u) > size(%ld)", (unsigned int)smplcnt, (unsigned long)size);
+ android_errorWriteLog(0x534e4554, "124525515");
+ return -EINVAL;
+ }
if (smplcnt > mCurrentSampleInfoAllocSize) {
uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
if (newPtr == NULL) {
@@ -5098,26 +5120,32 @@
}
status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
- off64_t offset, off64_t /* size */) {
+ off64_t offset, off64_t size) {
ALOGV("parseSampleAuxiliaryInformationOffsets");
+ if (size < 8) {
+ return -EINVAL;
+ }
// 14496-12 8.7.13
uint8_t version;
if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
return ERROR_IO;
}
offset++;
+ size--;
uint32_t flags;
if (!mDataSource->getUInt24(offset, &flags)) {
return ERROR_IO;
}
offset += 3;
+ size -= 3;
uint32_t entrycount;
if (!mDataSource->getUInt32(offset, &entrycount)) {
return ERROR_IO;
}
offset += 4;
+ size -= 4;
if (entrycount == 0) {
return OK;
}
@@ -5143,19 +5171,31 @@
for (size_t i = 0; i < entrycount; i++) {
if (version == 0) {
+ if (size < 4) {
+ ALOGW("b/124526959");
+ android_errorWriteLog(0x534e4554, "124526959");
+ return -EINVAL;
+ }
uint32_t tmp;
if (!mDataSource->getUInt32(offset, &tmp)) {
return ERROR_IO;
}
mCurrentSampleInfoOffsets[i] = tmp;
offset += 4;
+ size -= 4;
} else {
+ if (size < 8) {
+ ALOGW("b/124526959");
+ android_errorWriteLog(0x534e4554, "124526959");
+ return -EINVAL;
+ }
uint64_t tmp;
if (!mDataSource->getUInt64(offset, &tmp)) {
return ERROR_IO;
}
mCurrentSampleInfoOffsets[i] = tmp;
offset += 8;
+ size -= 8;
}
}
@@ -5477,16 +5517,12 @@
// apply some sanity (vs strict legality) checks
//
- // clamp the count of entries in the trun box, to avoid spending forever parsing
- // this box. Clamping (vs error) lets us play *something*.
- // 1 million is about 400 msecs on a Pixel3, should be no more than a couple seconds
- // on the slowest devices.
- static constexpr uint32_t kMaxTrunSampleCount = 1000000;
+ static constexpr uint32_t kMaxTrunSampleCount = 10000;
if (sampleCount > kMaxTrunSampleCount) {
- ALOGW("b/123389881 clamp sampleCount(%u) @ kMaxTrunSampleCount(%u)",
+ ALOGW("b/123389881 sampleCount(%u) > kMaxTrunSampleCount(%u)",
sampleCount, kMaxTrunSampleCount);
android_errorWriteLog(0x534e4554, "124389881 count");
-
+ return -EINVAL;
}
}
@@ -5530,7 +5566,12 @@
tmp.duration = sampleDuration;
tmp.compositionOffset = sampleCtsOffset;
memset(tmp.iv, 0, sizeof(tmp.iv));
- mCurrentSamples.add(tmp);
+ if (mCurrentSamples.add(tmp) < 0) {
+ ALOGW("b/123389881 failed saving sample(n=%zu)", mCurrentSamples.size());
+ android_errorWriteLog(0x534e4554, "124389881 allocation");
+ mCurrentSamples.clear();
+ return NO_MEMORY;
+ }
dataOffset += sampleSize;
}
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp
index 9dddf2c..a00812b 100644
--- a/media/extractors/mp4/SampleTable.cpp
+++ b/media/extractors/mp4/SampleTable.cpp
@@ -391,20 +391,11 @@
}
mTimeToSampleCount = U32_AT(&header[4]);
- if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
- // Choose this bound because
- // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
- // time-to-sample entry in the time-to-sample table.
- // 2) mTimeToSampleCount is the number of entries of the time-to-sample
- // table.
- // 3) We hope that the table size does not exceed UINT32_MAX.
+ if (mTimeToSampleCount > (data_size - 8) / (2 * sizeof(uint32_t))) {
ALOGE("Time-to-sample table size too large.");
return ERROR_OUT_OF_RANGE;
}
- // Note: At this point, we know that mTimeToSampleCount * 2 will not
- // overflow because of the above condition.
-
uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
mTotalSize += allocSize;
if (mTotalSize > kMaxTotalSize) {
@@ -540,6 +531,12 @@
}
uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t);
+ if (allocSize > data_size - 8) {
+ ALOGW("b/124771364 - allocSize(%lu) > size(%lu)",
+ (unsigned long)allocSize, (unsigned long)(data_size - 8));
+ android_errorWriteLog(0x534e4554, "124771364");
+ return ERROR_MALFORMED;
+ }
if (allocSize > kMaxTotalSize) {
ALOGE("Sync sample table size too large.");
return ERROR_OUT_OF_RANGE;
@@ -655,12 +652,13 @@
}
mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
- memset(mSampleTimeEntries, 0, sizeof(SampleTimeEntry) * mNumSampleSizes);
+
if (!mSampleTimeEntries) {
ALOGE("Cannot allocate sample entry table with %llu entries.",
(unsigned long long)mNumSampleSizes);
return;
}
+ memset(mSampleTimeEntries, 0, sizeof(SampleTimeEntry) * mNumSampleSizes);
uint32_t sampleIndex = 0;
uint64_t sampleTime = 0;
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index 97ad2b0..e017b3a 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -237,12 +237,12 @@
status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
- aaudio_handle_t streamHandle;
+ aaudio_handle_t streamHandle = 0;
aaudio::AAudioStreamRequest request;
aaudio::AAudioStreamConfiguration configuration;
- pid_t tid;
- int64_t nanoseconds;
- aaudio_result_t result;
+ pid_t tid = 0;
+ int64_t nanoseconds = 0;
+ aaudio_result_t result = AAUDIO_OK;
status_t status = NO_ERROR;
ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
@@ -285,7 +285,11 @@
case CLOSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(CLOSE_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = closeStream(streamHandle);
//ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
// streamHandle, result);
@@ -297,6 +301,7 @@
CHECK_INTERFACE(IAAudioService, data, reply);
status = data.readInt32(&streamHandle);
if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(GET_STREAM_DESCRIPTION) streamHandle failed!", __func__);
return status;
}
aaudio::AudioEndpointParcelable parcelable;
@@ -313,7 +318,11 @@
case START_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(START_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = startStream(streamHandle);
ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -323,7 +332,11 @@
case PAUSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(PAUSE_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = pauseStream(streamHandle);
ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -333,7 +346,11 @@
case STOP_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(STOP_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = stopStream(streamHandle);
ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -343,7 +360,11 @@
case FLUSH_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(FLUSH_STREAM) streamHandle failed!", __func__);
+ return status;
+ }
result = flushStream(streamHandle);
ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
streamHandle, result);
@@ -353,20 +374,40 @@
case REGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
- data.readInt32(&tid);
- data.readInt64(&nanoseconds);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
+ return status;
+ }
+ status = data.readInt32(&tid);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) tid failed!", __func__);
+ return status;
+ }
+ status = data.readInt64(&nanoseconds);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) nanoseconds failed!", __func__);
+ return status;
+ }
result = registerAudioThread(streamHandle, tid, nanoseconds);
- ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
- streamHandle, result);
+ ALOGV("BnAAudioService::%s(REGISTER_AUDIO_THREAD) 0x%08X, result = %d",
+ __func__, streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case UNREGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&streamHandle);
- data.readInt32(&tid);
+ status = data.readInt32(&streamHandle);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
+ return status;
+ }
+ status = data.readInt32(&tid);
+ if (status != NO_ERROR) {
+ ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) tid failed!", __func__);
+ return status;
+ }
result = unregisterAudioThread(streamHandle, tid);
ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
streamHandle, result);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 24d7c92..882a5c8 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -1410,6 +1410,7 @@
case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+ case SET_ALLOWED_CAPTURE_POLICY:
case AUDIO_MODULES_UPDATED: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e2795ac..92df3b7 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -40,6 +40,12 @@
"libstagefright_foundation",
"libutils"
],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library_static {
diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/libstagefright/foundation/OpusHeader.cpp
index 42ac026..784e802 100644
--- a/media/libstagefright/foundation/OpusHeader.cpp
+++ b/media/libstagefright/foundation/OpusHeader.cpp
@@ -300,6 +300,10 @@
*opusHeadSize = data_size;
return true;
} else if (memcmp(AOPUS_CSD_MARKER_PREFIX, data, AOPUS_CSD_MARKER_PREFIX_SIZE) == 0) {
+ if (data_size < AOPUS_UNIFIED_CSD_MINSIZE || data_size > AOPUS_UNIFIED_CSD_MAXSIZE) {
+ ALOGD("Unexpected size for unified opus csd %zu", data_size);
+ return false;
+ }
size_t i = 0;
bool found = false;
while (i <= data_size - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE) {
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 1e434cb..9df3508 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -338,6 +338,12 @@
ABitReader bits(buffer->data() + offset, buffer->size() - offset);
unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
+ if (buffer->size() < auxSize) {
+ ALOGE("b/123940919 auxSize %u", auxSize);
+ android_errorWriteLog(0x534e4554, "123940919");
+ queue->erase(queue->begin());
+ return MALFORMED_PACKET;
+ }
offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
}
@@ -346,6 +352,12 @@
it != headers.end(); ++it) {
const AUHeader &header = *it;
+ if (buffer->size() < header.mSize) {
+ ALOGE("b/123940919 AU_size %u", header.mSize);
+ android_errorWriteLog(0x534e4554, "123940919");
+ queue->erase(queue->begin());
+ return MALFORMED_PACKET;
+ }
if (buffer->size() < offset + header.mSize) {
return MALFORMED_PACKET;
}
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/libstagefright/tests/ESDS/Android.bp
new file mode 100644
index 0000000..1ad1a64
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "ESDSTest",
+ gtest: true,
+
+ srcs: [
+ "ESDSTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libdatasource",
+ "liblog",
+ "libmedia",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libstagefright_esds",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/libstagefright/tests/ESDS/AndroidTest.xml
new file mode 100644
index 0000000..a4fbc7f
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Test module config for ESDS unit test">
+ <option name="test-suite-tag" value="ESDSTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="ESDSTest->/data/local/tmp/ESDSTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip?unzip=true"
+ value="/data/local/tmp/ESDSTestRes/" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="ESDSTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/ESDSTestRes/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/libstagefright/tests/ESDS/ESDSTest.cpp
new file mode 100644
index 0000000..101e00c
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ESDSTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+#include <ESDS.h>
+#include <binder/ProcessState.h>
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MetaData.h>
+
+#include "ESDSTestEnvironment.h"
+
+using namespace android;
+
+static ESDSTestEnvironment *gEnv = nullptr;
+
+struct ESDSParams {
+ const char *inputFile;
+ int32_t objectTypeIndication;
+ const char *codecSpecificInfoData;
+ int32_t codecSpecificInfoDataSize;
+ int32_t bitrateMax;
+ int32_t bitrateAvg;
+};
+
+class ESDSUnitTest : public ::testing::TestWithParam<tuple<
+ /* InputFile */ const char *,
+ /* ObjectTypeIndication */ int32_t,
+ /* CodecSpecificInfoData */ const char *,
+ /* CodecSpecificInfoDataSize */ int32_t,
+ /* BitrateMax */ int32_t,
+ /* BitrateAvg */ int32_t>> {
+ public:
+ ESDSUnitTest() : mESDSData(nullptr) {
+ mESDSParams.inputFile = get<0>(GetParam());
+ mESDSParams.objectTypeIndication = get<1>(GetParam());
+ mESDSParams.codecSpecificInfoData = get<2>(GetParam());
+ mESDSParams.codecSpecificInfoDataSize = get<3>(GetParam());
+ mESDSParams.bitrateMax = get<4>(GetParam());
+ mESDSParams.bitrateAvg = get<5>(GetParam());
+ };
+
+ virtual void TearDown() override {
+ if (mDataSource) mDataSource.clear();
+ if (mInputFp) {
+ fclose(mInputFp);
+ mInputFp = nullptr;
+ }
+ }
+
+ virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(readESDSData()); }
+ const void *mESDSData;
+ size_t mESDSSize;
+ ESDSParams mESDSParams;
+
+ private:
+ void readESDSData() {
+ string inputFile = gEnv->getRes() + mESDSParams.inputFile;
+ mInputFp = fopen(inputFile.c_str(), "rb");
+ ASSERT_NE(mInputFp, nullptr) << "File open failed for file: " << inputFile;
+ int32_t fd = fileno(mInputFp);
+ ASSERT_GE(fd, 0) << "File descriptor invalid for file: " << inputFile;
+
+ struct stat buf;
+ status_t status = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(status, 0) << "Failed to get properties of input file: " << mESDSParams.inputFile;
+ size_t fileSize = buf.st_size;
+
+ mDataSource = new FileSource(dup(fd), 0, fileSize);
+ ASSERT_NE(mDataSource, nullptr) << "Unable to create data source for file: " << inputFile;
+
+ sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(mDataSource);
+ if (extractor == nullptr) {
+ mDataSource.clear();
+ ASSERT_TRUE(false) << "Unable to create extractor for file: " << inputFile;
+ }
+
+ size_t numTracks = extractor->countTracks();
+ ASSERT_GT(numTracks, 0) << "No tracks in file: " << inputFile;
+ ASSERT_TRUE(esdsDataPresent(numTracks, extractor))
+ << "Unable to find esds in any track in file: " << inputFile;
+ }
+
+ bool esdsDataPresent(size_t numTracks, sp<IMediaExtractor> extractor) {
+ bool foundESDS = false;
+ uint32_t type;
+ for (size_t i = 0; i < numTracks; ++i) {
+ sp<MetaData> trackMeta = extractor->getTrackMetaData(i);
+ if (trackMeta != nullptr &&
+ trackMeta->findData(kKeyESDS, &type, &mESDSData, &mESDSSize)) {
+ trackMeta->clear();
+ foundESDS = true;
+ break;
+ }
+ }
+ return foundESDS;
+ }
+
+ FILE *mInputFp;
+ sp<DataSource> mDataSource;
+};
+
+TEST_P(ESDSUnitTest, InvalidDataTest) {
+ void *invalidData = calloc(mESDSSize, 1);
+ ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+ ESDS esds(invalidData, mESDSSize);
+ free(invalidData);
+ ASSERT_NE(esds.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST(ESDSSanityUnitTest, ConstructorSanityTest) {
+ void *invalidData = malloc(1);
+ ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+ ESDS esds_zero(invalidData, 0);
+ free(invalidData);
+ ASSERT_NE(esds_zero.InitCheck(), OK) << "invalid ESDS data accepted";
+
+ ESDS esds_null(NULL, 0);
+ ASSERT_NE(esds_null.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST_P(ESDSUnitTest, CreateAndDestroyTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+}
+
+TEST_P(ESDSUnitTest, ObjectTypeIndicationTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ uint8_t objectTypeIndication;
+ status_t status = esds.getObjectTypeIndication(&objectTypeIndication);
+ ASSERT_EQ(status, OK) << "ESDS objectTypeIndication data invalid";
+ ASSERT_EQ(objectTypeIndication, mESDSParams.objectTypeIndication)
+ << "ESDS objectTypeIndication data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, CodecSpecificInfoTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ status_t status;
+ const void *codecSpecificInfo;
+ size_t codecSpecificInfoSize;
+ status = esds.getCodecSpecificInfo(&codecSpecificInfo, &codecSpecificInfoSize);
+ ASSERT_EQ(status, OK) << "ESDS getCodecSpecificInfo data invalid";
+ ASSERT_EQ(mESDSParams.codecSpecificInfoDataSize, codecSpecificInfoSize)
+ << "CodecSpecificInfo data doesn't match";
+ status = memcmp(codecSpecificInfo, mESDSParams.codecSpecificInfoData, codecSpecificInfoSize);
+ ASSERT_EQ(status, 0) << "CodecSpecificInfo data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, GetBitrateTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ uint32_t bitrateMax;
+ uint32_t bitrateAvg;
+ status_t status = esds.getBitRate(&bitrateMax, &bitrateAvg);
+ ASSERT_EQ(status, OK) << "ESDS bitRate data invalid";
+ ASSERT_EQ(bitrateMax, mESDSParams.bitrateMax) << "ESDS bitrateMax doesn't match";
+ ASSERT_EQ(bitrateAvg, mESDSParams.bitrateAvg) << "ESDS bitrateAvg doesn't match";
+ ASSERT_LE(bitrateAvg, bitrateMax) << "ESDS bitrateMax is less than bitrateAvg";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ ESDSUnitTestAll, ESDSUnitTest,
+ ::testing::Values(
+ // InputFile, ObjectTypeIndication, CodecSpecificInfoData,
+ // CodecSpecificInfoDataSize, BitrateMax, BitrateAvg
+ make_tuple("video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_22050hz.3gp", 64,
+ "\x13\x90", 2, 131072, 0),
+ make_tuple("video_1280x720_mp4_mpeg2_3000kbps_30fps_aac_stereo_128kbps_48000hz.mp4",
+ 97,
+ "\x00\x00\x01\xB3\x50\x02\xD0\x35\xFF\xFF\xE1\xA0\x00\x00\x01\xB5\x15"
+ "\x6A\x00\x01\x00\x00",
+ 22, 3415452, 3415452),
+ make_tuple("video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_11025hz.3gp", 64,
+ "\x15\x08", 2, 24576, 0)));
+
+int main(int argc, char **argv) {
+ // MediaExtractor needs binder thread pool
+ ProcessState::self()->startThreadPool();
+ gEnv = new ESDSTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ }
+ return status;
+}
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
new file mode 100644
index 0000000..4ca2303
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ESDS_TEST_ENVIRONMENT_H__
+#define __ESDS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ESDSTestEnvironment : public ::testing::Environment {
+ public:
+ ESDSTestEnvironment() : res("/data/local/tmp/") {}
+
+ // Parses the command line arguments
+ int initFromOptions(int argc, char **argv);
+
+ void setRes(const char *_res) { res = _res; }
+
+ const string getRes() const { return res; }
+
+ private:
+ string res;
+};
+
+int ESDSTestEnvironment::initFromOptions(int argc, char **argv) {
+ static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "P:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'P':
+ setRes(optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-P, --path: Resource files directory location\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+}
+
+#endif // __ESDS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/libstagefright/tests/ESDS/README.md
new file mode 100644
index 0000000..100fb86
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/README.md
@@ -0,0 +1,40 @@
+## Media Testing ##
+---
+#### ESDS Unit Test :
+The ESDS Unit Test Suite validates the ESDS class available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m ESDSTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip)
+Download, unzip and push these files into device for testing.
+
+```
+adb push ESDSTestRes /data/local/tmp/
+```
+
+usage: ESDSTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/ESDSTest -P /data/local/tmp/ESDSTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ESDSTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index a291939..c76b53d 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -45,6 +45,7 @@
#include "android-base/strings.h"
namespace android {
+static const int SN_EVENT_LOG_ID = 0x534e4554;
static const MtpOperationCode kSupportedOperationCodes[] = {
MTP_OPERATION_GET_DEVICE_INFO,
@@ -967,6 +968,17 @@
if (!parseDateTime(modified, modifiedTime))
modifiedTime = 0;
+ if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0) ||
+ (strchr(name, '/') != NULL)) {
+ char errMsg[80];
+
+ snprintf(errMsg, sizeof(errMsg), "Invalid name: %s", (const char *) name);
+ ALOGE("%s (b/130656917)", errMsg);
+ android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "130656917", -1, errMsg,
+ strlen(errMsg));
+
+ return MTP_RESPONSE_INVALID_PARAMETER;
+ }
if (path[path.size() - 1] != '/')
path.append("/");
path.append(name);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2a2e449..67e085c 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5614,7 +5614,10 @@
patchBuilder.addSink(filteredDevice);
}
- installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
+ // Add half reported latency to delayMs when muteWaitMs is null in order
+ // to avoid disordered sequence of muting volume and changing devices.
+ installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(),
+ muteWaitMs == 0 ? (delayMs + (outputDesc->latency() / 2)) : delayMs);
}
// update stream volumes according to new device
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 227adc7..f3f546f 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -989,11 +989,6 @@
ALOGV("%s() mAudioPolicyManager == NULL", __func__);
return NO_INIT;
}
- uint_t callingUid = IPCThreadState::self()->getCallingUid();
- if (uid != callingUid) {
- ALOGD("%s() uid invalid %d != %d", __func__, uid, callingUid);
- return PERMISSION_DENIED;
- }
return mAudioPolicyManager->setAllowedCapturePolicy(uid, capturePolicy);
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 595c3e8..336eb46 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -118,6 +118,8 @@
// ----------------------------------------------------------------------------
static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
+static const String16 sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
// Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java
static constexpr int32_t kVendorClientScore = 200;
@@ -1812,7 +1814,11 @@
}
auto clientUid = CameraThreadState::getCallingUid();
- sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid);
+ auto clientPid = CameraThreadState::getCallingPid();
+ bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
+ clientPid, clientUid);
+ sp<ServiceListener> serviceListener = new ServiceListener(this, listener,
+ clientUid, clientPid, openCloseCallbackAllowed);
auto ret = serviceListener->initialize();
if (ret != NO_ERROR) {
String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
@@ -2516,6 +2522,9 @@
sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
+
return OK;
}
@@ -2556,6 +2565,9 @@
sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName);
+
return OK;
}
@@ -3327,6 +3339,29 @@
});
}
+void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
+ const String16& clientPackageName) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (const auto& it : mListenerList) {
+ if (!it.second->isOpenCloseCallbackAllowed()) {
+ continue;
+ }
+
+ binder::Status ret;
+ String16 cameraId64(cameraId);
+ if (open) {
+ ret = it.second->getListener()->onCameraOpened(cameraId64, clientPackageName);
+ } else {
+ ret = it.second->getListener()->onCameraClosed(cameraId64);
+ }
+ if (!ret.isOk()) {
+ ALOGE("%s: Failed to trigger onCameraOpened/onCameraClosed callback: %d", __FUNCTION__,
+ ret.exceptionCode());
+ }
+ }
+}
+
template<class Func>
void CameraService::CameraState::updateStatus(StatusInternal status,
const String8& cameraId,
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 4e04f0e..0b09619 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -822,7 +822,9 @@
class ServiceListener : public virtual IBinder::DeathRecipient {
public:
ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener,
- int uid) : mParent(parent), mListener(listener), mListenerUid(uid) {}
+ int uid, int pid, bool openCloseCallbackAllowed) : mParent(parent),
+ mListener(listener), mListenerUid(uid), mListenerPid(pid),
+ mOpenCloseCallbackAllowed(openCloseCallbackAllowed) {}
status_t initialize() {
return IInterface::asBinder(mListener)->linkToDeath(this);
@@ -836,12 +838,16 @@
}
int getListenerUid() { return mListenerUid; }
+ int getListenerPid() { return mListenerPid; }
sp<hardware::ICameraServiceListener> getListener() { return mListener; }
+ bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; }
private:
wp<CameraService> mParent;
sp<hardware::ICameraServiceListener> mListener;
int mListenerUid;
+ int mListenerPid;
+ bool mOpenCloseCallbackAllowed = false;
};
// Guarded by mStatusListenerMutex
@@ -864,6 +870,13 @@
void updateStatus(StatusInternal status,
const String8& cameraId);
+ /**
+ * Update the opened/closed status of the given camera id.
+ *
+ * This method acqiures mStatusListenerLock.
+ */
+ void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName);
+
// flashlight control
sp<CameraFlashlight> mFlashlight;
// guard mTorchStatusMap
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 0f6be79..b9e5857 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -54,6 +54,15 @@
// TODO: no implementation yet.
return binder::Status::ok();
}
+ virtual binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
+ const ::android::String16& /*clientPackageId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
+ virtual binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
};
} // implementation
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index e319425..5811068 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -58,5 +58,8 @@
src: "seccomp_policy/mediacodec-x86.policy",
},
},
- required: ["crash_dump.policy"],
+ required: [
+ "crash_dump.policy",
+ "code_coverage.policy",
+ ],
}
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index cdd9d0c..88a79e7 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -70,7 +70,7 @@
LOCAL_MODULE := mediacodec.policy
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
+LOCAL_REQUIRED_MODULES := crash_dump.policy code_coverage.policy
# mediacodec runs in 32-bit combatibility mode. For 64 bit architectures,
# use the 32 bit policy
ifdef TARGET_2ND_ARCH
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 51564ca..b4a9ff6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -59,3 +59,5 @@
getrandom: 1
@include /system/etc/seccomp_policy/crash_dump.arm.policy
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index d9c4045..a9d32d6 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -69,3 +69,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 8705cf9..9af0ec7 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -84,3 +84,5 @@
getgid32: 1
getegid32: 1
getgroups32: 1
+
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index 85fd28d..e8ff2f6 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -79,3 +79,4 @@
getegid: 1
getgroups: 1
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index e906500..15d30ce 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -67,6 +67,9 @@
src: "seccomp_policy/mediaextractor-x86_64.policy",
},
},
- required: ["crash_dump.policy"],
+ required: [
+ "crash_dump.policy",
+ "code_coverage.policy",
+ ],
}
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index c61393d..02de431 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -58,3 +58,4 @@
_llseek: 1
@include /system/etc/seccomp_policy/crash_dump.arm.policy
+@include /system/etc/seccomp_policy/code_coverage.arm.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index e6c676c..8fd8787 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -44,3 +44,4 @@
sched_yield: 1
@include /system/etc/seccomp_policy/crash_dump.arm64.policy
+@include /system/etc/seccomp_policy/code_coverage.arm64.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index 56ad8df..05915d1 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -57,3 +57,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86.policy
+@include /system/etc/seccomp_policy/code_coverage.x86.policy
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
index 607a03e..e6a55d0 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -51,3 +51,4 @@
gettid: 1
@include /system/etc/seccomp_policy/crash_dump.x86_64.policy
+@include /system/etc/seccomp_policy/code_coverage.x86_64.policy
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 377d30b..51afdcd 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -40,6 +40,32 @@
#define HW_MODULE_PREFIX "primary"
namespace android {
+namespace {
+
+// Given an IMemory, returns a copy of its content along with its size.
+// Returns nullptr on failure or if input is nullptr.
+std::pair<std::unique_ptr<uint8_t[]>,
+ size_t> CopyToArray(const sp<IMemory>& mem) {
+ if (mem == nullptr) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ const size_t size = mem->size();
+ if (size == 0) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ std::unique_ptr<uint8_t[]> ar = std::make_unique<uint8_t[]>(size);
+ if (ar == nullptr) {
+ return std::make_pair(nullptr, 0);
+ }
+
+ memcpy(ar.get(), mem->pointer(), size);
+ return std::make_pair(std::move(ar), size);
+}
+
+}
+
SoundTriggerHwService::SoundTriggerHwService()
: BnSoundTriggerHwService(),
mNextUniqueId(1),
@@ -557,8 +583,13 @@
return NO_INIT;
}
- struct sound_trigger_sound_model *sound_model =
- (struct sound_trigger_sound_model *)modelMemory->pointer();
+ auto immutableMemory = CopyToArray(modelMemory);
+ if (immutableMemory.first == nullptr) {
+ return NO_MEMORY;
+ }
+
+ struct sound_trigger_sound_model* sound_model =
+ (struct sound_trigger_sound_model*) immutableMemory.first.get();
size_t structSize;
if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
@@ -568,9 +599,10 @@
}
if (sound_model->data_offset < structSize ||
- sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
- modelMemory->size() < sound_model->data_offset ||
- sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
+ sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
+ immutableMemory.second < sound_model->data_offset ||
+ sound_model->data_size >
+ (immutableMemory.second - sound_model->data_offset)) {
android_errorWriteLog(0x534e4554, "30148546");
ALOGE("loadSoundModel() data_size is too big");
return BAD_VALUE;
@@ -651,13 +683,19 @@
return NO_INIT;
}
- struct sound_trigger_recognition_config *config =
- (struct sound_trigger_recognition_config *)dataMemory->pointer();
+ auto immutableMemory = CopyToArray(dataMemory);
+ if (immutableMemory.first == nullptr) {
+ return NO_MEMORY;
+ }
+
+ struct sound_trigger_recognition_config* config =
+ (struct sound_trigger_recognition_config*) immutableMemory.first.get();
if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
- config->data_size > (UINT_MAX - config->data_offset) ||
- dataMemory->size() < config->data_offset ||
- config->data_size > (dataMemory->size() - config->data_offset)) {
+ config->data_size > (UINT_MAX - config->data_offset) ||
+ immutableMemory.second < config->data_offset ||
+ config->data_size >
+ (immutableMemory.second - config->data_offset)) {
ALOGE("startRecognition() data_size is too big");
return BAD_VALUE;
}