MOBILE

Android Security : Binder Interfaces

10/11/2010 2:06:06 PM
Binder is a kernel device driver that uses Linux’s shared memory feature to achieve efficient, secure IPC. System services are published as Binder interfaces and the AIDL (Android Interface Definition Language) is used not just to define system interfaces, but to allow developers to create their own Binder clients and servers. The terminology can be confusing, but servers generally subclass android.os.Binder and implement the onTransact() method, whereas clients receive a Binder interface as an android.os.IBinder reference and call its transact() method. Both transact() and onTransact() use instances of android.os.Parcel to exchange data efficiently (the native implementation of this Parcel formats data as it is expected by the kernel mode Binder device). Android’s support for Binder includes the interface Parcelable. Parcelable objects can be moved between processes through a Binder.

Under the covers, a Binder reference is a descriptor maintained by the Binder device (which is a kernel mode device driver). Binder IPC can be used to pass and return primitive types, Parcelable objects, file descriptors (which also allows memory maps), and Binders. Having a reference to a Binder interface allows calls to its interface—that is, you can call transact() and have a corresponding call to onTransact() occur on the server side—but this does not guarantee that the service exposing the interface will do what the caller requests. For example, any program can get a reference to the Zygote system service’s Binder and call the method on it to launch an application as some other user, but Zygote will ignore such requests from unauthorized processes.

Binder security has two key ways it can enforce security: by checking the caller’s identity and via Binder reference security.

Security by Caller Permission or Identity Checking

When a Binder interface is called, the identity of the caller is securely provided by the kernel. Android associates the calling application’s identity with the thread on which the request is handled (the application’s UID and its process’s current PID are provided). This allows the recipient to use their Context’s checkCallingPermission(String permission) or checkCallingPermissionOrSelf (String permission) method to validate the caller’s rights. Applications commonly want to enforce permissions they don’t have on callers; therefore, checkCallingPermissionOrSelf(String permission) allows the application to still call itself even if it lacks the normally needed permission. Binder services are free to make other binder calls, but these calls always occur with the service’s own identity (UID and PID) and not the identity of the caller.

Binder services also have access to the caller’s identity using the getCallingUid() and getCallingPid() static methods of the Binder class. These methods return the UID and process identifier (PID) of the process that made the Binder call. The identity information is securely communicated to the implementer of a Binder interface by the kernel. This is similar to how Unix domain sockets can tell you the identity of the caller, or most IPC mechanisms in Win32.

A Binder interface can be implemented a number of ways. The simplest is to use the AIDL compiler to create a Stub class, which you then subclass. Inside the implementations of the methods, the caller is automatically associated with the current thread, so calling Binder.getCallingUid() identifies the caller. Developers who direct requests to handlers or implement their own onTransact() (and forego AIDL) must realize that the identity of the caller is bound to the thread the call was received on and therefore must be determined before switching to a new thread to handle a request. A call to Binder.clearCallingIdentity() will also stop getCallingUid() and getCallingPid() from identifying the caller. Context’s checkPermission(String permission, int pid, int uid) method is useful for performing permission checks, even after the caller’s identity has been cleared by using stored UID and PID values.

Binder Reference Security

Binder references can be moved across a Binder interface. The Parcel.writeStrongBinder() and Parcel.readStrongBinder() methods allow this and provide some security assurances. When reading a Binder reference from a Parcel with readStrongBinder(), the receiver is assured (by the kernel’s Binder driver) that the writer of that Binder had a reference to the received Binder reference. This prevents callers from tricking servers by sending guesses of the numerical value used in the server’s process to represent a Binder the caller doesn’t have.

Getting a reference to a Binder isn’t always possible. (By Binder, I mean a reference to a Binder interface. In Java, this is represented by an android.os.Binder object.) Because servers can tell if callers had a particular Binder, not giving out references to a Binder can effectively be used as a security boundary. Although Zygote might not protect its Binder interfaces from exposure, many Binder objects are kept private. To use reference security, processes need to carefully limit the revealing of Binder objects. Once a process receives a Binder, it can do whatever it likes with it, passing it to others or calling its transact() method.

Binders are globally unique, which means if you create one, nobody else can create one that appears equal to it. A Binder doesn’t need to expose an interface—it might just serve as a unique value. A Binder can be passed between cooperating processes. A service could provide callers a Binder that acts as a key, knowing that only those who receive the key (or had it sent to them) can later send it back. This acts like an unguessable, easily generated password. The Activity Manager uses the reference nature of Binders to control the management of Surfaces and Activities.

Other  
 
Most View
BENQ XL2420TX – It’s The Way To Do 3D
Alternative iOS Browsers for iPad, iPhone and iPod Touch (Part 2)
IBGStar Blood Glucose Meter Kit
How to Buy…A TV TUNER (Part 2)
Windows 8 : Managing User Access and Security - Managing Local User Accounts and Groups (part 2) - Creating Local Groups for Workstations
Sharepoint 2010 : Administering Enterprise Content Management - Document Management (part 8) - Content Type Syndication
Head To Head - Samsung 46ES7000 VS Sony KDL-46HX853 (Part 2)
Optimisation Utility: Ashampoo Winoptimizer 9.0
Windows 7 : Command-Line and Automation Tools - Windows Script Host
CPU Cooler: Corsair Hydro H105
Top 10
New Camera For You – Nikon 1 AW1
Phase One IQ250, Hasselblad H5D-50c - Medium-format Media Systems: Bigger Gets Better
Kaveri APU - AMD A10-7700K
Fujifilm X-M1 – Review April 2014
Fujifilm X-T1 : Good To Go
Dedicated Gaming Monitors BeNQ XL2720Z
Cooler Master HAF Stacker Case
NZXT Phantom 530 – Shiny Case
Hart Audio Evo1 Active Loudspeaker Review (Part 2)
Hart Audio Evo1 Active Loudspeaker Review (Part 1)