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

Commit de38982c authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

Fix security hole in Geocoder APIs

Geocoder APIs are a mess, but this will at least validate the caller
properly, and pass the relevant information along to clients.

Bug: 158318462
Test: presubmits
Change-Id: I47b09962598a2346bd79caa643ba1d83069c0c19
parent c335e905
Loading
Loading
Loading
Loading
+17 −44
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;

import com.android.internal.util.Preconditions;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -77,12 +79,9 @@ public final class Geocoder {
     * @throws NullPointerException if Locale is null
     */
    public Geocoder(Context context, Locale locale) {
        if (locale == null) {
            throw new NullPointerException("locale == null");
        }
        mParams = new GeocoderParams(context, locale);
        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
        mService = ILocationManager.Stub.asInterface(b);
        mService = ILocationManager.Stub.asInterface(
                ServiceManager.getService(Context.LOCATION_SERVICE));
    }

    /**
@@ -122,12 +121,9 @@ public final class Geocoder {
     */
    public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
            throws IOException {
        if (latitude < -90.0 || latitude > 90.0) {
            throw new IllegalArgumentException("latitude == " + latitude);
        }
        if (longitude < -180.0 || longitude > 180.0) {
            throw new IllegalArgumentException("longitude == " + longitude);
        }
        Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude");
        Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "longitude");

        try {
            GeocodeListener listener = new GeocodeListener();
            mService.getFromLocation(latitude, longitude, maxResults, mParams, listener);
@@ -161,17 +157,7 @@ public final class Geocoder {
     * I/O problem occurs
     */
    public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
        if (locationName == null) {
            throw new IllegalArgumentException("locationName == null");
        }

        try {
            GeocodeListener listener = new GeocodeListener();
            mService.getFromLocationName(locationName, 0, 0, 0, 0, maxResults, mParams, listener);
            return listener.getResults();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return getFromLocationName(locationName, maxResults, 0, 0, 0, 0);
    }

    /**
@@ -210,27 +196,14 @@ public final class Geocoder {
     * I/O problem occurs
     */
    public List<Address> getFromLocationName(String locationName, int maxResults,
        double lowerLeftLatitude, double lowerLeftLongitude,
        double upperRightLatitude, double upperRightLongitude) throws IOException {
        if (locationName == null) {
            throw new IllegalArgumentException("locationName == null");
        }
        if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
            throw new IllegalArgumentException("lowerLeftLatitude == "
                + lowerLeftLatitude);
        }
        if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
            throw new IllegalArgumentException("lowerLeftLongitude == "
                + lowerLeftLongitude);
        }
        if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
            throw new IllegalArgumentException("upperRightLatitude == "
                + upperRightLatitude);
        }
        if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
            throw new IllegalArgumentException("upperRightLongitude == "
                + upperRightLongitude);
        }
            double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude,
            double upperRightLongitude) throws IOException {
        Preconditions.checkArgument(locationName != null);
        Preconditions.checkArgumentInRange(lowerLeftLatitude, -90.0, 90.0, "lowerLeftLatitude");
        Preconditions.checkArgumentInRange(lowerLeftLongitude, -180.0, 180.0, "lowerLeftLongitude");
        Preconditions.checkArgumentInRange(upperRightLatitude, -90.0, 90.0, "upperRightLatitude");
        Preconditions.checkArgumentInRange(upperRightLongitude, -180.0, 180.0,
                "upperRightLongitude");

        try {
            GeocodeListener listener = new GeocodeListener();
+60 −32
Original line number Diff line number Diff line
@@ -16,12 +16,16 @@

package android.location;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;

import java.util.Locale;
import java.util.Objects;

/**
 * This class contains extra parameters to pass to an IGeocodeProvider
@@ -34,49 +38,71 @@ import java.util.Locale;
 * @hide
 */
public class GeocoderParams implements Parcelable {
    private Locale mLocale;
    private String mPackageName;

    // used only for parcelling
    private GeocoderParams() {
    private final int mUid;
    private final String mPackageName;
    private final @Nullable String mAttributionTag;
    private final Locale mLocale;

    public GeocoderParams(Context context) {
        this(context, Locale.getDefault());
    }

    /**
     * This object is only constructed by the Geocoder class
     *
     * @hide
     */
    public GeocoderParams(Context context, Locale locale) {
        mLocale = locale;
        mPackageName = context.getPackageName();
        this(Process.myUid(), context.getPackageName(), context.getAttributionTag(), locale);
    }

    private GeocoderParams(int uid, String packageName, String attributionTag, Locale locale) {
        mUid = uid;
        mPackageName = Objects.requireNonNull(packageName);
        mAttributionTag = attributionTag;
        mLocale = Objects.requireNonNull(locale);
    }

    /**
     * returns the Geocoder's locale
     * Returns the client UID.
     */
    @UnsupportedAppUsage
    public Locale getLocale() {
        return mLocale;
    public int getClientUid() {
        return mUid;
    }

    /**
     * returns the package name of the Geocoder's client
     * Returns the client package name.
     */
    @UnsupportedAppUsage
    public String getClientPackage() {
    public @NonNull String getClientPackage() {
        return mPackageName;
    }

    public static final @android.annotation.NonNull Parcelable.Creator<GeocoderParams> CREATOR =
    /**
     * Returns the client attribution tag.
     */
    @UnsupportedAppUsage
    public @Nullable String getClientAttributionTag() {
        return mAttributionTag;
    }

    /**
     * Returns the locale.
     */
    @UnsupportedAppUsage
    public @NonNull Locale getLocale() {
        return mLocale;
    }

    public static final @NonNull Parcelable.Creator<GeocoderParams> CREATOR =
        new Parcelable.Creator<GeocoderParams>() {
            public GeocoderParams createFromParcel(Parcel in) {
            GeocoderParams gp = new GeocoderParams();
                int uid = in.readInt();
                String packageName = in.readString();
                String attributionTag = in.readString();
                String language = in.readString();
                String country = in.readString();
                String variant = in.readString();
            gp.mLocale = new Locale(language, country, variant);
            gp.mPackageName = in.readString();
            return gp;

                return new GeocoderParams(uid, packageName, attributionTag,
                        new Locale(language, country, variant));
            }

            public GeocoderParams[] newArray(int size) {
@@ -89,9 +115,11 @@ public class GeocoderParams implements Parcelable {
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mUid);
        parcel.writeString(mPackageName);
        parcel.writeString(mAttributionTag);
        parcel.writeString(mLocale.getLanguage());
        parcel.writeString(mLocale.getCountry());
        parcel.writeString(mLocale.getVariant());
        parcel.writeString(mPackageName);
    }
}
+11 −2
Original line number Diff line number Diff line
@@ -987,9 +987,13 @@ public class LocationManagerService extends ILocationManager.Stub {
    @Override
    public void getFromLocation(double latitude, double longitude, int maxResults,
            GeocoderParams params, IGeocodeListener listener) {
        // validate identity
        CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(),
                params.getClientAttributionTag());
        Preconditions.checkArgument(identity.getUid() == params.getClientUid());

        if (mGeocodeProvider != null) {
            mGeocodeProvider.getFromLocation(latitude, longitude, maxResults,
                    params, listener);
            mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, params, listener);
        } else {
            try {
                listener.onResults(null, Collections.emptyList());
@@ -1004,6 +1008,11 @@ public class LocationManagerService extends ILocationManager.Stub {
            double lowerLeftLatitude, double lowerLeftLongitude,
            double upperRightLatitude, double upperRightLongitude, int maxResults,
            GeocoderParams params, IGeocodeListener listener) {
        // validate identity
        CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(),
                params.getClientAttributionTag());
        Preconditions.checkArgument(identity.getUid() == params.getClientUid());

        if (mGeocodeProvider != null) {
            mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude,
                    lowerLeftLongitude, upperRightLatitude, upperRightLongitude,