This BJUG presentation is focused on the unique inter-process communication (IPC) mechanism introduced by Android, namely Binder. As such, we will be exploring the entire Android software stack, starting from the Linux kernel, moving up to the Linux userspace, reaching the Android framework and ending our journey with some real-life usages of Binder in Android applications.
We will show how widely used Binder actually is in Android, thus proving that it is a cornerstone of the operating system. The main focus is on the programming model exposed towards developers and we will highlight when, how and why it should be used.
https://bjug.ro/binding-android-piece-by-piece/
8. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Hiccup #1
Linux: process-unit component model
Security: each process is sandboxed
and run under a distinct system identity
Stability: if a process misbehaves (i.e.
crashes), it does not affect other
processes
Memory management: unneeded
processes are removed to free resources
(mainly memory)
Inter-process communication = ?
9. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Hiccup #1
Linux: process-unit component model
Security: each process is sandboxed
and run under a distinct system identity
Stability: if a process misbehaves (i.e.
crashes), it does not affect other
processes
Memory management: unneeded
processes are removed to free resources
(mainly memory)
Inter-process communication = sharing data across multiple
and commonly specialized processes using communication
protocols
10. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Android IPC
Android does not support System V IPCs (Posix):
1 SysV semaphores
2 SysV shared memory segments
3 SysV message queues
Why not?
1 they lead to global kernel resource leakage, i.e. there is no
way to automatically release a SysV semaphore allocated
in the kernel when:
a buggy or malicious process exits
a non-buggy and non-malicious process crashes or is
explicitely killed.
2 Killing processes automatically to make room for new ones
is an important part of Android’s application lifecycle
implementation
We can’t ignore potential malicious applications.
11. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Android IPC
So what’s left?
UNIX domain sockets
has support directly in the init process
used for low level services (e.g. ril)
file based, need a shared folder
no support in Java
TCP/IP sockets
not really useful for IPC
cannot use it internally in the software stack (does not
pass CTS)
pipes
does not support RPC calls
Files (including memory mapped files)
but what about small data?
relatively small support in Java
12. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
OpenBinder
Started at Be, Inc as a part of the Next generation BeOS
(2001)
Acquired by Palm
First real implementation in Palm Cobalt OS
(micro-kernel)
Palm switches to Linux, so does OpenBinder (2005)
Key lead engineer, Dianne Hackborn, hired by Google
(along most other engineers)
Re-written from scratch for Android, as Binder (2008)
OpenBinder dies, Binder lives!
13. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
What is Binder anyway?
IPC mechanism/system used for developing object
oriented system services over traditional kernels
built-in reference counting of object references (across
processes)
death-notification mechanism
built-in support for marshalling many common data types
ability to send file descriptors across processes
methods on remote objects can be invoked as if they were
local
local execution mode if client and service are in the same
process (no overhead whatsoever)
simplified APIs (especially for Java)
focused on scalability, stability, flexibility, low-latency, easy
to use
15. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
What is Binder used for?
Dianne Hackborn:
package manager, telephony manager, app widgets, audio
services, search manager, location manager, notification
manager, accessibility manager, connectivity manager, wifi
manager, input method manager, clipboard, status bar, window
manager, sensor service, alarm manager, content service,
activity manager, power manager, surface compositor
16. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Binder controversy
That must have hurt
Most of these questions related to the fact that I don’t think an interface
like this just slips into the kernel as a driver. Since it’s IPC, it’s totally
generic, and it’s not part of a standard (i.e. POSIX), we need to have
some better and more specific information about it (or at least I do)
Didn’t see that one coming
If for instance the main reason for Google using this interface is cause
a large number of android people once worked at Palm or BeOS, that’s
not reason enough for it to go into the kernel. Or if this binder interface
really fits well with Java or C++ people and they just love it, that’s not
really acceptable either..
18. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Down in the Linux kernel
driver to facilitate IPC:
$ adb s h e l l
s h e l l @ a n d r o i d :/ $ l s −l / dev / | grep b i n d e r
crw−rw−rw− root root 10 , 49 2015−09−07 20:23 b i n d e r
s h e l l @ a n d r o i d :/ $ cat / s y s / d e v i c e s / v i r t u a l / misc / b i n d e r / uevent
MAJOR=10
MINOR=49
DEVNAME=b i n d e r
supports: open, mmap, release, poll, and ioctl
key command - ioctl (sending commands and data):
BINDER WRITE READ
BINDER SET MAX THREADS
BINDER SET CONTEXT MGR
BINDER THREAD EXIT
BINDER VERSION
multi-thread aware (status per thread)
21. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
token address 0 (well-known address)
must be started before anything else
other processes use it find services → Mediator pattern
22. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
$ adb s h e l l
s h e l l @ a n d r o i d :/ $ s e r v i c e l i s t
Found 75 s e r v i c e s :
0 s i p : [ android . net . s i p . I S i p S e r v i c e ]
1 phone : [ com . android . i n t e r n a l . telephony . ITelephony ]
2 i p h o n e s u b i n f o : [ com . android . i n t e r n a l . telephony . IPhoneSubInfo ]
3 simphonebook : [ com . android . i n t e r n a l . telephony . IIccPhoneBook ]
4 isms : [ com . android . i n t e r n a l . telephony . ISms ]
5 p i e s e r v i c e : [ android . s e r v i c e . p i e . I P i e S e r v i c e ]
[ . . . ]
s h e l l @ a n d r o i d :/ $ dumpsys media . camera
Camera module HAL API v e r s i o n : 0x100
Camera module API v e r s i o n : 0x100
Camera module name : Exynos Camera
Camera module author : Paul Kocialkowski
Number of camera d e v i c e s : 2
Camera 0 s t a t i c i n f o r m a t i o n :
Facing : BACK
O r i e n t a t i o n : 90
Device v e r s i o n : 0x100
Device i s closed , no c l i e n t i n s t a n c e
Camera 1 s t a t i c i n f o r m a t i o n :
Facing : FRONT
O r i e n t a t i o n : 270
Device v e r s i o n : 0x100
Device i s closed , no c l i e n t i n s t a n c e
No a c t i v e camera c l i e n t s yet .
23. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
Simple inter process messaging system
In an object oriented view, the transaction data is called
parcel.
The procedure of building a parcel is called marshalling an
object.
The procedure of rebuilding a object from a parcel is
called unmarshalling an object.
24. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
c l a s s IServiceManager : p u b l i c I I n t e r f a c e
{
p u b l i c :
DECLARE META INTERFACE( ServiceManager ) ;
v i r t u a l sp<IBinder> g e t S e r v i c e ( const S t r i n g 1 6& name) const = 0;
v i r t u a l sp<IBinder> c h e c k S e r v i c e ( const S t r i n g 1 6& name) const = 0;
v i r t u a l Vector<String16> l i s t S e r v i c e s () = 0;
};
c l a s s BnServiceManager : p u b l i c BnInterface<IServiceManager>
{
p u b l i c :
v i r t u a l s t a t u s t onTransact ( u i n t 3 2 t code ,
const P a r c e l& data ,
P a r c e l ∗ r e p l y ,
u i n t 3 2 t f l a g s = 0) ;
};
methods are purely virtual → Proxy pattern
25. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
enum {
GET SERVICE TRANSACTION = I B i n d e r : : FIRST CALL TRANSACTION ,
CHECK SERVICE TRANSACTION ,
ADD SERVICE TRANSACTION ,
LIST SERVICES TRANSACTION ,
};
c l a s s BpServiceManager : p u b l i c BpInterface<IServiceManager> {
p u b l i c :
v i r t u a l sp<IBinder> g e t S e r v i c e ( const S t r i n g 1 6& name) const
{
P a r c e l data , r e p l y ;
data . w r i t e I n t e r f a c e T o k e n ( IServiceManager : : g e t I n t e r f a c e D e s c r i p t o r () ) ;
data . w r i t e S t r i n g 1 6 (name) ;
remote ()−>t r a n s a c t (CHECK SERVICE TRANSACTION , data , &r e p l y ) ;
r e t u r n r e p l y . readStrongBinder () ;
}
26. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
s t a t u s t BnServiceManager : : onTransact (
u i n t 3 2 t code , const P a r c e l& data , P a r c e l ∗ r e p l y , u i n t 3 2 t f l a g s ) {
switch ( code ) {
case GET SERVICE TRANSACTION : {
CHECK INTERFACE( IServiceManager , data , r e p l y ) ;
S t r i n g 1 6 which = data . r e a d S t r i n g 1 6 () ;
sp<IBinder> b = c o n s t c a s t<BnServiceManager∗>( t h i s )−>
g e t S e r v i c e ( which ) ;
r e p l y−>w r i t e S t r o n g B i n d e r ( b ) ;
r e t u r n NO ERROR;
} break ;
[ . . . ]
}
v i r t u a l sp<IBinder> g e t S e r v i c e ( const S t r i n g 1 6& name) const
{
unsigned n ;
f o r ( n = 0; n < 5; n++){
sp<IBinder> svc = c h e c k S e r v i c e (name) ;
i f ( svc != NULL) r e t u r n svc ;
ALOGI( ” Waiting f o r s e r v i c e %s . . . n” , S t r i n g 8 (name) . s t r i n g () ) ;
s l e e p (1) ;
}
r e t u r n NULL ;
}
IMPLEMENT META INTERFACE( ServiceManager , ” android . os . IServiceManager ” ) ;
}
27. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Moving up to the Linux userspace
$ adb s h e l l
s h e l l @ a n d r o i d :/ $ s e r v i c e c a l l −h
s e r v i c e : No s e r v i c e s p e c i f i e d f o r c a l l
Usage : s e r v i c e [−h|−?]
s e r v i c e l i s t
s e r v i c e check SERVICE
s e r v i c e c a l l SERVICE CODE [ i32 INT | s16 STR] . . .
Options :
i32 : Write the i n t e g e r INT i n t o the send p a r c e l .
s16 : Write the UTF−16 s t r i n g STR i n t o the send p a r c e l .
10| s h e l l @ a n d r o i d :/ $ s e r v i c e c a l l phone 2 s16 ”123456”
R e s u l t : P a r c e l (00000000 ’ . . . . ’ )
130| s h e l l @ a n d r o i d :/ $ pm l i s t packages | head
package : android
package : at . spardat . bcrmobile
package : com . adobe . r e a d e r
package : com . andrew . a p o l l o
package : com . android . backupconfirm
package : com . android . b l u e t o o t h
package : com . android . browser
package : com . android . c a l c u l a t o r 2
package : com . android . c a l e n d a r
package : com . android . c e l l b r o a d c a s t r e c e i v e r
28. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Reaching the Android framework
JNI wrappers over C++ APIs → Bridge pattern
wraps the entire middleware
exposed mainly through AIDL, but low-level APIs can be
called
all service references through from APIs are implemented
through AIDL / Binder
all interactions with the Android framework are mediated
through Binder (e.g. activity callbacks: onCreate,
onResume etc)
30. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Reaching the Android framework - AIDL
eases the implementation of Android remote services
defines a Java-like interface for such remote services
fully automated: parser generates Java classes:
Proxy class for client
Stub class exposed by a Service through onBind
allows sending: primitive data types, basic containers,
compound data types (i.e. Parcelable), Binder objects
etc.
paramater direction: in, out, inout
allows oneway (asynchronous calls)
33. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Why use it?
a more object-oriented approach for application
architectures
complicated business logic → message passing is
insufficient
strong coupling between Service and Activity
decoupling control logic from UI → allow customers to
create own UI by exposing an AIDL interface
better suited for engines, middlewares, frameworks etc.
34. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Step 1: define an AIDL interface
i n t e r f a c e ISecondary {
/∗∗
∗ Request the PID of t h i s s e r v i c e , to do e v i l t h i n g s with i t .
∗/
i n t getPid () ;
/∗∗
∗ This demonstrates the b a s i c types that you can use as parameters
∗ and r e t u r n v a l u e s i n AIDL .
∗/
void basicTypes ( i n t anInt , long aLong , boolean aBoolean , f l o a t aFloat ,
double aDouble , S t r i n g a S t r i n g ) ;
}
35. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Step 2: provide Stub implementation
p r i v a t e f i n a l ISecondary . Stub mSecondaryBinder = new ISecondary . Stub () {
p u b l i c i n t getPid () {
r e t u r n Process . myPid () ;
}
p u b l i c void basicTypes ( i n t anInt , long aLong , boolean aBoolean ,
f l o a t aFloat , double aDouble , S t r i n g a S t r i n g ) {
// do something with the data here
}
};
36. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Step 3: export it through a Service
@Override
p u b l i c I B i n d e r onBind ( I n t e n t i n t e n t ) {
// S e l e c t the i n t e r f a c e to r e t u r n . I f your s e r v i c e only implements
// a s i n g l e i n t e r f a c e , you can j u s t r e t u r n i t here without checking
// the I n t e n t .
i f ( IRemoteService . c l a s s . getName () . e q u a l s ( i n t e n t . getAction () ) ) {
r e t u r n mBinder ;
}
i f ( ISecondary . c l a s s . getName () . e q u a l s ( i n t e n t . getAction () ) ) {
r e t u r n mSecondaryBinder ;
}
r e t u r n n u l l ;
}
<s e r v i c e android : name=” . app . RemoteService ” android : p r o c e s s=” : remote ”>
<i n t e n t−f i l t e r >
<!−− These are the i n t e r f a c e s supported by the s e r v i c e , which
you can bind to . −−>
<a c t i o n
android : name=”com . example . android . a p i s . app . IRemoteService ”
/>
<a c t i o n android : name=”com . example . android . a p i s . app . ISecondary ”
/>
<a c t i o n
android : name=”com . example . android . a p i s . app . REMOTE SERVICE”
/>
</i n t e n t−f i l t e r >
</s e r v i c e >
37. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Step 4: Create a ServiceConnection
ISecondary mSecondaryService = n u l l ;
S e r v i c e C o n n e c t i o n mSecondaryConnection = new S e r v i c e C o n n e c t i o n () {
p u b l i c void onServiceConnected ( ComponentName className ,
I B i n d e r s e r v i c e ) {
mSecondaryService = ISecondary . Stub . a s I n t e r f a c e ( s e r v i c e ) ;
// s t a r t using mSecondaryService
}
p u b l i c void on S e rv i c e Di s c on n e c te d ( ComponentName className ) {
mSecondaryService = n u l l ;
}
};
38. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Step 5: Bind/Unbind the Service
boolean mIsBound = f a l s e ;
@Override
p u b l i c void onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {
[ . . . ]
b i n d S e r v i c e ( new I n t e n t ( ISecondary . c l a s s . getName () ) ,
mSecondaryConnection , Context . BIND AUTO CREATE) ;
mIsBound = t r u e ;
}
@Override
p u b l i c void onDestroy () {
[ . . . ]
i f ( mIsBound ) {
u n b i n d S e r v i c e ( mSecondaryConnection ) ;
}
}
39. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Using a Local Binder:
p u b l i c c l a s s MyLocalService extends S e r v i c e {
I B i n d e r mBinder = new LocalBinder () ;
@Override
p u b l i c I B i n d e r onBind ( I n t e n t i n t e n t ) {
r e t u r n mBinder ;
}
p u b l i c c l a s s LocalBinder extends Binder {
p u b l i c MyLocalService g e t I n s t a n c e () {
r e t u r n MyLocalService . t h i s ;
}
}
p u b l i c void myPulicMethod {
// do something
}
}
[ . . . ]
p u b l i c void onServiceConnected ( ComponentName name , I B i n d e r s e r v i c e ) {
mIsBound = t r u e ;
LocalBinder mLocalBinder = ( LocalBinder ) s e r v i c e ;
mLocalService = mLocalBinder . g e t I n s t a n c e () ;
}
40. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Sending complex data types (1):
p u b l i c c l a s s MyData implements P a r c e l a b l e {
p r i v a t e S t r i n g myString ;
p r i v a t e i n t myInt ;
p u b l i c MyData( S t r i n g myString , i n t myInt ){
t h i s . myString = myString ;
t h i s . myInt = myInt ;
}
p r i v a t e MyData( P a r c e l i n ){
t h i s . myString = i n . r e a d S t r i n g () ;
t h i s . myInt = i n . r e a d I n t () ;
}
@Override
p u b l i c void writeToParcel ( P a r c e l dest , i n t f l a g s ) {
dest . w r i t e S t r i n g ( myString ) ;
dest . w r i t e I n t ( myInt ) ;
}
p u b l i c s t a t i c f i n a l P a r c e l a b l e . Creator CREATOR = new
P a r c e l a b l e . Creator () {
p u b l i c MyData createFromParcel ( P a r c e l i n ) {
r e t u r n new MyData( i n ) ;
}
p u b l i c MyData [ ] newArray ( i n t s i z e ) {
r e t u r n new Student [ s i z e ] ;
}
};
}
41. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Sending complex data types (2):
specify direction in AIDL:
i n t e r f a c e IMyData {
void send ( i n o u t MyData myData ) ;
}
create parcelable AIDL file:
package my . package ;
p a r c e l a b l e MyData ;
42. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A simple example
Passing Binders through Binder:
i n t e r f a c e IRemoteService {
/∗∗
∗ Often you want to a l l o w a s e r v i c e to c a l l back to i t s c l i e n t s .
∗ This shows how to do so , by r e g i s t e r i n g a c a l l b a c k i n t e r f a c e with
∗ the s e r v i c e .
∗/
void r e g i s t e r C a l l b a c k ( I R e m o t e S e r v i c e C a l l b a c k cb ) ;
/∗∗
∗ Remove a p r e v i o u s l y r e g i s t e r e d c a l l b a c k i n t e r f a c e .
∗/
void u n r e g i s t e r C a l l b a c k ( I R e m o t e S e r v i c e C a l l b a c k cb ) ;
}
oneway i n t e r f a c e I R e m o t e S e r v i c e C a l l b a c k {
/∗∗
∗ C a l l e d when the s e r v i c e has a new v a l u e f o r you .
∗/
void valueChanged ( i n t v a l u e ) ;
}
API level ≥ 16 → can send Binders through Bundle (must manually
take care of ownership)
43. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
Specs:
1 a middleware for sensing, acquiring and storing contextual
data
2 what is context? anything measurable from the
environment
3 must enforce transparency (MVC architecture)
4 must enforce a stable and extensible API
5 must restrict contextual collectors by permissions
6 must manage the lifetime of collectors
7 must export data to other Android applications
8 must recognize collectors from any allowed application
on-the-fly
44. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
ICollector.aidl:
package ro . pub . acs . hyccups . c o l l e c t o r ;
import ro . pub . acs . hyccups . c o l l e c t o r . I c o n I n f o ;
i n t e r f a c e I C o l l e c t o r {
S t r i n g name () ;
I n t e n t view () ;
I c o n I n f o icon () ;
void s t a r t () ;
void stop () ;
}
package ro . pub . acs . hyccups . c o l l e c t o r ;
p a r c e l a b l e I c o n I n f o ;
45. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
Exposing a collector:
<p r o v i d e r
android : name=” . c o l l e c t o r s . memory . Model”
android : a u t h o r i t i e s=” ro . pub . acs . hyccups . t r a c e r . p r o v i d e r . memory”
android : exported=” t r u e ”
android : w r i t e P e r m i s s i o n=” ro . pub . acs . hyccups . p e r m i s s i o n . WRITE COLLECTOR DATA”
/>
<a c t i v i t y android : name=” . c o l l e c t o r s . memory . Viewer ”
android : icon=” @drawable /memory”>
<meta−data
android : name=” a u t h o r i t y ”
android : v a l u e=” ro . pub . acs . hyccups . t r a c e r . p r o v i d e r . memory” />
</a c t i v i t y >
<s e r v i c e
android : name=” . c o l l e c t o r s . memory . C o n t r o l l e r ”
android : exported=” f a l s e ”
android : p r o c e s s=” : t r a c e r ” >
<i n t e n t−f i l t e r >
<a c t i o n android : name=” ro . pub . acs . hyccups . c o l l e c t o r . I C o l l e c t o r ” />
<category android : name=” android . i n t e n t . category .DEFAULT” />
</i n t e n t−f i l t e r >
</s e r v i c e >
46. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
Binding anything appropriate:
f i n a l L i s t l i s t = new L i s t () ;
j a v a . u t i l . L i s t<R e s o l v e I n f o> i n f o s =
context . getPackageManager () . q u e r y I n t e n t S e r v i c e s (
new I n t e n t ( I C o l l e c t o r . c l a s s . getName () ) ,
PackageManager .MATCH DEFAULT ONLY) ;
f i n a l CountDownLatch b a r r i e r = new CountDownLatch ( i n f o s . s i z e () ) ;
f o r ( R e s o l v e I n f o i n f o : i n f o s ) {
// I n s t a n t i a t e a l l c o l l e c t o r s
new C o l l e c t o r ( context , info , new Requester () {
@Override
p u b l i c void o n F a i l e d ( S e r v i c e I n f o i n f o ) {
l i s t . f a i l e d ( i n f o ) ;
b a r r i e r . countDown () ;
}
@Override
p u b l i c void onDisconnected ( C o l l e c t o r c o l l e c t o r ) {
l i s t . remove ( c o l l e c t o r ) ;
}
@Override
p u b l i c void onConnected ( C o l l e c t o r c o l l e c t o r ) {
// I f the c o l l e c t o r s u c c e s s f u l l y connects , i t adds i t s e l f to the l i s t
l i s t . add ( c o l l e c t o r ) ;
b a r r i e r . countDown () ;
}
}) ;
}
49. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
Exposing additional functionality (1):
i n t e r f a c e IEngine {
void r e g i s t e r ( IChannel channel ) ;
void u n r e g i s t e r ( IChannel channel ) ;
void forward ( IChannel channel , i n o u t MessageWrapper message ) ;
void d i s s e m i n a t e ( IChannel channel , i n o u t MessageWrapper message ) ;
}
i n t e r f a c e IChannel {
S t r i n g getName () ;
oneway void o n R e g i s t e r e d () ;
oneway void onDisconnected ( S t r i n g e r r o r ) ;
oneway void onPeerConnected ( i n o u t Peer peer ) ;
oneway void onPeerDisconnected ( i n o u t Peer peer ) ;
oneway void onMessageReceived ( i n o u t MessageWrapper message ) ;
oneway void onDisseminationReceived ( i n o u t MessageWrapper message ) ;
}
50. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
A highly available middleware for context
acquisition
Exposing additional functionality (2):
<s e r v i c e
android : name=” . c o l l e c t o r s . o p p o r t u n i s t i c . C o n t r o l l e r ”
android : exported=” f a l s e ”
android : p r o c e s s=” : t r a c e r ” >
<i n t e n t−f i l t e r >
<a c t i o n android : name=” ro . pub . acs . hyccups . c o l l e c t o r . I C o l l e c t o r ” />
<category android : name=” android . i n t e n t . category .DEFAULT” />
</i n t e n t−f i l t e r >
<i n t e n t−f i l t e r >
<a c t i o n android : name=” ro . pub . acs . hyccups . o p p o r t u n i s t i c . IEngine ” />
<category android : name=” android . i n t e n t . category .DEFAULT” />
</i n t e n t−f i l t e r >
</s e r v i c e >
<s e r v i c e
android : name=” . c o l l e c t o r s . o p p o r t u n i s t i c . C o n t r o l l e r $ T r a c i n g C h a n n e l ”
android : exported=” f a l s e ”
android : p r o c e s s=” : t r a c e r ” >
<i n t e n t−f i l t e r >
<a c t i o n android : name=” ro . pub . acs . hyccups . o p p o r t u n i s t i c . IHost ” />
<category android : name=” android . i n t e n t . category .DEFAULT” />
</i n t e n t−f i l t e r >
</s e r v i c e >
52. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Exploit #1
Keylogger (Binder in the middle attack):
Binder service tokens were allocated incrementally
Attacker would identify the desired service token and kill
it’s process (InputManagerService)
Before the service would have time to recover → register
an infected version with the same token number
All input would then pass through the attacker’s code
Fixed by allocating token numbers randomly (still not
impossible for hackers).
53. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Exploit #2
Playing with in app data:
hack the linker to bypass binder flow and read buffers (on
rooted device)
programmers send sensitive data through Binder (between
Activities)
hacker reads the sensitive data by parsing the
command/reply buffer
hacker decompiles application to see how data is used
hacker uses non-privileged Binder call back into the
application using the sensitive data
Fixes:
nothing much that Android can do in this situation
programmers should always obfuscate their code (make life
harder for hackers)
programmers should never send sensitive data in the clear
over Binder (rather have overhead than security breach)
54. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Improvements
Binder is not yet a stable API and keeps on evolving
Currently uses SELinux for securing Binder calls
Does not block all cores when carrying out Binder
transaction (initial designs did...)
Rumours about switching to ADSP
56. Java User
Group
Radu Marin
Introduction
Implementation
Learn by doing
Improvements
Conclusions
Conclusions
Good:
unique IPC mechanism supporting object oriented system
services over traditional kernels (i.e. Linux)
extends Linux with the ability to send file descriptors
across processes
optimized for both local and remote execution; native
binary marshalling
simplified, object-oriented APIs
focused on scalability, stability, flexibility, low-latency, easy
to use
Bad:
ioctl() path is not optimal
Use it wisely and only when needed!
Never send sensitive data through Binder!