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

Commit 0d05e483 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Check same uid for permission and app-op

In permission checker we used to check the permission for the passed in
uid but the opp-op for the Binder.getCallingUid. In the case the calling
identity was cleared, PermissionChecker ended up checking the app-op of the
current process (often the system server).

Now we check the uid for both the permission and the app-op.

Test: Called PermissionChecker.checkPermission with the calling indentity
cleared.
Fixes: 124116218
Change-Id: Ic0b766f6c75bba1b9dae3e91c6adce85a76ae68f
parent 3661808c
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -309,6 +309,7 @@ package android.app {
    method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]);
    method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
    method public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
    method public static int opToDefaultMode(@NonNull String);
    method public static int opToDefaultMode(@NonNull String);
    method @Nullable public static String opToPermission(@NonNull String);
    method @Nullable public static String opToPermission(@NonNull String);
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
+38 −2
Original line number Original line Diff line number Diff line
@@ -4291,11 +4291,34 @@ public class AppOpsManager {
    /**
    /**
     * Like {@link #noteProxyOp(String, String)} but instead
     * Like {@link #noteProxyOp(String, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
     * {@link Binder#getCallingUid()}.
     */
     */
    public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
    public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
    }
    }


    /**
     * Like {@link #noteProxyOp(String, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires package with the {@code proxiedPackageName} to belong to
     * {@code proxiedUid}.
     *
     * @param op The op to note
     * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
     *                           noted for the "android" package
     * @param proxiedUid The uid the package belongs to
     *
     * @hide
     */
    @SystemApi
    public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
            int proxiedUid) {
        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
    }

    /**
    /**
     * Report that an application has started executing a long-running operation.  Note that you
     * Report that an application has started executing a long-running operation.  Note that you
     * must pass in both the uid and name of the application to be checked; this function will
     * must pass in both the uid and name of the application to be checked; this function will
@@ -4495,16 +4518,29 @@ public class AppOpsManager {
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     * @hide
     * @hide
     */
     */
    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
    public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
        logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
        logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
        try {
        try {
            return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
            return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
                    Binder.getCallingUid(), proxiedPackageName);
                    proxiedUid, proxiedPackageName);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
    }
    }


    /**
     * Like {@link #noteProxyOp(int, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires the package with {@code proxiedPackageName} to belongs to
     * {@link Binder#getCallingUid()}.
     *
     * @hide
     */
    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
        return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
    }

    /**
    /**
     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
     * returns {@link #MODE_ERRORED}.
     * returns {@link #MODE_ERRORED}.
+4 −2
Original line number Original line Diff line number Diff line
@@ -108,8 +108,7 @@ public final class PermissionChecker {
            packageName = packageNames[0];
            packageName = packageNames[0];
        }
        }


        if (appOpsManager.noteProxyOpNoThrow(op, packageName)
        if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid) != AppOpsManager.MODE_ALLOWED) {
                != AppOpsManager.MODE_ALLOWED) {
            return PERMISSION_DENIED_APP_OP;
            return PERMISSION_DENIED_APP_OP;
        }
        }


@@ -120,6 +119,9 @@ public final class PermissionChecker {
     * Checks whether your app has a given permission and whether the app op
     * Checks whether your app has a given permission and whether the app op
     * that corresponds to this permission is allowed.
     * that corresponds to this permission is allowed.
     *
     *
     * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
     * {@link Process#myUid()}.
     *
     * @param context Context for accessing resources.
     * @param context Context for accessing resources.
     * @param permission The permission to check.
     * @param permission The permission to check.
     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
     * @return The permission check result which is either {@link #PERMISSION_GRANTED}