diff options
| author | 2022-09-02 17:26:11 +0000 | |
|---|---|---|
| committer | 2022-09-02 17:26:11 +0000 | |
| commit | e264ab6190b2050cbe7302ff65172ee7a22e4f03 (patch) | |
| tree | 7a678841949bb3671deddeeb0b711918493e0dac | |
| parent | e766e4e525583cfe6e76100141af019af5c6f14d (diff) | |
| parent | de117f20ffd67c2aa554ef6772d272ad018d8a0c (diff) | |
Merge "Fix vulnerability that allowed attackers to start arbitary activities" into tm-qpr-dev am: de117f20ff
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19775871
Change-Id: Iad0b84f489fa749e146769650dc87cd7008e137a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
7 files changed, 112 insertions, 14 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 490a7a474ae7..96cbe2fcf719 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2403,6 +2403,16 @@ package android.service.dreams { method public final boolean shouldShowComplications(); } + public class DreamService extends android.app.Service implements android.view.Window.Callback { + method @Nullable public static android.service.dreams.DreamService.DreamMetadata getDreamMetadata(@NonNull android.content.Context, @Nullable android.content.pm.ServiceInfo); + } + + public static final class DreamService.DreamMetadata { + field @Nullable public final android.graphics.drawable.Drawable previewImage; + field @Nullable public final android.content.ComponentName settingsActivity; + field @NonNull public final boolean showComplications; + } + } package android.service.notification { diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 2d461c6cf92e..75155383855b 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.TestApi; import android.app.Activity; import android.app.ActivityTaskManager; import android.app.AlarmManager; @@ -1124,7 +1125,8 @@ public class DreamService extends Service implements Window.Callback { * @hide */ @Nullable - public static DreamMetadata getDreamMetadata(Context context, + @TestApi + public static DreamMetadata getDreamMetadata(@NonNull Context context, @Nullable ServiceInfo serviceInfo) { if (serviceInfo == null) return null; @@ -1183,7 +1185,8 @@ public class DreamService extends Service implements Window.Callback { } } - private static ComponentName convertToComponentName(String flattenedString, + @Nullable + private static ComponentName convertToComponentName(@Nullable String flattenedString, ServiceInfo serviceInfo) { if (flattenedString == null) { return null; @@ -1193,7 +1196,17 @@ public class DreamService extends Service implements Window.Callback { return new ComponentName(serviceInfo.packageName, flattenedString); } - return ComponentName.unflattenFromString(flattenedString); + // Ensure that the component is from the same package as the dream service. If not, + // treat the component as invalid and return null instead. + final ComponentName cn = ComponentName.unflattenFromString(flattenedString); + if (cn == null) return null; + if (!cn.getPackageName().equals(serviceInfo.packageName)) { + Log.w(TAG, + "Inconsistent package name in component: " + cn.getPackageName() + + ", should be: " + serviceInfo.packageName); + return null; + } + return cn; } /** @@ -1489,6 +1502,7 @@ public class DreamService extends Service implements Window.Callback { * * @hide */ + @TestApi public static final class DreamMetadata { @Nullable public final ComponentName settingsActivity; diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 0483a60ca378..7ae70eb6886b 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -147,6 +147,19 @@ android:resource="@xml/test_dream_metadata" /> </service> + <service + android:name="com.android.server.dreams.TestDreamServiceWithInvalidSettings" + android:exported="false" + android:label="Test Dream" > + <intent-filter> + <action android:name="android.service.dreams.DreamService" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="android.service.dream" + android:resource="@xml/test_dream_metadata_invalid" /> + </service> + <receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:exported="true"> diff --git a/services/tests/servicestests/res/xml/test_dream_metadata.xml b/services/tests/servicestests/res/xml/test_dream_metadata.xml index aa054f1e9fa4..9905c69474ad 100644 --- a/services/tests/servicestests/res/xml/test_dream_metadata.xml +++ b/services/tests/servicestests/res/xml/test_dream_metadata.xml @@ -15,5 +15,5 @@ --> <dream xmlns:android="http://schemas.android.com/apk/res/android" - android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity" + android:settingsActivity="com.android.frameworks.servicestests/.TestDreamSettingsActivity" android:showClockAndComplications="false" /> diff --git a/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml b/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml new file mode 100644 index 000000000000..47864d9cf62d --- /dev/null +++ b/services/tests/servicestests/res/xml/test_dream_metadata_invalid.xml @@ -0,0 +1,20 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<!-- The settings activity is in a different package, which is invalid --> +<dream xmlns:android="http://schemas.android.com/apk/res/android" + android:settingsActivity="com.android.server.dreams/.TestDreamSettingsActivity" + android:showClockAndComplications="false"/> diff --git a/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java index 74d2e0f231bb..0efd296fd8b6 100644 --- a/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/dreams/DreamServiceTest.java @@ -16,7 +16,8 @@ package com.android.server.dreams; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertFalse; import android.content.ComponentName; @@ -35,21 +36,36 @@ import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class DreamServiceTest { + private static final String TEST_PACKAGE_NAME = "com.android.frameworks.servicestests"; + @Test public void testMetadataParsing() throws PackageManager.NameNotFoundException { - final String testPackageName = "com.android.frameworks.servicestests"; final String testDreamClassName = "com.android.server.dreams.TestDreamService"; - final String testSettingsActivity = "com.android.server.dreams/.TestDreamSettingsActivity"; + final String testSettingsActivity = + "com.android.frameworks.servicestests/.TestDreamSettingsActivity"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); - final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertThat(metadata.settingsActivity).isEqualTo( + ComponentName.unflattenFromString(testSettingsActivity)); + assertFalse(metadata.showComplications); + } + + @Test + public void testMetadataParsing_invalidSettingsActivity() + throws PackageManager.NameNotFoundException { + final String testDreamClassName = + "com.android.server.dreams.TestDreamServiceWithInvalidSettings"; + final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName); + + assertThat(metadata.settingsActivity).isNull(); + } + private DreamService.DreamMetadata getDreamMetadata(String dreamClassName) + throws PackageManager.NameNotFoundException { + final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); final ServiceInfo si = context.getPackageManager().getServiceInfo( - new ComponentName(testPackageName, testDreamClassName), + new ComponentName(TEST_PACKAGE_NAME, dreamClassName), PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); - final DreamService.DreamMetadata metadata = DreamService.getDreamMetadata(context, si); - - assertEquals(0, metadata.settingsActivity.compareTo( - ComponentName.unflattenFromString(testSettingsActivity))); - assertFalse(metadata.showComplications); + return DreamService.getDreamMetadata(context, si); } } diff --git a/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java b/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java new file mode 100644 index 000000000000..5c7d02fb755c --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/dreams/TestDreamServiceWithInvalidSettings.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.dreams; + +import android.service.dreams.DreamService; + +/** + * Dream service implementation for unit testing, where the settings activity is invalid. + */ +public class TestDreamServiceWithInvalidSettings extends DreamService { +} |