Commit message: None
CVE: CVE-2016-6699
CWE: CWE-119
Vulnerability description: A remote code execution vulnerability in libstagefright in Mediaserver in Android 7.0 before 2016-11-01 could enable an attacker using a specially crafted file to cause memory corruption during media file and data processing. This issue is rated as Critical due to the possibility of remote code execution within the context of the Mediaserver process. Android ID: A-31373622.

Project: Android

sp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) {
 if (mDrmManagerClient == NULL) {
        mDrmManagerClient = new DrmManagerClient();
 }

 if (mDrmManagerClient == NULL) {
 return NULL;
 }

 if (mDecryptHandle == NULL) {
        mDecryptHandle = mDrmManagerClient->openDecryptSession(
 String8(mLastURI.c_str()), mime);
 }

 if (mDecryptHandle == NULL) {
 delete mDrmManagerClient;
        mDrmManagerClient = NULL;
 }

 return mDecryptHandle;
}

Project: Android

MediaHTTP::MediaHTTP(const sp<IMediaHTTPConnection> &conn)
 : mInitCheck((conn != NULL) ? OK : NO_INIT),
      mHTTPConnection(conn),
      mCachedSizeValid(false),
      mCachedSize(0ll),
      mDrmManagerClient(NULL) {
}

Project: Android

void MediaHTTP::clearDRMState_l() {
 if (mDecryptHandle != NULL) {
        CHECK(mDrmManagerClient);
        mDrmManagerClient->closeDecryptSession(mDecryptHandle);
        mDecryptHandle = NULL;
 }
}

Project: Android

void MediaHTTP::disconnect() {
    mName = String8("MediaHTTP(<disconnected>)");
 if (mInitCheck != OK) {
 return;
 }

    mHTTPConnection->disconnect();
}

Project: Android

uint32_t MediaHTTP::flags() {
 return kWantsPrefetching | kIsHTTPBasedSource;
}

Project: Android

void MediaHTTP::getDrmInfo(
        sp<DecryptHandle> &handle, DrmManagerClient **client) {
    handle = mDecryptHandle;
 *client = mDrmManagerClient;
}

Project: Android

status_t MediaHTTP::getSize(off64_t *size) {
 if (mInitCheck != OK) {
 return mInitCheck;
 }


 if (!mCachedSizeValid) {
        mCachedSize = mHTTPConnection->getSize();
        mCachedSizeValid = true;
 }

 *size = mCachedSize;

 return *size < 0 ? *size : static_cast<status_t>(OK);
}

Project: Android

String8 MediaHTTP::getUri() {
 if (mInitCheck != OK) {
 return String8::empty();
 }

 String8 uri;
 if (OK == mHTTPConnection->getUri(&uri)) {
 return uri;
 }
 return String8(mLastURI.c_str());
}

Project: Android

status_t MediaHTTP::initCheck() const {
 return mInitCheck;
}

Project: Android

ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) {
 if (mInitCheck != OK) {
 return mInitCheck;
 }

 int64_t startTimeUs = ALooper::GetNowUs();

 size_t numBytesRead = 0;
 while (numBytesRead < size) {
 size_t copy = size - numBytesRead;

 if (copy > 64 * 1024) {
            copy = 64 * 1024;
 }

 ssize_t n = mHTTPConnection->readAt(
                offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);

 if (n < 0) {
 return n;
 } else if (n == 0) {
 break;
 }

        numBytesRead += n;
 }

 int64_t delayUs = ALooper::GetNowUs() - startTimeUs;

    addBandwidthMeasurement(numBytesRead, delayUs);

 return numBytesRead;
}

Project: Android

status_t MediaHTTP::reconnectAtOffset(off64_t offset) {
 return connect(mLastURI.c_str(), &mLastHeaders, offset);
}

Project: Android

MediaHTTP::~MediaHTTP() {
    clearDRMState_l();
}