diff options
author | 2024-12-13 11:45:51 +0800 | |
---|---|---|
committer | 2024-12-13 16:10:30 +0800 | |
commit | 3fb8581fdad15386f12e21837b673b9fead43833 (patch) | |
tree | 722a0b521ec0ab2e5f20cb1a108537ed09fac027 | |
parent | ffdfbbda663302ad1336bfbc67beb5714b7900a3 (diff) |
[Catalyst] Provide pid for permission check
The pid is actually optional but provoide it for consistency.
Bug: 374115149
Flag: com.android.settings.flags.catalyst
Test: manual
Change-Id: I89daec8a60e961a6e98c769d0dbdbcffc1a6fcb4
12 files changed, 69 insertions, 57 deletions
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt index 7aece5185800..3c8d6ed0bf55 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt @@ -38,11 +38,11 @@ abstract class GetPreferenceGraphApiHandler( override suspend fun invoke( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: GetPreferenceGraphRequest, ): PreferenceGraphProto { - val builder = PreferenceGraphBuilder.of(application, myUid, callingUid, request) + val builder = PreferenceGraphBuilder.of(application, callingPid, callingUid, request) if (request.screenKeys.isEmpty()) { for (key in PreferenceScreenRegistry.preferenceScreens.keys) { builder.addPreferenceScreenFromRegistry(key) diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt index c8453efb9161..de5731eacfd7 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt @@ -83,14 +83,14 @@ class PreferenceGetterApiHandler( override fun hasPermission( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: PreferenceGetterRequest, - ) = permissionChecker.hasPermission(application, myUid, callingUid, request) + ) = permissionChecker.hasPermission(application, callingPid, callingUid, request) override suspend fun invoke( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: PreferenceGetterRequest, ): PreferenceGetterResponse { @@ -123,7 +123,7 @@ class PreferenceGetterApiHandler( val preferenceProto = metadata.toProto( application, - myUid, + callingPid, callingUid, screenMetadata, metadata.key == screenMetadata.key, diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt index 606710e6f356..0ce2db8278a3 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt @@ -65,7 +65,7 @@ private const val TAG = "PreferenceGraphBuilder" class PreferenceGraphBuilder private constructor( private val context: Context, - private val myUid: Int, + private val callingPid: Int, private val callingUid: Int, private val request: GetPreferenceGraphRequest, ) { @@ -81,7 +81,7 @@ private constructor( } } - fun build() = builder.build() + fun build(): PreferenceGraphProto = builder.build() /** * Adds an activity to the graph. @@ -268,16 +268,18 @@ private constructor( metadata: PreferenceMetadata, isRoot: Boolean, ) = - metadata.toProto(context, myUid, callingUid, screenMetadata, isRoot, request.flags).also { - if (metadata is PreferenceScreenMetadata) { - @Suppress("CheckReturnValue") addPreferenceScreenMetadata(metadata) - } - metadata.intent(context)?.resolveActivity(context.packageManager)?.let { - if (it.packageName == context.packageName) { - add(it.className) + metadata + .toProto(context, callingPid, callingUid, screenMetadata, isRoot, request.flags) + .also { + if (metadata is PreferenceScreenMetadata) { + @Suppress("CheckReturnValue") addPreferenceScreenMetadata(metadata) + } + metadata.intent(context)?.resolveActivity(context.packageManager)?.let { + if (it.packageName == context.packageName) { + add(it.className) + } } } - } private suspend fun String?.toActionTarget(extras: Bundle?): ActionTarget? { if (this.isNullOrEmpty()) return null @@ -343,16 +345,16 @@ private constructor( companion object { suspend fun of( context: Context, - myUid: Int, + callingPid: Int, callingUid: Int, request: GetPreferenceGraphRequest, - ) = PreferenceGraphBuilder(context, myUid, callingUid, request).also { it.init() } + ) = PreferenceGraphBuilder(context, callingPid, callingUid, request).also { it.init() } } } fun PreferenceMetadata.toProto( context: Context, - myUid: Int, + callingPid: Int, callingUid: Int, screenMetadata: PreferenceScreenMetadata, isRoot: Boolean, @@ -394,7 +396,7 @@ fun PreferenceMetadata.toProto( (!hasAvailable() || available) && (!hasRestricted() || !restricted) && metadata is PersistentPreference<*> && - metadata.getReadPermit(context, myUid, callingUid) == ReadWritePermit.ALLOW + metadata.getReadPermit(context, callingPid, callingUid) == ReadWritePermit.ALLOW ) { value = preferenceValueProto { when (metadata) { diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt index 56b169370e47..2828dec890ee 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt @@ -99,14 +99,14 @@ class PreferenceSetterApiHandler( override fun hasPermission( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: PreferenceSetterRequest, - ) = permissionChecker.hasPermission(application, myUid, callingUid, request) + ) = permissionChecker.hasPermission(application, callingPid, callingUid, request) override suspend fun invoke( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: PreferenceSetterRequest, ): Int { @@ -127,7 +127,7 @@ class PreferenceSetterApiHandler( fun <T> PreferenceMetadata.checkWritePermit(value: T): Int { @Suppress("UNCHECKED_CAST") val preference = (this as PersistentPreference<T>) - return when (preference.getWritePermit(application, value, myUid, callingUid)) { + return when (preference.getWritePermit(application, value, callingPid, callingUid)) { ReadWritePermit.ALLOW -> PreferenceSetterResult.OK ReadWritePermit.DISALLOW -> PreferenceSetterResult.DISALLOW ReadWritePermit.REQUIRE_APP_PERMISSION -> diff --git a/packages/SettingsLib/Ipc/README.md b/packages/SettingsLib/Ipc/README.md index ea2c3a1b52db..719d01e1c686 100644 --- a/packages/SettingsLib/Ipc/README.md +++ b/packages/SettingsLib/Ipc/README.md @@ -101,14 +101,14 @@ object EchoApiImpl : ApiHandler<String?, String?>, ApiDescriptor<String?, String?> by EchoApi { override suspend fun invoke( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: String?, ): String? = request override fun hasPermission( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: String?, ): Boolean = (request?.length ?: 0) <= 5 diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt index 4febd89a7da4..6d746e020243 100644 --- a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/ApiHandler.kt @@ -62,12 +62,17 @@ fun interface ApiPermissionChecker<R> { * Returns if the request is permitted. * * @param application application context - * @param myUid uid of current process + * @param callingPid pid of peer process * @param callingUid uid of peer process * @param request API request * @return `false` if permission is denied, otherwise `true` */ - fun hasPermission(application: Application, myUid: Int, callingUid: Int, request: R): Boolean + fun hasPermission( + application: Application, + callingPid: Int, + callingUid: Int, + request: R, + ): Boolean companion object { private val ALWAYS_ALLOW = ApiPermissionChecker<Any> { _, _, _, _ -> true } @@ -96,7 +101,7 @@ interface ApiHandler<Request, Response> : */ suspend fun invoke( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: Request, ): Response diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerService.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerService.kt index 0bdae38a0a24..7c80b5910f4b 100644 --- a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerService.kt +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerService.kt @@ -25,7 +25,6 @@ import android.os.IBinder import android.os.Looper import android.os.Message import android.os.Messenger -import android.os.Process import android.util.Log import androidx.annotation.VisibleForTesting import kotlinx.coroutines.CoroutineScope @@ -92,7 +91,6 @@ open class MessengerService( private val apiHandlers: Array<ApiHandler<*, *>>, private val permissionChecker: PermissionChecker, ) : Handler(looper) { - @VisibleForTesting internal val myUid = Process.myUid() val coroutineScope = CoroutineScope(asCoroutineDispatcher().immediate + SupervisorJob()) override fun handleMessage(msg: Message) { @@ -109,18 +107,22 @@ open class MessengerService( } val apiId = msg.what val txnId = msg.arg1 + val callingPid = msg.arg2 val callingUid = msg.sendingUid val data = msg.data // WARNING: never access "msg" beyond this point as it may be recycled by Looper val response = Message.obtain(null, apiId, txnId, ApiServiceException.CODE_OK) try { - if (permissionChecker.check(application, myUid, callingUid)) { + if (permissionChecker.check(application, callingPid, callingUid)) { @Suppress("UNCHECKED_CAST") val apiHandler = findApiHandler(apiId) as? ApiHandler<Any, Any> if (apiHandler != null) { val request = apiHandler.requestCodec.decode(data) - if (apiHandler.hasPermission(application, myUid, callingUid, request)) { - val result = apiHandler.invoke(application, myUid, callingUid, request) + if ( + apiHandler.hasPermission(application, callingPid, callingUid, request) + ) { + val result = + apiHandler.invoke(application, callingPid, callingUid, request) response.data = apiHandler.responseCodec.encode(result) } else { response.arg2 = ApiServiceException.CODE_PERMISSION_DENIED diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerServiceClient.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerServiceClient.kt index ef907e17d824..3f7eea5de779 100644 --- a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerServiceClient.kt +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/MessengerServiceClient.kt @@ -28,6 +28,7 @@ import android.os.IBinder import android.os.Looper import android.os.Message import android.os.Messenger +import android.os.Process import android.util.Log import androidx.annotation.OpenForTesting import androidx.annotation.VisibleForTesting @@ -190,6 +191,7 @@ constructor( private val metricsLogger: MetricsLogger?, ) : Handler(looper), ServiceConnection { private val clientMessenger = Messenger(this) + internal val myPid = Process.myPid() internal val pendingRequests = ArrayDeque<RequestWrapper<*, *>>() internal var serviceMessenger: Messenger? = null internal open var connectionState: Int = STATE_INIT @@ -364,7 +366,7 @@ constructor( drainPendingRequests() } val message = - obtainMessage(request.apiDescriptor.id, request.txnId, 0).apply { + obtainMessage(request.apiDescriptor.id, request.txnId, myPid).apply { replyTo = clientMessenger } try { diff --git a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/PermissionChecker.kt b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/PermissionChecker.kt index da9c955d5069..6653b663606d 100644 --- a/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/PermissionChecker.kt +++ b/packages/SettingsLib/Ipc/src/com/android/settingslib/ipc/PermissionChecker.kt @@ -18,6 +18,7 @@ package com.android.settingslib.ipc import android.app.Application import android.content.pm.PackageManager +import android.os.Process import androidx.collection.mutableIntIntMapOf /** Checker for permission. */ @@ -26,18 +27,18 @@ fun interface PermissionChecker { * Checks permission. * * @param application application context - * @param myUid uid of current process + * @param callingPid uid of peer process * @param callingUid uid of peer process */ - fun check(application: Application, myUid: Int, callingUid: Int): Boolean + fun check(application: Application, callingPid: Int, callingUid: Int): Boolean } /** Verifies apk signatures as permission check. */ class SignatureChecker : PermissionChecker { private val cache = mutableIntIntMapOf() - override fun check(application: Application, myUid: Int, callingUid: Int): Boolean = + override fun check(application: Application, callingPid: Int, callingUid: Int): Boolean = cache.getOrPut(callingUid) { - application.packageManager.checkSignatures(myUid, callingUid) + application.packageManager.checkSignatures(Process.myUid(), callingUid) } == PackageManager.SIGNATURE_MATCH } diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt index 668f981e215b..02e50b6f87fd 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt @@ -68,34 +68,34 @@ interface PersistentPreference<T> { PreferenceScreenRegistry.getKeyValueStore(context, this as PreferenceMetadata)!! /** - * Returns if the external application (identified by [callingUid]) has permission to read - * preference value. + * Returns if the external application (identified by [callingPid] and [callingUid]) has + * permission to read preference value. * * The underlying implementation does NOT need to check common states like isEnabled, * isRestricted or isAvailable. */ @ReadWritePermit - fun getReadPermit(context: Context, myUid: Int, callingUid: Int): Int = + fun getReadPermit(context: Context, callingPid: Int, callingUid: Int): Int = PreferenceScreenRegistry.getReadPermit( context, - myUid, + callingPid, callingUid, this as PreferenceMetadata, ) /** - * Returns if the external application (identified by [callingUid]) has permission to write - * preference with given [value]. + * Returns if the external application (identified by [callingPid] and [callingUid]) has + * permission to write preference with given [value]. * * The underlying implementation does NOT need to check common states like isEnabled, * isRestricted or isAvailable. */ @ReadWritePermit - fun getWritePermit(context: Context, value: T?, myUid: Int, callingUid: Int): Int = + fun getWritePermit(context: Context, value: T?, callingPid: Int, callingUid: Int): Int = PreferenceScreenRegistry.getWritePermit( context, value, - myUid, + callingPid, callingUid, this as PreferenceMetadata, ) diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt index 6646d6c32d15..4333a4b597b5 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt @@ -83,21 +83,21 @@ object PreferenceScreenRegistry : ReadWritePermitProvider { override fun getReadPermit( context: Context, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ) = - readWritePermitProvider?.getReadPermit(context, myUid, callingUid, preference) + readWritePermitProvider?.getReadPermit(context, callingPid, callingUid, preference) ?: ReadWritePermit.DISALLOW override fun getWritePermit( context: Context, value: Any?, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ) = - readWritePermitProvider?.getWritePermit(context, value, myUid, callingUid, preference) + readWritePermitProvider?.getWritePermit(context, value, callingPid, callingUid, preference) ?: ReadWritePermit.DISALLOW } @@ -120,7 +120,7 @@ interface ReadWritePermitProvider { @ReadWritePermit fun getReadPermit( context: Context, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ): Int @@ -129,7 +129,7 @@ interface ReadWritePermitProvider { fun getWritePermit( context: Context, value: Any?, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ): Int @@ -140,7 +140,7 @@ interface ReadWritePermitProvider { object : ReadWritePermitProvider { override fun getReadPermit( context: Context, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ) = ReadWritePermit.ALLOW @@ -148,7 +148,7 @@ interface ReadWritePermitProvider { override fun getWritePermit( context: Context, value: Any?, - myUid: Int, + callingPid: Int, callingUid: Int, preference: PreferenceMetadata, ) = ReadWritePermit.ALLOW diff --git a/packages/SettingsLib/Service/src/com/android/settingslib/service/PreferenceGraphApi.kt b/packages/SettingsLib/Service/src/com/android/settingslib/service/PreferenceGraphApi.kt index 1823ba641775..ae9642a38778 100644 --- a/packages/SettingsLib/Service/src/com/android/settingslib/service/PreferenceGraphApi.kt +++ b/packages/SettingsLib/Service/src/com/android/settingslib/service/PreferenceGraphApi.kt @@ -33,8 +33,8 @@ internal class PreferenceGraphApi( override fun hasPermission( application: Application, - myUid: Int, + callingPid: Int, callingUid: Int, request: GetPreferenceGraphRequest, - ) = permissionChecker.hasPermission(application, myUid, callingUid, request) + ) = permissionChecker.hasPermission(application, callingPid, callingUid, request) } |