Skip to content

Commit fe350cf

Browse files
authoredOct 25, 2024··
Update error codes doc for new "Safer Intent" rules. (#11639)
1 parent 0b2c17d commit fe350cf

File tree

1 file changed

+40
-32
lines changed

1 file changed

+40
-32
lines changed
 

‎documentation/android-binderchannel-status-codes.md

+40-32
Original file line numberDiff line numberDiff line change
@@ -27,69 +27,76 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
2727
</td>
2828
<td><a href="https://developer.android.com/training/package-visibility">Server app not visible</a>.
2929
</td>
30-
<td rowspan="6" >bindService() returns false
30+
<td rowspan="7" >bindService() returns false
3131
</td>
32-
<td rowspan="9" ><p>UNIMPLEMENTED<p>“The operation is not implemented or is not supported / enabled in this service.”
32+
<td rowspan="10" ><p>UNIMPLEMENTED<p>“The operation is not implemented or is not supported / enabled in this service.”
3333
</td>
3434
<td>Give up - This is an error in the client manifest.
3535
</td>
3636
</tr>
3737
<tr>
3838
<td>1
3939
</td>
40-
<td>Server app not installed
40+
<td>
41+
<a href="https://developer.android.com/about/versions/15/behavior-changes-15#safer-intents">Safer Intents</a> violation.
4142
</td>
4243
<td rowspan="8" >Direct the user to install/reinstall the server app.
4344
</td>
4445
</tr>
4546
<tr>
4647
<td>2
4748
</td>
48-
<td>Old version of the server app doesn’t declare the target android.app.Service in its manifest.
49+
<td>Server app not installed
4950
</td>
5051
</tr>
5152
<tr>
5253
<td>3
5354
</td>
54-
<td>Target android.app.Service is disabled
55+
<td>Old version of the server app doesn’t declare the target android.app.Service in its manifest.
5556
</td>
5657
</tr>
5758
<tr>
5859
<td>4
5960
</td>
60-
<td>The whole server app is disabled
61+
<td>Target android.app.Service is disabled
6162
</td>
6263
</tr>
6364
<tr>
6465
<td>5
6566
</td>
66-
<td>Server app predates <a href="https://developer.android.com/guide/topics/permissions/overview">the Android M permissions model</a> and the user must review and approve some newly requested permissions before it can run.
67+
<td>The whole server app is disabled
6768
</td>
6869
</tr>
6970
<tr>
7071
<td>6
7172
</td>
73+
<td>Server app predates <a href="https://developer.android.com/guide/topics/permissions/overview">the Android M permissions model</a> and the user must review and approve some newly requested permissions before it can run.
74+
</td>
75+
</tr>
76+
<tr>
77+
<td>7
78+
</td>
7279
<td>Target android.app.Service doesn’t recognize grpc binding Intent (old version of server app?)
7380
</td>
7481
<td>onNullBinding() ServiceConnection callback
7582
</td>
7683
</tr>
7784
<tr>
78-
<td>7
85+
<td>8
7986
</td>
8087
<td>Method not found on the io.grpc.Server (old version of server app?)
8188
</td>
8289
<td rowspan="2" >N/A
8390
</td>
8491
</tr>
8592
<tr>
86-
<td>8
93+
<td>9
8794
</td>
8895
<td>Request cardinality violation (old version of server app expects unary rather than streaming, say)
8996
</td>
9097
</tr>
9198
<tr>
92-
<td>9
99+
<td>10
93100
</td>
94101
<td>Old version of the server app exposes target android.app.Service but doesn’t android:export it.
95102
</td>
@@ -102,37 +109,37 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
102109
</td>
103110
</tr>
104111
<tr>
105-
<td>10
112+
<td>11
106113
</td>
107114
<td>Target android.app.Service requires an &lt;android:permission&gt; that client doesn’t hold.
108115
</td>
109116
<td>Prompt the user to grant the needed Android permission
110117
</td>
111118
</tr>
112119
<tr>
113-
<td>11
120+
<td>12
114121
</td>
115122
<td>Violations of the security policy for miscellaneous Android features like android:isolatedProcess, android:externalService, android:singleUser, instant apps, BIND_TREAT_LIKE_ACTIVITY, etc,
116123
</td>
117124
<td rowspan="3" >Give up - This is a programming or packaging error that only the app developer can fix.
118125
</td>
119126
</tr>
120127
<tr>
121-
<td>12
128+
<td>13
122129
</td>
123130
<td>Calling Android UID not allowed by ServerSecurityPolicy
124131
</td>
125132
<td rowspan="2" >N/A
126133
</td>
127134
</tr>
128135
<tr>
129-
<td>13
136+
<td>14
130137
</td>
131138
<td>Server Android UID not allowed by client’s SecurityPolicy
132139
</td>
133140
</tr>
134141
<tr>
135-
<td rowspan="3" >14
142+
<td rowspan="3" >15
136143
</td>
137144
<td rowspan="3" >Server process crashed or killed with request in flight.
138145
</td>
@@ -154,29 +161,29 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
154161
</td>
155162
</tr>
156163
<tr>
157-
<td>15
164+
<td>16
158165
</td>
159166
<td>Server app is currently being upgraded to a new version
160167
</td>
161168
<td rowspan="2" >onBindingDied() ServiceConnection callback
162169
</td>
163170
</tr>
164171
<tr>
165-
<td>16
172+
<td>17
166173
</td>
167174
<td>The whole server app or the target android.app.Service was disabled
168175
</td>
169176
</tr>
170177
<tr>
171-
<td>17
178+
<td>18
172179
</td>
173180
<td>Binder transaction buffer overflow
174181
</td>
175182
<td>IBinder.transact() throws TransactionTooLargeException
176183
</td>
177184
</tr>
178185
<tr>
179-
<td>18
186+
<td>19
180187
</td>
181188
<td>Source Context for bindService() is destroyed with a request in flight
182189
</td>
@@ -188,19 +195,19 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
188195
</td>
189196
<td rowspan="2" >Give up for now.
190197
<p>
191-
(Re. 18: The caller can try again later when the user opens the source Activity or restarts the source Service)
198+
(Re. 19: The caller can try again later when the user opens the source Activity or restarts the source Service)
192199
</td>
193200
</tr>
194201
<tr>
195-
<td>19
202+
<td>20
196203
</td>
197204
<td>Client application cancelled the request
198205
</td>
199206
<td>N/A
200207
</td>
201208
</tr>
202209
<tr>
203-
<td rowspan="2" >19
210+
<td rowspan="2" >21
204211
</td>
205212
<td rowspan="2" >Bug in Android itself or the way the io.grpc.binder transport uses it.
206213
</td>
@@ -218,15 +225,15 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
218225
</td>
219226
</tr>
220227
<tr>
221-
<td>20
228+
<td>22
222229
</td>
223230
<td>Flow-control protocol violation
224231
</td>
225232
<td rowspan="2" >N/A
226233
</td>
227234
</tr>
228235
<tr>
229-
<td>21
236+
<td>23
230237
</td>
231238
<td>Can’t parse request/response proto
232239
</td>
@@ -236,27 +243,27 @@ Consider the table that follows as an BinderChannel-specific addendum to the “
236243

237244
### Ambiguity
238245

239-
We say a status code is ambiguous if it maps to two error cases that reasonable clients want to handle differently. For instance, a client may have good reasons to handle error cases 9 and 10 above differently. But they can’t do so based on status code alone because those error cases map to the same one.
246+
We say a status code is ambiguous if it maps to two error cases that reasonable clients want to handle differently. For instance, a client may have good reasons to handle error cases 10 and 11 above differently. But they can’t do so based on status code alone because those error cases map to the same one.
240247

241-
In contrast, for example, even though error case 18 and 19 both map to the status code (`CANCELLED`), they are not ambiguous because we see no reason that clients would want to distinguish them. In both cases, clients will simply give up on the request.
248+
In contrast, for example, even though error case 19 and 20 both map to the status code (`CANCELLED`), they are not ambiguous because we see no reason that clients would want to distinguish them. In both cases, clients will simply give up on the request.
242249

243250

244251
#### Ambiguity of PERMISSION_DENIED and Mitigations
245252

246253
The mapping above has only one apparently ambiguous status code: `PERMISSION_DENIED`. However, this isn’t so bad because of the following:
247254

248-
The use of `<android:permission>`s for inter-app IPC access control (error case 10) is uncommon. Instead, we recommend that server apps only allow IPC from a limited set of client apps known in advance and identified by signature.
255+
The use of `<android:permission>`s for inter-app IPC access control (error case 11) is uncommon. Instead, we recommend that server apps only allow IPC from a limited set of client apps known in advance and identified by signature.
249256

250-
However, there may be gRPC server apps that want to use custom &lt;android:permission&gt;’s to let the end user decide which arbitrary other apps can make use of its gRPC services. In that case, clients should preempt error case 10 simply by [checking whether they hold the required permissions](https://developer.android.com/training/permissions/requesting) before sending a request.
257+
However, there may be gRPC server apps that want to use custom &lt;android:permission&gt;’s to let the end user decide which arbitrary other apps can make use of its gRPC services. In that case, clients should preempt error case 11 simply by [checking whether they hold the required permissions](https://developer.android.com/training/permissions/requesting) before sending a request.
251258

252-
Server apps can avoid error case 9 by never reusing an android.app.Service as a gRPC host if it has ever been android:exported=false in some previous app version. Instead they should simply create a new android.app.Service for this purpose.
259+
Server apps can avoid error case 10 by never reusing an android.app.Service as a gRPC host if it has ever been android:exported=false in some previous app version. Instead they should simply create a new android.app.Service for this purpose.
253260

254-
Only error cases 11 - 13 remain, making `PERMISSION_DENIED` unambiguous for the purpose of error handling. Reasonable client apps can handle it in a generic way by displaying an error message and/or proceeding with degraded functionality.
261+
Only error cases 12 - 14 remain, making `PERMISSION_DENIED` unambiguous for the purpose of error handling. Reasonable client apps can handle it in a generic way by displaying an error message and/or proceeding with degraded functionality.
255262

256263

257264
#### Non-Ambiguity of UNIMPLEMENTED
258265

259-
The `UNIMPLEMENTED` status code corresponds to quite a few different problems with the server app: It’s either not installed, too old, or disabled in whole or in part. Despite the diversity of underlying error cases, we believe most client apps will and should handle `UNIMPLEMENTED` in the same way: by sending the user to the app store to (re)install the server app. Reinstalling might be overkill for the disabled cases but most end users don't know what it means to enable/disable an app and there’s neither enough space in a UI dialog nor enough reader attention to explain it. Reinstalling is something users likely already understand and very likely to cure problems 1-8.
266+
The `UNIMPLEMENTED` status code corresponds to quite a few different problems with the server app: It’s either not installed, too old, misconfigured, or disabled in whole or in part. Despite the diversity of underlying error cases, we believe most client apps will and should handle `UNIMPLEMENTED` in the same way: by sending the user to the app store to (re)install the server app. Reinstalling might be overkill for the disabled cases but most end users don't know what it means to enable/disable an app and there’s neither enough space in a UI dialog nor enough reader attention to explain it. Reinstalling is something users likely already understand and likely to cure problems 0-9 (once a fixed version of the server is available).
260267

261268

262269
## Detailed Discussion of Binder Failure Modes
@@ -326,14 +333,15 @@ According to a review of the AOSP source code, there are in fact several cases:
326333
2. The target package is installed but does not declare the target Service in its manifest.
327334
3. The target package requests dangerous permissions but targets sdk &lt;= M and therefore requires a permissions review, but the caller is not running in the foreground and so it would be inappropriate to launch the review UI.
328335
4. The target package is not visible to the client due to [Android 11 package visibility rules](https://developer.android.com/training/package-visibility).
336+
5. One of the new [Safer Intents](https://developer.android.com/about/versions/15/behavior-changes-15#safer-intents) rules is violated. Most commonly, the bind `Intent` specifies a `ComponentName` explicitly but doesn't match any of its &lt;intent-filter&gt;s.
329337

330338
Status code mapping: **UNIMPLEMENTED**
331339

332340
(1) and (2) are interesting new possibilities unique to on-device RPC. (1) is straightforward and the most likely cause of (2) is that the user has an old version of the server app installed that predates its gRPC integration. Many clients will want to handle these cases, likely by directing the user to the app store in order to install/upgrade the server.
333341

334342
Unfortunately `UNIMPLEMENTED` doesn’t capture (3) but none of the other canonical status codes do either and we expect this case to be extremely rare.
335343

336-
(4) is intentially indistinguishable from (1) by Android design so we can't handle it differently. However, as a client manifest error, it's not something reasonable apps would handle at runtime anyway.
344+
(4) and (5) are intentially indistinguishable from (1) by Android design so we can't handle them differently. However, as an error in its own manifest, (4) isn't something a reasonable client would handle at runtime anyway. (5) is an error in the server manifest and so, just like the other cases, the best practice for handling it is to send the user to the app store in the hope that the server can be updated with a fix.
337345

338346
### bindService() throws SecurityException
339347

0 commit comments

Comments
 (0)
Please sign in to comment.