Ensure caller identity is restored in CP quick-path.
Bug: 172935267 Test: PoC in bug Change-Id: I69d5c792cf442e694a5b5ab15ce5913279a5545a
This commit is contained in:
@@ -227,57 +227,59 @@ public class ContentProviderHelper {
|
||||
cpr.name.flattenToShortString(), startTime);
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
|
||||
|
||||
checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
|
||||
// Return the provider instance right away since it already exists.
|
||||
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage,
|
||||
callingTag, stable, true, startTime, mService.mProcessList);
|
||||
|
||||
// In this case the provider instance already exists so we can return it right away.
|
||||
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag,
|
||||
stable, true, startTime, mService.mProcessList);
|
||||
|
||||
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
|
||||
final int verifiedAdj = cpr.proc.verifiedAdj;
|
||||
boolean success = mService.updateOomAdjLocked(cpr.proc, true,
|
||||
OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
|
||||
// XXX things have changed so updateOomAdjLocked doesn't actually tell us
|
||||
// if the process has been successfully adjusted. So to reduce races with
|
||||
// it, we will check whether the process still exists. Note that this doesn't
|
||||
// completely get rid of races with LMK killing the process, but should make
|
||||
// them much smaller.
|
||||
if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
|
||||
success = false;
|
||||
}
|
||||
maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
|
||||
checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
|
||||
if (ActivityManagerDebugConfig.DEBUG_PROVIDER) {
|
||||
Slog.i(TAG, "Adjust success: " + success);
|
||||
}
|
||||
// NOTE: there is still a race here where a signal could be
|
||||
// pending on the process even though we managed to update its
|
||||
// adj level. Not sure what to do about this, but at least
|
||||
// the race is now smaller.
|
||||
if (!success) {
|
||||
// Uh oh... it looks like the provider's process
|
||||
// has been killed on us. We need to wait for a new
|
||||
// process to be started, and make sure its death
|
||||
// doesn't kill our process.
|
||||
Slog.wtf(TAG, "Existing provider " + cpr.name.flattenToShortString()
|
||||
+ " is crashing; detaching " + r);
|
||||
boolean lastRef = decProviderCountLocked(conn, cpr, token, stable,
|
||||
false, false);
|
||||
if (!lastRef) {
|
||||
// This wasn't the last ref our process had on
|
||||
// the provider... we will be killed during cleaning up, bail.
|
||||
return null;
|
||||
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
|
||||
final int verifiedAdj = cpr.proc.verifiedAdj;
|
||||
boolean success = mService.updateOomAdjLocked(cpr.proc, true,
|
||||
OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
|
||||
// XXX things have changed so updateOomAdjLocked doesn't actually tell us
|
||||
// if the process has been successfully adjusted. So to reduce races with
|
||||
// it, we will check whether the process still exists. Note that this doesn't
|
||||
// completely get rid of races with LMK killing the process, but should make
|
||||
// them much smaller.
|
||||
if (success && verifiedAdj != cpr.proc.setAdj
|
||||
&& !isProcessAliveLocked(cpr.proc)) {
|
||||
success = false;
|
||||
}
|
||||
// We'll just start a new process to host the content provider
|
||||
providerRunning = false;
|
||||
conn = null;
|
||||
dyingProc = cpr.proc;
|
||||
} else {
|
||||
cpr.proc.verifiedAdj = cpr.proc.setAdj;
|
||||
maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
|
||||
checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
|
||||
if (ActivityManagerDebugConfig.DEBUG_PROVIDER) {
|
||||
Slog.i(TAG, "Adjust success: " + success);
|
||||
}
|
||||
// NOTE: there is still a race here where a signal could be
|
||||
// pending on the process even though we managed to update its
|
||||
// adj level. Not sure what to do about this, but at least
|
||||
// the race is now smaller.
|
||||
if (!success) {
|
||||
// Uh oh... it looks like the provider's process
|
||||
// has been killed on us. We need to wait for a new
|
||||
// process to be started, and make sure its death
|
||||
// doesn't kill our process.
|
||||
Slog.wtf(TAG, "Existing provider " + cpr.name.flattenToShortString()
|
||||
+ " is crashing; detaching " + r);
|
||||
boolean lastRef = decProviderCountLocked(conn, cpr, token, stable,
|
||||
false, false);
|
||||
if (!lastRef) {
|
||||
// This wasn't the last ref our process had on
|
||||
// the provider... we will be killed during cleaning up, bail.
|
||||
return null;
|
||||
}
|
||||
// We'll just start a new process to host the content provider
|
||||
providerRunning = false;
|
||||
conn = null;
|
||||
dyingProc = cpr.proc;
|
||||
} else {
|
||||
cpr.proc.verifiedAdj = cpr.proc.setAdj;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
if (!providerRunning) {
|
||||
|
||||
Reference in New Issue
Block a user