Make AccessCheckingService a SystemService.

And connect it with the existing parts of the system, so that we can
remove all the stub classes created for compilation.

The new implementations of the app op and permission service interface
are now published via LocalServices and available in services-core.

The external states are now actually available, including the package
states being provided by PackageManagerLocal. The callbacks are
temporarily being delivered by the new permission service because only
it has the blocking callbacks at the right timing during package
changes.

A new intialize() function is added for the new app op and permission
services. It is called when the core system services (including ours)
have read the on-disk state and are ready, so that our services can
now retrieve their dependent services and start working. Any call to
the new services before this call can't have meaningful results and
should be no-op'ed in some way.

Bug: 182523293
Test: presubmit
Change-Id: I9c4ec4b7d56ec9d97c4b097cacc7680fa0a08690
This commit is contained in:
Hai Zhang
2022-12-10 22:46:56 -08:00
parent 4a51535c33
commit a8c89fe807
19 changed files with 292 additions and 401 deletions

View File

@@ -16,11 +16,23 @@
package com.android.server.permission.access
import android.content.Context
import com.android.internal.annotations.Keep
import com.android.server.permission.access.external.PackageState
import com.android.server.LocalManagerRegistry
import com.android.server.LocalServices
import com.android.server.SystemService
import com.android.server.appop.AppOpsCheckingServiceInterface
import com.android.server.permission.access.appop.AppOpService
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.permission.PermissionService
import com.android.server.pm.PackageManagerLocal
import com.android.server.pm.UserManagerService
import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.PackageState
@Keep
class AccessCheckingService {
class AccessCheckingService(context: Context) : SystemService(context) {
@Volatile
private lateinit var state: AccessState
private val stateLock = Any()
@@ -29,14 +41,35 @@ class AccessCheckingService {
private val persistence = AccessPersistence(policy)
fun init() {
private lateinit var appOpService: AppOpService
private lateinit var permissionService: PermissionService
private lateinit var packageManagerLocal: PackageManagerLocal
private lateinit var userManagerService: UserManagerService
override fun onStart() {
appOpService = AppOpService(this)
permissionService = PermissionService(this)
LocalServices.addService(AppOpsCheckingServiceInterface::class.java, appOpService)
LocalServices.addService(PermissionManagerServiceInterface::class.java, permissionService)
}
fun initialize() {
packageManagerLocal =
LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
userManagerService = UserManagerService.getInstance()
val userIds = IntSet(userManagerService.userIdsIncludingPreCreated)
val packageStates = packageManagerLocal.packageStates
val state = AccessState()
state.systemState.userIds.apply {
// TODO: Get and add all user IDs.
// TODO: Maybe get and add all packages?
}
policy.initialize(state, userIds, packageStates)
persistence.read(state)
this.state = state
appOpService.initialize()
permissionService.initialize()
}
fun getDecision(subject: AccessUri, `object`: AccessUri): Int =
@@ -50,30 +83,60 @@ class AccessCheckingService {
}
}
fun onUserAdded(userId: Int) {
internal fun onUserAdded(userId: Int) {
mutateState {
with(policy) { onUserAdded(userId) }
}
}
fun onUserRemoved(userId: Int) {
internal fun onUserRemoved(userId: Int) {
mutateState {
with(policy) { onUserRemoved(userId) }
}
}
fun onPackageAdded(packageState: PackageState) {
internal fun onStorageVolumeMounted(volumeUuid: String?, isSystemUpdated: Boolean) {
val packageStates = packageManagerLocal.packageStates
mutateState {
with(policy) { onPackageAdded(packageState) }
with(policy) { onStorageVolumeMounted(packageStates, volumeUuid, isSystemUpdated) }
}
}
fun onPackageRemoved(packageState: PackageState) {
internal fun onPackageAdded(packageName: String) {
val packageStates = packageManagerLocal.packageStates
mutateState {
with(policy) { onPackageRemoved(packageState) }
with(policy) { onPackageAdded(packageStates, packageName) }
}
}
internal fun onPackageRemoved(packageName: String, appId: Int) {
val packageStates = packageManagerLocal.packageStates
mutateState {
with(policy) { onPackageRemoved(packageStates, packageName, appId) }
}
}
internal fun onPackageInstalled(
packageName: String,
params: PermissionManagerServiceInternal.PackageInstalledParams,
userId: Int
) {
val packageStates = packageManagerLocal.packageStates
mutateState {
with(policy) { onPackageInstalled(packageStates, packageName, params, userId) }
}
}
internal fun onPackageUninstalled(packageName: String, appId: Int, userId: Int) {
val packageStates = packageManagerLocal.packageStates
mutateState {
with(policy) { onPackageUninstalled(packageStates, packageName, appId, userId) }
}
}
private val PackageManagerLocal.packageStates: Map<String, PackageState>
get() = withUnfilteredSnapshot().use { it.packageStates }
internal inline fun <T> getState(action: GetStateScope.() -> T): T =
GetStateScope(state).action()

View File

@@ -22,11 +22,12 @@ import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.permission.access.appop.PackageAppOpPolicy
import com.android.server.permission.access.appop.UidAppOpPolicy
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.external.PackageState
import com.android.server.permission.access.permission.UidPermissionPolicy
import com.android.server.permission.access.util.forEachTag
import com.android.server.permission.access.util.tag
import com.android.server.permission.access.util.tagName
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.PackageState
class AccessPolicy private constructor(
private val schemePolicies: IndexedMap<String, IndexedMap<String, SchemePolicy>>
@@ -53,6 +54,17 @@ class AccessPolicy private constructor(
with(getSchemePolicy(subject, `object`)) { setDecision(subject, `object`, decision) }
}
fun initialize(state: AccessState, userIds: IntSet, packageStates: Map<String, PackageState>) {
state.systemState.apply {
this.userIds += userIds
this.packageStates = packageStates
packageStates.forEach { (_, packageState) ->
appIds.getOrPut(packageState.appId) { IndexedListSet() }
.add(packageState.packageName)
}
}
}
fun MutateStateScope.onUserAdded(userId: Int) {
newState.systemState.userIds += userId
newState.userStates[userId] = UserState()
@@ -69,18 +81,34 @@ class AccessPolicy private constructor(
}
}
fun MutateStateScope.onPackageAdded(packageState: PackageState) {
var isAppIdAdded = false
newState.systemState.apply {
packageStates[packageState.packageName] = packageState
appIds.getOrPut(packageState.appId) {
isAppIdAdded = true
IndexedListSet()
}.add(packageState.packageName)
fun MutateStateScope.onStorageVolumeMounted(
packageStates: Map<String, PackageState>,
volumeUuid: String?,
isSystemUpdated: Boolean
) {
newState.systemState.packageStates = packageStates
forEachSchemePolicy {
with(it) { onStorageVolumeMounted(volumeUuid, isSystemUpdated) }
}
}
fun MutateStateScope.onPackageAdded(
packageStates: Map<String, PackageState>,
packageName: String
) {
newState.systemState.packageStates = packageStates
var isAppIdAdded = false
val packageState = packageStates[packageName]
// TODO(zhanghai): Remove check before submission.
checkNotNull(packageState)
val appId = packageState.appId
newState.systemState.appIds.getOrPut(appId) {
isAppIdAdded = true
IndexedListSet()
}.add(packageName)
if (isAppIdAdded) {
forEachSchemePolicy {
with(it) { onAppIdAdded(packageState.appId) }
with(it) { onAppIdAdded(appId) }
}
}
forEachSchemePolicy {
@@ -88,30 +116,61 @@ class AccessPolicy private constructor(
}
}
fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
fun MutateStateScope.onPackageRemoved(
packageStates: Map<String, PackageState>,
packageName: String,
appId: Int
) {
newState.systemState.packageStates = packageStates
var isAppIdRemoved = false
newState.systemState.apply {
packageStates -= packageState.packageName
appIds.apply appIds@{
this[packageState.appId]?.apply {
this -= packageState.packageName
if (isEmpty()) {
this@appIds -= packageState.appId
isAppIdRemoved = true
}
// TODO(zhanghai): Remove check before submission.
check(packageName !in packageStates)
newState.systemState.appIds.apply appIds@{
this[appId]?.apply {
this -= packageName
if (isEmpty()) {
this@appIds -= appId
isAppIdRemoved = true
}
}
}
forEachSchemePolicy {
with(it) { onPackageRemoved(packageState) }
with(it) { onPackageRemoved(packageName, appId) }
}
if (isAppIdRemoved) {
forEachSchemePolicy {
with(it) { onAppIdRemoved(packageState.appId) }
with(it) { onAppIdRemoved(appId) }
}
}
}
fun MutateStateScope.onPackageInstalled(
packageStates: Map<String, PackageState>,
packageName: String,
params: PermissionManagerServiceInternal.PackageInstalledParams,
userId: Int
) {
newState.systemState.packageStates = packageStates
val packageState = packageStates[packageName]
// TODO(zhanghai): Remove check before submission.
checkNotNull(packageState)
forEachSchemePolicy {
with(it) { onPackageInstalled(packageState, params, userId) }
}
}
fun MutateStateScope.onPackageUninstalled(
packageStates: Map<String, PackageState>,
packageName: String,
appId: Int,
userId: Int
) {
newState.systemState.packageStates = packageStates
forEachSchemePolicy {
with(it) { onPackageUninstalled(packageName, appId, userId) }
}
}
fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {
forEachTag {
when (tagName) {
@@ -230,9 +289,22 @@ abstract class SchemePolicy {
open fun MutateStateScope.onAppIdRemoved(appId: Int) {}
open fun MutateStateScope.onStorageVolumeMounted(
volumeUuid: String?,
isSystemUpdated: Boolean
) {}
open fun MutateStateScope.onPackageAdded(packageState: PackageState) {}
open fun MutateStateScope.onPackageRemoved(packageState: PackageState) {}
open fun MutateStateScope.onPackageRemoved(packageName: String, appId: Int) {}
open fun MutateStateScope.onPackageInstalled(
packageState: PackageState,
params: PermissionManagerServiceInternal.PackageInstalledParams,
userId: Int
) {}
open fun MutateStateScope.onPackageUninstalled(packageName: String, appId: Int, userId: Int) {}
open fun BinaryXmlPullParser.parseSystemState(systemState: SystemState) {}

View File

@@ -18,8 +18,8 @@ package com.android.server.permission.access
import android.content.pm.PermissionGroupInfo
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.data.Permission
import com.android.server.permission.access.external.PackageState
import com.android.server.permission.access.permission.Permission
import com.android.server.pm.pkg.PackageState
class AccessState private constructor(
val systemState: SystemState,
@@ -32,8 +32,8 @@ class AccessState private constructor(
class SystemState private constructor(
val userIds: IntSet,
val packageStates: IndexedMap<String, PackageState>,
val disabledSystemPackageStates: IndexedMap<String, PackageState>,
var packageStates: Map<String, PackageState>,
var disabledSystemPackageStates: Map<String, PackageState>,
val appIds: IntMap<IndexedListSet<String>>,
// A map of KnownPackagesInt to a set of known package names
val knownPackages: IntMap<IndexedListSet<String>>,
@@ -59,7 +59,7 @@ class SystemState private constructor(
val permissions: IndexedMap<String, Permission>
) : WritableState() {
constructor() : this(
IntSet(), IndexedMap(), IndexedMap(), IntMap(), IntMap(), IntMap(), IndexedMap(),
IntSet(), emptyMap(), emptyMap(), IntMap(), IntMap(), IntMap(), IndexedMap(),
IndexedListSet(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(), IndexedMap(),
IndexedMap(), IndexedMap(), IndexedMap()
@@ -68,8 +68,8 @@ class SystemState private constructor(
fun copy(): SystemState =
SystemState(
userIds.copy(),
packageStates.copy { it },
disabledSystemPackageStates.copy { it },
packageStates,
disabledSystemPackageStates,
appIds.copy { it.copy() },
knownPackages.copy { it.copy() },
deviceAndProfileOwners.copy { it },

View File

@@ -16,8 +16,7 @@
package com.android.server.permission.access
import com.android.server.permission.access.external.UserHandle
import com.android.server.permission.access.external.UserHandleCompat
import android.os.UserHandle
sealed class AccessUri(
val scheme: String
@@ -70,7 +69,7 @@ data class UidUri(
val uid: Int
) : AccessUri(SCHEME) {
val userId: Int
get() = UserHandleCompat.getUserId(uid)
get() = UserHandle.getUserId(uid)
val appId: Int
get() = UserHandle.getAppId(uid)

View File

@@ -24,9 +24,13 @@ import com.android.server.appop.OnOpModeChangedListener
import com.android.server.permission.access.AccessCheckingService
import java.io.PrintWriter
class AppOpsCheckingServiceCompatImpl(
private val accessCheckingService: AccessCheckingService
class AppOpService(
private val service: AccessCheckingService
) : AppOpsCheckingServiceInterface {
fun initialize() {
TODO("Not yet implemented")
}
override fun getNonDefaultUidModes(uid: Int): SparseIntArray {
TODO("Not yet implemented")
}
@@ -139,6 +143,6 @@ class AppOpsCheckingServiceCompatImpl(
}
companion object {
private val LOG_TAG = AppOpsCheckingServiceCompatImpl::class.java.simpleName
private val LOG_TAG = AppOpService::class.java.simpleName
}
}

View File

@@ -23,7 +23,6 @@ import com.android.server.permission.access.MutateStateScope
import com.android.server.permission.access.PackageUri
import com.android.server.permission.access.UserState
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.external.PackageState
class PackageAppOpPolicy : BaseAppOpPolicy(PackageAppOpPersistence()) {
override val subjectScheme: String
@@ -48,9 +47,9 @@ class PackageAppOpPolicy : BaseAppOpPolicy(PackageAppOpPersistence()) {
newState.userStates[subject.userId]?.packageAppOpModes?.remove(subject.packageName)
}
override fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
override fun MutateStateScope.onPackageRemoved(packageName: String, appId: Int) {
newState.userStates.forEachIndexed { _, _, userState ->
userState.packageAppOpModes -= packageState.packageName
userState.packageAppOpModes -= packageName
}
}
}

View File

@@ -51,6 +51,8 @@ class IntSet private constructor(
fun copy(): IntSet = IntSet(array.clone())
}
fun IntSet(values: IntArray): IntSet = IntSet().apply{ this += values }
inline fun IntSet.allIndexed(predicate: (Int, Int) -> Boolean): Boolean {
for (index in 0 until size) {
if (!predicate(index, elementAt(index))) {
@@ -103,6 +105,14 @@ inline operator fun IntSet.plusAssign(element: Int) {
add(element)
}
operator fun IntSet.plusAssign(set: IntSet) {
set.forEachIndexed { _, it -> this += it }
}
operator fun IntSet.plusAssign(array: IntArray) {
array.forEach { this += it }
}
inline fun IntSet.removeAllIndexed(predicate: (Int, Int) -> Boolean) {
for (index in lastIndex downTo 0) {
if (predicate(index, elementAt(index))) {

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2021 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 com.android.server.permission.access.data
import com.android.server.permission.access.external.AndroidPackage
class Package(
private val androidPackage: AndroidPackage
) {
val name: String
get() = androidPackage.packageName
val adoptPermissions: List<String>
get() = androidPackage.adoptPermissions
val appId: Int
get() = androidPackage.appId
val requestedPermissions: List<String>
get() = androidPackage.requestedPermissions
override fun equals(other: Any?): Boolean {
throw NotImplementedError()
}
override fun hashCode(): Int {
throw NotImplementedError()
}
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright (C) 2022 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 com.android.server.permission.access.external
class CompatibilityPermissionInfo {
companion object {
val COMPAT_PERMS = arrayOf(CompatibilityPermissionInfo())
}
val name: String
get() = throw NotImplementedError()
val sdkVersion: Int
get() = throw NotImplementedError()
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2022 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 com.android.server.permission.access.external
class KnownPackages {
companion object {
const val PACKAGE_SYSTEM = 0
const val PACKAGE_SETUP_WIZARD = 1
const val PACKAGE_INSTALLER = 2
const val PACKAGE_VERIFIER = 4
const val PACKAGE_SYSTEM_TEXT_CLASSIFIER = 6
const val PACKAGE_PERMISSION_CONTROLLER = 7
const val PACKAGE_CONFIGURATOR = 10
const val PACKAGE_INCIDENT_REPORT_APPROVER = 11
const val PACKAGE_APP_PREDICTOR = 12
const val PACKAGE_COMPANION = 15
const val PACKAGE_RETAIL_DEMO = 16
const val PACKAGE_RECENTS = 17
}
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2021 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 com.android.server.permission.access.external
import android.content.pm.PermissionGroupInfo
import android.content.pm.PermissionInfo
object PackageInfoUtils {
fun generatePermissionInfo(parsedPermission: ParsedPermission, flags: Long): PermissionInfo {
throw NotImplementedError()
}
fun generatePermissionGroupInfo(
parsedPermissionGroup: ParsedPermissionGroup,
flags: Long
): PermissionGroupInfo {
throw NotImplementedError()
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2021 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 com.android.server.permission.access.external
import android.util.SparseArray
interface PackageState {
val androidPackage: AndroidPackage?
val appId: Int
val isSystem: Boolean
val isUpdatedSystemApp: Boolean
val packageName: String
val userStates: SparseArray<PackageUserState>
val hasSharedUser: Boolean
val sharedUserAppId: Int
val signingDetails: SigningDetails
}
interface AndroidPackage {
val packageName: String
val apexModuleName: String?
val appId: Int
val isPrivileged: Boolean
val isOem: Boolean
val isVendor: Boolean
val isProduct: Boolean
val isSystemExt: Boolean
val targetSdkVersion: Int
val adoptPermissions: List<String>
val permissions: List<ParsedPermission>
val permissionGroups: List<ParsedPermissionGroup>
val requestedPermissions: List<String>
val implicitPermissions: List<String>
}
interface ParsedPermission {
val name: String
val isTree: Boolean
val packageName: String
val isSignature: Boolean
val protectionLevel: Int
}
interface ParsedPermissionGroup {
val name: String
val packageName: String
}
interface PackageUserState {
val isInstantApp: Boolean
}

View File

@@ -1,24 +0,0 @@
/*
* Copyright (C) 2022 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 com.android.server.permission.access.external
class RoSystemProperties {
companion object {
const val CONTROL_PRIVAPP_PERMISSIONS_DISABLE = false
const val CONTROL_PRIVAPP_PERMISSIONS_ENFORCE = false
}
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2022 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 com.android.server.permission.access.external
object SigningDetails {
fun hasCommonSignerWithCapability(otherDetails: SigningDetails, flags: Int): Boolean {
throw NotImplementedError()
}
fun hasAncestorOrSelf(oldDetails: SigningDetails): Boolean {
throw NotImplementedError()
}
fun checkCapability(oldDetails: SigningDetails, flags: Int): Boolean {
throw NotImplementedError()
}
fun hasAncestorOrSelfWithDigest(certDigests: Set<String>): Boolean {
throw NotImplementedError()
}
class CertCapabilities {
companion object {
/** grant SIGNATURE permissions to pkgs with this cert */
var PERMISSION = 4
}
}
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2021 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 com.android.server.permission.access.external
interface UserHandle {
companion object {
fun getAppId(uid: Int): Int {
throw NotImplementedError()
}
}
}
object UserHandleCompat {
fun getUserId(uid: Int): Int {
throw NotImplementedError()
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.server.permission.access.data
package com.android.server.permission.access.permission
import android.content.pm.PermissionInfo
import com.android.server.permission.access.util.hasBits

View File

@@ -33,8 +33,9 @@ import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.permission.access.AccessCheckingService
import com.android.server.permission.access.PermissionUri
import com.android.server.permission.access.UidUri
import com.android.server.permission.access.data.Permission
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.util.hasBits
import com.android.server.pm.UserManagerService
import com.android.server.pm.permission.LegacyPermission
import com.android.server.pm.permission.LegacyPermissionSettings
import com.android.server.pm.permission.LegacyPermissionState
@@ -46,17 +47,24 @@ import java.io.PrintWriter
/**
* Modern implementation of [PermissionManagerServiceInterface].
*/
class ModernPermissionManagerServiceImpl(
class PermissionService(
private val service: AccessCheckingService
) : PermissionManagerServiceInterface {
private val policy =
service.getSchemePolicy(UidUri.SCHEME, PermissionUri.SCHEME) as UidPermissionPolicy
private val packageManagerInternal =
LocalServices.getService(PackageManagerInternal::class.java)
private lateinit var packageManagerInternal: PackageManagerInternal
private lateinit var packageManagerLocal: PackageManagerLocal
private lateinit var userManagerService: UserManagerService
private val packageManagerLocal =
LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
private val mountedStorageVolumes = IndexedSet<String?>()
fun initialize() {
packageManagerInternal = LocalServices.getService(PackageManagerInternal::class.java)
packageManagerLocal =
LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
userManagerService = UserManagerService.getInstance()
}
override fun getAllPermissionGroups(flags: Int): List<PermissionGroupInfo> {
TODO("Not yet implemented")
@@ -351,6 +359,8 @@ class ModernPermissionManagerServiceImpl(
}
override fun readLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) {
// Package settings has been read when this method is called.
service.initialize()
TODO("Not yet implemented")
}
@@ -375,15 +385,18 @@ class ModernPermissionManagerServiceImpl(
}
override fun onUserCreated(userId: Int) {
TODO("Not yet implemented")
service.onUserAdded(userId)
}
override fun onUserRemoved(userId: Int) {
TODO("Not yet implemented")
service.onUserRemoved(userId)
}
override fun onStorageVolumeMounted(volumeUuid: String, fingerprintChanged: Boolean) {
TODO("Not yet implemented")
service.onStorageVolumeMounted(volumeUuid, fingerprintChanged)
synchronized(mountedStorageVolumes) {
mountedStorageVolumes += volumeUuid
}
}
override fun onPackageAdded(
@@ -391,7 +404,18 @@ class ModernPermissionManagerServiceImpl(
isInstantApp: Boolean,
oldPackage: AndroidPackage?
) {
TODO("Not yet implemented")
synchronized(mountedStorageVolumes) {
if (androidPackage.volumeUuid !in mountedStorageVolumes) {
// Wait for the storage volume to be mounted and batch the state mutation there.
return
}
}
service.onPackageAdded(androidPackage.packageName)
}
override fun onPackageRemoved(androidPackage: AndroidPackage) {
// This may not be a full removal so ignored - we'll figure out full removal in
// onPackageUninstalled().
}
override fun onPackageInstalled(
@@ -400,21 +424,37 @@ class ModernPermissionManagerServiceImpl(
params: PermissionManagerServiceInternal.PackageInstalledParams,
userId: Int
) {
TODO("Not yet implemented")
synchronized(mountedStorageVolumes) {
if (androidPackage.volumeUuid !in mountedStorageVolumes) {
// Wait for the storage volume to be mounted and batch the state mutation there.
return
}
}
val userIds = if (userId == UserHandle.USER_ALL) {
userManagerService.userIdsIncludingPreCreated
} else {
intArrayOf(userId)
}
userIds.forEach { service.onPackageInstalled(androidPackage.packageName, params, it) }
}
override fun onPackageUninstalled(
packageName: String,
appId: Int,
androidPackage: AndroidPackage?,
sharedUserPkgs: MutableList<AndroidPackage>,
sharedUserPkgs: List<AndroidPackage>,
userId: Int
) {
TODO("Not yet implemented")
}
override fun onPackageRemoved(androidPackage: AndroidPackage) {
TODO("Not yet implemented")
val userIds = if (userId == UserHandle.USER_ALL) {
userManagerService.userIdsIncludingPreCreated
} else {
intArrayOf(userId)
}
userIds.forEach { service.onPackageUninstalled(packageName, appId, it) }
val packageState = packageManagerInternal.packageStates[packageName]
if (packageState == null) {
service.onPackageRemoved(packageName, appId)
}
}
/**

View File

@@ -22,7 +22,6 @@ import com.android.modules.utils.BinaryXmlPullParser
import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.permission.access.SystemState
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.data.Permission
import com.android.server.permission.access.util.attribute
import com.android.server.permission.access.util.attributeInt
import com.android.server.permission.access.util.attributeIntHex

View File

@@ -20,9 +20,11 @@ import android.Manifest
import android.content.pm.PackageManager
import android.content.pm.PermissionGroupInfo
import android.content.pm.PermissionInfo
import android.content.pm.SigningDetails
import android.os.Build
import android.os.UserHandle
import android.util.Log
import com.android.internal.os.RoSystemProperties
import com.android.modules.utils.BinaryXmlPullParser
import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.permission.access.AccessState
@@ -35,16 +37,13 @@ import com.android.server.permission.access.SystemState
import com.android.server.permission.access.UidUri
import com.android.server.permission.access.UserState
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.data.Permission
import com.android.server.permission.access.external.AndroidPackage
import com.android.server.permission.access.external.CompatibilityPermissionInfo
import com.android.server.permission.access.external.KnownPackages
import com.android.server.permission.access.external.PackageInfoUtils
import com.android.server.permission.access.external.PackageState
import com.android.server.permission.access.external.RoSystemProperties
import com.android.server.permission.access.external.SigningDetails
import com.android.server.permission.access.util.hasAnyBit
import com.android.server.permission.access.util.hasBits
import com.android.server.pm.KnownPackages
import com.android.server.pm.parsing.PackageInfoUtils
import com.android.server.pm.permission.CompatibilityPermissionInfo
import com.android.server.pm.pkg.AndroidPackage
import com.android.server.pm.pkg.PackageState
class UidPermissionPolicy : SchemePolicy() {
private val persistence = UidPermissionPersistence()
@@ -75,7 +74,7 @@ class UidPermissionPolicy : SchemePolicy() {
}
override fun MutateStateScope.onUserAdded(userId: Int) {
newState.systemState.packageStates.forEachValueIndexed { _, packageState ->
newState.systemState.packageStates.forEach { (_, packageState) ->
evaluateAllPermissionStatesForPackageAndUser(packageState, null, userId)
grantImplicitPermissions(packageState, userId)
}
@@ -179,7 +178,7 @@ class UidPermissionPolicy : SchemePolicy() {
packageState.androidPackage!!.permissionGroups.forEachIndexed { _, parsedPermissionGroup ->
val newPermissionGroup = PackageInfoUtils.generatePermissionGroupInfo(
parsedPermissionGroup, PackageManager.GET_META_DATA.toLong()
)
)!!
// TODO: Clear permission state on group take-over?
val permissionGroupName = newPermissionGroup.name
val oldPermissionGroup = newState.systemState.permissionGroups[permissionGroupName]
@@ -211,7 +210,7 @@ class UidPermissionPolicy : SchemePolicy() {
// }
val newPermissionInfo = PackageInfoUtils.generatePermissionInfo(
parsedPermission, PackageManager.GET_META_DATA.toLong()
)
)!!
// TODO: newPermissionInfo.flags |= PermissionInfo.FLAG_INSTALLED
val permissionName = newPermissionInfo.name
val oldPermission = if (parsedPermission.isTree) {
@@ -573,23 +572,24 @@ class UidPermissionPolicy : SchemePolicy() {
packageState: PackageState,
permission: Permission
): Boolean {
// check if the package is allow to use this signature permission. A package is allowed to
// use a signature permission if:
// - it has the same set of signing certificates as the source package
// - or its signing certificate was rotated from the source package's certificate
// - or its signing certificate is a previous signing certificate of the defining
// package, and the defining package still trusts the old certificate for permissions
// - or it shares a common signing certificate in its lineage with the defining package,
// and the defining package still trusts the old certificate for permissions
// - or it shares the above relationships with the system package
// Check if the package is allowed to use this signature permission. A package is allowed
// to use a signature permission if:
// - it has the same set of signing certificates as the source package
// - or its signing certificate was rotated from the source package's certificate
// - or its signing certificate is a previous signing certificate of the defining
// package, and the defining package still trusts the old certificate for permissions
// - or it shares a common signing certificate in its lineage with the defining package,
// and the defining package still trusts the old certificate for permissions
// - or it shares the above relationships with the system package
val packageSigningDetails = packageState.androidPackage!!.signingDetails
val sourceSigningDetails = newState.systemState
.packageStates[permission.packageName]?.signingDetails
.packageStates[permission.packageName]?.androidPackage?.signingDetails
val platformSigningDetails = newState.systemState
.packageStates[PLATFORM_PACKAGE_NAME]!!.signingDetails
return sourceSigningDetails?.hasCommonSignerWithCapability(packageState.signingDetails,
.packageStates[PLATFORM_PACKAGE_NAME]!!.androidPackage!!.signingDetails
return sourceSigningDetails?.hasCommonSignerWithCapability(packageSigningDetails,
SigningDetails.CertCapabilities.PERMISSION) == true ||
packageState.signingDetails.hasAncestorOrSelf(platformSigningDetails) ||
platformSigningDetails.checkCapability(packageState.signingDetails,
packageSigningDetails.hasAncestorOrSelf(platformSigningDetails) ||
platformSigningDetails.checkCapability(packageSigningDetails,
SigningDetails.CertCapabilities.PERMISSION)
}
@@ -629,7 +629,10 @@ class UidPermissionPolicy : SchemePolicy() {
androidPackage: AndroidPackage,
permissionName: String
): Boolean {
val apexModuleName = androidPackage.apexModuleName
// TODO(b/261913353): STOPSHIP: Add AndroidPackage.apexModuleName. The below is only for
// passing compilation but won't actually work.
//val apexModuleName = androidPackage.apexModuleName
val apexModuleName = androidPackage.packageName
val systemState = newState.systemState
val packageName = androidPackage.packageName
val permissionNames = when {
@@ -657,7 +660,10 @@ class UidPermissionPolicy : SchemePolicy() {
): Boolean {
// Different from the previous implementation, which may incorrectly use the APEX package
// name, we now use the APEX module name to be consistent with the allowlist.
val apexModuleName = androidPackage.apexModuleName
// TODO(b/261913353): STOPSHIP: Add AndroidPackage.apexModuleName. The below is only for
// passing compilation but won't actually work.
//val apexModuleName = androidPackage.apexModuleName
val apexModuleName = androidPackage.packageName
val systemState = newState.systemState
val packageName = androidPackage.packageName
val permissionNames = when {
@@ -741,7 +747,7 @@ class UidPermissionPolicy : SchemePolicy() {
return true
}
if (permission.isKnownSigner &&
packageState.signingDetails.hasAncestorOrSelfWithDigest(permission.knownCerts)) {
androidPackage.signingDetails.hasAncestorOrSelfWithDigest(permission.knownCerts)) {
// If the permission is to be granted to a known signer then check if any of this
// app's signing certificates are in the trusted certificate digest Set.
return true
@@ -840,7 +846,7 @@ class UidPermissionPolicy : SchemePolicy() {
return uid == ownerUid
}
override fun MutateStateScope.onPackageRemoved(packageState: PackageState) {
override fun MutateStateScope.onPackageRemoved(packageName: String, appId: Int) {
// TODO
}