summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Davidson <jpd@google.com>2014-11-11 13:20:01 -0800
committerJeff Davidson <jpd@google.com>2014-11-12 08:56:20 -0800
commitbc19c181c8c058c824e4fee907a05129e142c388 (patch)
tree666427f56a5be8afe891bc975343240f9ffbe654
parentda772234f6f9498bf02f31448bda16e9fcbd6bd2 (diff)
downloadframeworks_base-bc19c181c8c058c824e4fee907a05129e142c388.zip
frameworks_base-bc19c181c8c058c824e4fee907a05129e142c388.tar.gz
frameworks_base-bc19c181c8c058c824e4fee907a05129e142c388.tar.bz2
Enforce VPN control "permission" with an actual permission.
The current implementation uses a whitelist of package names. Use a system|signature permission instead of rolling our own security and add that permission to the existing set of whitelisted packages (SystemUI and VpnDialogs). In addition to being less of a security risk (using well-known methods like Context.enforceCallingPermission rather than manually querying PackageManager and checking UIDs for package names), this enables other system-privileged apps to control VPN as needed per the below bug. Bug: 18327583 Change-Id: I38617965c40d62cf1ac28e3cb382c0877fb1275d
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/VpnDialogs/AndroidManifest.xml2
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java27
5 files changed, 19 insertions, 25 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b03103e..1d067c8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2406,6 +2406,15 @@
android:description="@string/permdesc_controlWifiDisplay"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows an application to control VPN.
+ <p>Not for use by third-party applications.</p>
+ @hide -->
+ <permission android:name="android.permission.CONTROL_VPN"
+ android:label="@string/permlab_controlVpn"
+ android:description="@string/permdesc_controlVpn"
+ android:protectionLevel="signature|system" />
+ <uses-permission android:name="android.permission.CONTROL_VPN" />
+
<!-- @SystemApi Allows an application to capture audio output.
<p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d6bc38f..c41e13c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1652,6 +1652,11 @@
<string name="permdesc_controlWifiDisplay">Allows the app to control low-level features of Wifi displays.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_controlVpn">control Virtual Private Networks</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_controlVpn">Allows the app to control low-level features of Virtual Private Networks.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_captureAudioOutput">capture audio output</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_captureAudioOutput">Allows the app to capture and redirect audio output.</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b3e60d1..5f024ac 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -55,6 +55,7 @@
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+ <uses-permission android:name="android.permission.CONTROL_VPN" />
<!-- Physical hardware -->
<uses-permission android:name="android.permission.MANAGE_USB" />
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 03d920a..375c5d8 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -19,6 +19,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.vpndialogs">
+ <uses-permission android:name="android.permission.CONTROL_VPN" />
+
<application android:label="VpnDialogs"
android:allowBackup="false" >
<activity android:name=".ConfirmDialog"
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 83756aa..03c05ec 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -23,6 +23,7 @@ import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
+import android.Manifest;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.PendingIntent;
@@ -739,31 +740,7 @@ public class Vpn {
};
private void enforceControlPermission() {
- // System user is allowed to control VPN.
- if (Binder.getCallingUid() == Process.SYSTEM_UID) {
- return;
- }
- int appId = UserHandle.getAppId(Binder.getCallingUid());
- final long token = Binder.clearCallingIdentity();
- try {
- // System VPN dialogs are also allowed to control VPN.
- PackageManager pm = mContext.getPackageManager();
- ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
- if (((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == app.uid)) {
- return;
- }
- // SystemUI dialogs are also allowed to control VPN.
- ApplicationInfo sysUiApp = pm.getApplicationInfo("com.android.systemui", 0);
- if (((sysUiApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0) && (appId == sysUiApp.uid)) {
- return;
- }
- } catch (Exception e) {
- // ignore
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- throw new SecurityException("Unauthorized Caller");
+ mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller");
}
private class Connection implements ServiceConnection {