Merge "Remove hidden preconditions, binder usage in Vpn"
This commit is contained in:
@@ -23,8 +23,7 @@ import static android.net.RouteInfo.RTN_UNREACHABLE;
|
|||||||
import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
|
import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
|
||||||
import static android.os.UserHandle.PER_USER_RANGE;
|
import static android.os.UserHandle.PER_USER_RANGE;
|
||||||
|
|
||||||
import static com.android.internal.util.Preconditions.checkArgument;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -1096,13 +1095,14 @@ public class Vpn {
|
|||||||
return Process.myUid();
|
return Process.myUid();
|
||||||
}
|
}
|
||||||
PackageManager pm = mContext.getPackageManager();
|
PackageManager pm = mContext.getPackageManager();
|
||||||
return Binder.withCleanCallingIdentity(() -> {
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
return pm.getPackageUidAsUser(app, userId);
|
return pm.getPackageUidAsUser(app, userId);
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} finally {
|
||||||
});
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doesPackageTargetAtLeastQ(String packageName) {
|
private boolean doesPackageTargetAtLeastQ(String packageName) {
|
||||||
@@ -1278,15 +1278,16 @@ public class Vpn {
|
|||||||
// We are user controlled, not driven by NetworkRequest.
|
// We are user controlled, not driven by NetworkRequest.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Binder.withCleanCallingIdentity(() -> {
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
mNetworkAgent.register();
|
mNetworkAgent.register();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
// If register() throws, don't keep an unregistered agent.
|
// If register() throws, don't keep an unregistered agent.
|
||||||
mNetworkAgent = null;
|
mNetworkAgent = null;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
} finally {
|
||||||
});
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
|
mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
|
||||||
? Arrays.asList(mConfig.underlyingNetworks) : null);
|
? Arrays.asList(mConfig.underlyingNetworks) : null);
|
||||||
updateState(DetailedState.CONNECTED, "agentConnect");
|
updateState(DetailedState.CONNECTED, "agentConnect");
|
||||||
@@ -2024,13 +2025,16 @@ public class Vpn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void enforceNotRestrictedUser() {
|
private void enforceNotRestrictedUser() {
|
||||||
Binder.withCleanCallingIdentity(() -> {
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
final UserInfo user = mUserManager.getUserInfo(mUserId);
|
final UserInfo user = mUserManager.getUserInfo(mUserId);
|
||||||
|
|
||||||
if (user.isRestricted()) {
|
if (user.isRestricted()) {
|
||||||
throw new SecurityException("Restricted users cannot configure VPNs");
|
throw new SecurityException("Restricted users cannot configure VPNs");
|
||||||
}
|
}
|
||||||
});
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2823,8 +2827,10 @@ public class Vpn {
|
|||||||
|
|
||||||
LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) {
|
LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) {
|
||||||
super(TAG);
|
super(TAG);
|
||||||
checkArgument(racoon != null || mtpd != null, "Arguments to racoon and mtpd "
|
if (racoon == null && mtpd == null) {
|
||||||
+ "must not both be null");
|
throw new IllegalArgumentException(
|
||||||
|
"Arguments to racoon and mtpd must not both be null");
|
||||||
|
}
|
||||||
mConfig = config;
|
mConfig = config;
|
||||||
mDaemons = new String[] {"racoon", "mtpd"};
|
mDaemons = new String[] {"racoon", "mtpd"};
|
||||||
// TODO: clear arguments from memory once launched
|
// TODO: clear arguments from memory once launched
|
||||||
@@ -3149,8 +3155,8 @@ public class Vpn {
|
|||||||
*/
|
*/
|
||||||
public synchronized boolean provisionVpnProfile(
|
public synchronized boolean provisionVpnProfile(
|
||||||
@NonNull String packageName, @NonNull VpnProfile profile) {
|
@NonNull String packageName, @NonNull VpnProfile profile) {
|
||||||
checkNotNull(packageName, "No package name provided");
|
requireNonNull(packageName, "No package name provided");
|
||||||
checkNotNull(profile, "No profile provided");
|
requireNonNull(profile, "No profile provided");
|
||||||
|
|
||||||
verifyCallingUidAndPackage(packageName);
|
verifyCallingUidAndPackage(packageName);
|
||||||
enforceNotRestrictedUser();
|
enforceNotRestrictedUser();
|
||||||
@@ -3167,12 +3173,12 @@ public class Vpn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Permissions checked during startVpnProfile()
|
// Permissions checked during startVpnProfile()
|
||||||
Binder.withCleanCallingIdentity(
|
final long token = Binder.clearCallingIdentity();
|
||||||
() -> {
|
try {
|
||||||
getVpnProfileStore().put(
|
getVpnProfileStore().put(getProfileNameForPackage(packageName), encodedProfile);
|
||||||
getProfileNameForPackage(packageName),
|
} finally {
|
||||||
encodedProfile);
|
Binder.restoreCallingIdentity(token);
|
||||||
});
|
}
|
||||||
|
|
||||||
// TODO: if package has CONTROL_VPN, grant the ACTIVATE_PLATFORM_VPN appop.
|
// TODO: if package has CONTROL_VPN, grant the ACTIVATE_PLATFORM_VPN appop.
|
||||||
// This mirrors the prepareAndAuthorize that is used by VpnService.
|
// This mirrors the prepareAndAuthorize that is used by VpnService.
|
||||||
@@ -3192,26 +3198,28 @@ public class Vpn {
|
|||||||
*/
|
*/
|
||||||
public synchronized void deleteVpnProfile(
|
public synchronized void deleteVpnProfile(
|
||||||
@NonNull String packageName) {
|
@NonNull String packageName) {
|
||||||
checkNotNull(packageName, "No package name provided");
|
requireNonNull(packageName, "No package name provided");
|
||||||
|
|
||||||
verifyCallingUidAndPackage(packageName);
|
verifyCallingUidAndPackage(packageName);
|
||||||
enforceNotRestrictedUser();
|
enforceNotRestrictedUser();
|
||||||
|
|
||||||
Binder.withCleanCallingIdentity(
|
final long token = Binder.clearCallingIdentity();
|
||||||
() -> {
|
try {
|
||||||
// If this profile is providing the current VPN, turn it off, disabling
|
// If this profile is providing the current VPN, turn it off, disabling
|
||||||
// always-on as well if enabled.
|
// always-on as well if enabled.
|
||||||
if (isCurrentIkev2VpnLocked(packageName)) {
|
if (isCurrentIkev2VpnLocked(packageName)) {
|
||||||
if (mAlwaysOn) {
|
if (mAlwaysOn) {
|
||||||
// Will transitively call prepareInternal(VpnConfig.LEGACY_VPN).
|
// Will transitively call prepareInternal(VpnConfig.LEGACY_VPN).
|
||||||
setAlwaysOnPackage(null, false, null);
|
setAlwaysOnPackage(null, false, null);
|
||||||
} else {
|
} else {
|
||||||
prepareInternal(VpnConfig.LEGACY_VPN);
|
prepareInternal(VpnConfig.LEGACY_VPN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getVpnProfileStore().remove(getProfileNameForPackage(packageName));
|
getVpnProfileStore().remove(getProfileNameForPackage(packageName));
|
||||||
});
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3245,7 +3253,7 @@ public class Vpn {
|
|||||||
*/
|
*/
|
||||||
public synchronized void startVpnProfile(
|
public synchronized void startVpnProfile(
|
||||||
@NonNull String packageName) {
|
@NonNull String packageName) {
|
||||||
checkNotNull(packageName, "No package name provided");
|
requireNonNull(packageName, "No package name provided");
|
||||||
|
|
||||||
enforceNotRestrictedUser();
|
enforceNotRestrictedUser();
|
||||||
|
|
||||||
@@ -3254,15 +3262,17 @@ public class Vpn {
|
|||||||
throw new SecurityException("User consent not granted for package " + packageName);
|
throw new SecurityException("User consent not granted for package " + packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Binder.withCleanCallingIdentity(
|
final long token = Binder.clearCallingIdentity();
|
||||||
() -> {
|
try {
|
||||||
final VpnProfile profile = getVpnProfilePrivileged(packageName);
|
final VpnProfile profile = getVpnProfilePrivileged(packageName);
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
throw new IllegalArgumentException("No profile found for " + packageName);
|
throw new IllegalArgumentException("No profile found for " + packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
startVpnProfilePrivileged(profile, packageName);
|
startVpnProfilePrivileged(profile, packageName);
|
||||||
});
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startVpnProfilePrivileged(
|
private synchronized void startVpnProfilePrivileged(
|
||||||
@@ -3323,7 +3333,7 @@ public class Vpn {
|
|||||||
* @param packageName the package name of the app provisioning this profile
|
* @param packageName the package name of the app provisioning this profile
|
||||||
*/
|
*/
|
||||||
public synchronized void stopVpnProfile(@NonNull String packageName) {
|
public synchronized void stopVpnProfile(@NonNull String packageName) {
|
||||||
checkNotNull(packageName, "No package name provided");
|
requireNonNull(packageName, "No package name provided");
|
||||||
|
|
||||||
enforceNotRestrictedUser();
|
enforceNotRestrictedUser();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user