Merge "Add config permissions and GIDs handling."

This commit is contained in:
Hai Zhang
2022-12-19 11:24:17 +00:00
committed by Android (Google) Code Review
6 changed files with 288 additions and 91 deletions

View File

@@ -17,6 +17,10 @@
package com.android.server.permission.access
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManagerInternal
import android.os.SystemProperties
import android.os.UserHandle
import com.android.internal.annotations.Keep
import com.android.server.LocalManagerRegistry
import com.android.server.LocalServices
@@ -24,12 +28,16 @@ import com.android.server.SystemConfig
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.IntSet
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.KnownPackages
import com.android.server.pm.PackageManagerLocal
import com.android.server.pm.UserManagerService
import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.pm.pkg.PackageState
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@Keep
class AccessCheckingService(context: Context) : SystemService(context) {
@@ -44,6 +52,7 @@ class AccessCheckingService(context: Context) : SystemService(context) {
private lateinit var appOpService: AppOpService
private lateinit var permissionService: PermissionService
private lateinit var packageManagerInternal: PackageManagerInternal
private lateinit var packageManagerLocal: PackageManagerLocal
private lateinit var userManagerService: UserManagerService
private lateinit var systemConfig: SystemConfig
@@ -57,6 +66,7 @@ class AccessCheckingService(context: Context) : SystemService(context) {
}
fun initialize() {
packageManagerInternal = LocalServices.getService(PackageManagerInternal::class.java)
packageManagerLocal =
LocalManagerRegistry.getManagerOrThrow(PackageManagerLocal::class.java)
userManagerService = UserManagerService.getInstance()
@@ -64,19 +74,94 @@ class AccessCheckingService(context: Context) : SystemService(context) {
val userIds = IntSet(userManagerService.userIdsIncludingPreCreated)
val (packageStates, disabledSystemPackageStates) = packageManagerLocal.allPackageStates
val knownPackages = packageManagerInternal.knownPackages
val isLeanback = systemConfig.isLeanback
val configPermissions = systemConfig.permissions
val privilegedPermissionAllowlistPackages =
systemConfig.privilegedPermissionAllowlistPackages
val permissionAllowlist = systemConfig.permissionAllowlist
val implicitToSourcePermissions = systemConfig.implicitToSourcePermissions
val state = AccessState()
policy.initialize(
state, userIds, packageStates, disabledSystemPackageStates, permissionAllowlist
state, userIds, packageStates, disabledSystemPackageStates, knownPackages, isLeanback,
configPermissions, privilegedPermissionAllowlistPackages, permissionAllowlist,
implicitToSourcePermissions
)
persistence.read(state)
this.state = state
mutateState {
with(policy) { onInitialized() }
}
appOpService.initialize()
permissionService.initialize()
}
private val PackageManagerInternal.knownPackages: IntMap<Array<String>>
get() = IntMap<Array<String>>().apply {
this[KnownPackages.PACKAGE_INSTALLER] = getKnownPackageNames(
KnownPackages.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_PERMISSION_CONTROLLER] = getKnownPackageNames(
KnownPackages.PACKAGE_PERMISSION_CONTROLLER, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_VERIFIER] = getKnownPackageNames(
KnownPackages.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_SETUP_WIZARD] = getKnownPackageNames(
KnownPackages.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER] = getKnownPackageNames(
KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_CONFIGURATOR] = getKnownPackageNames(
KnownPackages.PACKAGE_CONFIGURATOR, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER] = getKnownPackageNames(
KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_APP_PREDICTOR] = getKnownPackageNames(
KnownPackages.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_COMPANION] = getKnownPackageNames(
KnownPackages.PACKAGE_COMPANION, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_RETAIL_DEMO] = getKnownPackageNames(
KnownPackages.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM
)
this[KnownPackages.PACKAGE_RECENTS] = getKnownPackageNames(
KnownPackages.PACKAGE_RECENTS, UserHandle.USER_SYSTEM
)
}
private val SystemConfig.isLeanback: Boolean
get() = PackageManager.FEATURE_LEANBACK in availableFeatures
private val SystemConfig.privilegedPermissionAllowlistPackages: IndexedListSet<String>
get() = IndexedListSet<String>().apply {
this += "android"
if (PackageManager.FEATURE_AUTOMOTIVE in availableFeatures) {
// Note that SystemProperties.get(String, String) forces returning an empty string
// even if we pass null for the def parameter.
val carServicePackage = SystemProperties.get("ro.android.car.carservice.package")
if (carServicePackage.isNotEmpty()) {
this += carServicePackage
}
}
}
private val SystemConfig.implicitToSourcePermissions: IndexedMap<String, IndexedListSet<String>>
get() = IndexedMap<String, IndexedListSet<String>>().apply {
splitPermissions.forEach { splitPermissionInfo ->
val sourcePermissionName = splitPermissionInfo.splitPermission
splitPermissionInfo.newPermissions.forEach { implicitPermissionName ->
getOrPut(implicitPermissionName) { IndexedListSet() } += sourcePermissionName
}
}
}
fun getDecision(subject: AccessUri, `object`: AccessUri): Int =
getState {
with(policy) { getDecision(subject, `object`) }
@@ -151,10 +236,15 @@ class AccessCheckingService(context: Context) : SystemService(context) {
Pair<Map<String, PackageState>, Map<String, PackageState>>
get() = withUnfilteredSnapshot().use { it.packageStates to it.disabledSystemPackageStates }
internal inline fun <T> getState(action: GetStateScope.() -> T): T =
GetStateScope(state).action()
@OptIn(ExperimentalContracts::class)
internal inline fun <T> getState(action: GetStateScope.() -> T): T {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return GetStateScope(state).action()
}
@OptIn(ExperimentalContracts::class)
internal inline fun mutateState(crossinline action: MutateStateScope.() -> Unit) {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
synchronized(stateLock) {
val oldState = state
val newState = oldState.copy()

View File

@@ -19,6 +19,7 @@ package com.android.server.permission.access
import android.util.Log
import com.android.modules.utils.BinaryXmlPullParser
import com.android.modules.utils.BinaryXmlSerializer
import com.android.server.SystemConfig
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
@@ -59,7 +60,12 @@ class AccessPolicy private constructor(
userIds: IntSet,
packageStates: Map<String, PackageState>,
disabledSystemPackageStates: Map<String, PackageState>,
permissionAllowlist: PermissionAllowlist
knownPackages: IntMap<Array<String>>,
isLeanback: Boolean,
configPermissions: Map<String, SystemConfig.PermissionEntry>,
privilegedPermissionAllowlistPackages: IndexedListSet<String>,
permissionAllowlist: PermissionAllowlist,
implicitToSourcePermissions: IndexedMap<String, IndexedListSet<String>>
) {
state.systemState.apply {
this.userIds += userIds
@@ -69,7 +75,12 @@ class AccessPolicy private constructor(
appIds.getOrPut(packageState.appId) { IndexedListSet() }
.add(packageState.packageName)
}
this.knownPackages = knownPackages
this.isLeanback = isLeanback
this.configPermissions = configPermissions
this.privilegedPermissionAllowlistPackages = privilegedPermissionAllowlistPackages
this.permissionAllowlist = permissionAllowlist
this.implicitToSourcePermissions = implicitToSourcePermissions
}
}
@@ -79,6 +90,12 @@ class AccessPolicy private constructor(
}
}
fun MutateStateScope.onInitialized() {
forEachSchemePolicy {
with(it) { onInitialized() }
}
}
fun MutateStateScope.onUserAdded(userId: Int) {
newState.systemState.userIds += userId
newState.userStates[userId] = UserState()
@@ -292,6 +309,8 @@ abstract class SchemePolicy {
open fun GetStateScope.onStateMutated() {}
open fun MutateStateScope.onInitialized() {}
open fun MutateStateScope.onUserAdded(userId: Int) {}
open fun MutateStateScope.onUserRemoved(userId: Int) {}

View File

@@ -17,6 +17,7 @@
package com.android.server.permission.access
import android.content.pm.PermissionGroupInfo
import com.android.server.SystemConfig
import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports
import com.android.server.permission.access.permission.Permission
import com.android.server.pm.permission.PermissionAllowlist
@@ -42,15 +43,15 @@ class SystemState private constructor(
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>>,
// A map of userId to packageName
val deviceAndProfileOwners: IntMap<String>,
// Whether the device supports leanback UI
// Mapping from KnownPackages keys to package names.
var knownPackages: IntMap<Array<String>>,
var isLeanback: Boolean,
val privilegedPermissionAllowlistSourcePackageNames: IndexedListSet<String>,
var configPermissions: Map<String, SystemConfig.PermissionEntry>,
var privilegedPermissionAllowlistPackages: IndexedListSet<String>,
var permissionAllowlist: PermissionAllowlist,
val implicitToSourcePermissions: Map<String, Set<String>>,
var implicitToSourcePermissions: IndexedMap<String, IndexedListSet<String>>,
// Mapping from user ID to package name.
var deviceAndProfileOwners: IntMap<String>,
val permissionGroups: IndexedMap<String, PermissionGroupInfo>,
val permissionTrees: IndexedMap<String, Permission>,
val permissions: IndexedMap<String, Permission>
@@ -61,11 +62,12 @@ class SystemState private constructor(
emptyMap(),
IntMap(),
IntMap(),
IntMap(),
false,
emptyMap(),
IndexedListSet(),
PermissionAllowlist(),
IndexedMap(),
IntMap(),
IndexedMap(),
IndexedMap(),
IndexedMap()
@@ -77,12 +79,13 @@ class SystemState private constructor(
packageStates,
disabledSystemPackageStates,
appIds.copy { it.copy() },
knownPackages.copy { it.copy() },
deviceAndProfileOwners.copy { it },
knownPackages,
isLeanback,
privilegedPermissionAllowlistSourcePackageNames.copy(),
configPermissions,
privilegedPermissionAllowlistPackages,
permissionAllowlist,
implicitToSourcePermissions,
deviceAndProfileOwners,
permissionGroups.copy { it },
permissionTrees.copy { it },
permissions.copy { it }

View File

@@ -17,13 +17,18 @@
package com.android.server.permission.access.permission
import android.content.pm.PermissionInfo
import android.os.UserHandle
import com.android.server.permission.access.util.hasBits
import libcore.util.EmptyArray
data class Permission(
val permissionInfo: PermissionInfo,
val isReconciled: Boolean,
val type: Int,
val appId: Int
val appId: Int,
@Suppress("ArrayInDataClass")
val gids: IntArray = EmptyArray.INT,
val areGidsPerUser: Boolean = false
) {
inline val name: String
get() = permissionInfo.name
@@ -37,36 +42,50 @@ data class Permission(
inline val isDynamic: Boolean
get() = type == TYPE_DYNAMIC
inline val protectionLevel: Int
@Suppress("DEPRECATION")
get() = permissionInfo.protectionLevel
inline val isInternal: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_INTERNAL
inline val isNormal: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_NORMAL
inline val isRuntime: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_DANGEROUS
inline val isAppOp: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_FLAG_APPOP
inline val isRemoved: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_REMOVED)
inline val isSoftRestricted: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED)
inline val isHardRestricted: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_HARD_RESTRICTED)
inline val isSignature: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_SIGNATURE
inline val isInternal: Boolean
get() = permissionInfo.protection == PermissionInfo.PROTECTION_INTERNAL
inline val isAppOp: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_APPOP)
inline val isAppPredictor: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR)
inline val isCompanion: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_COMPANION)
inline val isConfigurator: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_CONFIGURATOR)
inline val isDevelopment: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_DEVELOPMENT)
inline val isIncidentReportApprover: Boolean
get() = permissionInfo.protectionFlags
.hasBits(PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER)
inline val isInstaller: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_INSTALLER)
inline val isInstant: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_INSTANT)
inline val isKnownSigner: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER)
inline val isOem: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_OEM)
@@ -79,55 +98,54 @@ data class Permission(
inline val isPrivileged: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_PRIVILEGED)
inline val isRecents: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RECENTS)
inline val isRetailDemo: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO)
inline val isRole: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_ROLE)
inline val isRuntimeOnly: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY)
inline val isSetup: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_SETUP)
inline val isVerifier: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_VERIFIER)
inline val isVendorPrivileged: Boolean
get() = permissionInfo.protectionFlags
.hasBits(PROTECTION_FLAG_VENDOR_PRIVILEGED)
inline val isSystemTextClassifier: Boolean
get() = permissionInfo.protectionFlags
.hasBits(PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER)
inline val isConfigurator: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_CONFIGURATOR)
inline val isIncidentReportApprover: Boolean
inline val isVendorPrivileged: Boolean
get() = permissionInfo.protectionFlags
.hasBits(PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER)
.hasBits(PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED)
inline val isAppPredictor: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR)
inline val isVerifier: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_VERIFIER)
inline val isCompanion: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_COMPANION)
inline val isHardRestricted: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_HARD_RESTRICTED)
inline val isRetailDemo: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO)
inline val isRemoved: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_REMOVED)
inline val isRecents: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_RECENTS)
inline val isRole: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_ROLE)
inline val isKnownSigner: Boolean
get() = permissionInfo.protectionFlags.hasBits(PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER)
inline val hasGids: Boolean
get() = throw NotImplementedError()
inline val protectionLevel: Int
@Suppress("DEPRECATION")
get() = permissionInfo.protectionLevel
inline val isSoftRestricted: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED)
inline val knownCerts: Set<String>
get() = permissionInfo.knownCerts
inline val hasGids: Boolean
get() = gids.isNotEmpty()
fun getGidsForUser(userId: Int): IntArray =
if (areGidsPerUser) {
IntArray(gids.size) { i -> UserHandle.getUid(userId, gids[i]) }
} else {
gids.clone()
}
companion object {
// The permission is defined in an application manifest.
const val TYPE_MANIFEST = 0
@@ -135,8 +153,5 @@ data class Permission(
const val TYPE_CONFIG = 1
// The permission is defined dynamically.
const val TYPE_DYNAMIC = 2
// TODO: PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED is a testApi
const val PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000
}
}

