use of android.content.pm.PathPermission in project android_frameworks_base by DirtyUnicorns.
the class ActivityManagerService method checkContentProviderPermissionLocked.
/**
* Check if {@link ProcessRecord} has a possible chance at accessing the
* given {@link ProviderInfo}. Final permission checking is always done
* in {@link ContentProvider}.
*/
private final String checkContentProviderPermissionLocked(ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
boolean checkedGrants = false;
if (checkUser) {
// Looking for cross-user grants before enforcing the typical cross-users permissions
int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
return null;
}
checkedGrants = true;
}
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
if (userId != tmpTargetUserId) {
// When we actually went to determine the final targer user ID, this ended
// up different than our initial check for the authority. This is because
// they had asked for USER_CURRENT_OR_SELF and we ended up switching to
// SELF. So we need to re-check the grants again.
checkedGrants = false;
}
}
if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) {
return null;
}
if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) {
return null;
}
PathPermission[] pps = cpi.pathPermissions;
if (pps != null) {
int i = pps.length;
while (i > 0) {
i--;
PathPermission pp = pps[i];
String pprperm = pp.getReadPermission();
if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) {
return null;
}
String ppwperm = pp.getWritePermission();
if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, cpi.applicationInfo.uid, cpi.exported) == PackageManager.PERMISSION_GRANTED) {
return null;
}
}
}
if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
return null;
}
String msg;
if (!cpi.exported) {
msg = "Permission Denial: opening provider " + cpi.name + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid + ", uid=" + callingUid + ") that is not exported from uid " + cpi.applicationInfo.uid;
} else {
msg = "Permission Denial: opening provider " + cpi.name + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid + ", uid=" + callingUid + ") requires " + cpi.readPermission + " or " + cpi.writePermission;
}
Slog.w(TAG, msg);
return msg;
}
use of android.content.pm.PathPermission in project android_frameworks_base by AOSPA.
the class ContentProvider method enforceWritePermissionInner.
/** {@hide} */
protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
String missingPerm = null;
int strongestMode = MODE_ALLOWED;
if (UserHandle.isSameApp(uid, mMyUid)) {
return MODE_ALLOWED;
}
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getWritePermission();
if (componentPerm != null) {
final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
missingPerm = componentPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
// track if unprotected write is allowed; any denied
// <path-permission> below removes this ability
boolean allowDefaultWrite = (componentPerm == null);
final PathPermission[] pps = getPathPermissions();
if (pps != null) {
final String path = uri.getPath();
for (PathPermission pp : pps) {
final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) {
final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultWrite = false;
missingPerm = pathPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
}
}
// <provider> permission, then allow access.
if (allowDefaultWrite)
return MODE_ALLOWED;
}
// last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, callerToken) == PERMISSION_GRANTED) {
return MODE_ALLOWED;
}
// ignored through; otherwise we assume it should be a real error below.
if (strongestMode == MODE_IGNORED) {
return MODE_IGNORED;
}
final String failReason = mExported ? " requires " + missingPerm + ", or grantUriPermission()" : " requires the provider be exported, or grantUriPermission()";
throw new SecurityException("Permission Denial: writing " + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid + ", uid=" + uid + failReason);
}
use of android.content.pm.PathPermission in project android_frameworks_base by AOSPA.
the class ContentProvider method enforceReadPermissionInner.
/** {@hide} */
protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
String missingPerm = null;
int strongestMode = MODE_ALLOWED;
if (UserHandle.isSameApp(uid, mMyUid)) {
return MODE_ALLOWED;
}
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getReadPermission();
if (componentPerm != null) {
final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
missingPerm = componentPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
// track if unprotected read is allowed; any denied
// <path-permission> below removes this ability
boolean allowDefaultRead = (componentPerm == null);
final PathPermission[] pps = getPathPermissions();
if (pps != null) {
final String path = uri.getPath();
for (PathPermission pp : pps) {
final String pathPerm = pp.getReadPermission();
if (pathPerm != null && pp.match(path)) {
final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultRead = false;
missingPerm = pathPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
}
}
// <provider> permission, then allow access.
if (allowDefaultRead)
return MODE_ALLOWED;
}
// last chance, check against any uri grants
final int callingUserId = UserHandle.getUserId(uid);
final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid)) ? maybeAddUserId(uri, callingUserId) : uri;
if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, callerToken) == PERMISSION_GRANTED) {
return MODE_ALLOWED;
}
// ignored through; otherwise we assume it should be a real error below.
if (strongestMode == MODE_IGNORED) {
return MODE_IGNORED;
}
final String failReason = mExported ? " requires " + missingPerm + ", or grantUriPermission()" : " requires the provider be exported, or grantUriPermission()";
throw new SecurityException("Permission Denial: reading " + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid + ", uid=" + uid + failReason);
}
use of android.content.pm.PathPermission in project android_frameworks_base by ResurrectionRemix.
the class ContentProvider method enforceWritePermissionInner.
/** {@hide} */
protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
String missingPerm = null;
int strongestMode = MODE_ALLOWED;
if (UserHandle.isSameApp(uid, mMyUid)) {
return MODE_ALLOWED;
}
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getWritePermission();
if (componentPerm != null) {
final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
missingPerm = componentPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
// track if unprotected write is allowed; any denied
// <path-permission> below removes this ability
boolean allowDefaultWrite = (componentPerm == null);
final PathPermission[] pps = getPathPermissions();
if (pps != null) {
final String path = uri.getPath();
for (PathPermission pp : pps) {
final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) {
final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
if (mode == MODE_ALLOWED) {
return MODE_ALLOWED;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultWrite = false;
missingPerm = pathPerm;
strongestMode = Math.max(strongestMode, mode);
}
}
}
}
// <provider> permission, then allow access.
if (allowDefaultWrite)
return MODE_ALLOWED;
}
// last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, callerToken) == PERMISSION_GRANTED) {
return MODE_ALLOWED;
}
// ignored through; otherwise we assume it should be a real error below.
if (strongestMode == MODE_IGNORED) {
return MODE_IGNORED;
}
final String failReason = mExported ? " requires " + missingPerm + ", or grantUriPermission()" : " requires the provider be exported, or grantUriPermission()";
throw new SecurityException("Permission Denial: writing " + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid + ", uid=" + uid + failReason);
}
use of android.content.pm.PathPermission in project platform_frameworks_base by android.
the class ActivityManagerService method checkHoldingPermissionsInternalLocked.
private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
if (pi.applicationInfo.uid == uid) {
return true;
} else if (!pi.exported) {
return false;
}
boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
try {
// check if target holds top-level <provider> permissions
if (!readMet && pi.readPermission != null && considerUidPermissions && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
readMet = true;
}
if (!writeMet && pi.writePermission != null && considerUidPermissions && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
writeMet = true;
}
// track if unprotected read/write is allowed; any denied
// <path-permission> below removes this ability
boolean allowDefaultRead = pi.readPermission == null;
boolean allowDefaultWrite = pi.writePermission == null;
// check if target holds any <path-permission> that match uri
final PathPermission[] pps = pi.pathPermissions;
if (pps != null) {
final String path = grantUri.uri.getPath();
int i = pps.length;
while (i > 0 && (!readMet || !writeMet)) {
i--;
PathPermission pp = pps[i];
if (pp.match(path)) {
if (!readMet) {
final String pprperm = pp.getReadPermission();
if (DEBUG_URI_PERMISSION)
Slog.v(TAG_URI_PERMISSION, "Checking read perm for " + pprperm + " for " + pp.getPath() + ": match=" + pp.match(path) + " check=" + pm.checkUidPermission(pprperm, uid));
if (pprperm != null) {
if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
readMet = true;
} else {
allowDefaultRead = false;
}
}
}
if (!writeMet) {
final String ppwperm = pp.getWritePermission();
if (DEBUG_URI_PERMISSION)
Slog.v(TAG_URI_PERMISSION, "Checking write perm " + ppwperm + " for " + pp.getPath() + ": match=" + pp.match(path) + " check=" + pm.checkUidPermission(ppwperm, uid));
if (ppwperm != null) {
if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
writeMet = true;
} else {
allowDefaultWrite = false;
}
}
}
}
}
}
// <path-permission> above
if (allowDefaultRead)
readMet = true;
if (allowDefaultWrite)
writeMet = true;
} catch (RemoteException e) {
return false;
}
return readMet && writeMet;
}
Aggregations