Add config permissions and GIDs handling.
Also set up more actual system states, except for device and profile owners. Also add missing runtime-only permission handling, and reorder items in Permission.kt. Bug: 252884423 Test: presubmit Change-Id: I6faf6c192b11ee668cf442dd8b885e761eefea6b
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user