diff options
author | David Christie <dnchrist@google.com> | 2013-04-15 16:39:08 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-04-15 16:39:08 -0700 |
commit | e8ae4eafea69ccdffd91865f46ee2d569cdc1203 (patch) | |
tree | 5011287105fafab93dd1c1ec0affcaa8cf3d66cc /services/java | |
parent | 15717a32c497895b294396c0000bc571790d3691 (diff) | |
parent | feedb1b095f94e4bd153aeee78da07d963892071 (diff) | |
download | frameworks_base-e8ae4eafea69ccdffd91865f46ee2d569cdc1203.zip frameworks_base-e8ae4eafea69ccdffd91865f46ee2d569cdc1203.tar.gz frameworks_base-e8ae4eafea69ccdffd91865f46ee2d569cdc1203.tar.bz2 |
am feedb1b0: Merge "Fix security issues with LocationManager where apps with coarse permissions can get location updates too frequently by repeatedly calling getLastKnownLocation or by registering/unregistering location updates frequently." into jb-mr2-dev
* commit 'feedb1b095f94e4bd153aeee78da07d963892071':
Fix security issues with LocationManager where apps with coarse permissions can get location updates too frequently by repeatedly calling getLastKnownLocation or by registering/unregistering location updates frequently.
Diffstat (limited to 'services/java')
-rw-r--r-- | services/java/com/android/server/LocationManagerService.java | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 1e1cf5a..b47e8a0 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -116,6 +116,8 @@ public class LocationManagerService extends ILocationManager.Stub { private static final int MSG_LOCATION_CHANGED = 1; + private static final long NANOS_PER_MILLI = 1000000L; + // Location Providers may sometimes deliver location updates // slightly faster that requested - provide grace period so // we don't unnecessarily filter events that are otherwise on @@ -179,6 +181,11 @@ public class LocationManagerService extends ILocationManager.Stub { // mapping from provider name to last known location private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); + // same as mLastLocation, but is not updated faster than LocationFudger.FASTEST_INTERVAL_MS. + // locations stored here are not fudged for coarse permissions. + private final HashMap<String, Location> mLastLocationCoarseInterval = + new HashMap<String, Location>(); + // all providers that operate over proxy, for authorizing incoming location private final ArrayList<LocationProviderProxy> mProxyProviders = new ArrayList<LocationProviderProxy>(); @@ -423,6 +430,7 @@ public class LocationManagerService extends ILocationManager.Stub { mLocationHandler.removeMessages(MSG_LOCATION_CHANGED); synchronized (mLock) { mLastLocation.clear(); + mLastLocationCoarseInterval.clear(); for (LocationProviderInterface p : mProviders) { updateProviderListenersLocked(p.getName(), false, mCurrentUserId); } @@ -1407,7 +1415,14 @@ public class LocationManagerService extends ILocationManager.Stub { if (!isAllowedByUserSettingsLocked(name, uid)) return null; - Location location = mLastLocation.get(name); + Location location; + if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { + // Make sure that an app with coarse permissions can't get frequent location + // updates by calling LocationManager.getLastKnownLocation repeatedly. + location = mLastLocationCoarseInterval.get(name); + } else { + location = mLastLocation.get(name); + } if (location == null) { return null; } @@ -1673,7 +1688,8 @@ public class LocationManagerService extends ILocationManager.Stub { // Check whether sufficient time has passed long minTime = record.mRequest.getFastestInterval(); - long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) / 1000000L; + long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) + / NANOS_PER_MILLI; if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) { return false; } @@ -1726,13 +1742,30 @@ public class LocationManagerService extends ILocationManager.Stub { } lastLocation.set(location); + // Update last known coarse interval location if enough time has passed. + Location lastLocationCoarseInterval = mLastLocationCoarseInterval.get(provider); + if (lastLocationCoarseInterval == null) { + lastLocationCoarseInterval = new Location(location); + mLastLocationCoarseInterval.put(provider, lastLocationCoarseInterval); + } + long timeDiffNanos = location.getElapsedRealtimeNanos() + - lastLocationCoarseInterval.getElapsedRealtimeNanos(); + if (timeDiffNanos > LocationFudger.FASTEST_INTERVAL_MS * NANOS_PER_MILLI) { + lastLocationCoarseInterval.set(location); + } + // Don't ever return a coarse location that is more recent than the allowed update + // interval (i.e. don't allow an app to keep registering and unregistering for + // location updates to overcome the minimum interval). + noGPSLocation = + lastLocationCoarseInterval.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); + // Skip if there are no UpdateRecords for this provider. ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); if (records == null || records.size() == 0) return; // Fetch coarse location Location coarseLocation = null; - if (noGPSLocation != null && !noGPSLocation.equals(lastNoGPSLocation)) { + if (noGPSLocation != null) { coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); } @@ -2021,6 +2054,7 @@ public class LocationManagerService extends ILocationManager.Stub { addProviderLocked(provider); mMockProviders.put(name, provider); mLastLocation.put(name, null); + mLastLocationCoarseInterval.put(name, null); updateProvidersLocked(); } Binder.restoreCallingIdentity(identity); @@ -2043,6 +2077,7 @@ public class LocationManagerService extends ILocationManager.Stub { addProviderLocked(realProvider); } mLastLocation.put(provider, null); + mLastLocationCoarseInterval.put(provider, null); updateProvidersLocked(); Binder.restoreCallingIdentity(identity); } @@ -2174,6 +2209,13 @@ public class LocationManagerService extends ILocationManager.Stub { pw.println(" " + provider + ": " + location); } + pw.println(" Last Known Locations Coarse Intervals:"); + for (Map.Entry<String, Location> entry : mLastLocationCoarseInterval.entrySet()) { + String provider = entry.getKey(); + Location location = entry.getValue(); + pw.println(" " + provider + ": " + location); + } + mGeofenceManager.dump(pw); if (mEnabledProviders.size() > 0) { |