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
This commit is contained in:
chiachangwang
2023-04-10 13:31:51 +00:00
parent 66f740be09
commit 4e9fced556

View File

@@ -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);
}
}