Merge "Prevent an app to check if the specified VPN app is set VPN always-on" into sc-dev am: 34137fbbff am: 4718cfc880

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15501962

Change-Id: I7fc00bc5538907af452f661576fa19b8e4470f7a
This commit is contained in:
Lucas Lin
2021-12-23 12:55:00 +00:00
committed by Automerger Merge Worker

View File

@@ -17,6 +17,8 @@
package com.android.server.connectivity; package com.android.server.connectivity;
import static android.Manifest.permission.BIND_VPN_SERVICE; import static android.Manifest.permission.BIND_VPN_SERVICE;
import static android.Manifest.permission.CONTROL_VPN;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -932,6 +934,7 @@ public class Vpn {
* - oldPackage null, newPackage non-null: ConfirmDialog calling prepareVpn(). * - oldPackage null, newPackage non-null: ConfirmDialog calling prepareVpn().
* - oldPackage null, newPackage=LEGACY_VPN: Used internally to disconnect * - oldPackage null, newPackage=LEGACY_VPN: Used internally to disconnect
* and revoke any current app VPN and re-prepare legacy vpn. * and revoke any current app VPN and re-prepare legacy vpn.
* - oldPackage null, newPackage null: always returns true for backward compatibility.
* *
* TODO: Rename the variables - or split this method into two - and end this confusion. * TODO: Rename the variables - or split this method into two - and end this confusion.
* TODO: b/29032008 Migrate code from prepare(oldPackage=non-null, newPackage=LEGACY_VPN) * TODO: b/29032008 Migrate code from prepare(oldPackage=non-null, newPackage=LEGACY_VPN)
@@ -945,6 +948,18 @@ public class Vpn {
*/ */
public synchronized boolean prepare( public synchronized boolean prepare(
String oldPackage, String newPackage, @VpnManager.VpnType int vpnType) { String oldPackage, String newPackage, @VpnManager.VpnType int vpnType) {
// Except for Settings and VpnDialogs, the caller should be matched one of oldPackage or
// newPackage. Otherwise, non VPN owner might get the VPN always-on status of the VPN owner.
// See b/191382886.
if (mContext.checkCallingOrSelfPermission(CONTROL_VPN) != PERMISSION_GRANTED) {
if (oldPackage != null) {
verifyCallingUidAndPackage(oldPackage);
}
if (newPackage != null) {
verifyCallingUidAndPackage(newPackage);
}
}
if (oldPackage != null) { if (oldPackage != null) {
// Stop an existing always-on VPN from being dethroned by other apps. // Stop an existing always-on VPN from being dethroned by other apps.
if (mAlwaysOn && !isCurrentPreparedPackage(oldPackage)) { if (mAlwaysOn && !isCurrentPreparedPackage(oldPackage)) {
@@ -1859,14 +1874,13 @@ public class Vpn {
} }
private void enforceControlPermission() { private void enforceControlPermission() {
mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller"); mContext.enforceCallingPermission(CONTROL_VPN, "Unauthorized Caller");
} }
private void enforceControlPermissionOrInternalCaller() { private void enforceControlPermissionOrInternalCaller() {
// Require the caller to be either an application with CONTROL_VPN permission or a process // Require the caller to be either an application with CONTROL_VPN permission or a process
// in the system server. // in the system server.
mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_VPN, mContext.enforceCallingOrSelfPermission(CONTROL_VPN, "Unauthorized Caller");
"Unauthorized Caller");
} }
private void enforceSettingsPermission() { private void enforceSettingsPermission() {
@@ -3176,8 +3190,9 @@ public class Vpn {
} }
private void verifyCallingUidAndPackage(String packageName) { private void verifyCallingUidAndPackage(String packageName) {
if (getAppUid(packageName, mUserId) != Binder.getCallingUid()) { final int callingUid = Binder.getCallingUid();
throw new SecurityException("Mismatched package and UID"); if (getAppUid(packageName, mUserId) != callingUid) {
throw new SecurityException(packageName + " does not belong to uid " + callingUid);
} }
} }