Fix issue #2845673: android:exported="false" is not obeyed
Thou shall obey.
Change-Id: I09f163a0db7cc9189c8d7f5116cc8ca9d4f7a76c
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c88e086..c96d562 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3298,10 +3298,6 @@
Slog.e(TAG, "Failed to find provider info for " + name);
return null;
}
- if (holder.permissionFailure != null) {
- throw new SecurityException("Permission " + holder.permissionFailure
- + " required for provider " + name);
- }
IContentProvider prov = installProvider(context, holder.provider,
holder.info, true);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 81b28b9..416f289 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -326,28 +326,19 @@
/** Information you can retrieve about a particular application. */
public static class ContentProviderHolder implements Parcelable {
public final ProviderInfo info;
- public final String permissionFailure;
public IContentProvider provider;
public boolean noReleaseNeeded;
public ContentProviderHolder(ProviderInfo _info) {
info = _info;
- permissionFailure = null;
}
- public ContentProviderHolder(ProviderInfo _info,
- String _permissionFailure) {
- info = _info;
- permissionFailure = _permissionFailure;
- }
-
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
info.writeToParcel(dest, 0);
- dest.writeString(permissionFailure);
if (provider != null) {
dest.writeStrongBinder(provider.asBinder());
} else {
@@ -369,7 +360,6 @@
private ContentProviderHolder(Parcel source) {
info = ProviderInfo.CREATOR.createFromParcel(source);
- permissionFailure = source.readString();
provider = ContentProviderNative.asInterface(
source.readStrongBinder());
noReleaseNeeded = source.readInt() != 0;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 9b9f796..dc4e9c4 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -86,6 +86,7 @@
private String mReadPermission;
private String mWritePermission;
private PathPermission[] mPathPermissions;
+ private boolean mExported;
private Transport mTransport = new Transport();
@@ -257,9 +258,9 @@
final Context context = getContext();
final String rperm = getReadPermission();
final int pid = Binder.getCallingPid();
- if (rperm == null
+ if (mExported && (rperm == null
|| context.checkPermission(rperm, pid, uid)
- == PackageManager.PERMISSION_GRANTED) {
+ == PackageManager.PERMISSION_GRANTED)) {
return;
}
@@ -303,9 +304,9 @@
final Context context = getContext();
final String wperm = getWritePermission();
final int pid = Binder.getCallingPid();
- if (wperm == null
+ if (mExported && (wperm == null
|| context.checkPermission(wperm, pid, uid)
- == PackageManager.PERMISSION_GRANTED) {
+ == PackageManager.PERMISSION_GRANTED)) {
return true;
}
@@ -786,6 +787,7 @@
setReadPermission(info.readPermission);
setWritePermission(info.writePermission);
setPathPermissions(info.pathPermissions);
+ mExported = info.exported;
}
ContentProvider.this.onCreate();
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 4762ddb..9d31502 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1162,7 +1162,7 @@
} catch (RemoteException e) {
}
} catch (NameNotFoundException e) {
- Log.w(TAG, "Unable to create context for heavy notification", e);
+ Slog.w(TAG, "Unable to create context for heavy notification", e);
}
} break;
case CANCEL_HEAVY_NOTIFICATION_MSG: {
@@ -2367,7 +2367,7 @@
}
if (proc == null) {
- Log.w(TAG, "crashApplication: nothing for uid=" + uid
+ Slog.w(TAG, "crashApplication: nothing for uid=" + uid
+ " initialPid=" + initialPid
+ " packageName=" + packageName);
return;
@@ -4051,6 +4051,9 @@
return false;
}
}
+ if (!pi.exported && pi.applicationInfo.uid != uid) {
+ return false;
+ }
return true;
} catch (RemoteException e) {
return false;
@@ -4199,8 +4202,8 @@
if (perm == null) {
perm = new UriPermission(targetUid, uri);
targetUris.put(uri, perm);
-
}
+
perm.modeFlags |= modeFlags;
if (activity == null) {
perm.globalModeFlags |= modeFlags;
@@ -4221,6 +4224,11 @@
void grantUriPermissionFromIntentLocked(int callingUid,
String targetPkg, Intent intent, ActivityRecord activity) {
+ if (DEBUG_URI_PERMISSION) Slog.v(TAG,
+ "Grant URI perm to " + (intent != null ? intent.getData() : null)
+ + " from " + intent + "; flags=0x"
+ + Integer.toHexString(intent != null ? intent.getFlags() : 0));
+
if (intent == null) {
return;
}
@@ -4899,13 +4907,12 @@
}
private final String checkContentProviderPermissionLocked(
- ProviderInfo cpi, ProcessRecord r, int mode) {
+ ProviderInfo cpi, ProcessRecord r) {
final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
cpi.exported ? -1 : cpi.applicationInfo.uid)
- == PackageManager.PERMISSION_GRANTED
- && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
+ == PackageManager.PERMISSION_GRANTED) {
return null;
}
if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
@@ -4922,8 +4929,7 @@
PathPermission pp = pps[i];
if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
cpi.exported ? -1 : cpi.applicationInfo.uid)
- == PackageManager.PERMISSION_GRANTED
- && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
+ == PackageManager.PERMISSION_GRANTED) {
return null;
}
if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
@@ -4934,6 +4940,15 @@
}
}
+ HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
+ if (perms != null) {
+ for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
+ if (uri.getKey().getAuthority().equals(cpi.authority)) {
+ return null;
+ }
+ }
+ }
+
String msg = "Permission Denial: opening provider " + cpi.name
+ " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+ ", uid=" + callingUid + ") requires "
@@ -4963,10 +4978,9 @@
cpr = mProvidersByName.get(name);
if (cpr != null) {
cpi = cpr.info;
- if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
- return new ContentProviderHolder(cpi,
- cpi.readPermission != null
- ? cpi.readPermission : cpi.writePermission);
+ String msg;
+ if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
+ throw new SecurityException(msg);
}
if (r != null && cpr.canRunHere(r)) {
@@ -5026,10 +5040,9 @@
return null;
}
- if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
- return new ContentProviderHolder(cpi,
- cpi.readPermission != null
- ? cpi.readPermission : cpi.writePermission);
+ String msg;
+ if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
+ throw new SecurityException(msg);
}
if (!mSystemReady && !mDidUpdate && !mWaitingUpdate
@@ -6180,7 +6193,7 @@
Binder.restoreCallingIdentity(origId);
}
int res = result.get();
- Log.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
+ Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
}
}