From 4e9fced5568558af8866e46e62ba790a39517644 Mon Sep 17 00:00:00 2001 From: chiachangwang Date: Mon, 10 Apr 2023 13:31:51 +0000 Subject: [PATCH] Clear calling identity before calling to DeviceIdleController There are two possible ways to stop a VPN for a VpnManager apps, deleteVpnProfile() and stopVpnProfile(). Both of them will result in a VpnManagerEvent to notify that the VPN is stopped. The call stack to send a VpnManagerEvent will Call to DeviceIdleController.addPowerSaveTempWhitelistApp which requires UPDATE_DEVICE_STATS permission. Vpn calls it to allow VpnManager app to temporarily run background services to handle the event. This action is done inside the system and should not requires callers' permission. The calling identity is cleared in deleteVpnProfile() but not in stopVpnProfile(). This results in receiving a SecurityException on calling VPN apps, and crash apps without UPDATE_DEVICE_STATS permission(which is not required). Bug: 276457150 Test: atest FrameworksNetTests Change-Id: I1956cbff9374dbed91374974f3a62aeed0b75f27 --- .../com/android/server/connectivity/Vpn.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 7e48f68dcefca..0f17139e26781 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -969,15 +969,21 @@ public class Vpn { // Allow VpnManager app to temporarily run background services to handle this error. // If an app requires anything beyond this grace period, they MUST either declare // themselves as a foreground service, or schedule a job/workitem. - DeviceIdleInternal idleController = mDeps.getDeviceIdleInternal(); - idleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName, - VPN_MANAGER_EVENT_ALLOWLIST_DURATION_MS, mUserId, false, REASON_VPN, - "VpnManager event"); + final long token = Binder.clearCallingIdentity(); try { - return mUserIdContext.startService(intent) != null; - } catch (RuntimeException e) { - Log.e(TAG, "Service of VpnManager app " + intent + " failed to start", e); - return false; + final DeviceIdleInternal idleController = mDeps.getDeviceIdleInternal(); + idleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName, + VPN_MANAGER_EVENT_ALLOWLIST_DURATION_MS, mUserId, false, REASON_VPN, + "VpnManager event"); + + try { + return mUserIdContext.startService(intent) != null; + } catch (RuntimeException e) { + Log.e(TAG, "Service of VpnManager app " + intent + " failed to start", e); + return false; + } + } finally { + Binder.restoreCallingIdentity(token); } }