Merge "Fix issue with acquiring singleton content provider from another user" into sc-dev am: a575e65fdb am: 38f097a480

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14463094

Change-Id: Ie562d1f8e2c625468de3e659d461d8d9915a00d8
This commit is contained in:
Jing Ji
2021-05-08 20:59:53 +00:00
committed by Automerger Merge Worker
4 changed files with 18 additions and 9 deletions

View File

@@ -19,6 +19,7 @@ package com.android.server.am;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import android.annotation.UserIdInt;
import android.os.Binder; import android.os.Binder;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Slog; import android.util.Slog;
@@ -52,15 +53,21 @@ public final class ContentProviderConnection extends Binder {
// The provider of this connection is now dead. // The provider of this connection is now dead.
public boolean dead; public boolean dead;
// The original user id when this connection was requested, it could be different from
// the client's user id because the client could request to access a content provider
// living in a different user if it has the permission.
@UserIdInt final int mExpectedUserId;
// For debugging. // For debugging.
private int mNumStableIncs; private int mNumStableIncs;
private int mNumUnstableIncs; private int mNumUnstableIncs;
public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client, public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client,
String _clientPackage) { String _clientPackage, @UserIdInt int _expectedUserId) {
provider = _provider; provider = _provider;
client = _client; client = _client;
clientPackage = _clientPackage; clientPackage = _clientPackage;
mExpectedUserId = _expectedUserId;
createTime = SystemClock.elapsedRealtime(); createTime = SystemClock.elapsedRealtime();
} }

View File

@@ -150,6 +150,7 @@ public class ContentProviderHelper {
ContentProviderConnection conn = null; ContentProviderConnection conn = null;
ProviderInfo cpi = null; ProviderInfo cpi = null;
boolean providerRunning = false; boolean providerRunning = false;
final int expectedUserId = userId;
synchronized (mService) { synchronized (mService) {
long startTime = SystemClock.uptimeMillis(); long startTime = SystemClock.uptimeMillis();
@@ -239,7 +240,8 @@ public class ContentProviderHelper {
// Return the provider instance right away since it already exists. // Return the provider instance right away since it already exists.
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage,
callingTag, stable, true, startTime, mService.mProcessList); callingTag, stable, true, startTime, mService.mProcessList,
expectedUserId);
checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
final int verifiedAdj = cpr.proc.mState.getVerifiedAdj(); final int verifiedAdj = cpr.proc.mState.getVerifiedAdj();
@@ -490,7 +492,7 @@ public class ContentProviderHelper {
mProviderMap.putProviderByName(name, cpr); mProviderMap.putProviderByName(name, cpr);
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag,
stable, false, startTime, mService.mProcessList); stable, false, startTime, mService.mProcessList, expectedUserId);
if (conn != null) { if (conn != null) {
conn.waiting = true; conn.waiting = true;
} }
@@ -1286,7 +1288,7 @@ public class ContentProviderHelper {
private ContentProviderConnection incProviderCountLocked(ProcessRecord r, private ContentProviderConnection incProviderCountLocked(ProcessRecord r,
final ContentProviderRecord cpr, IBinder externalProcessToken, int callingUid, final ContentProviderRecord cpr, IBinder externalProcessToken, int callingUid,
String callingPackage, String callingTag, boolean stable, boolean updateLru, String callingPackage, String callingTag, boolean stable, boolean updateLru,
long startTime, ProcessList processList) { long startTime, ProcessList processList, @UserIdInt int expectedUserId) {
if (r == null) { if (r == null) {
cpr.addExternalProcessHandleLocked(externalProcessToken, callingUid, callingTag); cpr.addExternalProcessHandleLocked(externalProcessToken, callingUid, callingTag);
return null; return null;
@@ -1303,7 +1305,8 @@ public class ContentProviderHelper {
} }
// Create a new ContentProviderConnection. The reference count is known to be 1. // Create a new ContentProviderConnection. The reference count is known to be 1.
ContentProviderConnection conn = new ContentProviderConnection(cpr, r, callingPackage); ContentProviderConnection conn = new ContentProviderConnection(cpr, r, callingPackage,
expectedUserId);
conn.startAssociationIfNeeded(); conn.startAssociationIfNeeded();
conn.initializeCount(stable); conn.initializeCount(stable);
cpr.connections.add(conn); cpr.connections.add(conn);

View File

@@ -189,7 +189,6 @@ final class ContentProviderRecord implements ComponentName.WithComponentName {
*/ */
void onProviderPublishStatusLocked(boolean status) { void onProviderPublishStatusLocked(boolean status) {
final int numOfConns = connections.size(); final int numOfConns = connections.size();
final int userId = UserHandle.getUserId(appInfo.uid);
for (int i = 0; i < numOfConns; i++) { for (int i = 0; i < numOfConns; i++) {
final ContentProviderConnection conn = connections.get(i); final ContentProviderConnection conn = connections.get(i);
if (conn.waiting && conn.client != null) { if (conn.waiting && conn.client != null) {
@@ -201,7 +200,7 @@ final class ContentProviderRecord implements ComponentName.WithComponentName {
+ appInfo.uid + " for provider " + appInfo.uid + " for provider "
+ info.authority + ": launching app became null"); + info.authority + ": launching app became null");
EventLogTags.writeAmProviderLostProcess( EventLogTags.writeAmProviderLostProcess(
userId, UserHandle.getUserId(appInfo.uid),
appInfo.packageName, appInfo.packageName,
appInfo.uid, info.authority); appInfo.uid, info.authority);
} else { } else {
@@ -217,7 +216,7 @@ final class ContentProviderRecord implements ComponentName.WithComponentName {
try { try {
thread.notifyContentProviderPublishStatus( thread.notifyContentProviderPublishStatus(
newHolder(status ? conn : null, false), newHolder(status ? conn : null, false),
info.authority, userId, status); info.authority, conn.mExpectedUserId, status);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }

View File

@@ -2078,7 +2078,7 @@ public class MockingOomAdjusterTests {
doReturn(hasExternalProviders).when(record).hasExternalProcessHandles(); doReturn(hasExternalProviders).when(record).hasExternalProcessHandles();
} }
ContentProviderConnection conn = spy(new ContentProviderConnection(record, client, ContentProviderConnection conn = spy(new ContentProviderConnection(record, client,
client.info.packageName)); client.info.packageName, UserHandle.getUserId(client.uid)));
record.connections.add(conn); record.connections.add(conn);
client.mProviders.addProviderConnection(conn); client.mProviders.addProviderConnection(conn);
return record; return record;