Is the interprocess communication provided by Binder in Android protected against man in the middle attacks? Is there any documentation that provides this info?
Binder uses a capability-based security model. Each binder object represents a capability; handing that object to another process grants the process access to that capability. From that perspective, you prevent man in the middle attacks by not handing an important binder object to the man in the middle. If a process doesn't get handed a binder object, it can not access it in any way.
Regarding the "cross-binder reference forgery" issue discussed in the paper, if I am understanding the specific scenario they are talking about, I think their addendum about user space is a little weaker than I would agree with. They make the mistake I think of looking at the special C code written for the ServiceManager. Formally, I would consider the C++ user space code (consisting in particular of Parcel) as being part of the Binder architecture. This code in particular makes sure to deal with such attempts at spoofing when you call its readBinder() and related methods.
I don't agree with the statement that it is a flaw that the kernel is not completely ensuring integrity of the data. The only way I could imagine for it to do that would be to defined a standard typed data structure for binder transactions, so that it could read and verify the contents of the parcel. This puts too much knowledge in the kernel in my opinion, and for no real benefit. No matter how much you put there, user space will need to do some kind of validation of the incoming transaction to ensure it matches its expectations. Today this is done at the level of validating that primitive data read operations on Parcel (readBinder(), readString16(), readInt(), etc) are written to avoid attacks. Pushing more validation to the kernel will still require validation in user space that data types are correct, and now you have actually moved some opportunities for attacks (due to bugs in this code) from user space to the kernel.
One final thing about binder security is that it is important to realize that at the platform level there is another important security model implemented on top of the binder infrastructure. This is the permission/uid-based system, where services can check the uid of incoming calls to verify them against their allowed permissions.
This security model has another spoofing vulnerability that it must deal with. A typical scenario would be an application receiving the IBinder for the Activity Manager Service (since everyone can get that). The API of the Activity Manager Service is deeply based on checking the uid of incoming calls to determine what is allowed -- for example if a call to bindService() is made, it will check to see if that uid has permission to bind to the given service. A malicious app could try to play games here by handing the activity manager IBinder to another system service, for example as an IWindow to the window manager. If it knows the transactions that the second system service will make, it could set things up so that it makes a call that it thinks is say resizeWindow() but actually ends up becoming a call to bindService() when it comes put in the activity manager (if those two calls are mapped to the same transaction ID).
This vulnerability exists because the binder system is not typed in any way, "method" calls are simply transactions being sent with an integer transaction code and data buffer.
To protect against this, the user space typed interfaces generated by aidl always put at the start of their transaction buffer the name of the interface they are intending to call, and the receiving code of the transaction checks the interface name at the front of the buffer to ensure that it matches its own interace. This way the spoofer in the scenario above will be caught when the activity manager sees that it has an incoming call whose interface was for a window.
Anyway, for most practical use by Android developers, uid-based security is just as relevant as the core binder capability model. In some cases you will enforce security by restricting which processes get access to a binder. An example for this would be how there is an IBinder representing each activity, which only the system process and the process running the activity share.
In other cases and IBinder object will be shared with any interested processes, but enforce security at point of call based on uid. If you are using aidl to supply your standard implementation of such interfaces, your own implementation of such security can be done based on what meaning you want to apply to uids. For example, you could use the standard facility to associated permissions with uids and ask the package manager if the incoming uid has a permission.
The Binder has one identified security flaw which may make it susceptible to a MITM attack: http://crypto.hyperlink.cz/files/xbinder.pdf . To quote TFA:
the attacker can manage the target to further pass on or call its “protected” binder (that the attacker is not invited to call directly). We call this a cross-binder reference forgery (XBRF)
The author goes on to say that there are defenses in Android against this attack, but that
in some situations, a careful manipulation with the transaction data prepared by an attacking process may still lead to a successful XBRF exploit
One gets the impression that Binder seems to be relatively secure for carefully-written code, but there is some risk.
Related
Binders are used for Inter(not intra) Process Communication/Remote Method Invocation so why/how the communication between Activity and Service is possible via binders where there are no different processes involvement.
When the very first component of an app is initialized a request to the kernal is triggeres (I think via ActivityManagerService(Native)-AMS > AMN) (running in system_process) for a new process fork if no corresponding process exists. Once the process is created then any other component (say a Service) belongs to the same process unless specified. Now this service wants to communicate to an Activity of the same process. Then why IBinder is one of the option?
Doesn't that violate the underlying principle on which Binders are created?
Interprocess communication is done by writing data to some source such as a socket or pipe, and another process reading it. There's no reason that the same process can't read and write though- it's less efficient than other means of passing data within a process, but it still works.
As for why would you use it in the same process- the alternative would be for Android to have two ways of communicating with services, one way for if they're the same process, and one way for it they aren't. That would complicate things for the framework for minimal gain. It would greatly complicate things for Services where the client may or may not be in the same process (say a service that is used by both the client app and other apps by the same company). So they just use the same method for both.
Binders are intended to be a construct of an IPC - this is true but, if used in the same process to communicate between an Activity and a Service, there is no performance cost, i.e, it is converted into a direct call instead of an RPC.
Don't assume that Binders will only be used for IPC but it is a general purpose communication mechanism in Android.
You won't find this documented normally anywhere. I found it in one of the discussion between Commonsware and Dianne Hackborne(designer of the binder concept in the Android team).
I am wondering if there'll be an extra cost to query the content provider within the same process. I'm aware that the Content Provider is transacting data by the binder, and all the data transition between binder service and binder client will be passing by binder driver in kernel space.
I suspect if it still uses the same approach while we use the content provider in the same process and therefore causes extra overhead such as latency, extra computing...etc.
Here's the scenario - in the multi-process app, you will normally require your storage system to use the binder system to pass data between processes, but at the same time, you will also need to pass data within the same process.
What's the common approach if you have a multiprocess android app? For now, I know a third-party solution MMKV but I am not sure if there's an official solution to avoid this kind of overhead (if it even exists).
I am wondering if there'll be extra cost to query content provider within the same process
There definitely will be overhead incurred by using ContentProvider, compared with simply calling methods on an object. Inter-process communication (IPC) is not free. This is one of the reasons for the complaints about performance of the Storage Access Framework, which relies heavily on ContentProvider.
The fact that the ContentProvider is in the same process as the consumer should not eliminate this overhead.
anyone knows why the Android developers team have implemented the Content-Resolver as a middleman to get data from a Content-Provider. Why not asking data directly from the Content-Provider ?
It means that the Content-Resolver has a special job, what is it ?
Why not asking data directly from the Content-Provider ?
A content: Uri may refer to a ContentProvider in another app. You cannot work with that ContentProvider directly; inter-process communication (IPC) is required. Hence, the API was designed around that IPC model.
ContentResolvers are designed to create an interface for applications to securely access and/or modify data in other applications which run in separate processes. It creates a common contract for content consumer registrations, requests, updates, binding, etc. to be passed between a particular ContentProvider and the content consumer that runs in another process.
Creating a proper and durable interface for transferring data across processes in Android is complex. If you had to create your own IPC client then it would be time consuming and you would likely overlook important aspects of the implementation. A "direct" connection to the ContentProvider is what a ContentResolver provides, but with a lot of the complexity already addressed. It is a convenience to already have that created and well-defined on both sides.
This is a little like a postal delivery system. If you use the postal service, you put an address on a piece of mail and the postal service (ContentResolver) finds the appropriate place to deliver the message (ContentProvider), and then returns any messages to you in response to your message. Your postal service will also handle new address registrations, tell you if the address is invalid, if the package is too big, if the recipient at the destination address is not accepting messages right now, waits if the message queue is full, handles situations where the vehicle carrying the message breaks down, etc. And in the case of ContentResolvers there are a few other things.
You could handle all of that yourself but when you think about real-life message delivery, it's not simple and much easier to use something built by someone else. Likewise for interprocess communication (IPC) in Android. It's not a perfect analogy but hopefully that helps clarify the need for a ContentResolver.
to understand the AIDL in android, i want one real life example, means the at what scenario of development we need to use AIDL.
by reading the Android Docs ... It puts me in confusion and so many question, so it is hard to read whole doc for me, can anyone help me
is it for communicating with outside the phone.
or to communicating with different apps, (why we need to communicate with other apps)
what kind of service they are talking in docs
AIDL is used for Binder. Binder is a mechanism to do RPC calls on/from an Android Service.
When to use AIDL? When you need a Service. When do you need a Service? If you want to share data and control something in another application, you need a service using AIDL as an interface. (A Content Provider is used when sharing data only).
Services can be used within your application as the model roll in the MVC-pattern.
AIDL is Android Interface Definition Language. This basically allows you to do IPC calls.
Use: There are situations where one process would need to talk to other to obtain certain information.
Example: Process A needs info of Call status to determine whether it needs to change Call Type (for example Audio to Video Call or Vice-versa). You may get call status from certain listeners but to change Call type from Audio to Video, Process A needs a hook to change. This "Hook" or way of changing calls is typically part of Telephony Classes which are part of Telephony Process. So in order to obtain such an information from Telephony process, One may write a telephony service (which runs as a part of android telephony process), which will allow you to query or change call type. Since Process A(Client) here is using this remote Service which communicates with Telephony process to alter call type, it needs to have an interface to talk to service. Since Telephony service is the provider, and Process A (client) is the user, they both need to agree on an interface (protocol) they can understand and adhere to. Such an interface is AIDL, which allows you to talk (via a remote service) to Telephony process and get some work done.
Simply put in laymen terms, AIDL is an "agreement" Client gets, which tells it about how to talk to service. Service itself will have a copy of that agreement(since it published for it's clients). Service will then implement details on how it handles once a request arrives or say when someone is talking to it
So process A requests to change call via Service, Service gets the request, it talks to telephony process(since it's part of it) and changes call to video.
An important point to note is, AIDL is only necessary for multithreading environment. You could do away with Binders if you don't need to deal with multithreaded arch.
Another real world example is Google Play License is using AIDL.
I have the same thinking about an example of AIDL, it's very difficult to find an idea to make an example app which uses AIDL. Then I have an idea about it create a LocalLogServerApp. Maybe it can not become a production app but it still shows some value in using AIDL
The main function of this app is
Receive the local log from other local apps (another app need to implement AIDL to send log)
Save the log to datastore
Display the logs
Maybe do something with the local log (eg: search, delete)
Maybe notify developer when error log happened
The benefit of this app
The local log can use when you have some very strange issues which sometimes happened in a few moments and in some specific device. In this case, common Log won't help, debug won't help, Firebase Log may help but Firebase receive log from multiple device.
Reusable, many apps can use it with less code
Hope you find this idea helpful to find another better AIDL example
https://github.com/PhanVanLinh/AndroidLocalLogServer
https://github.com/PhanVanLinh/AndroidLocalLogClientTest
1 - is it for communicating with outside the phone.
Its communicating with outside the app.
2 - or to communicating with different apps, (why we need to communicate with other apps)
As #GodOnScooter mentioned, when your app communicates with telephony service which is actually an other part.
3 - what kind of service they are talking in docs?
This is a service which runs in different process of a system, To bind to this service you need IPC(inter process communication), AIDL is used to implement this.
What is the advantage of using Binder for IPC over (Semaphores , Message Queue, PIPES) in Android stack?
Old question (and likely unmonitored by the poster), but worth answering:
A) All filesystem-based or filesystem-representable IPC mechanisms (notably pipes), can't be used because of a lack of a world-writable directory, where all processes can mkfifo/create the filesystem/socket representation of their IPC port (/dev/socket notwithstanding, which is used for system processes, e.g. rile, zygote, and their ilk).
B) None of the suggested mechanisms have the capability of "service location" which is required for Android. In UNIX, there's an RPC portmapper, and Android needs similar functionality. Enter: The ServiceManager, which can use binder to register as a context manager, to register/lookup service handles on the fly
C) There is an extensive need for serialization - be it intents, or other messages. Binder provides the parcel abstraction, which can be used for data marshaling by the Parcel.java.
D) SysV has other issues than Mr. Lambada's answer which are more paramount, notably race conditions, and lack of authorization.
E) Message queues and pipes can't pass descriptors. UNIX Domain sockets may, but can't be used because of (A) (again, unless you're root/system, like zygote, rild, installd..)
F) Binder is really lightweight, and has built-in authorization mechanisms. It also has nifty features like waking up the recipient process, as well as memory sharing, which the other mechanisms simply don't have. (and remember, no mmap(2), because of the file problem in (A) for named mappings).
and - let's not forget
G) Binder was started at Palm (ah, nostalgia) (q.v. OpenBinder). Ex-palmers got to Android, and brought their code in with them.
From the ndk's docs/system/libc/SYSV-IPC.html file:
Android does not support System V IPCs, i.e. the facilities provided by the following standard Posix headers:
<sys/sem.h> /* SysV semaphores */
<sys/shm.h> /* SysV shared memory segments */
<sys/msg.h> /* SysV message queues */
<sys/ipc.h> /* General IPC definitions */
The reason for this is due to the fact that, by design, they lead to global kernel resource leakage.
For example, 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 explicitly killed.
Killing processes automatically to make room for new ones is an important part of Android's application lifecycle implementation. This means
that, even assuming only non-buggy and non-malicious code, it is very likely that over time, the kernel global tables used to implement SysV IPCs will fill
up.
At that point, strange failures are likely to occur and prevent programs that use them to run properly until the next reboot of the system.
Binders are used to to communicate over process boundaries since different processes don't share a common VM context => no more direct access to each others Objects (memory). Both parties within the same process (usually things that are within the same app) means (imho) that you should not use Binders since they slow down / complexify things unnecessary.
Binders are usually not used directly but rather via the "Service" or the "Messenger" classes. While communication with a Service is done via a full api of functions, the communication with a Messenger has to use "Message"s. Messengers a lot simpler to implement.
Apart from using Binders you can use anything that is available from any VM instance like "LocalSocket"s, Files, ContentProviders, Intents, ...
Binders are not ideal for transferring large data streams (like audio/video) since every object has to be converted to (and back from) a Parcel. All the conversion takes time. Much better in that case would be a LocalSocket for example.
Binders are used to enable remote procedure calls. You could implement RPC using the synchronization tools you mention but you would also need to write a lot of code to make it come together... with a Binder (normally only used within an Android Service) you have much less code to write; barely more than your actual remote functions.