mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-09-16 06:22:26 +00:00
d98f33a337
TODO: - f/w/b - settings Signed-off-by: Tavi <tavi@divested.dev>
210 lines
9.9 KiB
Diff
210 lines
9.9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
|
|
Date: Wed, 6 Oct 2021 03:05:49 +0300
|
|
Subject: [PATCH] enforce INTERNET permission per-uid instead of per-appId
|
|
|
|
13: 0a4c2f9719
|
|
---
|
|
bpf_progs/netd.c | 10 +--
|
|
.../connectivity/PermissionMonitor.java | 63 ++++++++++++++-----
|
|
2 files changed, 48 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
|
|
index 59bbfbae51..6bcc863043 100644
|
|
--- a/bpf_progs/netd.c
|
|
+++ b/bpf_progs/netd.c
|
|
@@ -653,14 +653,8 @@ DEFINE_XTBPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_den
|
|
}
|
|
|
|
static __always_inline inline uint8_t get_app_permissions(uint32_t uid) {
|
|
- /*
|
|
- * A given app is guaranteed to have the same app ID in all the profiles in
|
|
- * which it is installed, and install permission is granted to app for all
|
|
- * user at install time so we only check the appId part of a request uid at
|
|
- * run time. See UserHandle#isSameApp for detail.
|
|
- */
|
|
- uint32_t appId = uid % AID_USER_OFFSET; // == PER_USER_RANGE == 100000
|
|
- uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
|
|
+ uint32_t uid = (gid_uid & 0xffffffff);
|
|
+ uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&uid);
|
|
// if UID not in map, then default to just INTERNET permission.
|
|
return permissions ? *permissions : BPF_PERMISSION_INTERNET;
|
|
}
|
|
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|
index c9b6387e0e..4443c4316e 100755
|
|
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
|
|
@@ -426,6 +426,11 @@ public class PermissionMonitor {
|
|
userAllContext.registerReceiver(
|
|
mIntentReceiver, intentFilter, null /* broadcastPermission */, handler);
|
|
|
|
+ mPackageManager.addOnPermissionsChangeListener(uid -> {
|
|
+ // traffic permissions are INTERNET and UPDATE_DEVICE_STATS
|
|
+ handler.post(() -> sendPackagePermissionsForUid(uid, getTrafficPermissionForUid(uid)));
|
|
+ });
|
|
+
|
|
// Listen to EXTERNAL_APPLICATIONS_AVAILABLE is that an app becoming available means it may
|
|
// need to gain a permission. But an app that becomes unavailable can neither gain nor lose
|
|
// permissions on that account, it just can no longer run. Thus, doesn't need to listen to
|
|
@@ -599,7 +604,7 @@ public class PermissionMonitor {
|
|
mUsersTrafficPermissions.put(user, addedUserAppIds);
|
|
// Generate appIds from all users and send result to netd.
|
|
final SparseIntArray appIds = makeAppIdsTrafficPermForAllUsers();
|
|
- sendAppIdsTrafficPermission(appIds);
|
|
+ sendUidsTrafficPermission(user.getIdentifier(), appIds);
|
|
|
|
// Log user added
|
|
mPermissionUpdateLogs.log("New user(" + user.getIdentifier() + ") added: nPerm uids="
|
|
@@ -648,7 +653,7 @@ public class PermissionMonitor {
|
|
appIds.put(appId, PERMISSION_UNINSTALLED);
|
|
}
|
|
}
|
|
- sendAppIdsTrafficPermission(appIds);
|
|
+ sendUidsTrafficPermission(user.getIdentifier(), appIds);
|
|
|
|
// Log user removed
|
|
mPermissionUpdateLogs.log("User(" + user.getIdentifier() + ") removed: nPerm uids="
|
|
@@ -772,16 +777,25 @@ public class PermissionMonitor {
|
|
}
|
|
}
|
|
|
|
- private synchronized int getAppIdTrafficPermission(int appId) {
|
|
+ private synchronized int getUidTrafficPermission(final int uid) {
|
|
+ final int userId = UserHandle.getUserId(uid);
|
|
+
|
|
int permission = PERMISSION_NONE;
|
|
boolean installed = false;
|
|
+
|
|
for (UserHandle user : mUsersTrafficPermissions.keySet()) {
|
|
+ if (user.getIdentifier() != userId) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
final SparseIntArray userApps = mUsersTrafficPermissions.get(user);
|
|
+ final int appId = UserHandle.getAppId(uid);
|
|
final int appIdx = userApps.indexOfKey(appId);
|
|
if (appIdx >= 0) {
|
|
permission |= userApps.valueAt(appIdx);
|
|
installed = true;
|
|
}
|
|
+ break;
|
|
}
|
|
return installed ? permission : PERMISSION_UNINSTALLED;
|
|
}
|
|
@@ -800,8 +814,8 @@ public class PermissionMonitor {
|
|
updateAppIdTrafficPermission(uid);
|
|
// Get the appId permission from all users then send the latest permission to netd.
|
|
final int appId = UserHandle.getAppId(uid);
|
|
- final int appIdTrafficPerm = getAppIdTrafficPermission(appId);
|
|
- sendPackagePermissionsForAppId(appId, appIdTrafficPerm);
|
|
+ final int uidTrafficPerm = getUidTrafficPermission(uid);
|
|
+ sendPackagePermissionsForUid(uid, uidTrafficPerm);
|
|
|
|
final int currentPermission = mUidToNetworkPerm.get(uid, PERMISSION_NONE);
|
|
final int permission = highestPermissionForUid(uid, currentPermission, packageName);
|
|
@@ -831,7 +845,7 @@ public class PermissionMonitor {
|
|
mPermissionUpdateLogs.log("Package add: uid=" + uid
|
|
+ ", nPerm=(" + permissionToString(permission) + "/"
|
|
+ permissionToString(currentPermission) + ")"
|
|
- + ", tPerm=" + permissionToString(appIdTrafficPerm));
|
|
+ + ", tPerm=" + permissionToString(uidTrafficPerm));
|
|
}
|
|
|
|
private int highestUidNetworkPermission(int uid) {
|
|
@@ -864,8 +878,8 @@ public class PermissionMonitor {
|
|
updateAppIdTrafficPermission(uid);
|
|
// Get the appId permission from all users then send the latest permission to netd.
|
|
final int appId = UserHandle.getAppId(uid);
|
|
- final int appIdTrafficPerm = getAppIdTrafficPermission(appId);
|
|
- sendPackagePermissionsForAppId(appId, appIdTrafficPerm);
|
|
+ final int uidTrafficPerm = getUidTrafficPermission(uid);
|
|
+ sendPackagePermissionsForUid(uid, uidTrafficPerm);
|
|
|
|
// If the newly-removed package falls within some VPN's uid range, update Netd with it.
|
|
// This needs to happen before the mUidToNetworkPerm update below, since
|
|
@@ -885,7 +899,7 @@ public class PermissionMonitor {
|
|
mPermissionUpdateLogs.log("Package remove: uid=" + uid
|
|
+ ", nPerm=(" + permissionToString(permission) + "/"
|
|
+ permissionToString(currentPermission) + ")"
|
|
- + ", tPerm=" + permissionToString(appIdTrafficPerm));
|
|
+ + ", tPerm=" + permissionToString(uidTrafficPerm));
|
|
|
|
if (permission != currentPermission) {
|
|
final SparseIntArray apps = new SparseIntArray();
|
|
@@ -1169,14 +1183,17 @@ public class PermissionMonitor {
|
|
* @hide
|
|
*/
|
|
@VisibleForTesting
|
|
- void sendPackagePermissionsForAppId(int appId, int permissions) {
|
|
+ void sendPackagePermissionsForUid(int uid, int permissions) {
|
|
+ int userId = UserHandle.getUserId(uid);
|
|
+ int appId = UserHandle.getAppId(uid);
|
|
+
|
|
SparseIntArray netdPermissionsAppIds = new SparseIntArray();
|
|
netdPermissionsAppIds.put(appId, permissions);
|
|
if (hasSdkSandbox(appId)) {
|
|
int sdkSandboxAppId = sProcessShim.toSdkSandboxUid(appId);
|
|
netdPermissionsAppIds.put(sdkSandboxAppId, permissions);
|
|
}
|
|
- sendAppIdsTrafficPermission(netdPermissionsAppIds);
|
|
+ sendUidsTrafficPermission(userId, netdPermissionsAppIds);
|
|
}
|
|
|
|
/**
|
|
@@ -1188,7 +1205,7 @@ public class PermissionMonitor {
|
|
* @hide
|
|
*/
|
|
@VisibleForTesting
|
|
- void sendAppIdsTrafficPermission(SparseIntArray netdPermissionsAppIds) {
|
|
+ void sendUidsTrafficPermission(final int userId, SparseIntArray netdPermissionsAppIds) {
|
|
ensureRunningOnHandlerThread();
|
|
final ArrayList<Integer> allPermissionAppIds = new ArrayList<>();
|
|
final ArrayList<Integer> internetPermissionAppIds = new ArrayList<>();
|
|
@@ -1223,29 +1240,41 @@ public class PermissionMonitor {
|
|
if (allPermissionAppIds.size() != 0) {
|
|
mBpfNetMaps.setNetPermForUids(
|
|
PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
|
|
- toIntArray(allPermissionAppIds));
|
|
+ appIdListToUidArray(userId, allPermissionAppIds));
|
|
}
|
|
if (internetPermissionAppIds.size() != 0) {
|
|
mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET,
|
|
- toIntArray(internetPermissionAppIds));
|
|
+ appIdListToUidArray(userId, internetPermissionAppIds));
|
|
}
|
|
if (updateStatsPermissionAppIds.size() != 0) {
|
|
mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS,
|
|
- toIntArray(updateStatsPermissionAppIds));
|
|
+ appIdListToUidArray(userId, updateStatsPermissionAppIds));
|
|
}
|
|
if (noPermissionAppIds.size() != 0) {
|
|
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE,
|
|
- toIntArray(noPermissionAppIds));
|
|
+ appIdListToUidArray(userId, noPermissionAppIds));
|
|
}
|
|
if (uninstalledAppIds.size() != 0) {
|
|
mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED,
|
|
- toIntArray(uninstalledAppIds));
|
|
+ appIdListToUidArray(userId, uninstalledAppIds));
|
|
}
|
|
} catch (RemoteException | ServiceSpecificException e) {
|
|
Log.e(TAG, "Pass appId list of special permission failed." + e);
|
|
}
|
|
}
|
|
|
|
+ private static int[] appIdListToUidArray(int userId, ArrayList<Integer> appIds) {
|
|
+ final int cnt = appIds.size();
|
|
+ int[] array = new int[cnt];
|
|
+
|
|
+ for (int i = 0; i < cnt; ++i) {
|
|
+ int appId = appIds.get(i).intValue();
|
|
+ array[i] = UserHandle.getUid(userId, appId);
|
|
+ }
|
|
+
|
|
+ return array;
|
|
+ }
|
|
+
|
|
private synchronized void onSettingChanged() {
|
|
// Step1. Update uids allowed to use restricted networks and compute the set of uids to
|
|
// update.
|