diff options
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 1 | ||||
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 22 | ||||
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/id3/ID3.cpp | 57 | ||||
-rw-r--r-- | services/audioflinger/Effects.cpp | 23 | ||||
-rw-r--r-- | services/soundtrigger/SoundTriggerHwService.cpp | 38 |
7 files changed, 130 insertions, 25 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index a57e548..61afe99 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -559,6 +559,12 @@ void MediaPlayerService::removeClient(wp<Client> client) mClients.remove(client); } +bool MediaPlayerService::hasClient(wp<Client> client) +{ + Mutex::Autolock lock(mLock); + return mClients.indexOf(client) != NAME_NOT_FOUND; +} + MediaPlayerService::Client::Client( const sp<MediaPlayerService>& service, pid_t pid, int32_t connId, const sp<IMediaPlayerClient>& client, @@ -1055,6 +1061,10 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& playe ALOGV("setNextPlayer"); Mutex::Autolock l(mLock); sp<Client> c = static_cast<Client*>(player.get()); + if (c != NULL && !mService->hasClient(c)) { + return BAD_VALUE; + } + mNextClient = c; if (c != NULL) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index ff8f550..2bd7ec5 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -227,6 +227,7 @@ public: virtual status_t dump(int fd, const Vector<String16>& args); void removeClient(wp<Client> client); + bool hasClient(wp<Client> client); // For battery usage tracking purpose struct BatteryUsageInfo { diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index bb59ae4..1dd631a 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -210,8 +210,17 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { PortInfo *port = editPortInfo(1); OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader; + OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size; + if ((outHeader->nAllocLen < yFrameSize) || + (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) { + ALOGE("Too small output buffer for reference frame: %lu bytes", + (unsigned long)outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "30033990"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } PVSetReferenceYUV(mHandle, outHeader->pBuffer); - mFramesConfigured = true; } @@ -229,7 +238,16 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { int32_t bufferSize = inHeader->nFilledLen; int32_t tmp = bufferSize; - OMX_U32 frameSize = (mWidth * mHeight * 3) / 2; + OMX_U32 frameSize; + OMX_U64 yFrameSize = (OMX_U64)mWidth * (OMX_U64)mHeight; + if (yFrameSize > ((OMX_U64)UINT32_MAX / 3) * 2) { + ALOGE("Frame size too large"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + frameSize = (OMX_U32)(yFrameSize + (yFrameSize / 2)); + if (outHeader->nAllocLen < frameSize) { android_errorWriteLog(0x534e4554, "27833616"); ALOGE("Insufficient output buffer size"); diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index 7638bb7..2eb51c9 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -116,6 +116,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { ALOGE("Failed to get default encoding parameters"); return OMX_ErrorUndefined; } + if (mFramerate == 0) { + ALOGE("Framerate should not be 0"); + return OMX_ErrorUndefined; + } mEncParams->encMode = mEncodeMode; mEncParams->encWidth[0] = mWidth; mEncParams->encHeight[0] = mHeight; diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 4f4248c..d1fd0d9 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -77,7 +77,10 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1) mFirstFrameOffset(0), mVersion(ID3_UNKNOWN), mRawSize(0) { - sp<MemorySource> source = new MemorySource(data, size); + sp<MemorySource> source = new (std::nothrow) MemorySource(data, size); + + if (source == NULL) + return; mIsValid = parseV2(source, 0); @@ -543,6 +546,10 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { n -= skipped; } + if (n <= 0) { + return; + } + if (encoding == 0x00) { // supposedly ISO 8859-1 id->setTo((const char*)frameData + 1, n); @@ -556,11 +563,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; #if BYTE_ORDER == LITTLE_ENDIAN - framedatacopy = new char16_t[len]; - for (int i = 0; i < len; i++) { - framedatacopy[i] = bswap_16(framedata[i]); + if (len > 0) { + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } + for (int i = 0; i < len; i++) { + framedatacopy[i] = bswap_16(framedata[i]); + } + framedata = framedatacopy; } - framedata = framedatacopy; #endif id->setTo(framedata, len); if (framedatacopy != NULL) { @@ -573,15 +585,26 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; if (*framedata == 0xfffe) { - // endianness marker doesn't match host endianness, convert - framedatacopy = new char16_t[len]; + // endianness marker != host endianness, convert & skip + if (len <= 1) { + return; // nothing after the marker + } + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } for (int i = 0; i < len; i++) { framedatacopy[i] = bswap_16(framedata[i]); } framedata = framedatacopy; - } - // If the string starts with an endianness marker, skip it - if (*framedata == 0xfeff) { + // and skip over the marker + framedata++; + len--; + } else if (*framedata == 0xfeff) { + // endianness marker == host endianness, skip it + if (len <= 1) { + return; // nothing after the marker + } framedata++; len--; } @@ -596,12 +619,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { } if (eightBit) { // collapse to 8 bit, then let the media scanner client figure out the real encoding - char *frame8 = new char[len]; - for (int i = 0; i < len; i++) { - frame8[i] = framedata[i]; + char *frame8 = new (std::nothrow) char[len]; + if (frame8 != NULL) { + for (int i = 0; i < len; i++) { + frame8[i] = framedata[i]; + } + id->setTo(frame8, len); + delete [] frame8; + } else { + id->setTo(framedata, len); } - id->setTo(frame8, len); - delete [] frame8; } else { id->setTo(framedata, len); } diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index e57aab1..5505d2e 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -543,6 +543,13 @@ status_t AudioFlinger::EffectModule::remove_effect_from_hal_l() return NO_ERROR; } +// round up delta valid if value and divisor are positive. +template <typename T> +static T roundUpDelta(const T &value, const T &divisor) { + T remainder = value % divisor; + return remainder == 0 ? 0 : divisor - remainder; +} + status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -564,6 +571,22 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, android_errorWriteLog(0x534e4554, "29251553"); return -EINVAL; } + if ((cmdCode == EFFECT_CMD_SET_PARAM + || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used + (sizeof(effect_param_t) > cmdSize + || ((effect_param_t *)pCmdData)->psize > cmdSize + - sizeof(effect_param_t) + || ((effect_param_t *)pCmdData)->vsize > cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) > + cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + - ((effect_param_t *)pCmdData)->vsize)) { + android_errorWriteLog(0x534e4554, "30204301"); + return -EINVAL; + } status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 371c81a..a1cc6ff 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -565,6 +565,22 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM struct sound_trigger_sound_model *sound_model = (struct sound_trigger_sound_model *)modelMemory->pointer(); + size_t structSize; + if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { + structSize = sizeof(struct sound_trigger_phrase_sound_model); + } else { + structSize = sizeof(struct sound_trigger_sound_model); + } + + 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)) { + android_errorWriteLog(0x534e4554, "30148546"); + ALOGE("loadSoundModel() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mModels.size() >= mDescriptor.properties.max_sound_models) { @@ -634,11 +650,23 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha return PERMISSION_DENIED; } - if (dataMemory != 0 && dataMemory->pointer() == NULL) { - ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()"); + if (dataMemory == 0 || dataMemory->pointer() == NULL) { + ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); return BAD_VALUE; } + + struct sound_trigger_recognition_config *config = + (struct sound_trigger_recognition_config *)dataMemory->pointer(); + + 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)) { + ALOGE("startRecognition() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { return INVALID_OPERATION; @@ -647,17 +675,11 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha if (model == 0) { return BAD_VALUE; } - if ((dataMemory == 0) || - (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) { - return BAD_VALUE; - } if (model->mState == Model::STATE_ACTIVE) { return INVALID_OPERATION; } - struct sound_trigger_recognition_config *config = - (struct sound_trigger_recognition_config *)dataMemory->pointer(); //TODO: get capture handle and device from audio policy service config->capture_handle = model->mCaptureIOHandle; |