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 com.android.server.permission.access 18 19 import android.content.Context 20 import android.content.pm.PackageManager 21 import android.content.pm.PackageManagerInternal 22 import android.os.SystemProperties 23 import android.os.UserHandle 24 import com.android.internal.annotations.Keep 25 import com.android.server.LocalManagerRegistry 26 import com.android.server.LocalServices 27 import com.android.server.SystemConfig 28 import com.android.server.SystemService 29 import com.android.server.appop.AppOpsCheckingServiceInterface 30 import com.android.server.permission.access.appop.AppOpService 31 import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports 32 import com.android.server.permission.access.permission.PermissionService 33 import com.android.server.pm.KnownPackages 34 import com.android.server.pm.PackageManagerLocal 35 import com.android.server.pm.UserManagerService 36 import com.android.server.pm.permission.PermissionManagerServiceInterface 37 import com.android.server.pm.pkg.PackageState 38 import kotlin.contracts.ExperimentalContracts 39 import kotlin.contracts.InvocationKind 40 import kotlin.contracts.contract 41 42 @Keep 43 class AccessCheckingService(context: Context) : SystemService(context) { 44 @Volatile 45 private lateinit var state: AccessState 46 private val stateLock = Any() 47 48 private val policy = AccessPolicy() 49 50 private val persistence = AccessPersistence(policy) 51 52 private lateinit var appOpService: AppOpService 53 private lateinit var permissionService: PermissionService 54 55 private lateinit var packageManagerInternal: PackageManagerInternal 56 private lateinit var packageManagerLocal: PackageManagerLocal 57 private lateinit var userManagerService: UserManagerService 58 private lateinit var systemConfig: SystemConfig 59 60 override fun onStart() { 61 appOpService = AppOpService(this) 62 permissionService = PermissionService(this) 63 64 LocalServices.addService(AppOpsCheckingServiceInterface::class.java, appOpService) 65 LocalServices.addService(PermissionManagerServiceInterface::class.java, permissionService) 66 } 67 68 fun initialize() { 69 packageManagerInternal = LocalServices.getService(PackageManagerInternal::class.java) 70 packageManagerLocal = 71 LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java) 72 userManagerService = UserManagerService.getInstance() 73 systemConfig = SystemConfig.getInstance() 74 75 val userIds = IntSet(userManagerService.userIdsIncludingPreCreated) 76 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 77 val knownPackages = packageManagerInternal.knownPackages 78 val isLeanback = systemConfig.isLeanback 79 val configPermissions = systemConfig.permissions 80 val privilegedPermissionAllowlistPackages = 81 systemConfig.privilegedPermissionAllowlistPackages 82 val permissionAllowlist = systemConfig.permissionAllowlist 83 val implicitToSourcePermissions = systemConfig.implicitToSourcePermissions 84 85 val state = AccessState() 86 policy.initialize( 87 state, userIds, packageStates, disabledSystemPackageStates, knownPackages, isLeanback, 88 configPermissions, privilegedPermissionAllowlistPackages, permissionAllowlist, 89 implicitToSourcePermissions 90 ) 91 persistence.initialize() 92 persistence.read(state) 93 this.state = state 94 95 mutateState { 96 with(policy) { onInitialized() } 97 } 98 99 appOpService.initialize() 100 permissionService.initialize() 101 } 102 103 private val SystemConfig.isLeanback: Boolean 104 get() = PackageManager.FEATURE_LEANBACK in availableFeatures 105 106 private val SystemConfig.privilegedPermissionAllowlistPackages: IndexedListSet<String> 107 get() = IndexedListSet<String>().apply { 108 this += "android" 109 if (PackageManager.FEATURE_AUTOMOTIVE in availableFeatures) { 110 // Note that SystemProperties.get(String, String) forces returning an empty string 111 // even if we pass null for the def parameter. 112 val carServicePackage = SystemProperties.get("ro.android.car.carservice.package") 113 if (carServicePackage.isNotEmpty()) { 114 this += carServicePackage 115 } 116 } 117 } 118 119 private val SystemConfig.implicitToSourcePermissions: IndexedMap<String, IndexedListSet<String>> 120 get() = IndexedMap<String, IndexedListSet<String>>().apply { 121 splitPermissions.forEach { splitPermissionInfo -> 122 val sourcePermissionName = splitPermissionInfo.splitPermission 123 splitPermissionInfo.newPermissions.forEach { implicitPermissionName -> 124 getOrPut(implicitPermissionName) { IndexedListSet() } += sourcePermissionName 125 } 126 } 127 } 128 129 fun getDecision(subject: AccessUri, `object`: AccessUri): Int = 130 getState { 131 with(policy) { getDecision(subject, `object`) } 132 } 133 134 fun setDecision(subject: AccessUri, `object`: AccessUri, decision: Int) { 135 mutateState { 136 with(policy) { setDecision(subject, `object`, decision) } 137 } 138 } 139 140 internal fun onUserAdded(userId: Int) { 141 mutateState { 142 with(policy) { onUserAdded(userId) } 143 } 144 } 145 146 internal fun onUserRemoved(userId: Int) { 147 mutateState { 148 with(policy) { onUserRemoved(userId) } 149 } 150 } 151 152 internal fun onStorageVolumeMounted(volumeUuid: String?, isSystemUpdated: Boolean) { 153 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 154 val knownPackages = packageManagerInternal.knownPackages 155 mutateState { 156 with(policy) { 157 onStorageVolumeMounted( 158 packageStates, disabledSystemPackageStates, knownPackages, volumeUuid, 159 isSystemUpdated 160 ) 161 } 162 } 163 } 164 165 internal fun onPackageAdded(packageName: String) { 166 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 167 val knownPackages = packageManagerInternal.knownPackages 168 mutateState { 169 with(policy) { 170 onPackageAdded( 171 packageStates, disabledSystemPackageStates, knownPackages, packageName 172 ) 173 } 174 } 175 } 176 177 internal fun onPackageRemoved(packageName: String, appId: Int) { 178 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 179 val knownPackages = packageManagerInternal.knownPackages 180 mutateState { 181 with(policy) { 182 onPackageRemoved( 183 packageStates, disabledSystemPackageStates, knownPackages, packageName, appId 184 ) 185 } 186 } 187 } 188 189 internal fun onPackageInstalled(packageName: String, userId: Int) { 190 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 191 val knownPackages = packageManagerInternal.knownPackages 192 mutateState { 193 with(policy) { 194 onPackageInstalled( 195 packageStates, disabledSystemPackageStates, knownPackages, packageName, userId 196 ) 197 } 198 } 199 } 200 201 internal fun onPackageUninstalled(packageName: String, appId: Int, userId: Int) { 202 val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates 203 val knownPackages = packageManagerInternal.knownPackages 204 mutateState { 205 with(policy) { 206 onPackageUninstalled( 207 packageStates, disabledSystemPackageStates, knownPackages, packageName, appId, 208 userId 209 ) 210 } 211 } 212 } 213 214 internal fun onSystemReady() { 215 mutateState { 216 with(policy) { onSystemReady() } 217 } 218 } 219 220 private val PackageManagerLocal.allPackageStates: 221 Pair<Map<String, PackageState>, Map<String, PackageState>> 222 get() = withUnfilteredSnapshot().use { it.packageStates to it.disabledSystemPackageStates } 223 224 private val PackageManagerInternal.knownPackages: IntMap<Array<String>> 225 get() = IntMap<Array<String>>().apply { 226 this[KnownPackages.PACKAGE_INSTALLER] = getKnownPackageNames( 227 KnownPackages.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM 228 ) 229 this[KnownPackages.PACKAGE_PERMISSION_CONTROLLER] = getKnownPackageNames( 230 KnownPackages.PACKAGE_PERMISSION_CONTROLLER, UserHandle.USER_SYSTEM 231 ) 232 this[KnownPackages.PACKAGE_VERIFIER] = getKnownPackageNames( 233 KnownPackages.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM 234 ) 235 this[KnownPackages.PACKAGE_SETUP_WIZARD] = getKnownPackageNames( 236 KnownPackages.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM 237 ) 238 this[KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER] = getKnownPackageNames( 239 KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER, UserHandle.USER_SYSTEM 240 ) 241 this[KnownPackages.PACKAGE_CONFIGURATOR] = getKnownPackageNames( 242 KnownPackages.PACKAGE_CONFIGURATOR, UserHandle.USER_SYSTEM 243 ) 244 this[KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER] = getKnownPackageNames( 245 KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER, UserHandle.USER_SYSTEM 246 ) 247 this[KnownPackages.PACKAGE_APP_PREDICTOR] = getKnownPackageNames( 248 KnownPackages.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM 249 ) 250 this[KnownPackages.PACKAGE_COMPANION] = getKnownPackageNames( 251 KnownPackages.PACKAGE_COMPANION, UserHandle.USER_SYSTEM 252 ) 253 this[KnownPackages.PACKAGE_RETAIL_DEMO] = getKnownPackageNames( 254 KnownPackages.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM 255 ) 256 this[KnownPackages.PACKAGE_RECENTS] = getKnownPackageNames( 257 KnownPackages.PACKAGE_RECENTS, UserHandle.USER_SYSTEM 258 ) 259 } 260 261 @OptIn(ExperimentalContracts::class) 262 internal inline fun <T> getState(action: GetStateScope.() -> T): T { 263 contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } 264 return GetStateScope(state).action() 265 } 266 267 @OptIn(ExperimentalContracts::class) 268 internal inline fun mutateState(crossinline action: MutateStateScope.() -> Unit) { 269 contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } 270 synchronized(stateLock) { 271 val oldState = state 272 val newState = oldState.copy() 273 MutateStateScope(oldState, newState).action() 274 persistence.write(newState) 275 state = newState 276 with(policy) { GetStateScope(newState).onStateMutated() } 277 } 278 } 279 280 internal fun getSchemePolicy(subjectScheme: String, objectScheme: String): SchemePolicy = 281 policy.getSchemePolicy(subjectScheme, objectScheme) 282 } 283