1 /* 2 * Copyright (C) 2024 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_2024_0024; 18 19 import static android.Manifest.permission.CREATE_USERS; 20 import static android.os.Environment.buildPath; 21 22 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 23 24 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 25 import static com.android.sts.common.SystemUtil.poll; 26 27 import static com.google.common.truth.Truth.assertWithMessage; 28 import static com.google.common.truth.TruthJUnit.assume; 29 30 import android.app.Instrumentation; 31 import android.content.BroadcastReceiver; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.content.IntentFilter; 35 import android.content.pm.UserInfo; 36 import android.os.Build; 37 import android.os.Environment; 38 import android.os.UserManager; 39 import android.platform.test.annotations.AsbSecurityTest; 40 import android.security.cts.R; 41 import android.support.test.uiautomator.By; 42 import android.support.test.uiautomator.BySelector; 43 import android.support.test.uiautomator.UiDevice; 44 import android.support.test.uiautomator.Until; 45 46 import androidx.test.runner.AndroidJUnit4; 47 48 import com.android.sts.common.util.StsExtraBusinessLogicTestCase; 49 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 53 import java.util.List; 54 import java.util.concurrent.CompletableFuture; 55 import java.util.concurrent.TimeUnit; 56 import java.util.regex.Pattern; 57 58 @RunWith(AndroidJUnit4.class) 59 public class CVE_2024_0024 extends StsExtraBusinessLogicTestCase { 60 private static final int MAX_UNSIGNED_SHORT = (1 << 16) - 1; 61 UserManager mUserManager = null; 62 UserInfo mUserInfo = null; 63 64 @AsbSecurityTest(cveBugId = 293602317) 65 @Test grantSmsPermission()66 public void grantSmsPermission() { 67 try { 68 final Instrumentation instrumentation = getInstrumentation(); 69 final Context context = instrumentation.getContext(); 70 mUserManager = context.getSystemService(UserManager.class); 71 72 // Check if the device supports multiple users 73 assume().withMessage("This device does not support multiple users") 74 .that(mUserManager.supportsMultipleUsers()) 75 .isTrue(); 76 77 // Launch pocActivity 78 context.startActivity( 79 new Intent(context, PocActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 80 81 // Fetch and add the flag 'RECEIVER_NOT_EXPORTED' for 'TIRAMISU' and above versions to 82 // keep the code consistent 83 final int requiredFlag = 84 Build.VERSION.SDK_INT >= 33 /* TIRAMISU */ 85 ? (int) Context.class.getField("RECEIVER_NOT_EXPORTED").get(context) 86 : 0; 87 88 // Check if there is an exception while calling vulnerable function in PocActivity 89 // Register a broadcast receiver to get broadcast from PocActivity 90 CompletableFuture<String> broadcastReceived = new CompletableFuture<String>(); 91 context.registerReceiver( 92 new BroadcastReceiver() { 93 @Override 94 public void onReceive(Context context, Intent intent) { 95 try { 96 broadcastReceived.complete( 97 intent.getStringExtra( 98 context.getString( 99 R.string.CVE_2024_0024_exception))); 100 } catch (Exception e) { 101 // Ignore exceptions here 102 } 103 } 104 }, 105 new IntentFilter(context.getString(R.string.CVE_2024_0024_action)), 106 requiredFlag); 107 108 // Wait for broadcast from PocActivity 109 String exception = broadcastReceived.get(10_000L /* timeout */, TimeUnit.MILLISECONDS); 110 assume().withMessage("Exception occurred in PocActivity " + exception) 111 .that(exception) 112 .isNull(); 113 114 // Click ok 115 UiDevice uiDevice = UiDevice.getInstance(instrumentation); 116 BySelector okButtonSelector = By.text(Pattern.compile("ok", Pattern.CASE_INSENSITIVE)); 117 uiDevice.wait(Until.hasObject(okButtonSelector), 5_000L /* timeout */); 118 uiDevice.findObject(okButtonSelector).click(); 119 120 // Poll till user CVE_2024_0024_user is created and get it's user info 121 assume().withMessage("CVE_2024_0024_user was not found") 122 .that( 123 poll( 124 () -> { 125 return runWithShellPermissionIdentity( 126 () -> { 127 final List<UserInfo> list = 128 mUserManager.getUsers(); 129 for (UserInfo info : list) { 130 if (info.name.contains( 131 "CVE_2024_0024_user")) { 132 mUserInfo = info; 133 return true; 134 } 135 } 136 return false; 137 }, 138 CREATE_USERS); 139 })) 140 .isTrue(); 141 142 assume().withMessage("Unable to get created user's info").that(mUserInfo).isNotNull(); 143 assertWithMessage( 144 "Device is vulnerable to b/293602317 !!" 145 + " Create and persist a new secondary user without any" 146 + " restrictions via a super large accountType") 147 .that( 148 poll( 149 () -> { 150 return (buildPath( 151 Environment 152 .getDataSystemDirectory(), 153 "users", 154 mUserInfo.id + ".xml") 155 .length() 156 > MAX_UNSIGNED_SHORT - 1); 157 })) 158 .isFalse(); 159 } catch (Exception e) { 160 assume().that(e).isNull(); 161 } finally { 162 try { 163 mUserManager.removeUser(mUserInfo.id); 164 } catch (Exception ignore) { 165 // Ignore unintended exceptions 166 } 167 } 168 } 169 } 170