Merge "Sanitize app op service inputs" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c1b8e88329
@@ -446,8 +446,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
int[] ops) {
|
int[] ops) {
|
||||||
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
|
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
|
||||||
Binder.getCallingPid(), Binder.getCallingUid(), null);
|
Binder.getCallingPid(), Binder.getCallingUid(), null);
|
||||||
|
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||||
|
if (resolvedPackageName == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Ops pkgOps = getOpsLocked(uid, packageName, false);
|
Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false);
|
||||||
if (pkgOps == null) {
|
if (pkgOps == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -465,7 +469,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
|
|
||||||
private void pruneOp(Op op, int uid, String packageName) {
|
private void pruneOp(Op op, int uid, String packageName) {
|
||||||
if (op.time == 0 && op.rejectTime == 0) {
|
if (op.time == 0 && op.rejectTime == 0) {
|
||||||
Ops ops = getOpsLocked(uid, packageName, false);
|
Ops ops = getOpsRawLocked(uid, packageName, false);
|
||||||
if (ops != null) {
|
if (ops != null) {
|
||||||
ops.remove(op.op);
|
ops.remove(op.op);
|
||||||
if (ops.size() <= 0) {
|
if (ops.size() <= 0) {
|
||||||
@@ -879,8 +883,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
public int checkOperation(int code, int uid, String packageName) {
|
public int checkOperation(int code, int uid, String packageName) {
|
||||||
verifyIncomingUid(uid);
|
verifyIncomingUid(uid);
|
||||||
verifyIncomingOp(code);
|
verifyIncomingOp(code);
|
||||||
|
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||||
|
if (resolvedPackageName == null) {
|
||||||
|
return AppOpsManager.MODE_IGNORED;
|
||||||
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (isOpRestricted(uid, code, packageName)) {
|
if (isOpRestricted(uid, code, resolvedPackageName)) {
|
||||||
return AppOpsManager.MODE_IGNORED;
|
return AppOpsManager.MODE_IGNORED;
|
||||||
}
|
}
|
||||||
code = AppOpsManager.opToSwitch(code);
|
code = AppOpsManager.opToSwitch(code);
|
||||||
@@ -891,7 +899,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
return uidMode;
|
return uidMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Op op = getOpLocked(code, uid, packageName, false);
|
Op op = getOpLocked(code, uid, resolvedPackageName, false);
|
||||||
if (op == null) {
|
if (op == null) {
|
||||||
return AppOpsManager.opToDefaultMode(code);
|
return AppOpsManager.opToDefaultMode(code);
|
||||||
}
|
}
|
||||||
@@ -975,6 +983,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int checkPackage(int uid, String packageName) {
|
public int checkPackage(int uid, String packageName) {
|
||||||
|
Preconditions.checkNotNull(packageName);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (getOpsRawLocked(uid, packageName, true) != null) {
|
if (getOpsRawLocked(uid, packageName, true) != null) {
|
||||||
return AppOpsManager.MODE_ALLOWED;
|
return AppOpsManager.MODE_ALLOWED;
|
||||||
@@ -988,26 +997,39 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
public int noteProxyOperation(int code, String proxyPackageName,
|
public int noteProxyOperation(int code, String proxyPackageName,
|
||||||
int proxiedUid, String proxiedPackageName) {
|
int proxiedUid, String proxiedPackageName) {
|
||||||
verifyIncomingOp(code);
|
verifyIncomingOp(code);
|
||||||
final int proxyMode = noteOperationUnchecked(code, Binder.getCallingUid(),
|
final int proxyUid = Binder.getCallingUid();
|
||||||
proxyPackageName, -1, null);
|
String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
|
||||||
|
if (resolveProxyPackageName == null) {
|
||||||
|
return AppOpsManager.MODE_IGNORED;
|
||||||
|
}
|
||||||
|
final int proxyMode = noteOperationUnchecked(code, proxyUid,
|
||||||
|
resolveProxyPackageName, -1, null);
|
||||||
if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
|
if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
|
||||||
return proxyMode;
|
return proxyMode;
|
||||||
}
|
}
|
||||||
return noteOperationUnchecked(code, proxiedUid, proxiedPackageName,
|
String resolveProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName);
|
||||||
Binder.getCallingUid(), proxyPackageName);
|
if (resolveProxiedPackageName == null) {
|
||||||
|
return AppOpsManager.MODE_IGNORED;
|
||||||
|
}
|
||||||
|
return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
|
||||||
|
proxyMode, resolveProxyPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int noteOperation(int code, int uid, String packageName) {
|
public int noteOperation(int code, int uid, String packageName) {
|
||||||
verifyIncomingUid(uid);
|
verifyIncomingUid(uid);
|
||||||
verifyIncomingOp(code);
|
verifyIncomingOp(code);
|
||||||
return noteOperationUnchecked(code, uid, packageName, 0, null);
|
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||||
|
if (resolvedPackageName == null) {
|
||||||
|
return AppOpsManager.MODE_IGNORED;
|
||||||
|
}
|
||||||
|
return noteOperationUnchecked(code, uid, resolvedPackageName, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int noteOperationUnchecked(int code, int uid, String packageName,
|
private int noteOperationUnchecked(int code, int uid, String packageName,
|
||||||
int proxyUid, String proxyPackageName) {
|
int proxyUid, String proxyPackageName) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Ops ops = getOpsLocked(uid, packageName, true);
|
Ops ops = getOpsRawLocked(uid, packageName, true);
|
||||||
if (ops == null) {
|
if (ops == null) {
|
||||||
if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
|
if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
|
||||||
+ " package " + packageName);
|
+ " package " + packageName);
|
||||||
@@ -1055,16 +1077,20 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
public int startOperation(IBinder token, int code, int uid, String packageName) {
|
public int startOperation(IBinder token, int code, int uid, String packageName) {
|
||||||
verifyIncomingUid(uid);
|
verifyIncomingUid(uid);
|
||||||
verifyIncomingOp(code);
|
verifyIncomingOp(code);
|
||||||
|
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||||
|
if (resolvedPackageName == null) {
|
||||||
|
return AppOpsManager.MODE_IGNORED;
|
||||||
|
}
|
||||||
ClientState client = (ClientState)token;
|
ClientState client = (ClientState)token;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Ops ops = getOpsLocked(uid, packageName, true);
|
Ops ops = getOpsRawLocked(uid, resolvedPackageName, true);
|
||||||
if (ops == null) {
|
if (ops == null) {
|
||||||
if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
|
if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
|
||||||
+ " package " + packageName);
|
+ " package " + resolvedPackageName);
|
||||||
return AppOpsManager.MODE_ERRORED;
|
return AppOpsManager.MODE_ERRORED;
|
||||||
}
|
}
|
||||||
Op op = getOpLocked(ops, code, true);
|
Op op = getOpLocked(ops, code, true);
|
||||||
if (isOpRestricted(uid, code, packageName)) {
|
if (isOpRestricted(uid, code, resolvedPackageName)) {
|
||||||
return AppOpsManager.MODE_IGNORED;
|
return AppOpsManager.MODE_IGNORED;
|
||||||
}
|
}
|
||||||
final int switchCode = AppOpsManager.opToSwitch(code);
|
final int switchCode = AppOpsManager.opToSwitch(code);
|
||||||
@@ -1074,7 +1100,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
if (uidMode != AppOpsManager.MODE_ALLOWED) {
|
if (uidMode != AppOpsManager.MODE_ALLOWED) {
|
||||||
if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
|
if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
|
||||||
+ switchCode + " (" + code + ") uid " + uid + " package "
|
+ switchCode + " (" + code + ") uid " + uid + " package "
|
||||||
+ packageName);
|
+ resolvedPackageName);
|
||||||
op.rejectTime = System.currentTimeMillis();
|
op.rejectTime = System.currentTimeMillis();
|
||||||
return uidMode;
|
return uidMode;
|
||||||
}
|
}
|
||||||
@@ -1082,12 +1108,13 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
|
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
|
||||||
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
|
if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
|
||||||
if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
|
if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
|
||||||
+ switchCode + " (" + code + ") uid " + uid + " package " + packageName);
|
+ switchCode + " (" + code + ") uid " + uid + " package "
|
||||||
|
+ resolvedPackageName);
|
||||||
op.rejectTime = System.currentTimeMillis();
|
op.rejectTime = System.currentTimeMillis();
|
||||||
return switchOp.mode;
|
return switchOp.mode;
|
||||||
}
|
}
|
||||||
if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid
|
if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid
|
||||||
+ " package " + packageName);
|
+ " package " + resolvedPackageName);
|
||||||
if (op.nesting == 0) {
|
if (op.nesting == 0) {
|
||||||
op.time = System.currentTimeMillis();
|
op.time = System.currentTimeMillis();
|
||||||
op.rejectTime = 0;
|
op.rejectTime = 0;
|
||||||
@@ -1105,9 +1132,16 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
public void finishOperation(IBinder token, int code, int uid, String packageName) {
|
public void finishOperation(IBinder token, int code, int uid, String packageName) {
|
||||||
verifyIncomingUid(uid);
|
verifyIncomingUid(uid);
|
||||||
verifyIncomingOp(code);
|
verifyIncomingOp(code);
|
||||||
ClientState client = (ClientState)token;
|
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||||
|
if (resolvedPackageName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(token instanceof ClientState)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClientState client = (ClientState) token;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Op op = getOpLocked(code, uid, packageName, true);
|
Op op = getOpLocked(code, uid, resolvedPackageName, true);
|
||||||
if (op == null) {
|
if (op == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1123,6 +1157,9 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int permissionToOpCode(String permission) {
|
public int permissionToOpCode(String permission) {
|
||||||
|
if (permission == null) {
|
||||||
|
return AppOpsManager.OP_NONE;
|
||||||
|
}
|
||||||
return AppOpsManager.permissionToOpCode(permission);
|
return AppOpsManager.permissionToOpCode(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1172,15 +1209,6 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
return uidState;
|
return uidState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Ops getOpsLocked(int uid, String packageName, boolean edit) {
|
|
||||||
if (uid == 0) {
|
|
||||||
packageName = "root";
|
|
||||||
} else if (uid == Process.SHELL_UID) {
|
|
||||||
packageName = "com.android.shell";
|
|
||||||
}
|
|
||||||
return getOpsRawLocked(uid, packageName, edit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
|
private Ops getOpsRawLocked(int uid, String packageName, boolean edit) {
|
||||||
UidState uidState = getUidStateLocked(uid, edit);
|
UidState uidState = getUidStateLocked(uid, edit);
|
||||||
if (uidState == null) {
|
if (uidState == null) {
|
||||||
@@ -1266,7 +1294,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Op getOpLocked(int code, int uid, String packageName, boolean edit) {
|
private Op getOpLocked(int code, int uid, String packageName, boolean edit) {
|
||||||
Ops ops = getOpsLocked(uid, packageName, edit);
|
Ops ops = getOpsRawLocked(uid, packageName, edit);
|
||||||
if (ops == null) {
|
if (ops == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1324,7 +1352,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
|
if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
|
||||||
// If we are the system, bypass user restrictions for certain codes
|
// If we are the system, bypass user restrictions for certain codes
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Ops ops = getOpsLocked(uid, packageName, true);
|
Ops ops = getOpsRawLocked(uid, packageName, true);
|
||||||
if ((ops != null) && ops.isPrivileged) {
|
if ((ops != null) && ops.isPrivileged) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1589,7 +1617,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
out.startTag(null, "uid");
|
out.startTag(null, "uid");
|
||||||
out.attribute(null, "n", Integer.toString(pkg.getUid()));
|
out.attribute(null, "n", Integer.toString(pkg.getUid()));
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Ops ops = getOpsLocked(pkg.getUid(), pkg.getPackageName(), false);
|
Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), false);
|
||||||
// Should always be present as the list of PackageOps is generated
|
// Should always be present as the list of PackageOps is generated
|
||||||
// from Ops.
|
// from Ops.
|
||||||
if (ops != null) {
|
if (ops != null) {
|
||||||
@@ -2181,6 +2209,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public void setUserRestrictions(Bundle restrictions, IBinder token, int userHandle) {
|
public void setUserRestrictions(Bundle restrictions, IBinder token, int userHandle) {
|
||||||
checkSystemUid("setUserRestrictions");
|
checkSystemUid("setUserRestrictions");
|
||||||
|
Preconditions.checkNotNull(restrictions);
|
||||||
Preconditions.checkNotNull(token);
|
Preconditions.checkNotNull(token);
|
||||||
final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
|
final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
|
||||||
for (int i = 0; i < opRestrictions.length; ++i) {
|
for (int i = 0; i < opRestrictions.length; ++i) {
|
||||||
@@ -2395,6 +2424,17 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String resolvePackageName(int uid, String packageName) {
|
||||||
|
if (uid == 0) {
|
||||||
|
return "root";
|
||||||
|
} else if (uid == Process.SHELL_UID) {
|
||||||
|
return "com.android.shell";
|
||||||
|
} else if (uid == Process.SYSTEM_UID && packageName == null) {
|
||||||
|
return "android";
|
||||||
|
}
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
private static String[] getPackagesForUid(int uid) {
|
private static String[] getPackagesForUid(int uid) {
|
||||||
String[] packageNames = null;
|
String[] packageNames = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user