View File

@@ -40,6 +40,7 @@ import android.os.UserHandle
import android.permission.IOnPermissionsChangeListener
import android.permission.PermissionManager
import android.provider.Settings
import android.util.IntArray as GrowingIntArray
import android.util.Log
import com.android.internal.compat.IPlatformCompat
import com.android.server.FgThread
@@ -61,6 +62,7 @@ import com.android.server.pm.permission.LegacyPermissionState
import com.android.server.pm.permission.PermissionManagerServiceInterface
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.AndroidPackage
import libcore.util.EmptyArray
import java.io.FileDescriptor
import java.io.PrintWriter
@@ -77,6 +79,7 @@ class PermissionService(
private lateinit var packageManagerInternal: PackageManagerInternal
private lateinit var packageManagerLocal: PackageManagerLocal
private lateinit var platformCompat: IPlatformCompat
private lateinit var systemConfig: SystemConfig
private lateinit var userManagerService: UserManagerService
private val mountedStorageVolumes = IndexedSet<String?>()
@@ -94,6 +97,7 @@ class PermissionService(
platformCompat = IPlatformCompat.Stub.asInterface(
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)
)
systemConfig = SystemConfig.getInstance()
userManagerService = UserManagerService.getInstance()
handlerThread = ServiceThread(LOG_TAG, Process.THREAD_PRIORITY_BACKGROUND, true)
@@ -263,7 +267,10 @@ class PermissionService(
}
override fun getPermissionGids(permissionName: String, userId: Int): IntArray {
TODO("Not yet implemented")
val permission = service.getState {
with(policy) { getPermissions()[permissionName] }
} ?: return EmptyArray.INT
return permission.getGidsForUser(userId)
}
override fun addPermission(permissionInfo: PermissionInfo, async: Boolean): Boolean {
@@ -286,6 +293,29 @@ class PermissionService(
TODO("Not yet implemented")
}
override fun getGidsForUid(uid: Int): IntArray {
val appId = UserHandle.getAppId(uid)
val userId = UserHandle.getUserId(uid)
val permissionFlags = service.getState {
with(policy) { getUidPermissionFlags(appId, userId) }
} ?: return EmptyArray.INT
val gids = GrowingIntArray.wrap(systemConfig.globalGids)
permissionFlags.forEachIndexed { _, permissionName, flags ->
if (!PermissionFlags.isPermissionGranted(flags)) {
return@forEachIndexed
}
val permission = service.getState {
with(policy) { getPermissions()[permissionName] }
} ?: return@forEachIndexed
val permissionGids = permission.getGidsForUser(userId)
if (permissionGids.isEmpty()) {
return@forEachIndexed
}
gids.addAll(permissionGids)
}
return gids.toArray()
}
override fun grantRuntimePermission(packageName: String, permissionName: String, userId: Int) {
TODO("Not yet implemented")
}
@@ -306,14 +336,6 @@ class PermissionService(
TODO("Not yet implemented")
}
override fun addOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
onPermissionsChangeListeners.addListener(listener)
}
override fun removeOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
onPermissionsChangeListeners.removeListener(listener)
}
override fun getPermissionFlags(packageName: String, permissionName: String, userId: Int): Int {
// TODO: Implement permission checks.
val appId = 0
@@ -493,21 +515,29 @@ class PermissionService(
TODO("Not yet implemented")
}
override fun addOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
onPermissionsChangeListeners.addListener(listener)
}
override fun removeOnPermissionsChangeListener(listener: IOnPermissionsChangeListener) {
onPermissionsChangeListeners.removeListener(listener)
}
override fun addOnRuntimePermissionStateChangedListener(
listener: PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener
) {
TODO("Not yet implemented")
// TODO: Should be removed once we remove PermissionPolicyService.
}
override fun removeOnRuntimePermissionStateChangedListener(
listener: PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener
) {
TODO("Not yet implemented")
// TODO: Should be removed once we remove PermissionPolicyService.
}
override fun getSplitPermissions(): List<SplitPermissionInfoParcelable> {
return PermissionManager.splitPermissionInfoListToParcelableList(
SystemConfig.getInstance().splitPermissions
systemConfig.splitPermissions
)
}
@@ -534,10 +564,6 @@ class PermissionService(
return appOpPermissionPackageNames
}
override fun getGidsForUid(uid: Int): IntArray {
TODO("Not yet implemented")
}
override fun backupRuntimePermissions(userId: Int): ByteArray? {
TODO("Not yet implemented")
}

