Commit message: None
CVE: CVE-2016-3924
CWE: CWE-200
Vulnerability description: services/audioflinger/Effects.cpp in mediaserver in Android 4.x before 4.4.4, 5.0.x before 5.0.2, 5.1.x before 5.1.1, 6.x before 2016-10-01, and 7.0 before 2016-10-01 does not validate EFFECT_CMD_SET_PARAM and EFFECT_CMD_SET_PARAM_DEFERRED commands, which allows attackers to obtain sensitive information via a crafted application, aka internal bug 30204301.

Project: Android

void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
 bool enabled)
{
 ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
 if (enabled) {
 if (index < 0) {
            index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
 if (index < 0) {
 return;
 }
 if (!isEffectEligibleForSuspend(effect->desc())) {
 return;
 }
            setEffectSuspended_l(&effect->desc().type, enabled);
            index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
 if (index < 0) {
                ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
 return;
 }
 }
        ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
            effect->desc().type.timeLow);
        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
 if (desc->mEffect == 0) {
            desc->mEffect = effect;
            effect->setEnabled(false);
            effect->setSuspended(true);
 }
 } else {
 if (index < 0) {
 return;
 }
        ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
            effect->desc().type.timeLow);
        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
        desc->mEffect.clear();
        effect->setSuspended(false);
 }
}

Project: Android

sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
{
 size_t size = mEffects.size();

 for (size_t i = 0; i < size; i++) {
 if (id == 0 || mEffects[i]->id() == id) {
 return mEffects[i];
 }
 }
 return 0;
}

Project: Android

void AudioFlinger::EffectChain::getSuspendEligibleEffects(
 Vector< sp<AudioFlinger::EffectModule> > &effects)
{
    effects.clear();
 for (size_t i = 0; i < mEffects.size(); i++) {
 if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
            effects.add(mEffects[i]);
 }
 }
}

Project: Android

size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
{
 Mutex::Autolock _l(mLock);
 size_t size = mEffects.size();
 uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;

 for (size_t i = 0; i < size; i++) {
 if (effect == mEffects[i]) {
 if (mEffects[i]->state() == EffectModule::ACTIVE ||
                    mEffects[i]->state() == EffectModule::STOPPING) {
                mEffects[i]->stop();
 }
 if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
 delete[] effect->inBuffer();
 } else {
 if (i == size - 1 && i != 0) {
                    mEffects[i - 1]->setOutBuffer(mOutBuffer);
                    mEffects[i - 1]->configure();
 }
 }
            mEffects.removeAt(i);
            ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %zu", effect.get(),
 this, i);
 break;
 }
 }

 return mEffects.size();
}

Project: Android

bool AudioFlinger::EffectModule::suspended() const
{
 Mutex::Autolock _l(mLock);
 return mSuspended;
}

Project: Android

AudioFlinger::EffectHandle::~EffectHandle()
{
    ALOGV("Destructor %p", this);

 if (mEffect == 0) {
        mDestroyed = true;
 return;
 }
    mEffect->lock();
    mDestroyed = true;
    mEffect->unlock();
    disconnect(false);
}