diff options
author | Jeff Davidson <jpd@google.com> | 2014-11-11 13:20:01 -0800 |
---|---|---|
committer | Jeff Davidson <jpd@google.com> | 2014-11-12 08:56:20 -0800 |
commit | bc19c181c8c058c824e4fee907a05129e142c388 (patch) | |
tree | 666427f56a5be8afe891bc975343240f9ffbe654 | |
parent | da772234f6f9498bf02f31448bda16e9fcbd6bd2 (diff) | |
download | frameworks_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.xml | 9 | ||||
-rw-r--r-- | core/res/res/values/strings.xml | 5 | ||||
-rw-r--r-- | packages/SystemUI/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | packages/VpnDialogs/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/Vpn.java | 27 |
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 { |