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
This commit is contained in:
@@ -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 @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 public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
|
||||
method public static int opToDefaultMode(@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);
|
||||
|
||||
@@ -4291,11 +4291,34 @@ public class AppOpsManager {
|
||||
/**
|
||||
* Like {@link #noteProxyOp(String, String)} but instead
|
||||
* 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) {
|
||||
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
|
||||
* 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}.
|
||||
* @hide
|
||||
*/
|
||||
public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
|
||||
public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
|
||||
logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
|
||||
try {
|
||||
return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
|
||||
Binder.getCallingUid(), proxiedPackageName);
|
||||
proxiedUid, proxiedPackageName);
|
||||
} catch (RemoteException e) {
|
||||
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
|
||||
* returns {@link #MODE_ERRORED}.
|
||||
|
||||
@@ -108,8 +108,7 @@ public final class PermissionChecker {
|
||||
packageName = packageNames[0];
|
||||
}
|
||||
|
||||
if (appOpsManager.noteProxyOpNoThrow(op, packageName)
|
||||
!= AppOpsManager.MODE_ALLOWED) {
|
||||
if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid) != AppOpsManager.MODE_ALLOWED) {
|
||||
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
|
||||
* 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 permission The permission to check.
|
||||
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
|
||||
|
||||
Reference in New Issue
Block a user