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

Commit 9f139b57 authored by Andrey Yepin's avatar Andrey Yepin
Browse files

Verify that the caller has permissions for the icons it provided.

Bug: 277207798
Test: manual testing: first reroduce the issue as described in the
 ticket then check that it is not reproduceable after the fix.
Merged-In: Ic8cb75ed586e94c5895065f772bfb21013396dd0
Change-Id: I6a9ced763e76e05d24ac177bf51508e7b732437a
parent 1e973616
Loading
Loading
Loading
Loading
+60 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.app;

import static android.content.ContentProvider.getUriWithoutUserId;
import static android.content.ContentProvider.getUserIdFromUri;

import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -30,7 +31,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.IUriGrantsManager;
import android.app.SharedElementCallback;
import android.app.UriGrantsManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
@@ -67,6 +70,7 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
@@ -747,7 +751,11 @@ public class ChooserActivity extends ResolverActivity implements
                    targets = null;
                    break;
                }
                targets[i] = (ChooserTarget) pa[i];
                ChooserTarget chooserTarget = (ChooserTarget) pa[i];
                if (!hasValidIcon(chooserTarget)) {
                    chooserTarget = removeIcon(chooserTarget);
                }
                targets[i] = chooserTarget;
            }
            mCallerChooserTargets = targets;
        }
@@ -4013,6 +4021,7 @@ public class ChooserActivity extends ResolverActivity implements
                            mChooserActivity.createContextAsUser(mUserHandle, 0 /* flags */);
                    mChooserActivity.filterServiceTargets(contextAsUser,
                            mOriginalTarget.getResolveInfo().activityInfo.packageName, targets);
                    targets = mChooserActivity.removeUnaccessibleIcons(targets);
                    final Message msg = Message.obtain();
                    msg.what = ChooserHandler.CHOOSER_TARGET_SERVICE_RESULT;
                    msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
@@ -4275,4 +4284,54 @@ public class ChooserActivity extends ResolverActivity implements
    protected void maybeLogProfileChange() {
        getChooserActivityLogger().logShareheetProfileChanged();
    }

    private List<ChooserTarget> removeUnaccessibleIcons(@Nullable List<ChooserTarget> targets) {
        if (targets == null) {
            return null;
        }
        ArrayList<ChooserTarget> checkedTargets = new ArrayList<>(targets.size());
        for (ChooserTarget target: targets) {
            checkedTargets.add(hasValidIcon(target) ? target : removeIcon(target));
        }
        return checkedTargets;
    }

    private boolean hasValidIcon(ChooserTarget target) {
        Icon icon = target.getIcon();
        if (icon == null) {
            return true;
        }
        if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {
            Uri uri = icon.getUri();
            try {
                getUriGrantsManager().checkGrantUriPermission_ignoreNonSystem(
                        getLaunchedFromUid(),
                        getPackageName(),
                        getUriWithoutUserId(uri),
                        Intent.FLAG_GRANT_READ_URI_PERMISSION,
                        getUserIdFromUri(uri)
                );
            } catch (SecurityException | RemoteException e) {
                Log.e(TAG, "Failed to get URI permission for: " + uri, e);
                return false;
            }
        }
        return true;
    }

    private IUriGrantsManager getUriGrantsManager() {
        return UriGrantsManager.getService();
    }

    private static ChooserTarget removeIcon(ChooserTarget target) {
        if (target == null) {
            return null;
        }
        return new ChooserTarget(
                target.getTitle(),
                null,
                target.getScore(),
                target.getComponentName(),
                target.getIntentExtras());
    }
}