View File

@@ -78,6 +78,38 @@ class UidPermissionPolicy : SchemePolicy() {
onPermissionFlagsChangedListeners.forEachIndexed { _, it -> it.onStateMutated() }
}
override fun MutateStateScope.onInitialized() {
newState.systemState.configPermissions.forEach { (permissionName, permissionEntry) ->
val permissions = newState.systemState.permissions
val oldPermission = permissions[permissionName]
val newPermission = if (oldPermission != null) {
if (permissionEntry.gids != null) {
oldPermission.copy(
gids = permissionEntry.gids, areGidsPerUser = permissionEntry.perUser
)
} else {
return@forEach
}
} else {
@Suppress("DEPRECATION")
val permissionInfo = PermissionInfo().apply {
name = permissionName
packageName = PLATFORM_PACKAGE_NAME
protectionLevel = PermissionInfo.PROTECTION_SIGNATURE
}
if (permissionEntry.gids != null) {
Permission(
permissionInfo, false, Permission.TYPE_CONFIG, 0, permissionEntry.gids,
permissionEntry.perUser
)
} else {
Permission(permissionInfo, false, Permission.TYPE_CONFIG, 0)
}
}
permissions[permissionName] = newPermission
}
}
override fun MutateStateScope.onUserAdded(userId: Int) {
newState.systemState.packageStates.forEach { (_, packageState) ->
evaluateAllPermissionStatesForPackageAndUser(packageState, userId, null)
@@ -142,6 +174,7 @@ class UidPermissionPolicy : SchemePolicy() {
addPermissionGroups(packageState)
addPermissions(packageState, changedPermissionNames)
// TODO: revokeStoragePermissionsIfScopeExpandedInternal()
// TODO: revokeSystemAlertWindowIfUpgradedPast23()
trimPermissions(packageState.packageName, changedPermissionNames)
trimPermissionStates(packageState.appId)
changedPermissionNames.forEachIndexed { _, permissionName ->
@@ -348,6 +381,8 @@ class UidPermissionPolicy : SchemePolicy() {
if (packageState != null && androidPackage == null) {
return
}
// TODO: STOPSHIP: We may need to retain permission definitions by disabled system packages
// to retain their permission state.
val isPermissionTreeRemoved = systemState.permissionTrees.removeAllIndexed {
_, permissionTreeName, permissionTree ->
@@ -417,6 +452,7 @@ class UidPermissionPolicy : SchemePolicy() {
val requestedPermissions = IndexedSet<String>()
forEachPackageInAppId(appId) {
requestedPermissions += it.androidPackage!!.requestedPermissions
// TODO: STOPSHIP: Retain permissions requested by disabled system packages.
}
newState.userStates.forEachIndexed { _, userId, userState ->
userState.uidPermissionFlags[appId].forEachReversedIndexed { _, permissionName, _ ->
@@ -556,12 +592,21 @@ class UidPermissionPolicy : SchemePolicy() {
} else if (permission.isRuntime) {
var newFlags = oldFlags and PermissionFlags.MASK_RUNTIME
if (getAppIdTargetSdkVersion(appId, permissionName) < Build.VERSION_CODES.M) {
newFlags = newFlags or PermissionFlags.LEGACY_GRANTED
// Explicitly check against the old state to determine if this permission is new.
val isNewPermission =
getOldStatePermissionFlags(appId, userId, permissionName) == 0
if (isNewPermission) {
newFlags = newFlags or PermissionFlags.IMPLICIT
if (permission.isRuntimeOnly) {
// Different from the old implementation, which simply skips a runtime-only
// permission, we now only allow holding on to the restriction related flags,
// since such flags may only be set one-time in some cases, and disallow all
// other flags thus keeping it revoked.
newFlags = newFlags and PermissionFlags.MASK_EXEMPT
} else {
newFlags = newFlags or PermissionFlags.LEGACY_GRANTED
// Explicitly check against the old state to determine if this permission is
// new.
val isNewPermission =
getOldStatePermissionFlags(appId, userId, permissionName) == 0
if (isNewPermission) {
newFlags = newFlags or PermissionFlags.IMPLICIT
}
}
} else {
newFlags = newFlags andInv PermissionFlags.LEGACY_GRANTED
@@ -743,8 +788,7 @@ class UidPermissionPolicy : SchemePolicy() {
if (!androidPackage.isPrivileged) {
return true
}
if (permission.packageName !in
newState.systemState.privilegedPermissionAllowlistSourcePackageNames) {
if (permission.packageName !in newState.systemState.privilegedPermissionAllowlistPackages) {
return true
}
val allowlistState = getPrivilegedPermissionAllowlistState(androidPackage, permission.name)