321 lines
15 KiB
Diff
321 lines
15 KiB
Diff
![]() |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|||
|
From: Pratyush <codelab@pratyush.dev>
|
|||
|
Date: Wed, 13 Oct 2021 22:20:53 +0530
|
|||
|
Subject: [PATCH] use uid instead of app id
|
|||
|
|
|||
|
---
|
|||
|
.../connectivity/PermissionMonitor.java | 142 +++++++++---------
|
|||
|
1 file changed, 68 insertions(+), 74 deletions(-)
|
|||
|
|
|||
|
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|||
|
index a43ee18b3..8625f3c80 100755
|
|||
|
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|||
|
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|||
|
@@ -225,42 +225,44 @@ public class PermissionMonitor {
|
|||
|
// mUidsAllowedOnRestrictedNetworks.
|
|||
|
updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext));
|
|||
|
|
|||
|
- List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
|
|||
|
- | MATCH_ANY_USER);
|
|||
|
- if (apps == null) {
|
|||
|
- loge("No apps");
|
|||
|
- return;
|
|||
|
- }
|
|||
|
-
|
|||
|
SparseIntArray netdPermsUids = new SparseIntArray();
|
|||
|
|
|||
|
- for (PackageInfo app : apps) {
|
|||
|
- int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
|
|||
|
- if (uid < 0) {
|
|||
|
+ mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
|
|||
|
+
|
|||
|
+ for(UserHandle user : mUsers){
|
|||
|
+ PackageManager pmUser = mContext.createContextAsUser(user,0).getPackageManager();
|
|||
|
+ List<PackageInfo> apps = pmUser.getInstalledPackages(GET_PERMISSIONS);
|
|||
|
+ if (apps == null) {
|
|||
|
+ loge("No apps");
|
|||
|
continue;
|
|||
|
}
|
|||
|
- mAllApps.add(UserHandle.getAppId(uid));
|
|||
|
|
|||
|
- boolean isNetwork = hasNetworkPermission(app);
|
|||
|
- boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
|
|||
|
+ for (PackageInfo app : apps) {
|
|||
|
+ int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
|
|||
|
+ if (uid < 0) {
|
|||
|
+ continue;
|
|||
|
+ }
|
|||
|
+ mAllApps.add(uid);
|
|||
|
|
|||
|
- if (isNetwork || hasRestrictedPermission) {
|
|||
|
- Boolean permission = mApps.get(UserHandle.getAppId(uid));
|
|||
|
- // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
|
|||
|
- // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
|
|||
|
- if (permission == null || permission == NETWORK) {
|
|||
|
- mApps.put(UserHandle.getAppId(uid), hasRestrictedPermission);
|
|||
|
+ boolean isNetwork = hasNetworkPermission(app);
|
|||
|
+ boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
|
|||
|
+
|
|||
|
+ if (isNetwork || hasRestrictedPermission) {
|
|||
|
+ Boolean permission = mApps.get(uid);
|
|||
|
+ // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
|
|||
|
+ // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
|
|||
|
+ if (permission == null || permission == NETWORK) {
|
|||
|
+ mApps.put(uid, hasRestrictedPermission);
|
|||
|
+ }
|
|||
|
}
|
|||
|
- }
|
|||
|
|
|||
|
- //TODO: unify the management of the permissions into one codepath.
|
|||
|
- int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
|||
|
- app.requestedPermissionsFlags);
|
|||
|
- netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
|||
|
+ //TODO: unify the management of the permissions into one codepath.
|
|||
|
+ int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
|||
|
+ app.requestedPermissionsFlags);
|
|||
|
+ netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
- mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
|
|||
|
-
|
|||
|
final SparseArray<String> netdPermToSystemPerm = new SparseArray<>();
|
|||
|
netdPermToSystemPerm.put(INetd.PERMISSION_INTERNET, INTERNET);
|
|||
|
netdPermToSystemPerm.put(INetd.PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
|
|||
|
@@ -280,7 +282,7 @@ public class PermissionMonitor {
|
|||
|
}
|
|||
|
|
|||
|
public void onInternetPermissionChanged(int uid) {
|
|||
|
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
|
|||
|
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
|||
|
}
|
|||
|
|
|||
|
@VisibleForTesting
|
|||
|
@@ -291,9 +293,7 @@ public class PermissionMonitor {
|
|||
|
// is only installed on some users because the uid cannot match some other app – this uid is
|
|||
|
// in effect not installed and can't be run.
|
|||
|
// TODO (b/192431153): Change appIds back to uids.
|
|||
|
- for (int uid : uids) {
|
|||
|
- mUidsAllowedOnRestrictedNetworks.add(UserHandle.getAppId(uid));
|
|||
|
- }
|
|||
|
+ mUidsAllowedOnRestrictedNetworks.addAll(uids);
|
|||
|
}
|
|||
|
|
|||
|
@VisibleForTesting
|
|||
|
@@ -315,7 +315,7 @@ public class PermissionMonitor {
|
|||
|
if (appInfo == null) return false;
|
|||
|
// Check whether package's uid is in allowed on restricted networks uid list. If so, this
|
|||
|
// uid can have netd system permission.
|
|||
|
- return mUidsAllowedOnRestrictedNetworks.contains(UserHandle.getAppId(appInfo.uid));
|
|||
|
+ return mUidsAllowedOnRestrictedNetworks.contains(appInfo.uid);
|
|||
|
}
|
|||
|
|
|||
|
@VisibleForTesting
|
|||
|
@@ -351,14 +351,14 @@ public class PermissionMonitor {
|
|||
|
// networks. mApps contains the result of checks for both hasNetworkPermission and
|
|||
|
// hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of
|
|||
|
// permissions at least.
|
|||
|
- return mApps.containsKey(UserHandle.getAppId(uid));
|
|||
|
+ return mApps.containsKey(uid);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Returns whether the given uid has permission to use restricted networks.
|
|||
|
*/
|
|||
|
public synchronized boolean hasRestrictedNetworksPermission(int uid) {
|
|||
|
- return Boolean.TRUE.equals(mApps.get(UserHandle.getAppId(uid)));
|
|||
|
+ return Boolean.TRUE.equals(mApps.get(uid));
|
|||
|
}
|
|||
|
|
|||
|
private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
|
|||
|
@@ -424,21 +424,17 @@ public class PermissionMonitor {
|
|||
|
* permission.
|
|||
|
*/
|
|||
|
@VisibleForTesting
|
|||
|
- protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
|
|||
|
+ protected Boolean highestPermissionForUid(Boolean currentPermission, String name, int uid) {
|
|||
|
if (currentPermission == SYSTEM) {
|
|||
|
return currentPermission;
|
|||
|
}
|
|||
|
- try {
|
|||
|
- final PackageInfo app = mPackageManager.getPackageInfo(name,
|
|||
|
- GET_PERMISSIONS | MATCH_ANY_USER);
|
|||
|
+ final PackageInfo app = getPackageInfo(name, UserHandle.getUserHandleForUid(uid));
|
|||
|
+ if(app != null){
|
|||
|
final boolean isNetwork = hasNetworkPermission(app);
|
|||
|
final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
|
|||
|
if (isNetwork || hasRestrictedPermission) {
|
|||
|
currentPermission = hasRestrictedPermission;
|
|||
|
}
|
|||
|
- } catch (NameNotFoundException e) {
|
|||
|
- // App not found.
|
|||
|
- loge("NameNotFoundException " + name);
|
|||
|
}
|
|||
|
return currentPermission;
|
|||
|
}
|
|||
|
@@ -450,7 +446,7 @@ public class PermissionMonitor {
|
|||
|
final String[] packages = mPackageManager.getPackagesForUid(uid);
|
|||
|
if (packages != null && packages.length > 0) {
|
|||
|
for (String name : packages) {
|
|||
|
- final PackageInfo app = getPackageInfo(name);
|
|||
|
+ PackageInfo app = getPackageInfo(name, UserHandle.getUserHandleForUid(uid));
|
|||
|
if (app != null && app.requestedPermissions != null) {
|
|||
|
permission |= getNetdPermissionMask(app.requestedPermissions,
|
|||
|
app.requestedPermissionsFlags);
|
|||
|
@@ -474,17 +470,16 @@ public class PermissionMonitor {
|
|||
|
public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
|
|||
|
// TODO: Netd is using appId for checking traffic permission. Correct the methods that are
|
|||
|
// using appId instead of uid actually
|
|||
|
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
|
|||
|
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
|||
|
|
|||
|
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
|
|||
|
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
|
|||
|
- final int appId = UserHandle.getAppId(uid);
|
|||
|
- final Boolean permission = highestPermissionForUid(mApps.get(appId), packageName);
|
|||
|
- if (permission != mApps.get(appId)) {
|
|||
|
- mApps.put(appId, permission);
|
|||
|
+ final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName, uid);
|
|||
|
+ if (permission != mApps.get(uid)) {
|
|||
|
+ mApps.put(uid, permission);
|
|||
|
|
|||
|
Map<Integer, Boolean> apps = new HashMap<>();
|
|||
|
- apps.put(appId, permission);
|
|||
|
+ apps.put(uid, permission);
|
|||
|
update(mUsers, apps, true);
|
|||
|
}
|
|||
|
|
|||
|
@@ -499,7 +494,7 @@ public class PermissionMonitor {
|
|||
|
updateVpnUids(vpn.getKey(), changedUids, true);
|
|||
|
}
|
|||
|
}
|
|||
|
- mAllApps.add(appId);
|
|||
|
+ mAllApps.add(uid);
|
|||
|
}
|
|||
|
|
|||
|
private Boolean highestUidNetworkPermission(int uid) {
|
|||
|
@@ -509,7 +504,7 @@ public class PermissionMonitor {
|
|||
|
for (String name : packages) {
|
|||
|
// If multiple packages have the same UID, give the UID all permissions that
|
|||
|
// any package in that UID has.
|
|||
|
- permission = highestPermissionForUid(permission, name);
|
|||
|
+ permission = highestPermissionForUid(permission, name, uid);
|
|||
|
if (permission == SYSTEM) {
|
|||
|
break;
|
|||
|
}
|
|||
|
@@ -529,7 +524,7 @@ public class PermissionMonitor {
|
|||
|
public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
|
|||
|
// TODO: Netd is using appId for checking traffic permission. Correct the methods that are
|
|||
|
// using appId instead of uid actually
|
|||
|
- sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
|
|||
|
+ sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
|||
|
|
|||
|
// If the newly-removed package falls within some VPN's uid range, update Netd with it.
|
|||
|
// This needs to happen before the mApps update below, since removeBypassingUids() depends
|
|||
|
@@ -544,11 +539,11 @@ public class PermissionMonitor {
|
|||
|
}
|
|||
|
// If the package has been removed from all users on the device, clear it form mAllApps.
|
|||
|
if (mPackageManager.getNameForUid(uid) == null) {
|
|||
|
- mAllApps.remove(UserHandle.getAppId(uid));
|
|||
|
+ mAllApps.remove(uid);
|
|||
|
}
|
|||
|
|
|||
|
Map<Integer, Boolean> apps = new HashMap<>();
|
|||
|
- final Boolean permission = highestUidNetworkPermission(uid);
|
|||
|
+ final Boolean permission = highestPermissionForUid(null, packageName,uid);
|
|||
|
if (permission == SYSTEM) {
|
|||
|
// An app with this UID still has the SYSTEM permission.
|
|||
|
// Therefore, this UID must already have the SYSTEM permission.
|
|||
|
@@ -556,23 +551,22 @@ public class PermissionMonitor {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
- final int appId = UserHandle.getAppId(uid);
|
|||
|
- if (permission == mApps.get(appId)) {
|
|||
|
+ if (permission == mApps.get(uid)) {
|
|||
|
// The permissions of this UID have not changed. Nothing to do.
|
|||
|
return;
|
|||
|
} else if (permission != null) {
|
|||
|
- mApps.put(appId, permission);
|
|||
|
- apps.put(appId, permission);
|
|||
|
+ mApps.put(uid, permission);
|
|||
|
+ apps.put(uid, permission);
|
|||
|
update(mUsers, apps, true);
|
|||
|
} else {
|
|||
|
- mApps.remove(appId);
|
|||
|
- apps.put(appId, NETWORK); // doesn't matter which permission we pick here
|
|||
|
+ mApps.remove(uid);
|
|||
|
+ apps.put(uid, NETWORK); // doesn't matter which permission we pick here
|
|||
|
update(mUsers, apps, false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static int getNetdPermissionMask(String[] requestedPermissions,
|
|||
|
- int[] requestedPermissionsFlags) {
|
|||
|
+ int[] requestedPermissionsFlags) {
|
|||
|
int permissions = 0;
|
|||
|
if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
|
|||
|
for (int i = 0; i < requestedPermissions.length; i++) {
|
|||
|
@@ -588,11 +582,10 @@ public class PermissionMonitor {
|
|||
|
return permissions;
|
|||
|
}
|
|||
|
|
|||
|
- private PackageInfo getPackageInfo(String packageName) {
|
|||
|
+ private PackageInfo getPackageInfo(String packageName, UserHandle user) {
|
|||
|
try {
|
|||
|
- PackageInfo app = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS
|
|||
|
- | MATCH_ANY_USER);
|
|||
|
- return app;
|
|||
|
+ return mContext.createContextAsUser(user, 0).getPackageManager()
|
|||
|
+ .getPackageInfo(packageName, GET_PERMISSIONS);
|
|||
|
} catch (NameNotFoundException e) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
@@ -681,7 +674,7 @@ public class PermissionMonitor {
|
|||
|
*/
|
|||
|
private void removeBypassingUids(Set<Integer> uids, int vpnAppUid) {
|
|||
|
uids.remove(vpnAppUid);
|
|||
|
- uids.removeIf(uid -> mApps.getOrDefault(UserHandle.getAppId(uid), NETWORK) == SYSTEM);
|
|||
|
+ uids.removeIf(uid -> mApps.getOrDefault(uid, NETWORK) == SYSTEM);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
@@ -823,13 +816,12 @@ public class PermissionMonitor {
|
|||
|
for (Integer uid : uidsToUpdate) {
|
|||
|
final Boolean permission = highestUidNetworkPermission(uid);
|
|||
|
|
|||
|
- final int appId = UserHandle.getAppId(uid);
|
|||
|
if (null == permission) {
|
|||
|
- removedUids.put(appId, NETWORK); // Doesn't matter which permission is set here.
|
|||
|
- mApps.remove(appId);
|
|||
|
+ removedUids.put(uid, NETWORK); // Doesn't matter which permission is set here.
|
|||
|
+ mApps.remove(uid);
|
|||
|
} else {
|
|||
|
- updatedUids.put(appId, permission);
|
|||
|
- mApps.put(appId, permission);
|
|||
|
+ updatedUids.put(uid, permission);
|
|||
|
+ mApps.put(uid, permission);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
@@ -844,12 +836,14 @@ public class PermissionMonitor {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
- for (String app : pkgList) {
|
|||
|
- final PackageInfo info = getPackageInfo(app);
|
|||
|
- if (info == null || info.applicationInfo == null) continue;
|
|||
|
+ for (UserHandle user : mUsers){
|
|||
|
+ for (String app : pkgList) {
|
|||
|
+ final PackageInfo info = getPackageInfo(app, user);
|
|||
|
+ if (info == null || info.applicationInfo == null) continue;
|
|||
|
|
|||
|
- final int appId = info.applicationInfo.uid;
|
|||
|
- onPackageAdded(app, appId); // Use onPackageAdded to add package one by one.
|
|||
|
+ final int appId = info.applicationInfo.uid;
|
|||
|
+ onPackageAdded(app, appId); // Use onPackageAdded to add package one by one.
|
|||
|
+ }
|
|||
|
}
|
|||
|
}
|
|||
|
|