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

Commit b1648e6c authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Fix bug3 13933442 Search - for security reasons only index data...

...from wellknown SearchIndexablesProvider

Check if the SearchIndexablesProvider is:

- having the correct android.permission.READ_SEARCH_INDEXABLES
read/write permissions
- a privileged one (like Settings App, Phone App)

Change-Id: I5fd1fef46716cca0e439196e24b607ff5506495c
parent f79af8b2
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
@@ -221,6 +223,9 @@ public class Index {
        final int size = list.size();
        for (int n = 0; n < size; n++) {
            final ResolveInfo info = list.get(n);
            if (!isWellKnownProvider(info)) {
                continue;
            }
            final String authority = info.providerInfo.authority;
            final String packageName = info.providerInfo.packageName;
            addIndexablesFromRemoteProvider(packageName, authority);
@@ -229,6 +234,45 @@ public class Index {
        return updateInternal();
    }

    /**
     * Only allow a "well known" SearchIndexablesProvider. The provider should:
     *
     * - have read/write {@link android.Manifest.permission#READ_SEARCH_INDEXABLES}
     * - be from a privileged package
     */
    private boolean isWellKnownProvider(ResolveInfo info) {
        final String authority = info.providerInfo.authority;
        final String packageName = info.providerInfo.applicationInfo.packageName;

        if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) {
            return false;
        }

        final String readPermission = info.providerInfo.readPermission;
        final String writePermission = info.providerInfo.writePermission;

        if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) {
            return false;
        }

        if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) ||
            !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) {
            return false;
        }

        return isPrivilegedPackage(packageName);
    }

    private boolean isPrivilegedPackage(String packageName) {
        final PackageManager pm = mContext.getPackageManager();
        try {
            PackageInfo packInfo = pm.getPackageInfo(packageName, 0);
            return ((packInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0);
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    public boolean updateFromRemoteProvider(String packageName, String authority) {
        if (!addIndexablesFromRemoteProvider(packageName, authority)) {
            return false;