Commit message: None
CVE: CVE-2016-0829
CWE: CWE-254
Vulnerability description: The BnGraphicBufferProducer::onTransact function in libs/gui/IGraphicBufferConsumer.cpp in mediaserver in Android 4.x before 4.4.4, 5.x before 5.1.1 LMY49H, and 6.x before 2016-03-01 does not initialize a certain output data structure, which allows attackers to obtain sensitive information, and consequently bypass an unspecified protection mechanism, by triggering a QUEUE_BUFFER action, as demonstrated by obtaining Signature or SignatureOrSystem access, aka internal bug 26338109.

Project: Android

 virtual status_t connect(const sp<IBinder>& token,
 int api, bool producerControlledByApp, QueueBufferOutput* output) {
 Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeStrongBinder(token);
        data.writeInt32(api);
        data.writeInt32(producerControlledByApp);
 status_t result = remote()->transact(CONNECT, data, &reply);
 if (result != NO_ERROR) {
 return result;
 }
        memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
        result = reply.readInt32();
 return result;
 }

Project: Android

 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
 Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(async);
        data.writeInt32(w);
        data.writeInt32(h);
        data.writeInt32(format);
        data.writeInt32(usage);
 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
 if (result != NO_ERROR) {
 return result;
 }
 *buf = reply.readInt32();
 bool nonNull = reply.readInt32();
 if (nonNull) {
 *fence = new Fence();
            reply.read(**fence);
 }
        result = reply.readInt32();
 return result;
 }

Project: Android

status_t IGraphicBufferProducer::QueueBufferInput::flatten(
 void*& buffer, size_t& size, int*& fds, size_t& count) const
{
 if (size < getFlattenedSize()) {
 return NO_MEMORY;
 }
 FlattenableUtils::write(buffer, size, timestamp);
 FlattenableUtils::write(buffer, size, isAutoTimestamp);
 FlattenableUtils::write(buffer, size, crop);
 FlattenableUtils::write(buffer, size, scalingMode);
 FlattenableUtils::write(buffer, size, transform);
 FlattenableUtils::write(buffer, size, async);
 return fence->flatten(buffer, size, fds, count);
}

Project: Android

 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
 Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(bufferIdx);
 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
 if (result != NO_ERROR) {
 return result;
 }
 bool nonNull = reply.readInt32();
 if (nonNull) {
 *buf = new GraphicBuffer();
            reply.read(**buf);
 }
        result = reply.readInt32();
 return result;
 }

Project: Android

status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
 void const*& buffer, size_t& size, int const*& fds, size_t& count)
{
 size_t minNeeded =
 sizeof(timestamp)
 + sizeof(isAutoTimestamp)
 + sizeof(crop)
 + sizeof(scalingMode)
 + sizeof(transform)
 + sizeof(async);

 if (size < minNeeded) {
 return NO_MEMORY;
 }

 FlattenableUtils::read(buffer, size, timestamp);
 FlattenableUtils::read(buffer, size, isAutoTimestamp);
 FlattenableUtils::read(buffer, size, crop);
 FlattenableUtils::read(buffer, size, scalingMode);
 FlattenableUtils::read(buffer, size, transform);
 FlattenableUtils::read(buffer, size, async);

    fence = new Fence();
 return fence->unflatten(buffer, size, fds, count);
}