From 61ecb02f544d9abd098506afb50cb514818f4eb4 Mon Sep 17 00:00:00 2001 From: Victoria Lease Date: Tue, 13 Nov 2012 15:12:51 -0800 Subject: [PATCH] Resolve LocationManager + ActivityManager conflict LocationManagerService was serially stuffing the same Location into multiple Intents, which it would immediately hand off to ActivityManagerService, running as a different thread in the same process. LocationManager would continue to work with that Location while ActivityManagerService worked with a Parceled version of it. However, Location.mExtras is also a Bundle, and both ActivityManagerService and LocationManagerService ended up working with references to the same Bundle. ActivityManagerService needs it in Parceled form (ie mParceledData != null), but LocationManagerService was triggering Bundle.unparcel() when referencing the data contained within. As a result, LocationManagerService was able to trigger NPE (or worse) in ActivityManagerService by manipulating the mExtras member of a Location that was in the process of being reported to listeners. To resolve this issue, I copy-construct a new Location to report to each listener. This should prevent ActivityManagerService and LocationManagerService from referencing the same Bundle data, as Location's copy constructor also copyconstructs the mExtras member, rather than simply share references. Bug: 7518371 Change-Id: I1a92615cba361831494447d5de085a8d910b6b2c --- services/java/com/android/server/LocationManagerService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 89fa6d0580fbe..7a55497c7f24e 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -506,7 +506,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } } else { Intent statusChanged = new Intent(); - statusChanged.putExtras(extras); + statusChanged.putExtras(new Bundle(extras)); statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); try { synchronized (this) { @@ -541,7 +541,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } } else { Intent locationChanged = new Intent(); - locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); + locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location)); try { synchronized (this) { // synchronize to ensure incrementPendingBroadcastsLocked()