Support cross-user VPN calls (with permission)
Settings and SystemUI need to act on other users than USER_OWNER.
This is gated by INTERACT_ACROSS_USERS_FULL in addition to the existing
CONTROL_VPN checks, so the number of processes able to interfere with
other profiles' VPNs should be quite small.
Bug: 20692490
Bug: 20747154
Bug: 20872408
Change-Id: I6e5d7220f73435bec350719e7b4715935caf4e19
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index aeecdf3..e1ec8a6 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -298,13 +298,15 @@
}
/**
- * Set whether the current package has the ability to launch VPNs without user intervention.
+ * Set whether a package has the ability to launch VPNs without user intervention.
*/
- public void setPackageAuthorization(boolean authorized) {
+ public void setPackageAuthorization(String packageName, boolean authorized) {
// Check if the caller is authorized.
enforceControlPermission();
- if (mPackage == null || VpnConfig.LEGACY_VPN.equals(mPackage)) {
+ int uid = getAppUid(packageName, mUserHandle);
+ if (uid == -1 || VpnConfig.LEGACY_VPN.equals(packageName)) {
+ // Authorization for nonexistent packages (or fake ones) can't be updated.
return;
}
@@ -312,10 +314,10 @@
try {
AppOpsManager appOps =
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
- appOps.setMode(AppOpsManager.OP_ACTIVATE_VPN, mOwnerUID, mPackage,
+ appOps.setMode(AppOpsManager.OP_ACTIVATE_VPN, uid, packageName,
authorized ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
} catch (Exception e) {
- Log.wtf(TAG, "Failed to set app ops for package " + mPackage, e);
+ Log.wtf(TAG, "Failed to set app ops for package " + packageName + ", uid " + uid, e);
} finally {
Binder.restoreCallingIdentity(token);
}