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

Commit 397ad580 authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

Add whitelist for location settings piercing

Use a whitelist to control which packages may use location piercing
settings on LocationRequest.

Test: Manually
Bug: 118883513
Change-Id: I16e8496c49b6bef016cb7f090969ed97a39e38c2
parent 0affe5da
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -9492,6 +9492,14 @@ public final class Settings {
        public static final String LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST =
            "location_background_throttle_package_whitelist";
        /**
         * Packages that are whitelisted for ignoring location settings (may retrieve location even
         * when user location settings are off), for emergency purposes.
         * @hide
         */
        public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST =
                "location_ignore_settings_package_whitelist";
        /**
         * Whether to disable location status callbacks in preparation for deprecation.
         * @hide
+22 −0
Original line number Diff line number Diff line
@@ -140,6 +140,10 @@ public class SystemConfig {
    // without throttling, as read from the configuration files.
    final ArraySet<String> mAllowUnthrottledLocation = new ArraySet<>();

    // These are the packages that are white-listed to be able to retrieve location even when user
    // location settings are off, for emergency purposes, as read from the configuration files.
    final ArraySet<String> mAllowIgnoreLocationSettings = new ArraySet<>();

    // These are the action strings of broadcasts which are whitelisted to
    // be delivered anonymously even to apps which target O+.
    final ArraySet<String> mAllowImplicitBroadcasts = new ArraySet<>();
@@ -255,6 +259,10 @@ public class SystemConfig {
        return mAllowUnthrottledLocation;
    }

    public ArraySet<String> getAllowIgnoreLocationSettings() {
        return mAllowIgnoreLocationSettings;
    }

    public ArraySet<String> getLinkedApps() {
        return mLinkedApps;
    }
@@ -682,6 +690,20 @@ public class SystemConfig {
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                    case "allow-ignore-location-settings": {
                        if (allowAll) {
                            String pkgname = parser.getAttributeValue(null, "package");
                            if (pkgname == null) {
                                Slog.w(TAG, "<" + name + "> without package in "
                                        + permFile + " at " + parser.getPositionDescription());
                            } else {
                                mAllowIgnoreLocationSettings.add(pkgname);
                            }
                        } else {
                            logNotAllowedInPartition(name, permFile, parser);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                    case "allow-implicit-broadcast": {
                        if (allowAll) {
                            String action = parser.getAttributeValue(null, "action");
+1 −0
Original line number Diff line number Diff line
@@ -298,6 +298,7 @@ public class SettingsBackupTest {
                    Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
                    Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS,
                    Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
                    Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST,
                    Settings.Global.LOCATION_DISABLE_STATUS_CALLBACKS,
                    Settings.Global.LOCATION_LAST_LOCATION_MAX_AGE_MILLIS,
                    Settings.Global.LOCATION_GLOBAL_KILL_SWITCH,
+58 −8
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ public class LocationManagerService extends ILocationManager.Stub {

    private final ArraySet<String> mBackgroundThrottlePackageWhitelist = new ArraySet<>();

    private final ArraySet<String> mIgnoreSettingsPackageWhitelist = new ArraySet<>();

    @GuardedBy("mLock")
    private final ArrayMap<IBinder, Identity> mGnssMeasurementsListeners = new ArrayMap<>();

@@ -353,6 +355,18 @@ public class LocationManagerService extends ILocationManager.Stub {
                        }
                    }
                }, UserHandle.USER_ALL);
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(
                        Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST),
                true,
                new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
                        synchronized (mLock) {
                            onIgnoreSettingsWhitelistChangedLocked();
                        }
                    }
                }, UserHandle.USER_ALL);

        new PackageMonitor() {
            @Override
@@ -550,6 +564,25 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
    }

    @GuardedBy("lock")
    private void onIgnoreSettingsWhitelistChangedLocked() {
        String setting = Settings.Global.getString(
                mContext.getContentResolver(),
                Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST);
        if (setting == null) {
            setting = "";
        }

        mIgnoreSettingsPackageWhitelist.clear();
        mIgnoreSettingsPackageWhitelist.addAll(
                SystemConfig.getInstance().getAllowIgnoreLocationSettings());
        mIgnoreSettingsPackageWhitelist.addAll(Arrays.asList(setting.split(",")));

        for (LocationProvider p : mProviders) {
            applyRequirementsLocked(p);
        }
    }

    @GuardedBy("mLock")
    private void onUserProfilesChangedLocked() {
        mCurrentUserProfiles = mUserManager.getProfileIdsWithDisabled(mCurrentUserId);
@@ -1299,8 +1332,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                    if (provider == null) {
                        continue;
                    }
                    if (!provider.isUseableLocked()
                            && !updateRecord.mRealRequest.isLocationSettingsIgnored()) {
                    if (!provider.isUseableLocked() && !isSettingsExemptLocked(updateRecord)) {
                        continue;
                    }

@@ -1988,7 +2020,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                }

                // requests that ignore location settings will never provider notifications
                if (record.mRealRequest.isLocationSettingsIgnored()) {
                if (isSettingsExemptLocked(record)) {
                    continue;
                }

@@ -2052,8 +2084,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                        record.mReceiver.mAllowedResolutionLevel)) {
                    continue;
                }
                if (!provider.isUseableLocked()
                        && !record.mRealRequest.isLocationSettingsIgnored()) {
                if (!provider.isUseableLocked() && !isSettingsExemptLocked(record)) {
                    continue;
                }

@@ -2163,6 +2194,25 @@ public class LocationManagerService extends ILocationManager.Stub {
        return false;
    }

    @GuardedBy("mLock")
    private boolean isSettingsExemptLocked(UpdateRecord record) {
        if (!record.mRealRequest.isLocationSettingsIgnored()) {
            return false;
        }

        if (mBackgroundThrottlePackageWhitelist.contains(record.mReceiver.mIdentity.mPackageName)) {
            return true;
        }

        for (LocationProvider provider : mProviders) {
            if (record.mReceiver.mIdentity.mPackageName.equals(provider.getPackageLocked())) {
                return true;
            }
        }

        return false;
    }

    private class UpdateRecord {
        final String mProvider;
        private final LocationRequest mRealRequest;  // original request from client
@@ -2306,7 +2356,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
        // make getFastestInterval() the minimum of interval and fastest interval
        if (sanitizedRequest.getFastestInterval() > sanitizedRequest.getInterval()) {
            request.setFastestInterval(request.getInterval());
            sanitizedRequest.setFastestInterval(request.getInterval());
        }
        return sanitizedRequest;
    }
@@ -2418,7 +2468,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            oldRecord.disposeLocked(false);
        }

        if (!provider.isUseableLocked() && !request.isLocationSettingsIgnored()) {
        if (!provider.isUseableLocked() && !isSettingsExemptLocked(record)) {
            // Notify the listener that updates are currently disabled - but only if the request
            // does not ignore location settings
            receiver.callProviderEnabledLocked(name, false);
@@ -3056,7 +3106,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            Receiver receiver = r.mReceiver;
            boolean receiverDead = false;

            if (!provider.isUseableLocked() && !r.mRealRequest.isLocationSettingsIgnored()) {
            if (!provider.isUseableLocked() && !isSettingsExemptLocked(r)) {
                continue;
            }