From 9c9045241a4da37b94617fa24a2be2013931fe62 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Wed, 12 Jan 2022 14:27:25 +0100 Subject: [PATCH 1/3] Add a new UID range for supplemental processes. These are processes that are spawned alongside regular app processes. They have their own UID range, such that they can be properly isolated from applications. Add some APIs in Process that allows the system and mainline modules to verify that a particular UID belongs to a supplemental process, and to map between the supplemental process and the corresponding app process. Bug: 215012578 Test: N/A Change-Id: I02aaaa1c2bcf9d141ddc97747eb6d7edd52d7b92 --- core/api/current.txt | 1 + core/api/module-lib-current.txt | 3 ++ core/java/android/os/Process.java | 60 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/core/api/current.txt b/core/api/current.txt index 0ce315adc3104..f58e4260a09ed 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32515,6 +32515,7 @@ package android.os { method public static final boolean is64Bit(); method public static boolean isApplicationUid(int); method public static final boolean isIsolated(); + method public static final boolean isSupplemental(); method public static final void killProcess(int); method public static final int myPid(); method @NonNull public static String myProcessName(); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 9abf00bb250b8..dbb26ac647a55 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -376,6 +376,9 @@ package android.os { } public class Process { + method public static final boolean isSupplemental(int); + method public static final int toAppUid(int); + method public static final int toSupplementalUid(int); field public static final int NFC_UID = 1027; // 0x403 field public static final int VPN_UID = 1016; // 0x3f8 } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index a63f68a343d27..2fe0622681127 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -279,6 +279,26 @@ public class Process { */ public static final int LAST_APPLICATION_UID = 19999; + /** + * Defines the start of a range of UIDs going from this number to + * {@link #LAST_SUPPLEMENTAL_UID} that are reserved for assigning to + * supplemental processes. There is a 1-1 mapping between a supplemental + * process UID and the app that it belongs to, which can be computed by + * subtracting (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID) from the + * uid of a supplemental process. + * + * Note that there are no GIDs associated with these processes; storage + * attribution for them will be done using project IDs. + * @hide + */ + public static final int FIRST_SUPPLEMENTAL_UID = 20000; + + /** + * Last UID that is used for supplemental processes. + * @hide + */ + public static final int LAST_SUPPLEMENTAL_UID = 29999; + /** * First uid used for fully isolated sandboxed processes spawned from an app zygote * @hide @@ -880,6 +900,46 @@ public class Process { || (uid >= FIRST_APP_ZYGOTE_ISOLATED_UID && uid <= LAST_APP_ZYGOTE_ISOLATED_UID); } + /** + * Returns whether the provided UID belongs to a supplemental process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final boolean isSupplemental(int uid) { + uid = UserHandle.getAppId(uid); + return (uid >= FIRST_SUPPLEMENTAL_UID && uid <= LAST_SUPPLEMENTAL_UID); + } + + /** + * + * Returns the app process corresponding to a supplemental process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int toAppUid(int uid) { + return uid - (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID); + } + + /** + * + * Returns the supplemental process corresponding to an app process. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int toSupplementalUid(int uid) { + return uid + (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID); + } + + /** + * Returns whether the current process is a supplemental process. + */ + public static final boolean isSupplemental() { + return isSupplemental(myUid()); + } + /** * Returns the UID assigned to a particular user name, or -1 if there is * none. If the given string consists of only numbers, it is converted From 174211109ccfa047d80d5df571de3c3579b95768 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Mon, 17 Jan 2022 19:08:09 +0100 Subject: [PATCH 2/3] Rename ServiceRecord.isolatedProc to isolationHostProc. This member is used to keep track of a process that we have started for hosting a service. For normal services, we don't need to keep track, because we can identify the process that should host the service by matching its uid with the uid off the service. This however is not true for isolated processes (which have their own uid), and now it's also not true for supplemental processes (which also run in their own UID range). To make clear that this will no longer just be used for isolated processes, rename to isolationHostProc. Bug: 215012578 Test: N/A Change-Id: Ida90829ae196bf1161892e3da822444c913885ba --- .../com/android/server/am/ActiveServices.java | 16 ++++++++-------- .../java/com/android/server/am/OomAdjuster.java | 2 +- .../com/android/server/am/ServiceRecord.java | 11 ++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index e040319b8aeee..888710857706b 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -4138,7 +4138,7 @@ public final class ActiveServices { // for a previous process to come up. To deal with this, we store // in the service any current isolated process it is running in or // waiting to have come up. - app = r.isolatedProc; + app = r.isolationHostProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingRecord = HostingRecord.byWebviewZygote(r.instanceName); @@ -4165,7 +4165,7 @@ public final class ActiveServices { return msg; } if (isolated) { - r.isolatedProc = app; + r.isolationHostProc = app; } } @@ -4976,7 +4976,7 @@ public final class ActiveServices { try { for (int i=0; i(); } @@ -5321,7 +5321,7 @@ public final class ActiveServices { sr.app.mServices.updateBoundClientUids(); } sr.setProcess(null, null, 0, null); - sr.isolatedProc = null; + sr.isolationHostProc = null; sr.executeNesting = 0; synchronized (mAm.mProcessStats.mLock) { sr.forceClearTracker(); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index b1234962efc23..bdfd02e9c25a8 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -598,7 +598,7 @@ public class OomAdjuster { for (int i = psr.numberOfConnections() - 1; i >= 0; i--) { ConnectionRecord cr = psr.getConnectionAt(i); ProcessRecord service = (cr.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 - ? cr.binding.service.isolatedProc : cr.binding.service.app; + ? cr.binding.service.isolationHostProc : cr.binding.service.app; if (service == null || service == pr) { continue; } diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 9b32e61763f36..24e7ba4a32b96 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -102,7 +102,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // IBinder -> ConnectionRecord of all bound clients ProcessRecord app; // where this service is running or null. - ProcessRecord isolatedProc; // keep track of isolated process, if requested + ProcessRecord isolationHostProc; // process which we've started for this service (used for + // isolated and supplemental processes) ServiceState tracker; // tracking service execution, may be null ServiceState restartTracker; // tracking service restart boolean allowlistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? @@ -352,8 +353,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN if (app != null) { app.dumpDebug(proto, ServiceRecordProto.APP); } - if (isolatedProc != null) { - isolatedProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); + if (isolationHostProc != null) { + isolationHostProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); } proto.write(ServiceRecordProto.WHITELIST_MANAGER, allowlistManager); proto.write(ServiceRecordProto.DELAYED, delayed); @@ -455,8 +456,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir); } pw.print(prefix); pw.print("app="); pw.println(app); - if (isolatedProc != null) { - pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); + if (isolationHostProc != null) { + pw.print(prefix); pw.print("isolationHostProc="); pw.println(isolationHostProc); } if (allowlistManager) { pw.print(prefix); pw.print("allowlistManager="); pw.println(allowlistManager); From a42d1cf2ac650d7a6be79384c42fc08dfa533ec7 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Mon, 17 Jan 2022 19:57:05 +0100 Subject: [PATCH 3/3] Make ProcessRecord.isolated more robust. There will be additional cases beyond isolated services where the UID of the process is different from the UID of the defining package. Explicitly check for the isolated UID range. Bug: 215012578 Test: N/A Change-Id: I39c351f10876ffc2bdb7680bfab9ebf8bddc8153 --- services/core/java/com/android/server/am/ProcessRecord.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c830554c398b7..be187e21db47d 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -513,7 +513,7 @@ class ProcessRecord implements WindowProcessListener { } } processInfo = procInfo; - isolated = _info.uid != _uid; + isolated = Process.isIsolated(_uid); appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID && UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID); uid = _uid;