Files
notes/docs/lectures/mdp/08_binders.md
T

5.0 KiB

Binder Principles

IPC - Inter-process communication

An API for IPC does not exist; however, a communication paradigm between separate process components that everything uses at some level does exist

  • Each process has its own address space
    • Provides data isolation
    • Prevents direct interaction between different processes
  • We have to use binders for communication
    • Binder is fundamentally a kernel driver
      • Provides lightweight remote procedure calls (RPC)
      • Reading and writing parcels between processes
    • Per-process thread pools for handling requests
    • Synchronous calls between processes

img

Note: binder is a kernel driver

Ideal IPC

img

This is an idealised abstraction

Binder as Intermediary

img

The client asks the binder driver to do something; it'll then use one of its threads to talk to the service. It needs a thread pool, as if another client makes a request, it needs to be handled sequentially.

All communication is mediated by the binder driver. This is possible because of the privileged position of the kernel in an operating system, e.g. access to kernel space.

Binder Facilities

Calls
  • Simple inter-process messaging system
  • one-way or two-way
Identifying
  • Via PID or UID (user ID)
  • This is down to the privileged position of the kernel
    • Cannot be deceived as it has access to all memory
Notification
  • Link to death
    • Leaked service connections
Managing
  • Reference counting
  • Object mapping across processes
  • Sleeping and waking worker threads
Indirect Functionality
  • Can use a binder object as a globally unique token
  • Sharing a file descriptor to shared memory

Binder Implementation

  • API for apps
    • AIDL
    • Java API Wrapper
      • Exposes the IBinder interface
      • Wraps the middleware layer
      • Parcelable object marshalling interface
  • Native Middleware
    • Implements the user space (within a process) facilities of the Binder framework
    • Marshalling and un-marshalling of specific data to primitives
    • Provides interaction with the Binder kernel driver
  • Kernel Driver
    • Supports ioctl (input/output system controls) from middleware
    • Supports cross-process file operations, memory mapping
    • Thread pool for each service application for IPC
    • Mapping of objects between processes via copy_from_user, copy_to_user

img

/dev/binder - appears as a device, as it's a driver

Binder Transactions

The proxy binder will call IBinder.transact() and then the binder driver will call Binder.onTransact() on the stub

img

Binder maintains a pool of transaction threads in each process

  • To dispatch all IPC coming from other processes

  • If process A calls process B

    • Calling thread in A blocks in transact()
    • Sends the transaction to process B
    • Next available thread in process B receives the incoming transaction, calls onTransact() on the target object, replies with the resultant parcel
    • Thread in process A returns, resumes execution
  • Reliant on Service B responding in a timely manner

    • Hence catching remote exceptions & transaction failures
    • Developer-defined worker threads
    • Handling multiple calls from multiple transaction threads

Proxy object that's making the transact call and the stub object that makes the onTransact() call.

img

IPC Abstractions

Intent
  • Highest-level abstraction
  • Asynchronous message passing
    • Messenger
Inter-process method invocation
  • AIDL
Binder
  • Kernel Driver

img

Binder Security

Binder doesn't deal with security

  • Enables a trusted execution environment
  • Transactions via the kernel
    • Client identity is managed by the kernel
      • Binder.getCallingUid(), Binder.getCallingPid()
  • Access controlled in two ways:
    1. Limit who can obtain a reference to a binder object
      • Interface reference security
      • Client cannot guess address of a service
        • The binder driver knows who has knowledge of which objects
    2. Check caller identity before performing an action on the binder objects
      • Service asks package number manager about UID permissions
      • Check whether it holds a permission we want to enforce via PackageManager.getPackageInfo(...)

Binder Performance

Explicit limitations
  • Transactional buffer size 1 Mb per process for all concurrent transactions in a process
    • Many moderately sized transactions could exhaust its limit
      • Arguments and return values are too large
    • Keep transaction data small
Implicit Limitation
  • Data is copied
    • Duplication of memory resources
  • Native binary marshalling
    • Better than reflection-based serialisation
    • Still has overhead of parcel marshalling
  • Not ideal for large data streams
    • You wouldn't want to pass videos through bundles
    • Instead, we pass file descriptors to shared memory regions