Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a4f32f9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Remove hidden preconditions, binder usage in Vpn" am: 9ffdbe8b am: 156b5e7c

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

Change-Id: I7f2854a11806066a4caf540380990546cd05bbe7
parents f5aa7cbc 156b5e7c
Loading
Loading
Loading
Loading
+65 −55
Original line number Diff line number Diff line
@@ -24,8 +24,7 @@ import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
import static android.os.PowerWhitelistManager.REASON_VPN;
import static android.os.UserHandle.PER_USER_RANGE;

import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;

import android.Manifest;
import android.annotation.NonNull;
@@ -1098,13 +1097,14 @@ public class Vpn {
            return Process.myUid();
        }
        PackageManager pm = mContext.getPackageManager();
        return Binder.withCleanCallingIdentity(() -> {
        final long token = Binder.clearCallingIdentity();
        try {
            return pm.getPackageUidAsUser(app, userId);
        } catch (NameNotFoundException e) {
            return -1;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        });
    }

    private boolean doesPackageTargetAtLeastQ(String packageName) {
@@ -1280,15 +1280,16 @@ public class Vpn {
                // We are user controlled, not driven by NetworkRequest.
            }
        };
        Binder.withCleanCallingIdentity(() -> {
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkAgent.register();
        } catch (final Exception e) {
            // If register() throws, don't keep an unregistered agent.
            mNetworkAgent = null;
            throw e;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        });
        mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
                ? Arrays.asList(mConfig.underlyingNetworks) : null);
        updateState(DetailedState.CONNECTED, "agentConnect");
@@ -2026,13 +2027,16 @@ public class Vpn {
    }

    private void enforceNotRestrictedUser() {
        Binder.withCleanCallingIdentity(() -> {
        final long token = Binder.clearCallingIdentity();
        try {
            final UserInfo user = mUserManager.getUserInfo(mUserId);

            if (user.isRestricted()) {
                throw new SecurityException("Restricted users cannot configure VPNs");
            }
        });
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /**
@@ -2825,8 +2829,10 @@ public class Vpn {

        LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) {
            super(TAG);
            checkArgument(racoon != null || mtpd != null, "Arguments to racoon and mtpd "
                    + "must not both be null");
            if (racoon == null && mtpd == null) {
                throw new IllegalArgumentException(
                        "Arguments to racoon and mtpd must not both be null");
            }
            mConfig = config;
            mDaemons = new String[] {"racoon", "mtpd"};
            // TODO: clear arguments from memory once launched
@@ -3151,8 +3157,8 @@ public class Vpn {
     */
    public synchronized boolean provisionVpnProfile(
            @NonNull String packageName, @NonNull VpnProfile profile) {
        checkNotNull(packageName, "No package name provided");
        checkNotNull(profile, "No profile provided");
        requireNonNull(packageName, "No package name provided");
        requireNonNull(profile, "No profile provided");

        verifyCallingUidAndPackage(packageName);
        enforceNotRestrictedUser();
@@ -3169,12 +3175,12 @@ public class Vpn {
        }

        // Permissions checked during startVpnProfile()
        Binder.withCleanCallingIdentity(
                () -> {
                    getVpnProfileStore().put(
                            getProfileNameForPackage(packageName),
                            encodedProfile);
                });
        final long token = Binder.clearCallingIdentity();
        try {
            getVpnProfileStore().put(getProfileNameForPackage(packageName), encodedProfile);
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        // TODO: if package has CONTROL_VPN, grant the ACTIVATE_PLATFORM_VPN appop.
        // This mirrors the prepareAndAuthorize that is used by VpnService.
@@ -3194,13 +3200,13 @@ public class Vpn {
     */
    public synchronized void deleteVpnProfile(
            @NonNull String packageName) {
        checkNotNull(packageName, "No package name provided");
        requireNonNull(packageName, "No package name provided");

        verifyCallingUidAndPackage(packageName);
        enforceNotRestrictedUser();

        Binder.withCleanCallingIdentity(
                () -> {
        final long token = Binder.clearCallingIdentity();
        try {
            // If this profile is providing the current VPN, turn it off, disabling
            // always-on as well if enabled.
            if (isCurrentIkev2VpnLocked(packageName)) {
@@ -3213,7 +3219,9 @@ public class Vpn {
            }

            getVpnProfileStore().remove(getProfileNameForPackage(packageName));
                });
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /**
@@ -3247,7 +3255,7 @@ public class Vpn {
     */
    public synchronized void startVpnProfile(
            @NonNull String packageName) {
        checkNotNull(packageName, "No package name provided");
        requireNonNull(packageName, "No package name provided");

        enforceNotRestrictedUser();

@@ -3256,15 +3264,17 @@ public class Vpn {
            throw new SecurityException("User consent not granted for package " + packageName);
        }

        Binder.withCleanCallingIdentity(
                () -> {
        final long token = Binder.clearCallingIdentity();
        try {
            final VpnProfile profile = getVpnProfilePrivileged(packageName);
            if (profile == null) {
                throw new IllegalArgumentException("No profile found for " + packageName);
            }

            startVpnProfilePrivileged(profile, packageName);
                });
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    private synchronized void startVpnProfilePrivileged(
@@ -3325,7 +3335,7 @@ public class Vpn {
     * @param packageName the package name of the app provisioning this profile
     */
    public synchronized void stopVpnProfile(@NonNull String packageName) {
        checkNotNull(packageName, "No package name provided");
        requireNonNull(packageName, "No package name provided");

        enforceNotRestrictedUser();