DivestOS/Patches/LineageOS-20.0/android_packages_modules_Connectivity/0001-Network_Permission-2.patch
Tad 4bab1c31d7
Churn
Signed-off-by: Tad <tad@spotco.us>
2023-07-19 16:05:51 -04:00

209 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
---
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 24b3fed58..065f41fd8 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -429,14 +429,8 @@ DEFINE_BPF_PROG_EXT("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_cr
KVER(4, 14, 0), KVER_INF, false, "fs_bpf_netd_readonly", "")
(struct bpf_sock* sk) {
uint64_t gid_uid = bpf_get_current_uid_gid();
- /*
- * 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 = (gid_uid & 0xffffffff) % 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 (!permissions) {
// UID not in map. Default to just INTERNET permission.
return 1;
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index 3bf7fdcb5..520dc9e51 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -392,6 +392,11 @@ public class PermissionMonitor {
public synchronized void startMonitoring() {
log("Monitoring");
+ mPackageManager.addOnPermissionsChangeListener(uid -> {
+ // traffic permissions are INTERNET and UPDATE_DEVICE_STATS
+ sendPackagePermissionsForUid(uid, getTrafficPermissionForUid(uid));
+ });
+
final Context userAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -566,7 +571,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="
@@ -614,7 +619,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="
@@ -734,16 +739,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;
}
@@ -761,8 +775,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);
@@ -792,7 +806,7 @@ public class PermissionMonitor {
mPermissionUpdateLogs.log("Package add: name=" + packageName + ", uid=" + uid
+ ", nPerm=(" + permissionToString(permission) + "/"
+ permissionToString(currentPermission) + ")"
- + ", tPerm=" + permissionToString(appIdTrafficPerm));
+ + ", tPerm=" + permissionToString(uidTrafficPerm));
}
private int highestUidNetworkPermission(int uid) {
@@ -824,8 +838,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
@@ -845,7 +859,7 @@ public class PermissionMonitor {
mPermissionUpdateLogs.log("Package remove: name=" + packageName + ", uid=" + uid
+ ", nPerm=(" + permissionToString(permission) + "/"
+ permissionToString(currentPermission) + ")"
- + ", tPerm=" + permissionToString(appIdTrafficPerm));
+ + ", tPerm=" + permissionToString(uidTrafficPerm));
if (permission != currentPermission) {
final SparseIntArray apps = new SparseIntArray();
@@ -1134,14 +1148,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);
}
/**
@@ -1153,7 +1170,7 @@ public class PermissionMonitor {
* @hide
*/
@VisibleForTesting
- void sendAppIdsTrafficPermission(SparseIntArray netdPermissionsAppIds) {
+ void sendUidsTrafficPermission(final int userId, SparseIntArray netdPermissionsAppIds) {
final ArrayList<Integer> allPermissionAppIds = new ArrayList<>();
final ArrayList<Integer> internetPermissionAppIds = new ArrayList<>();
final ArrayList<Integer> updateStatsPermissionAppIds = new ArrayList<>();
@@ -1187,29 +1204,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;
+ }
+
/** Should only be used by unit tests */
@VisibleForTesting
public Set<UidRange> getVpnInterfaceUidRanges(String iface) {