1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.security.cts;
18 
19 import android.platform.test.annotations.AppModeInstant;
20 import android.platform.test.annotations.AppModeFull;
21 import android.util.Log;
22 import android.platform.test.annotations.AsbSecurityTest;
23 
24 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
25 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
26 import com.android.tradefed.log.LogUtil.CLog;
27 
28 import org.junit.After;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 import static org.junit.Assert.*;
35 import static org.hamcrest.CoreMatchers.*;
36 
37 /**
38  * Test that collects test results from test package android.security.cts.CVE_2021_0481.
39  *
40  * When this test builds, it also builds a support APK containing
41  * {@link android.sample.cts.CVE_2021_0481.SampleDeviceTest}, the results of which are
42  * collected from the hostside and reported accordingly.
43  */
44 @RunWith(DeviceJUnit4ClassRunner.class)
45 public class CVE_2021_0481 extends BaseHostJUnit4Test {
46     private static final String TEST_PKG = "android.security.cts.CVE_2021_0481";
47     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
48     private static final String TEST_APP = "CVE-2021-0481.apk";
49 
50     private static final String DEVICE_DIR1 = "/data/user_de/0/com.android.settings/shared_prefs/";
51     private static final String DEVICE_DIR2 = "/data/user_de/0/com.android.settings/cache/";
52 
53     //defined originally as
54     //private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
55     //in com.android.settings.users.EditUserPhotoController class
56     private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
57     private static final String TEST_FILE_NAME = "cve_2021_0481.txt";
58 
59     @Before
setUp()60     public void setUp() throws Exception {
61         uninstallPackage(getDevice(), TEST_PKG);
62     }
63 
64     @Test
65     @AsbSecurityTest(cveBugId = 172939189)
66     @AppModeFull
testRunDeviceTest()67     public void testRunDeviceTest() throws Exception {
68 
69         String cmd;
70 
71         //delete a source file just in case AdbUtils.pushResource()
72         //doesn't overwrite existing file
73         cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
74         AdbUtils.runCommandLine(cmd, getDevice());
75 
76         //push the source file to a device
77         AdbUtils.pushResource("/" + TEST_FILE_NAME, DEVICE_DIR1 + TEST_FILE_NAME, getDevice());
78 
79         //delete a destination file which is supposed to be created by a vulnerable device
80         //by coping TEST_FILE_NAME -> TAKE_PICTURE_FILE_NAME
81         cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
82         AdbUtils.runCommandLine(cmd, getDevice());
83 
84         installPackage();
85 
86         //ensure the screen is woken up.
87         //KEYCODE_WAKEUP wakes up the screen
88         //KEYCODE_MENU called twice unlocks the screen (if locked)
89         //Note: (applies to Android 12 only):
90         //      KEYCODE_MENU called less than twice doesnot unlock the screen
91         //      no matter how many times KEYCODE_HOME is called.
92         //      This is likely a timing issue which has to be investigated further
93         getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
94         getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
95         getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
96         getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
97 
98         //run the test
99         Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testUserPhotoSetUp"));
100 
101         //go to home screen after test
102         getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
103 
104         //Check if TEST_FILE_NAME has been copied by "Evil activity"
105         //If the file has been copied then it means the vulnerability is active so the test fails.
106         cmd = "cmp -s " + DEVICE_DIR1 + TEST_FILE_NAME + " " +
107             DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME + "; echo $?";
108         String result =  AdbUtils.runCommandLine(cmd, getDevice()).trim();
109         CLog.i(cmd + " -->" + result);
110 
111         //Delete files created by this test
112         cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
113         AdbUtils.runCommandLine(cmd, getDevice());
114         cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
115         AdbUtils.runCommandLine(cmd, getDevice());
116 
117         //final assert
118         assertThat(result, not(is("0")));
119     }
120 
installPackage()121     private void installPackage() throws Exception {
122         installPackage(TEST_APP, new String[0]);
123     }
124 }
125 
126