Fix exploit where can hide the fact that a location was mocked am: a206a0f17e am: d417e54872
am: 3380a77516

Change-Id: Ice61f337e1fcfd0569431538e475d94f9d205423
(cherry picked from commit 0a8978f04b4cc2e273545568b424756ee5a40a3d)
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 468ead0..66d40de 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -87,6 +87,8 @@
 import android.os.UserManager;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
 
@@ -2505,9 +2507,22 @@
             if (mockProvider == null) {
                 throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
             }
+
+            // Ensure that the location is marked as being mock. There's some logic to do this in
+            // handleLocationChanged(), but it fails if loc has the wrong provider (bug 33091107).
+            Location mock = new Location(loc);
+            mock.setIsFromMockProvider(true);
+
+            if (!TextUtils.isEmpty(loc.getProvider()) && !provider.equals(loc.getProvider())) {
+                // The location has an explicit provider that is different from the mock provider
+                // name. The caller may be trying to fool us via bug 33091107.
+                EventLog.writeEvent(0x534e4554, "33091107", Binder.getCallingUid(),
+                        provider + "!=" + loc.getProvider());
+            }
+
             // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required
             long identity = Binder.clearCallingIdentity();
-            mockProvider.setLocation(loc);
+            mockProvider.setLocation(mock);
             Binder.restoreCallingIdentity(identity);
         }
     }