• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.CVE_2022_20360;
18 
19 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
20 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
21 
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assume.assumeFalse;
24 import static org.junit.Assume.assumeNoException;
25 import static org.junit.Assume.assumeTrue;
26 
27 import android.app.KeyguardManager;
28 import android.app.UiAutomation;
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.nfc.NfcAdapter;
33 import android.nfc.NfcManager;
34 import android.os.PowerManager;
35 import android.os.UserManager;
36 import android.provider.Settings;
37 
38 import androidx.test.runner.AndroidJUnit4;
39 
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 import java.lang.reflect.Constructor;
44 import java.lang.reflect.Method;
45 
46 @RunWith(AndroidJUnit4.class)
47 public class DeviceTest {
48 
49     @Test
testSecureNfcPreferenceController()50     public void testSecureNfcPreferenceController() {
51         boolean secureNfcEnabled = false;
52         NfcAdapter nfcAdapter = null;
53         UiAutomation uiAutomation = null;
54         try {
55             Context context = getApplicationContext();
56             NfcManager nfcManager = context.getSystemService(NfcManager.class);
57             nfcAdapter = nfcManager.getDefaultAdapter();
58             uiAutomation = getInstrumentation().getUiAutomation();
59 
60             // Secure NFC APIs require device to be unlocked hence check if device is unlocked
61             PowerManager powerManager = context.getSystemService(PowerManager.class);
62             KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
63             assumeTrue(context.getString(R.string.msgDeviceLocked),
64                     powerManager.isInteractive() && !keyguardManager.isKeyguardLocked());
65 
66 
67             // Save secure NFC state(enabled/disabled) and disable secure NFC for test
68             secureNfcEnabled = nfcAdapter.isSecureNfcEnabled();
69             if (secureNfcEnabled) {
70                 nfcAdapter.enableSecureNfc(false);
71             }
72             assumeFalse(context.getString(R.string.disableSecureNfcFailed),
73                     nfcAdapter.isSecureNfcEnabled());
74 
75             // Retrieve settings package name dynamically
76             Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
77             ComponentName settingsComponent =
78                     settingsIntent.resolveActivity(context.getPackageManager());
79             String settingsPkgName = settingsComponent != null ? settingsComponent.getPackageName()
80                     : context.getString(R.string.defaultSettingsPkg);
81 
82             // Get vulnerable method 'setChecked' using reflection
83             Context settingsContext = context.createPackageContext(settingsPkgName,
84                     Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
85             ClassLoader settingsClassLoader = settingsContext.getClassLoader();
86             Class<?> targetClass = settingsClassLoader.loadClass(settingsPkgName
87                     + context.getString(R.string.secureNfcPreferenceControllerClassName));
88             Constructor<?> targetClassCstr =
89                     targetClass.getConstructor(Context.class, String.class);
90             Object targetClassobject =
91                     targetClassCstr.newInstance(context, context.getString(R.string.key));
92             Method setCheckedMethod = targetClass
93                     .getDeclaredMethod(context.getString(R.string.setCheckedMethod), boolean.class);
94             setCheckedMethod.setAccessible(true);
95 
96             // Check if current user is guest user
97             uiAutomation.adoptShellPermissionIdentity(android.Manifest.permission.CREATE_USERS);
98             UserManager userManager = context.getSystemService(UserManager.class);
99             assumeTrue(userManager.isGuestUser());
100 
101             // Invoke vulnerable method 'setChecked'
102             boolean retVal = (boolean) setCheckedMethod.invoke(targetClassobject, true);
103             assertFalse(context.getString(R.string.msgTestFail), retVal);
104         } catch (Exception e) {
105             assumeNoException(e);
106         } finally {
107             try {
108                 // Disable secure NFC if it was disabled before the test
109                 if (!secureNfcEnabled) {
110                     nfcAdapter.enableSecureNfc(false);
111                 }
112             } catch (Exception ignored) {
113                 // Ignore any exception here
114             } finally {
115                 uiAutomation.dropShellPermissionIdentity();
116             }
117         }
118     }
119 }
120