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
Thermaltake Toughpower Grand PLATINUM 700W
Samsung Chromebook - Is It Worth The Value Equation (Part 2)
Windows Vista : Windows PowerShell (part 1) - CmdLets and Aliases, Pipelines
Group Test: Which Are The Best Cases On The Market? (Part 3) - Silverstone Fortress FT03 Elysium
Manage Add-Ons For Internet Explorer (Part 1)
The Jaguar F-Type Coupe – Staggeringly Pretty (Part 3)
DirectX 10 Game Programming : 3D Introduction - Vertex Buffers
Thermalright Macho Rev.A - Take The Low Noise Crown
Evercool Silent Shark CPU Cooler Review (Part 1)
Not Bad For A Monkey (Part 2)
Top 10
Review : Garmin Fenix 2
Middle-earth: Shadow Of Mordor
Review : Leica V-Lux (Typ 114)
Review : Apple iPad Air 2
Review : Apple iMac with Retina 5K display
Review : Toshiba Satellite L50-B
Review : HP Stream 11
Review : Acer Chromebook 13
Using Exchange Server 2010 Antispam Tools (part 6) - Sender Reputation
Using Exchange Server 2010 Antispam Tools (part 5) - Sender Filtering, Sender ID