1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.usespermissiondiffcertapp; 18 19 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_CLEAR_PRIMARY_CLIP; 20 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_GRANT_URI; 21 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_REVOKE_URI; 22 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_SET_PRIMARY_CLIP; 23 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_ACTIVITY; 24 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_SERVICE; 25 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_VERIFY_OUTGOING_PERSISTED; 26 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_INTENT; 27 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_MODE; 28 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_PACKAGE_NAME; 29 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_URI; 30 31 import android.content.ClipData; 32 import android.content.ClipboardManager; 33 import android.content.ContentResolver; 34 import android.content.ContentValues; 35 import android.content.Intent; 36 import android.content.UriPermission; 37 import android.database.Cursor; 38 import android.net.Uri; 39 import android.os.Bundle; 40 import android.provider.CalendarContract; 41 import android.provider.ContactsContract; 42 import android.test.AndroidTestCase; 43 import android.util.Log; 44 45 import androidx.test.InstrumentationRegistry; 46 47 import com.android.cts.permissiondeclareapp.UtilsProvider; 48 49 import java.io.IOException; 50 import java.util.List; 51 52 /** 53 * Tests that signature-enforced permissions cannot be accessed by apps signed 54 * with different certs than app that declares the permission. 55 * 56 * Accesses app cts/tests/appsecurity-tests/test-apps/PermissionDeclareApp/... 57 */ 58 public class AccessPermissionWithDiffSigTest extends AndroidTestCase { 59 private static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature"); 60 private static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting"); 61 private static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath"); 62 private static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse( 63 "content://ctspermissionwithsignaturepathrestricting"); 64 private static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider"); 65 private static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting"); 66 private static final String EXPECTED_MIME_TYPE = "got/theMIME"; 67 68 private static final Uri AMBIGUOUS_URI_COMPAT = Uri.parse("content://ctsambiguousprovidercompat"); 69 private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME"; 70 private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider"); 71 72 private static final Uri[] GRANTABLE = new Uri[] { 73 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"), 74 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 75 Uri.withAppendedPath(PERM_URI_PATH, "foo"), 76 }; 77 78 private static final Uri[] NOT_GRANTABLE = new Uri[] { 79 Uri.withAppendedPath(PERM_URI, "foo"), 80 Uri.withAppendedPath(PRIV_URI, "foo"), 81 Uri.withAppendedPath(PERM_URI_PATH_RESTRICTING, "foo"), 82 CalendarContract.CONTENT_URI, 83 ContactsContract.AUTHORITY_URI, 84 }; 85 86 @Override tearDown()87 protected void tearDown() throws Exception { 88 super.tearDown(); 89 90 // Always dispose, usually to clean up from failed tests 91 ReceiveUriActivity.finishCurInstanceSync(); 92 } 93 assertReadingContentUriNotAllowed(Uri uri, String msg)94 private void assertReadingContentUriNotAllowed(Uri uri, String msg) { 95 try { 96 getContext().getContentResolver().query(uri, null, null, null, null); 97 fail("expected SecurityException reading " + uri + ": " + msg); 98 } catch (SecurityException expected) { 99 assertNotNull("security exception's error message.", expected.getMessage()); 100 } 101 } 102 assertReadingContentUriAllowed(Uri uri)103 private void assertReadingContentUriAllowed(Uri uri) { 104 try { 105 getContext().getContentResolver().query(uri, null, null, null, null); 106 } catch (SecurityException e) { 107 fail("unexpected SecurityException reading " + uri + ": " + e.getMessage()); 108 } 109 } 110 assertReadingClipNotAllowed(ClipData clip)111 private void assertReadingClipNotAllowed(ClipData clip) { 112 assertReadingClipNotAllowed(clip, null); 113 } 114 assertReadingClipNotAllowed(ClipData clip, String msg)115 private void assertReadingClipNotAllowed(ClipData clip, String msg) { 116 for (int i=0; i<clip.getItemCount(); i++) { 117 ClipData.Item item = clip.getItemAt(i); 118 Uri uri = item.getUri(); 119 if (uri != null) { 120 assertReadingContentUriNotAllowed(uri, msg); 121 } else { 122 Intent intent = item.getIntent(); 123 uri = intent.getData(); 124 if (uri != null) { 125 assertReadingContentUriNotAllowed(uri, msg); 126 } 127 ClipData intentClip = intent.getClipData(); 128 if (intentClip != null) { 129 assertReadingClipNotAllowed(intentClip, msg); 130 } 131 } 132 } 133 } 134 assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode)135 private void assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode) { 136 try { 137 getContext().getContentResolver().openFileDescriptor(uri, mode).close(); 138 fail("expected SecurityException writing " + uri + ": " + msg); 139 } catch (IOException e) { 140 throw new IllegalStateException(e); 141 } catch (SecurityException expected) { 142 assertNotNull("security exception's error message.", expected.getMessage()); 143 } 144 } 145 assertContentUriAllowed(Uri uri)146 private void assertContentUriAllowed(Uri uri) { 147 assertReadingContentUriAllowed(uri); 148 assertWritingContentUriAllowed(uri); 149 } 150 assertContentUriNotAllowed(Uri uri, String msg)151 private void assertContentUriNotAllowed(Uri uri, String msg) { 152 assertReadingContentUriNotAllowed(uri, msg); 153 assertWritingContentUriNotAllowed(uri, msg); 154 } 155 assertWritingContentUriNotAllowed(Uri uri, String msg)156 private void assertWritingContentUriNotAllowed(Uri uri, String msg) { 157 final ContentResolver resolver = getContext().getContentResolver(); 158 try { 159 resolver.insert(uri, new ContentValues()); 160 fail("expected SecurityException inserting " + uri + ": " + msg); 161 } catch (SecurityException expected) { 162 assertNotNull("security exception's error message.", expected.getMessage()); 163 } 164 165 try { 166 resolver.update(uri, new ContentValues(), null, null); 167 fail("expected SecurityException updating " + uri + ": " + msg); 168 } catch (SecurityException expected) { 169 assertNotNull("security exception's error message.", expected.getMessage()); 170 } 171 172 try { 173 resolver.delete(uri, null, null); 174 fail("expected SecurityException deleting " + uri + ": " + msg); 175 } catch (SecurityException expected) { 176 assertNotNull("security exception's error message.", expected.getMessage()); 177 } 178 179 try { 180 getContext().getContentResolver().openOutputStream(uri).close(); 181 fail("expected SecurityException writing " + uri + ": " + msg); 182 } catch (IOException e) { 183 throw new IllegalStateException(e); 184 } catch (SecurityException expected) { 185 assertNotNull("security exception's error message.", expected.getMessage()); 186 } 187 188 assertOpenFileDescriptorModeNotAllowed(uri, msg, "w"); 189 assertOpenFileDescriptorModeNotAllowed(uri, msg, "wt"); 190 assertOpenFileDescriptorModeNotAllowed(uri, msg, "wa"); 191 assertOpenFileDescriptorModeNotAllowed(uri, msg, "rw"); 192 assertOpenFileDescriptorModeNotAllowed(uri, msg, "rwt"); 193 } 194 assertWritingContentUriAllowed(Uri uri)195 private void assertWritingContentUriAllowed(Uri uri) { 196 final ContentResolver resolver = getContext().getContentResolver(); 197 try { 198 resolver.insert(uri, new ContentValues()); 199 resolver.update(uri, new ContentValues(), null, null); 200 resolver.delete(uri, null, null); 201 202 resolver.openOutputStream(uri).close(); 203 resolver.openFileDescriptor(uri, "w").close(); 204 resolver.openFileDescriptor(uri, "wt").close(); 205 resolver.openFileDescriptor(uri, "wa").close(); 206 resolver.openFileDescriptor(uri, "rw").close(); 207 resolver.openFileDescriptor(uri, "rwt").close(); 208 } catch (IOException e) { 209 fail("unexpected IOException writing " + uri + ": " + e.getMessage()); 210 } catch (SecurityException e) { 211 fail("unexpected SecurityException writing " + uri + ": " + e.getMessage()); 212 } 213 } 214 assertWritingClipNotAllowed(ClipData clip)215 private void assertWritingClipNotAllowed(ClipData clip) { 216 assertWritingClipNotAllowed(clip, null); 217 } 218 assertWritingClipNotAllowed(ClipData clip, String msg)219 private void assertWritingClipNotAllowed(ClipData clip, String msg) { 220 for (int i=0; i<clip.getItemCount(); i++) { 221 ClipData.Item item = clip.getItemAt(i); 222 Uri uri = item.getUri(); 223 if (uri != null) { 224 assertWritingContentUriNotAllowed(uri, msg); 225 } else { 226 Intent intent = item.getIntent(); 227 uri = intent.getData(); 228 if (uri != null) { 229 assertWritingContentUriNotAllowed(uri, msg); 230 } 231 ClipData intentClip = intent.getClipData(); 232 if (intentClip != null) { 233 assertWritingClipNotAllowed(intentClip, msg); 234 } 235 } 236 } 237 } 238 239 /** 240 * Test that the ctspermissionwithsignature content provider cannot be read, 241 * since this app lacks the required certs 242 */ testReadProviderWithDiff()243 public void testReadProviderWithDiff() { 244 assertReadingContentUriRequiresPermission(PERM_URI, 245 "com.android.cts.permissionWithSignature"); 246 } 247 248 /** 249 * Test that the ctspermissionwithsignature content provider cannot be written, 250 * since this app lacks the required certs 251 */ testWriteProviderWithDiff()252 public void testWriteProviderWithDiff() { 253 assertWritingContentUriRequiresPermission(PERM_URI, 254 "com.android.cts.permissionWithSignature"); 255 } 256 257 /** 258 * Test that the ctsprivateprovider content provider cannot be read, 259 * since it is not exported from its app. 260 */ testReadProviderWhenPrivate()261 public void testReadProviderWhenPrivate() { 262 assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read private provider"); 263 } 264 265 /** 266 * Test that the ctsambiguousprovider content provider cannot be read, 267 * since it doesn't have an "exported=" line. 268 */ testReadProviderWhenAmbiguous()269 public void testReadProviderWhenAmbiguous() { 270 assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read ambiguous provider"); 271 } 272 273 /** 274 * Old App Compatibility Test 275 * 276 * Test that the ctsambiguousprovidercompat content provider can be read for older 277 * API versions, because it didn't specify either exported=true or exported=false. 278 */ testReadProviderWhenAmbiguousCompat()279 public void testReadProviderWhenAmbiguousCompat() { 280 assertReadingContentUriAllowed(AMBIGUOUS_URI_COMPAT); 281 } 282 283 /** 284 * Old App Compatibility Test 285 * 286 * Test that the ctsambiguousprovidercompat content provider can be written for older 287 * API versions, because it didn't specify either exported=true or exported=false. 288 */ testWriteProviderWhenAmbiguousCompat()289 public void testWriteProviderWhenAmbiguousCompat() { 290 assertWritingContentUriAllowed(AMBIGUOUS_URI_COMPAT); 291 } 292 293 /** 294 * Test that the ctsprivateprovider content provider cannot be written, 295 * since it is not exported from its app. 296 */ testWriteProviderWhenPrivate()297 public void testWriteProviderWhenPrivate() { 298 assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write private provider"); 299 } 300 301 /** 302 * Test that the ctsambiguousprovider content provider cannot be written, 303 * since it doesn't have an exported= line. 304 */ testWriteProviderWhenAmbiguous()305 public void testWriteProviderWhenAmbiguous() { 306 assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider"); 307 } 308 makeSingleClipData(Uri uri)309 private static ClipData makeSingleClipData(Uri uri) { 310 return new ClipData("foo", new String[] { "foo/bar" }, 311 new ClipData.Item(uri)); 312 } 313 makeMultiClipData(Uri uri)314 private static ClipData makeMultiClipData(Uri uri) { 315 Uri grantClip1Uri = Uri.withAppendedPath(uri, "clip1"); 316 Uri grantClip2Uri = Uri.withAppendedPath(uri, "clip2"); 317 Uri grantClip3Uri = Uri.withAppendedPath(uri, "clip3"); 318 Uri grantClip4Uri = Uri.withAppendedPath(uri, "clip4"); 319 Uri grantClip5Uri = Uri.withAppendedPath(uri, "clip5"); 320 ClipData clip = new ClipData("foo", new String[] { "foo/bar" }, 321 new ClipData.Item(grantClip1Uri)); 322 clip.addItem(new ClipData.Item(grantClip2Uri)); 323 // Intents in the ClipData should allow their data: and clip URIs 324 // to be granted, but only respect the grant flags of the top-level 325 // Intent. 326 clip.addItem(new ClipData.Item(new Intent(Intent.ACTION_VIEW, grantClip3Uri))); 327 Intent intent = new Intent(Intent.ACTION_VIEW, grantClip4Uri); 328 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 329 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 330 clip.addItem(new ClipData.Item(intent)); 331 intent = new Intent(Intent.ACTION_VIEW); 332 intent.setClipData(new ClipData("foo", new String[] { "foo/bar" }, 333 new ClipData.Item(grantClip5Uri))); 334 clip.addItem(new ClipData.Item(intent)); 335 return clip; 336 } 337 makeClipIntent(ClipData clip, int flags)338 private static Intent makeClipIntent(ClipData clip, int flags) { 339 Intent intent = new Intent(); 340 intent.setClipData(clip); 341 intent.addFlags(flags); 342 return intent; 343 } 344 makeClipIntent(Uri uri, int flags)345 private static Intent makeClipIntent(Uri uri, int flags) { 346 return makeClipIntent(makeMultiClipData(uri), flags); 347 } 348 doTryGrantUriActivityPermissionToSelf(Uri uri, int mode)349 private void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) { 350 Uri grantDataUri = Uri.withAppendedPath(uri, "data"); 351 Intent grantIntent = new Intent(); 352 grantIntent.setData(grantDataUri); 353 grantIntent.addFlags(mode | Intent.FLAG_ACTIVITY_NEW_TASK); 354 grantIntent.setClass(getContext(), ReceiveUriActivity.class); 355 try { 356 ReceiveUriActivity.clearStarted(); 357 getContext().startActivity(grantIntent); 358 ReceiveUriActivity.waitForStart(); 359 fail("expected SecurityException granting " + grantDataUri + " to activity"); 360 } catch (SecurityException e) { 361 // This is what we want. 362 } 363 364 grantIntent = makeClipIntent(uri, mode | Intent.FLAG_ACTIVITY_NEW_TASK); 365 grantIntent.setClass(getContext(), ReceiveUriActivity.class); 366 try { 367 ReceiveUriActivity.clearStarted(); 368 getContext().startActivity(grantIntent); 369 ReceiveUriActivity.waitForStart(); 370 fail("expected SecurityException granting " + grantIntent.getClipData() + " to activity"); 371 } catch (SecurityException e) { 372 // This is what we want. 373 } 374 } 375 376 /** 377 * Test that we can't grant a permission to ourself. 378 */ testGrantReadUriActivityPermissionToSelf()379 public void testGrantReadUriActivityPermissionToSelf() { 380 doTryGrantUriActivityPermissionToSelf( 381 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"), 382 Intent.FLAG_GRANT_READ_URI_PERMISSION); 383 } 384 385 /** 386 * Test that we can't grant a permission to ourself. 387 */ testGrantWriteUriActivityPermissionToSelf()388 public void testGrantWriteUriActivityPermissionToSelf() { 389 doTryGrantUriActivityPermissionToSelf( 390 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"), 391 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 392 } 393 394 /** 395 * Test that we can't grant a permission to ourself. 396 */ testGrantReadUriActivityPrivateToSelf()397 public void testGrantReadUriActivityPrivateToSelf() { 398 doTryGrantUriActivityPermissionToSelf( 399 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 400 Intent.FLAG_GRANT_READ_URI_PERMISSION); 401 } 402 403 /** 404 * Test that we can't grant a permission to ourself. 405 */ testGrantWriteUriActivityPrivateToSelf()406 public void testGrantWriteUriActivityPrivateToSelf() { 407 doTryGrantUriActivityPermissionToSelf( 408 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 409 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 410 } 411 doTryGrantUriServicePermissionToSelf(Uri uri, int mode)412 private void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) { 413 Uri grantDataUri = Uri.withAppendedPath(uri, "data"); 414 Intent grantIntent = new Intent(); 415 grantIntent.setData(grantDataUri); 416 grantIntent.addFlags(mode); 417 grantIntent.setClass(getContext(), ReceiveUriService.class); 418 try { 419 getContext().startService(grantIntent); 420 fail("expected SecurityException granting " + grantDataUri + " to service"); 421 } catch (SecurityException e) { 422 // This is what we want. 423 } 424 425 grantIntent = makeClipIntent(uri, mode); 426 grantIntent.setClass(getContext(), ReceiveUriService.class); 427 try { 428 getContext().startService(grantIntent); 429 fail("expected SecurityException granting " + grantIntent.getClipData() + " to service"); 430 } catch (SecurityException e) { 431 // This is what we want. 432 } 433 } 434 435 /** 436 * Test that we can't grant a permission to ourself. 437 */ testGrantReadUriServicePermissionToSelf()438 public void testGrantReadUriServicePermissionToSelf() { 439 doTryGrantUriServicePermissionToSelf( 440 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"), 441 Intent.FLAG_GRANT_READ_URI_PERMISSION); 442 } 443 444 /** 445 * Test that we can't grant a permission to ourself. 446 */ testGrantWriteUriServicePermissionToSelf()447 public void testGrantWriteUriServicePermissionToSelf() { 448 doTryGrantUriServicePermissionToSelf( 449 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"), 450 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 451 } 452 453 /** 454 * Test that we can't grant a permission to ourself. 455 */ testGrantReadUriServicePrivateToSelf()456 public void testGrantReadUriServicePrivateToSelf() { 457 doTryGrantUriServicePermissionToSelf( 458 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 459 Intent.FLAG_GRANT_READ_URI_PERMISSION); 460 } 461 462 /** 463 * Test that we can't grant a permission to ourself. 464 */ testGrantWriteUriServicePrivateToSelf()465 public void testGrantWriteUriServicePrivateToSelf() { 466 doTryGrantUriServicePermissionToSelf( 467 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 468 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 469 } 470 grantUriPermissionFail(Uri uri, int mode, boolean service)471 private void grantUriPermissionFail(Uri uri, int mode, boolean service) { 472 Uri grantDataUri = Uri.withAppendedPath(uri, "data"); 473 Intent grantIntent = new Intent(); 474 grantIntent.setData(grantDataUri); 475 grantIntent.addFlags(mode); 476 grantIntent.setClass(getContext(), 477 service ? ReceiveUriService.class : ReceiveUriActivity.class); 478 Intent intent = new Intent(); 479 intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY); 480 intent.putExtra(EXTRA_INTENT, grantIntent); 481 try { 482 call(intent); 483 fail("Able to grant URI permission to " + grantDataUri + " when should not"); 484 } catch (Exception expected) { 485 } 486 487 grantIntent = makeClipIntent(uri, mode); 488 grantIntent.setClass(getContext(), 489 service ? ReceiveUriService.class : ReceiveUriActivity.class); 490 intent = new Intent(); 491 intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY); 492 intent.putExtra(EXTRA_INTENT, grantIntent); 493 try { 494 call(intent); 495 fail("Able to grant URI permission to " + grantIntent.getClipData() 496 + " when should not"); 497 } catch (Exception expected) { 498 } 499 } 500 doTestGrantUriPermissionFail(Uri uri)501 private void doTestGrantUriPermissionFail(Uri uri) { 502 for (boolean service : new boolean[] { false, true }) { 503 for (int flags : new int[] { 504 Intent.FLAG_GRANT_READ_URI_PERMISSION, Intent.FLAG_GRANT_WRITE_URI_PERMISSION 505 }) { 506 grantUriPermissionFail(uri, 507 flags, service); 508 grantUriPermissionFail(uri, 509 flags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, service); 510 grantUriPermissionFail(uri, 511 flags | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, service); 512 } 513 } 514 } 515 516 /** 517 * Test that the ctspermissionwithsignature content provider can not grant 518 * URI permissions to others. 519 */ testGrantPermissionNonGrantingFail()520 public void testGrantPermissionNonGrantingFail() { 521 doTestGrantUriPermissionFail(PERM_URI); 522 } 523 524 /** 525 * Test that the ctspermissionwithsignaturegranting content provider can not grant 526 * URI permissions to paths outside of the grant tree 527 */ testGrantPermissionOutsideGrantingFail()528 public void testGrantPermissionOutsideGrantingFail() { 529 doTestGrantUriPermissionFail(PERM_URI_GRANTING); 530 doTestGrantUriPermissionFail(Uri.withAppendedPath(PERM_URI_GRANTING, "invalid")); 531 } 532 533 /** 534 * Test that the ctsprivateprovider content provider can not grant 535 * URI permissions to others. 536 */ testGrantPrivateNonGrantingFail()537 public void testGrantPrivateNonGrantingFail() { 538 doTestGrantUriPermissionFail(PRIV_URI); 539 } 540 541 /** 542 * Test that the ctsambiguousprovider content provider can not grant 543 * URI permissions to others. 544 */ testGrantAmbiguousNonGrantingFail()545 public void testGrantAmbiguousNonGrantingFail() { 546 doTestGrantUriPermissionFail(AMBIGUOUS_URI); 547 } 548 549 /** 550 * Test that the ctsprivateprovidergranting content provider can not grant 551 * URI permissions to paths outside of the grant tree 552 */ testGrantPrivateOutsideGrantingFail()553 public void testGrantPrivateOutsideGrantingFail() { 554 doTestGrantUriPermissionFail(PRIV_URI_GRANTING); 555 doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid")); 556 } 557 call(Intent intent)558 private void call(Intent intent) { 559 final Bundle extras = new Bundle(); 560 extras.putParcelable(Intent.EXTRA_INTENT, intent); 561 getContext().getContentResolver().call(UtilsProvider.URI, "", "", extras); 562 } 563 grantClipUriPermission(ClipData clip, int mode, boolean service)564 private void grantClipUriPermission(ClipData clip, int mode, boolean service) { 565 Intent grantIntent = new Intent(); 566 if (clip.getItemCount() == 1) { 567 grantIntent.setData(clip.getItemAt(0).getUri()); 568 } else { 569 grantIntent.setClipData(clip); 570 // Make this Intent unique from the one that started it. 571 for (int i=0; i<clip.getItemCount(); i++) { 572 Uri uri = clip.getItemAt(i).getUri(); 573 if (uri != null) { 574 grantIntent.addCategory(uri.toString()); 575 } 576 } 577 } 578 grantIntent.addFlags(mode); 579 grantIntent.setClass(getContext(), 580 service ? ReceiveUriService.class : ReceiveUriActivity.class); 581 Intent intent = new Intent(); 582 intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY); 583 intent.putExtra(EXTRA_INTENT, grantIntent); 584 call(intent); 585 } 586 grantClipUriPermissionViaContext(Uri uri, int mode)587 private void grantClipUriPermissionViaContext(Uri uri, int mode) { 588 Intent intent = new Intent(); 589 intent.setAction(ACTION_GRANT_URI); 590 intent.putExtra(EXTRA_PACKAGE_NAME, getContext().getPackageName()); 591 intent.putExtra(EXTRA_URI, uri); 592 intent.putExtra(EXTRA_MODE, mode); 593 call(intent); 594 } 595 revokeClipUriPermissionViaContext(Uri uri, int mode)596 private void revokeClipUriPermissionViaContext(Uri uri, int mode) { 597 Intent intent = new Intent(); 598 intent.setAction(ACTION_REVOKE_URI); 599 intent.putExtra(EXTRA_URI, uri); 600 intent.putExtra(EXTRA_MODE, mode); 601 call(intent); 602 } 603 setPrimaryClip(ClipData clip)604 private void setPrimaryClip(ClipData clip) { 605 Intent intent = new Intent(); 606 intent.setAction(ACTION_SET_PRIMARY_CLIP); 607 intent.setClipData(clip); 608 call(intent); 609 } 610 clearPrimaryClip()611 private void clearPrimaryClip() { 612 Intent intent = new Intent(); 613 intent.setAction(ACTION_CLEAR_PRIMARY_CLIP); 614 call(intent); 615 } 616 assertReadingClipAllowed(ClipData clip)617 private void assertReadingClipAllowed(ClipData clip) { 618 for (int i=0; i<clip.getItemCount(); i++) { 619 ClipData.Item item = clip.getItemAt(i); 620 Uri uri = item.getUri(); 621 if (uri != null) { 622 Cursor c = getContext().getContentResolver().query(uri, 623 null, null, null, null); 624 if (c != null) { 625 c.close(); 626 } 627 } else { 628 Intent intent = item.getIntent(); 629 uri = intent.getData(); 630 if (uri != null) { 631 Cursor c = getContext().getContentResolver().query(uri, 632 null, null, null, null); 633 if (c != null) { 634 c.close(); 635 } 636 } 637 ClipData intentClip = intent.getClipData(); 638 if (intentClip != null) { 639 assertReadingClipAllowed(intentClip); 640 } 641 } 642 } 643 } 644 doTestGrantActivityUriReadPermission(Uri uri, boolean useClip)645 private void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) { 646 final Uri subUri = Uri.withAppendedPath(uri, "foo"); 647 final Uri subSubUri = Uri.withAppendedPath(subUri, "bar"); 648 final Uri sub2Uri = Uri.withAppendedPath(uri, "yes"); 649 final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no"); 650 651 final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri); 652 final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri); 653 654 // Precondition: no current access. 655 assertReadingClipNotAllowed(subClip, "shouldn't read when starting test"); 656 assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test"); 657 658 // -------------------------------- 659 660 ReceiveUriActivity.clearStarted(); 661 grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false); 662 ReceiveUriActivity.waitForStart(); 663 664 // See if we now have access to the provider. 665 assertReadingClipAllowed(subClip); 666 667 // But not writing. 668 assertWritingClipNotAllowed(subClip, "shouldn't write from granted read"); 669 670 // And not to the base path. 671 assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI"); 672 673 // And not to a sub path. 674 assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI"); 675 676 // -------------------------------- 677 678 ReceiveUriActivity.clearNewIntent(); 679 grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false); 680 ReceiveUriActivity.waitForNewIntent(); 681 682 if (false) { 683 synchronized (this) { 684 Log.i("**", "******************************* WAITING!!!"); 685 try { 686 wait(10000); 687 } catch (InterruptedException e) { 688 } 689 } 690 } 691 692 // See if we now have access to the provider. 693 assertReadingClipAllowed(sub2Clip); 694 695 // And still have access to the original URI. 696 assertReadingClipAllowed(subClip); 697 698 // But not writing. 699 assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read"); 700 701 // And not to the base path. 702 assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI"); 703 704 // And not to a sub path. 705 assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI"); 706 707 // And make sure we can't generate a permission to a running activity. 708 doTryGrantUriActivityPermissionToSelf( 709 Uri.withAppendedPath(uri, "hah"), 710 Intent.FLAG_GRANT_READ_URI_PERMISSION); 711 doTryGrantUriActivityPermissionToSelf( 712 Uri.withAppendedPath(uri, "hah"), 713 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 714 715 // -------------------------------- 716 717 // Dispose of activity. 718 ReceiveUriActivity.finishCurInstanceSync(); 719 720 synchronized (this) { 721 Log.i("**", "******************************* WAITING!!!"); 722 try { 723 wait(100); 724 } catch (InterruptedException e) { 725 } 726 } 727 728 // Ensure reading no longer allowed. 729 assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI"); 730 assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI"); 731 } 732 assertWritingClipAllowed(ClipData clip)733 private void assertWritingClipAllowed(ClipData clip) { 734 for (int i=0; i<clip.getItemCount(); i++) { 735 ClipData.Item item = clip.getItemAt(i); 736 Uri uri = item.getUri(); 737 if (uri != null) { 738 getContext().getContentResolver().insert(uri, new ContentValues()); 739 } else { 740 Intent intent = item.getIntent(); 741 uri = intent.getData(); 742 if (uri != null) { 743 getContext().getContentResolver().insert(uri, new ContentValues()); 744 } 745 ClipData intentClip = intent.getClipData(); 746 if (intentClip != null) { 747 assertWritingClipAllowed(intentClip); 748 } 749 } 750 } 751 } 752 doTestGrantActivityUriWritePermission(Uri uri, boolean useClip)753 private void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) { 754 final Uri subUri = Uri.withAppendedPath(uri, "foo"); 755 final Uri subSubUri = Uri.withAppendedPath(subUri, "bar"); 756 final Uri sub2Uri = Uri.withAppendedPath(uri, "yes"); 757 final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no"); 758 759 final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri); 760 final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri); 761 762 // Precondition: no current access. 763 assertWritingClipNotAllowed(subClip, "shouldn't write when starting test"); 764 assertWritingClipNotAllowed(sub2Clip, "shouldn't write when starting test"); 765 766 // -------------------------------- 767 768 ReceiveUriActivity.clearStarted(); 769 grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 770 ReceiveUriActivity.waitForStart(); 771 772 // See if we now have access to the provider. 773 assertWritingClipAllowed(subClip); 774 775 // But not reading. 776 assertReadingClipNotAllowed(subClip, "shouldn't read from granted write"); 777 778 // And not to the base path. 779 assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI"); 780 781 // And not a sub-path. 782 assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI"); 783 784 // -------------------------------- 785 786 ReceiveUriActivity.clearNewIntent(); 787 grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 788 ReceiveUriActivity.waitForNewIntent(); 789 790 if (false) { 791 synchronized (this) { 792 Log.i("**", "******************************* WAITING!!!"); 793 try { 794 wait(10000); 795 } catch (InterruptedException e) { 796 } 797 } 798 } 799 800 // See if we now have access to the provider. 801 assertWritingClipAllowed(sub2Clip); 802 803 // And still have access to the original URI. 804 assertWritingClipAllowed(subClip); 805 806 // But not reading. 807 assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write"); 808 809 // And not to the base path. 810 assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI"); 811 812 // And not a sub-path. 813 assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI"); 814 815 // And make sure we can't generate a permission to a running activity. 816 doTryGrantUriActivityPermissionToSelf( 817 Uri.withAppendedPath(uri, "hah"), 818 Intent.FLAG_GRANT_READ_URI_PERMISSION); 819 doTryGrantUriActivityPermissionToSelf( 820 Uri.withAppendedPath(uri, "hah"), 821 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 822 823 // -------------------------------- 824 825 // Dispose of activity. 826 ReceiveUriActivity.finishCurInstanceSync(); 827 828 synchronized (this) { 829 Log.i("**", "******************************* WAITING!!!"); 830 try { 831 wait(100); 832 } catch (InterruptedException e) { 833 } 834 } 835 836 // Ensure writing no longer allowed. 837 assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI"); 838 assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI"); 839 } 840 841 /** 842 * Test that the ctspermissionwithsignaturegranting content provider can grant a read 843 * permission. 844 */ testGrantReadPermissionFromStartActivity()845 public void testGrantReadPermissionFromStartActivity() { 846 doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, false); 847 doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, true); 848 } 849 850 /** 851 * Test that the ctspermissionwithsignaturegranting content provider can grant a write 852 * permission. 853 */ testGrantWritePermissionFromStartActivity()854 public void testGrantWritePermissionFromStartActivity() { 855 doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, true); 856 doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, false); 857 } 858 859 /** 860 * Test that the ctsprivateprovidergranting content provider can grant a read 861 * permission. 862 */ testGrantReadPrivateFromStartActivity()863 public void testGrantReadPrivateFromStartActivity() { 864 doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, false); 865 doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, true); 866 } 867 868 /** 869 * Test that the ctsprivateprovidergranting content provider can grant a write 870 * permission. 871 */ testGrantWritePrivateFromStartActivity()872 public void testGrantWritePrivateFromStartActivity() { 873 doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, true); 874 doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, false); 875 } 876 doTestGrantServiceUriReadPermission(Uri uri, boolean useClip)877 private void doTestGrantServiceUriReadPermission(Uri uri, boolean useClip) { 878 final Uri subUri = Uri.withAppendedPath(uri, "foo"); 879 final Uri subSubUri = Uri.withAppendedPath(subUri, "bar"); 880 final Uri sub2Uri = Uri.withAppendedPath(uri, "yes"); 881 final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no"); 882 883 ReceiveUriService.stop(getContext()); 884 885 final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri); 886 final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri); 887 888 // Precondition: no current access. 889 assertReadingClipNotAllowed(subClip, "shouldn't read when starting test"); 890 assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test"); 891 892 // -------------------------------- 893 894 ReceiveUriService.clearStarted(); 895 grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 896 ReceiveUriService.waitForStart(); 897 898 int firstStartId = ReceiveUriService.getCurStartId(); 899 900 // See if we now have access to the provider. 901 assertReadingClipAllowed(subClip); 902 903 // But not writing. 904 assertWritingClipNotAllowed(subClip, "shouldn't write from granted read"); 905 906 // And not to the base path. 907 assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI"); 908 909 // And not to a sub path. 910 assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI"); 911 912 // -------------------------------- 913 914 // Send another Intent to it. 915 ReceiveUriService.clearStarted(); 916 grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true); 917 ReceiveUriService.waitForStart(); 918 919 if (false) { 920 synchronized (this) { 921 Log.i("**", "******************************* WAITING!!!"); 922 try { 923 wait(10000); 924 } catch (InterruptedException e) { 925 } 926 } 927 } 928 929 // See if we now have access to the provider. 930 assertReadingClipAllowed(sub2Clip); 931 932 // And still to the previous URI. 933 assertReadingClipAllowed(subClip); 934 935 // But not writing. 936 assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read"); 937 938 // And not to the base path. 939 assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI"); 940 941 // And not to a sub path. 942 assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI"); 943 944 // -------------------------------- 945 946 // Stop the first command. 947 ReceiveUriService.stopCurWithId(firstStartId); 948 949 // Ensure reading no longer allowed. 950 assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI"); 951 952 // And make sure we can't generate a permission to a running service. 953 doTryGrantUriActivityPermissionToSelf(subUri, 954 Intent.FLAG_GRANT_READ_URI_PERMISSION); 955 doTryGrantUriActivityPermissionToSelf(subUri, 956 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 957 958 // -------------------------------- 959 960 // Dispose of service. 961 ReceiveUriService.stopSync(getContext()); 962 963 // Ensure reading no longer allowed. 964 assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI"); 965 assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI"); 966 } 967 doTestGrantServiceUriWritePermission(Uri uri, boolean useClip)968 private void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) { 969 final Uri subUri = Uri.withAppendedPath(uri, "foo"); 970 final Uri subSubUri = Uri.withAppendedPath(subUri, "bar"); 971 final Uri sub2Uri = Uri.withAppendedPath(uri, "yes"); 972 final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no"); 973 974 ReceiveUriService.stop(getContext()); 975 976 final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri); 977 final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri); 978 979 // Precondition: no current access. 980 assertReadingClipNotAllowed(subClip, "shouldn't read when starting test"); 981 assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test"); 982 983 // -------------------------------- 984 985 ReceiveUriService.clearStarted(); 986 grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 987 ReceiveUriService.waitForStart(); 988 989 int firstStartId = ReceiveUriService.getCurStartId(); 990 991 // See if we now have access to the provider. 992 assertWritingClipAllowed(subClip); 993 994 // But not reading. 995 assertReadingClipNotAllowed(subClip, "shouldn't read from granted write"); 996 997 // And not to the base path. 998 assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI"); 999 1000 // And not a sub-path. 1001 assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI"); 1002 1003 // -------------------------------- 1004 1005 // Send another Intent to it. 1006 ReceiveUriService.clearStarted(); 1007 grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true); 1008 ReceiveUriService.waitForStart(); 1009 1010 // See if we now have access to the provider. 1011 assertWritingClipAllowed(sub2Clip); 1012 1013 // And still to the previous URI. 1014 assertWritingClipAllowed(subClip); 1015 1016 // But not reading. 1017 assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write"); 1018 1019 // And not to the base path. 1020 assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI"); 1021 1022 // And not a sub-path. 1023 assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI"); 1024 1025 if (false) { 1026 synchronized (this) { 1027 Log.i("**", "******************************* WAITING!!!"); 1028 try { 1029 wait(10000); 1030 } catch (InterruptedException e) { 1031 } 1032 } 1033 } 1034 1035 // -------------------------------- 1036 1037 // Stop the first command. 1038 ReceiveUriService.stopCurWithId(firstStartId); 1039 1040 // Ensure writing no longer allowed. 1041 assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI"); 1042 1043 // And make sure we can't generate a permission to a running service. 1044 doTryGrantUriActivityPermissionToSelf(subUri, 1045 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1046 doTryGrantUriActivityPermissionToSelf(subUri, 1047 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1048 1049 // -------------------------------- 1050 1051 // Dispose of service. 1052 ReceiveUriService.stopSync(getContext()); 1053 1054 // Ensure writing no longer allowed. 1055 assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI"); 1056 assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI"); 1057 } 1058 testGrantReadPermissionFromStartService()1059 public void testGrantReadPermissionFromStartService() { 1060 doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, false); 1061 doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, true); 1062 } 1063 testGrantWritePermissionFromStartService()1064 public void testGrantWritePermissionFromStartService() { 1065 doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, false); 1066 doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, true); 1067 } 1068 testGrantReadPrivateFromStartService()1069 public void testGrantReadPrivateFromStartService() { 1070 doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, false); 1071 doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, true); 1072 } 1073 testGrantWritePrivateFromStartService()1074 public void testGrantWritePrivateFromStartService() { 1075 doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, false); 1076 doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, true); 1077 } 1078 1079 /** 1080 * Test that ctspermissionwithsignaturepath can't grant read permissions 1081 * on paths it doesn't have permission to. 1082 */ testGrantReadUriActivityPathPermissionToSelf()1083 public void testGrantReadUriActivityPathPermissionToSelf() { 1084 doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH, 1085 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1086 } 1087 1088 /** 1089 * Test that ctspermissionwithsignaturepath can't grant write permissions 1090 * on paths it doesn't have permission to. 1091 */ testGrantWriteUriActivityPathPermissionToSelf()1092 public void testGrantWriteUriActivityPathPermissionToSelf() { 1093 doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH, 1094 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1095 } 1096 1097 /** 1098 * Test that ctspermissionwithsignaturepath can't grant read permissions 1099 * on paths it doesn't have permission to. 1100 */ testGrantReadUriActivitySubPathPermissionToSelf()1101 public void testGrantReadUriActivitySubPathPermissionToSelf() { 1102 doTryGrantUriActivityPermissionToSelf( 1103 Uri.withAppendedPath(PERM_URI_PATH, "foo"), 1104 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1105 } 1106 1107 /** 1108 * Test that ctspermissionwithsignaturepath can't grant write permissions 1109 * on paths it doesn't have permission to. 1110 */ testGrantWriteUriActivitySubPathPermissionToSelf()1111 public void testGrantWriteUriActivitySubPathPermissionToSelf() { 1112 doTryGrantUriActivityPermissionToSelf( 1113 Uri.withAppendedPath(PERM_URI_PATH, "foo"), 1114 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1115 } 1116 1117 /** 1118 * Test that the ctspermissionwithsignaturepath content provider can grant a read 1119 * permission. 1120 */ testGrantReadPathPermissionFromStartActivity()1121 public void testGrantReadPathPermissionFromStartActivity() { 1122 doTestGrantActivityUriReadPermission(PERM_URI_PATH, false); 1123 doTestGrantActivityUriReadPermission(PERM_URI_PATH, true); 1124 } 1125 1126 /** 1127 * Test that the ctspermissionwithsignaturepath content provider can grant a write 1128 * permission. 1129 */ testGrantWritePathPermissionFromStartActivity()1130 public void testGrantWritePathPermissionFromStartActivity() { 1131 doTestGrantActivityUriWritePermission(PERM_URI_PATH, false); 1132 doTestGrantActivityUriWritePermission(PERM_URI_PATH, true); 1133 } 1134 1135 /** 1136 * Test that the ctspermissionwithsignaturepath content provider can grant a read 1137 * permission. 1138 */ testGrantReadPathPermissionFromStartService()1139 public void testGrantReadPathPermissionFromStartService() { 1140 doTestGrantServiceUriReadPermission(PERM_URI_PATH, false); 1141 doTestGrantServiceUriReadPermission(PERM_URI_PATH, true); 1142 } 1143 1144 /** 1145 * Test that the ctspermissionwithsignaturepath content provider can grant a write 1146 * permission. 1147 */ testGrantWritePathPermissionFromStartService()1148 public void testGrantWritePathPermissionFromStartService() { 1149 doTestGrantServiceUriWritePermission(PERM_URI_PATH, false); 1150 doTestGrantServiceUriWritePermission(PERM_URI_PATH, true); 1151 } 1152 1153 /** 1154 * Verify that we can access paths outside the {@code path-permission} 1155 * protections, which should only rely on {@code provider} permissions. 1156 */ testRestrictingProviderNoMatchingPath()1157 public void testRestrictingProviderNoMatchingPath() { 1158 assertReadingContentUriAllowed(PERM_URI_PATH_RESTRICTING); 1159 assertWritingContentUriAllowed(PERM_URI_PATH_RESTRICTING); 1160 1161 // allowed by no top-level permission 1162 final Uri test = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("fo").build(); 1163 assertReadingContentUriAllowed(test); 1164 assertWritingContentUriAllowed(test); 1165 } 1166 1167 /** 1168 * Verify that paths under {@code path-permission} restriction aren't 1169 * allowed, even though the {@code provider} requires no permissions. 1170 */ testRestrictingProviderMatchingPathDenied()1171 public void testRestrictingProviderMatchingPathDenied() { 1172 // rejected by "foo" prefix 1173 final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("foo").build(); 1174 assertReadingContentUriNotAllowed(test1, null); 1175 assertWritingContentUriNotAllowed(test1, null); 1176 1177 // rejected by "foo" prefix 1178 final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon() 1179 .appendPath("foo").appendPath("ba").build(); 1180 assertReadingContentUriNotAllowed(test2, null); 1181 assertWritingContentUriNotAllowed(test2, null); 1182 } 1183 1184 /** 1185 * Test that shady {@link Uri} are blocked by {@code path-permission}. 1186 */ testRestrictingProviderMatchingShadyPaths()1187 public void testRestrictingProviderMatchingShadyPaths() { 1188 assertContentUriAllowed( 1189 Uri.parse("content://ctspermissionwithsignaturepathrestricting/")); 1190 assertContentUriAllowed( 1191 Uri.parse("content://ctspermissionwithsignaturepathrestricting//")); 1192 assertContentUriAllowed( 1193 Uri.parse("content://ctspermissionwithsignaturepathrestricting///")); 1194 assertContentUriNotAllowed( 1195 Uri.parse("content://ctspermissionwithsignaturepathrestricting/foo"), null); 1196 assertContentUriNotAllowed( 1197 Uri.parse("content://ctspermissionwithsignaturepathrestricting//foo"), null); 1198 assertContentUriNotAllowed( 1199 Uri.parse("content://ctspermissionwithsignaturepathrestricting///foo"), null); 1200 assertContentUriNotAllowed( 1201 Uri.parse("content://ctspermissionwithsignaturepathrestricting/foo//baz"), null); 1202 } 1203 1204 /** 1205 * Verify that at least one {@code path-permission} rule will grant access, 1206 * even if the caller doesn't hold another matching {@code path-permission}. 1207 */ testRestrictingProviderMultipleMatchingPath()1208 public void testRestrictingProviderMultipleMatchingPath() { 1209 // allowed by narrow "foo/bar" prefix 1210 final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon() 1211 .appendPath("foo").appendPath("bar").build(); 1212 assertReadingContentUriAllowed(test1); 1213 assertWritingContentUriAllowed(test1); 1214 1215 // allowed by narrow "foo/bar" prefix 1216 final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon() 1217 .appendPath("foo").appendPath("bar2").build(); 1218 assertReadingContentUriAllowed(test2); 1219 assertWritingContentUriAllowed(test2); 1220 } 1221 testGetMimeTypePermission()1222 public void testGetMimeTypePermission() { 1223 // Precondition: no current access. 1224 assertReadingContentUriNotAllowed(PERM_URI, "shouldn't read when starting test"); 1225 assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test"); 1226 1227 // All apps should be able to get MIME type regardless of permission. 1228 assertEquals(getContext().getContentResolver().getType(PERM_URI), EXPECTED_MIME_TYPE); 1229 } 1230 testGetMimeTypePrivate()1231 public void testGetMimeTypePrivate() { 1232 // Precondition: no current access. 1233 assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read when starting test"); 1234 assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test"); 1235 1236 // All apps should be able to get MIME type even if provider is private. 1237 assertEquals(getContext().getContentResolver().getType(PRIV_URI), EXPECTED_MIME_TYPE); 1238 } 1239 testGetMimeTypeAmbiguous()1240 public void testGetMimeTypeAmbiguous() { 1241 // Precondition: no current access. 1242 assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read when starting test"); 1243 assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write when starting test"); 1244 1245 // All apps should be able to get MIME type even if provider is private. 1246 assertEquals(getContext().getContentResolver().getType(AMBIGUOUS_URI), EXPECTED_MIME_TYPE); 1247 } 1248 1249 /** 1250 * Old App Compatibility Test 1251 * 1252 * We should be able to access the mime type of a content provider of an older 1253 * application, even if that application didn't explicitly declare either 1254 * exported=true or exported=false 1255 */ testGetMimeTypeAmbiguousCompat()1256 public void testGetMimeTypeAmbiguousCompat() { 1257 // All apps should be able to get MIME type even if provider is private. 1258 assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS, 1259 getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT)); 1260 } 1261 1262 /** 1263 * Validate behavior of persistable permission grants. 1264 */ testGrantPersistableUriPermission()1265 public void testGrantPersistableUriPermission() { 1266 final ContentResolver resolver = getContext().getContentResolver(); 1267 1268 final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo"); 1269 final ClipData clip = makeSingleClipData(target); 1270 1271 // Make sure we can't see the target 1272 assertReadingClipNotAllowed(clip, "reading should have failed"); 1273 assertWritingClipNotAllowed(clip, "writing should have failed"); 1274 1275 // Make sure we can't take a grant we don't have 1276 try { 1277 resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1278 fail("taking read should have failed"); 1279 } catch (SecurityException expected) { 1280 } 1281 1282 // And since we were just installed, no persisted grants yet 1283 assertNoPersistedUriPermission(); 1284 1285 // Now, let's grant ourselves some access 1286 ReceiveUriActivity.clearStarted(); 1287 grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION 1288 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 1289 ReceiveUriActivity.waitForStart(); 1290 1291 // We should now have reading access, even before taking the persistable 1292 // grant. Persisted grants should still be empty. 1293 assertReadingClipAllowed(clip); 1294 assertWritingClipNotAllowed(clip, "writing should have failed"); 1295 assertNoPersistedUriPermission(); 1296 1297 // Take the read grant and verify we have it! 1298 long before = System.currentTimeMillis(); 1299 resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1300 long after = System.currentTimeMillis(); 1301 assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after); 1302 1303 // Make sure we can't take a grant we don't have 1304 try { 1305 resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1306 fail("taking write should have failed"); 1307 } catch (SecurityException expected) { 1308 } 1309 1310 // Launch again giving ourselves persistable read and write access 1311 ReceiveUriActivity.clearNewIntent(); 1312 grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION 1313 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 1314 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 1315 ReceiveUriActivity.waitForNewIntent(); 1316 1317 // Previous persisted grant should be unchanged 1318 assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after); 1319 1320 // We should have both read and write; read is persisted, and write 1321 // isn't persisted yet. 1322 assertReadingClipAllowed(clip); 1323 assertWritingClipAllowed(clip); 1324 1325 // Take again, but still only read; should just update timestamp 1326 before = System.currentTimeMillis(); 1327 resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1328 after = System.currentTimeMillis(); 1329 assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after); 1330 1331 // And take yet again, both read and write 1332 before = System.currentTimeMillis(); 1333 resolver.takePersistableUriPermission(target, 1334 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1335 after = System.currentTimeMillis(); 1336 assertPersistedUriPermission(target, 1337 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 1338 before, after); 1339 1340 // Now drop the persisted grant; write first, then read 1341 resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1342 assertPersistedUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after); 1343 resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1344 assertNoPersistedUriPermission(); 1345 1346 // And even though we dropped the persistable grants, our activity is 1347 // still running with the global grants (until reboot). 1348 assertReadingClipAllowed(clip); 1349 assertWritingClipAllowed(clip); 1350 1351 ReceiveUriActivity.finishCurInstanceSync(); 1352 } 1353 assertNoPersistedUriPermission()1354 private void assertNoPersistedUriPermission() { 1355 assertPersistedUriPermission(null, 0, -1, -1); 1356 } 1357 assertPersistedUriPermission(Uri uri, int flags, long before, long after)1358 private void assertPersistedUriPermission(Uri uri, int flags, long before, long after) { 1359 // Assert local 1360 final List<UriPermission> perms = getContext() 1361 .getContentResolver().getPersistedUriPermissions(); 1362 if (uri != null) { 1363 assertEquals("expected exactly one permission", 1, perms.size()); 1364 1365 final UriPermission perm = perms.get(0); 1366 assertEquals("unexpected uri", uri, perm.getUri()); 1367 1368 final long actual = perm.getPersistedTime(); 1369 if (before != -1) { 1370 assertTrue("found " + actual + " before " + before, actual >= before); 1371 } 1372 if (after != -1) { 1373 assertTrue("found " + actual + " after " + after, actual <= after); 1374 } 1375 1376 final boolean expectedRead = (flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0; 1377 final boolean expectedWrite = (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0; 1378 assertEquals("unexpected read status", expectedRead, perm.isReadPermission()); 1379 assertEquals("unexpected write status", expectedWrite, perm.isWritePermission()); 1380 1381 } else { 1382 assertEquals("expected zero permissions", 0, perms.size()); 1383 } 1384 1385 // And assert remote 1386 Intent intent = new Intent(); 1387 intent.setAction(ACTION_VERIFY_OUTGOING_PERSISTED); 1388 intent.putExtra(EXTRA_URI, uri); 1389 call(intent); 1390 } 1391 1392 /** 1393 * Validate behavior of prefix permission grants. 1394 */ testGrantPrefixUriPermission()1395 public void testGrantPrefixUriPermission() throws Exception { 1396 final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo1"); 1397 final Uri targetMeow = Uri.withAppendedPath(target, "meow"); 1398 final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat"); 1399 1400 final ClipData clip = makeSingleClipData(target); 1401 final ClipData clipMeow = makeSingleClipData(targetMeow); 1402 final ClipData clipMeowCat = makeSingleClipData(targetMeowCat); 1403 1404 // Make sure we can't see the target 1405 assertReadingClipNotAllowed(clip, "reading should have failed"); 1406 assertWritingClipNotAllowed(clip, "writing should have failed"); 1407 1408 // Give ourselves prefix read access 1409 ReceiveUriActivity.clearStarted(); 1410 grantClipUriPermission(clipMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION 1411 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 1412 ReceiveUriActivity.waitForStart(); 1413 1414 // Verify prefix read access 1415 assertReadingClipNotAllowed(clip, "reading should have failed"); 1416 assertReadingClipAllowed(clipMeow); 1417 assertReadingClipAllowed(clipMeowCat); 1418 assertWritingClipNotAllowed(clip, "writing should have failed"); 1419 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1420 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1421 1422 // Now give ourselves exact write access 1423 ReceiveUriActivity.clearNewIntent(); 1424 grantClipUriPermission(clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false); 1425 ReceiveUriActivity.waitForNewIntent(); 1426 1427 // Verify we have exact write access, but not prefix write 1428 assertReadingClipNotAllowed(clip, "reading should have failed"); 1429 assertReadingClipAllowed(clipMeow); 1430 assertReadingClipAllowed(clipMeowCat); 1431 assertWritingClipAllowed(clip); 1432 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1433 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1434 1435 ReceiveUriActivity.finishCurInstanceSync(); 1436 } 1437 testGrantPersistablePrefixUriPermission()1438 public void testGrantPersistablePrefixUriPermission() { 1439 final ContentResolver resolver = getContext().getContentResolver(); 1440 1441 final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo2"); 1442 final Uri targetMeow = Uri.withAppendedPath(target, "meow"); 1443 1444 final ClipData clip = makeSingleClipData(target); 1445 final ClipData clipMeow = makeSingleClipData(targetMeow); 1446 1447 // Make sure we can't see the target 1448 assertReadingClipNotAllowed(clip, "reading should have failed"); 1449 1450 // Give ourselves prefix read access 1451 ReceiveUriActivity.clearStarted(); 1452 grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION 1453 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 1454 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false); 1455 ReceiveUriActivity.waitForStart(); 1456 1457 // Verify prefix read access 1458 assertReadingClipAllowed(clip); 1459 assertReadingClipAllowed(clipMeow); 1460 1461 // Verify we can persist direct grant 1462 long before = System.currentTimeMillis(); 1463 resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1464 long after = System.currentTimeMillis(); 1465 assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after); 1466 1467 // But we can't take anywhere under the prefix 1468 try { 1469 resolver.takePersistableUriPermission(targetMeow, 1470 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1471 fail("taking under prefix should have failed"); 1472 } catch (SecurityException expected) { 1473 } 1474 1475 // Should still have access regardless of taking 1476 assertReadingClipAllowed(clip); 1477 assertReadingClipAllowed(clipMeow); 1478 1479 // And clean up our grants 1480 resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1481 assertNoPersistedUriPermission(); 1482 1483 ReceiveUriActivity.finishCurInstanceSync(); 1484 } 1485 1486 /** 1487 * Validate behavior of directly granting/revoking permission grants. 1488 */ testDirectGrantRevokeUriPermission()1489 public void testDirectGrantRevokeUriPermission() throws Exception { 1490 final ContentResolver resolver = getContext().getContentResolver(); 1491 1492 final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo3"); 1493 final Uri targetMeow = Uri.withAppendedPath(target, "meow"); 1494 final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat"); 1495 1496 final ClipData clip = makeSingleClipData(target); 1497 final ClipData clipMeow = makeSingleClipData(targetMeow); 1498 final ClipData clipMeowCat = makeSingleClipData(targetMeowCat); 1499 1500 // Make sure we can't see the target 1501 assertReadingClipNotAllowed(clipMeow, "reading should have failed"); 1502 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1503 1504 // Give ourselves some grants: 1505 // /meow/cat WRITE|PERSISTABLE 1506 // /meow READ|PREFIX 1507 // /meow WRITE 1508 grantClipUriPermissionViaContext(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION 1509 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 1510 grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION 1511 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 1512 grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1513 1514 long before = System.currentTimeMillis(); 1515 resolver.takePersistableUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1516 long after = System.currentTimeMillis(); 1517 assertPersistedUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after); 1518 1519 // Verify they look good 1520 assertReadingClipNotAllowed(clip, "reading should have failed"); 1521 assertReadingClipAllowed(clipMeow); 1522 assertReadingClipAllowed(clipMeowCat); 1523 assertWritingClipNotAllowed(clip, "writing should have failed"); 1524 assertWritingClipAllowed(clipMeow); 1525 assertWritingClipAllowed(clipMeowCat); 1526 1527 // Revoke anyone with write under meow 1528 revokeClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1529 1530 // This should have nuked persisted permission at lower level, but it 1531 // shoulnd't have touched our prefix read. 1532 assertReadingClipNotAllowed(clip, "reading should have failed"); 1533 assertReadingClipAllowed(clipMeow); 1534 assertReadingClipAllowed(clipMeowCat); 1535 assertWritingClipNotAllowed(clip, "writing should have failed"); 1536 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1537 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1538 assertNoPersistedUriPermission(); 1539 1540 // Revoking read at top of tree should nuke everything else 1541 revokeClipUriPermissionViaContext(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1542 assertReadingClipNotAllowed(clip, "reading should have failed"); 1543 assertReadingClipNotAllowed(clipMeow, "reading should have failed"); 1544 assertReadingClipNotAllowed(clipMeowCat, "reading should have failed"); 1545 assertWritingClipNotAllowed(clip, "writing should have failed"); 1546 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1547 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1548 assertNoPersistedUriPermission(); 1549 } 1550 1551 /** 1552 * Validate behavior of a direct permission grant, where the receiver of 1553 * that permission revokes it. 1554 */ testDirectGrantReceiverRevokeUriPermission()1555 public void testDirectGrantReceiverRevokeUriPermission() throws Exception { 1556 final ContentResolver resolver = getContext().getContentResolver(); 1557 1558 final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo3"); 1559 final Uri targetMeow = Uri.withAppendedPath(target, "meow"); 1560 final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat"); 1561 1562 final ClipData clip = makeSingleClipData(target); 1563 final ClipData clipMeow = makeSingleClipData(targetMeow); 1564 final ClipData clipMeowCat = makeSingleClipData(targetMeowCat); 1565 1566 // Make sure we can't see the target 1567 assertReadingClipNotAllowed(clipMeow, "reading should have failed"); 1568 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1569 1570 // Give ourselves some grants: 1571 // /meow/cat WRITE|PERSISTABLE 1572 // /meow READ|PREFIX 1573 // /meow WRITE 1574 grantClipUriPermissionViaContext(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION 1575 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 1576 grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION 1577 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 1578 grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1579 1580 long before = System.currentTimeMillis(); 1581 resolver.takePersistableUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1582 long after = System.currentTimeMillis(); 1583 assertPersistedUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after); 1584 1585 // Verify they look good 1586 assertReadingClipNotAllowed(clip, "reading should have failed"); 1587 assertReadingClipAllowed(clipMeow); 1588 assertReadingClipAllowed(clipMeowCat); 1589 assertWritingClipNotAllowed(clip, "writing should have failed"); 1590 assertWritingClipAllowed(clipMeow); 1591 assertWritingClipAllowed(clipMeowCat); 1592 1593 // Revoke anyone with write under meow 1594 getContext().revokeUriPermission(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1595 1596 // This should have nuked persisted permission at lower level, but it 1597 // shoulnd't have touched our prefix read. 1598 assertReadingClipNotAllowed(clip, "reading should have failed"); 1599 assertReadingClipAllowed(clipMeow); 1600 assertReadingClipAllowed(clipMeowCat); 1601 assertWritingClipNotAllowed(clip, "writing should have failed"); 1602 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1603 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1604 assertNoPersistedUriPermission(); 1605 1606 // Revoking read at top of tree should nuke everything else 1607 getContext().revokeUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1608 assertReadingClipNotAllowed(clip, "reading should have failed"); 1609 assertReadingClipNotAllowed(clipMeow, "reading should have failed"); 1610 assertReadingClipNotAllowed(clipMeowCat, "reading should have failed"); 1611 assertWritingClipNotAllowed(clip, "writing should have failed"); 1612 assertWritingClipNotAllowed(clipMeow, "writing should have failed"); 1613 assertWritingClipNotAllowed(clipMeowCat, "writing should have failed"); 1614 assertNoPersistedUriPermission(); 1615 } 1616 testClipboardWithPermission()1617 public void testClipboardWithPermission() throws Exception { 1618 for (Uri target : GRANTABLE) { 1619 final ClipData clip = makeSingleClipData(target); 1620 1621 // Normally we can't see the underlying clip data 1622 assertReadingClipNotAllowed(clip); 1623 assertWritingClipNotAllowed(clip); 1624 1625 // Use shell's permissions to ensure we can access the clipboard 1626 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1627 .adoptShellPermissionIdentity(); 1628 ClipData clipFromClipboard; 1629 try { 1630 // But if someone puts it on the clipboard, we can read it 1631 setPrimaryClip(clip); 1632 clipFromClipboard = getContext() 1633 .getSystemService(ClipboardManager.class).getPrimaryClip(); 1634 } finally { 1635 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1636 .dropShellPermissionIdentity(); 1637 } 1638 assertClipDataEquals(clip, clipFromClipboard); 1639 assertReadingClipAllowed(clipFromClipboard); 1640 assertWritingClipNotAllowed(clipFromClipboard); 1641 1642 // And if clipboard is cleared, we lose access 1643 clearPrimaryClip(); 1644 assertReadingClipNotAllowed(clipFromClipboard); 1645 assertWritingClipNotAllowed(clipFromClipboard); 1646 } 1647 } 1648 testClipboardWithoutPermission()1649 public void testClipboardWithoutPermission() throws Exception { 1650 for (Uri target : NOT_GRANTABLE) { 1651 final ClipData clip = makeSingleClipData(target); 1652 1653 // Can't see it directly 1654 assertReadingClipNotAllowed(clip); 1655 assertWritingClipNotAllowed(clip); 1656 1657 // Can't put on clipboard if we don't own it 1658 try { 1659 setPrimaryClip(clip); 1660 fail("Unexpected ability to put protected data " + clip + " on clipboard!"); 1661 } catch (Exception expected) { 1662 } 1663 } 1664 } 1665 assertClipDataEquals(ClipData expected, ClipData actual)1666 private static void assertClipDataEquals(ClipData expected, ClipData actual) { 1667 assertEquals(expected.getItemCount(), actual.getItemCount()); 1668 for (int i = 0; i < expected.getItemCount(); i++) { 1669 final ClipData.Item expectedItem = expected.getItemAt(i); 1670 final ClipData.Item actualItem = actual.getItemAt(i); 1671 assertEquals(expectedItem.getText(), actualItem.getText()); 1672 assertEquals(expectedItem.getHtmlText(), actualItem.getHtmlText()); 1673 assertEquals(expectedItem.getIntent(), actualItem.getIntent()); 1674 assertEquals(expectedItem.getUri(), actualItem.getUri()); 1675 } 1676 } 1677 } 1678