From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zoraver Kang <zkang@wpi.edu>
Date: Mon, 16 Sep 2019 16:41:30 -0400
Subject: [PATCH] Enforce INTERNET as a runtime permission.

---
 .../connectivity/PermissionMonitor.java       | 59 ++++++++++++-------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 56f4959a9714..0b2012fa759a 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -29,6 +29,7 @@ import static android.os.Process.INVALID_UID;
 import static android.os.Process.SYSTEM_UID;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -55,6 +56,7 @@ import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -80,6 +82,7 @@ public class PermissionMonitor {
     private static final int VERSION_Q = Build.VERSION_CODES.Q;
 
     private final PackageManager mPackageManager;
+    private final PackageManagerInternal mPackageManagerInternal;
     private final UserManager mUserManager;
     private final INetd mNetd;
 
@@ -104,26 +107,6 @@ public class PermissionMonitor {
 
     private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
 
-        private int getPermissionForUid(int uid) {
-            int permission = 0;
-            // Check all the packages for this UID. The UID has the permission if any of the
-            // packages in it has the permission.
-            String[] packages = mPackageManager.getPackagesForUid(uid);
-            if (packages != null && packages.length > 0) {
-                for (String name : packages) {
-                    final PackageInfo app = getPackageInfo(name);
-                    if (app != null && app.requestedPermissions != null) {
-                        permission |= getNetdPermissionMask(app.requestedPermissions,
-                              app.requestedPermissionsFlags);
-                    }
-                }
-            } else {
-                // The last package of this uid is removed from device. Clean the package up.
-                permission = INetd.PERMISSION_UNINSTALLED;
-            }
-            return permission;
-        }
-
         @Override
         public void onPackageAdded(String packageName, int uid) {
             sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
@@ -140,10 +123,46 @@ public class PermissionMonitor {
         }
     }
 
+    private int getPermissionForUid(int uid) {
+        int permission = 0;
+        // Check all the packages for this UID. The UID has the permission if any of the
+        // packages in it has the permission.
+        String[] packages = mPackageManager.getPackagesForUid(uid);
+        if (packages != null && packages.length > 0) {
+            for (String name : packages) {
+                final PackageInfo app = getPackageInfo(name);
+                if (app != null && app.requestedPermissions != null) {
+                    permission |= getNetdPermissionMask(app.requestedPermissions,
+                          app.requestedPermissionsFlags);
+                }
+            }
+        } else {
+            // The last package of this uid is removed from device. Clean the package up.
+            permission = INetd.PERMISSION_UNINSTALLED;
+        }
+        return permission;
+    }
+
+    // implements OnRuntimePermissionStateChangedListener
+    private void enforceINTERNETAsRuntimePermission(@NonNull String packageName,
+            @UserIdInt int userId) {
+        // userId is _not_ uid
+        int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
+        sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+    }
+
     public PermissionMonitor(Context context, INetd netd) {
         mPackageManager = context.getPackageManager();
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mNetd = netd;
+
+        mPackageManagerInternal = LocalServices.getService(
+                PackageManagerInternal.class);
+
+        final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        permManagerInternal.addOnRuntimePermissionStateChangedListener(
+                this::enforceINTERNETAsRuntimePermission);
     }
 
     // Intended to be called only once at startup, after the system is ready. Installs a broadcast
