Stronger constraints around install session IDs.
Generate positive, non-zero session IDs, and don't recycle them within a given boot. Guard against ID starvation by crazy apps. Bug: 16792837 Change-Id: I6035afe4d942d358b5ca12b4f818c55885b74aba
This commit is contained in:
committed by
Jeff Sharkey
parent
966e258396
commit
f174c6e6de
@@ -114,6 +114,9 @@ public class PackageInstaller {
|
||||
*
|
||||
* @throws IOException if parameters were unsatisfiable, such as lack of
|
||||
* disk space or unavailable media.
|
||||
* @return positive, non-zero unique ID that represents the created session.
|
||||
* This ID remains consistent across device reboots until the
|
||||
* session is finalized. IDs are not reused during a given boot.
|
||||
*/
|
||||
public int createSession(@NonNull InstallSessionParams params) throws IOException {
|
||||
try {
|
||||
|
||||
@@ -121,8 +121,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
||||
private static final String ATTR_REFERRER_URI = "referrerUri";
|
||||
private static final String ATTR_ABI_OVERRIDE = "abiOverride";
|
||||
|
||||
/** Automatically destroy sessions older than this */
|
||||
private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS;
|
||||
/** Upper bound on number of active sessions for a UID */
|
||||
private static final long MAX_ACTIVE_SESSIONS = 1024;
|
||||
/** Upper bound on number of historical sessions for a UID */
|
||||
private static final long MAX_HISTORICAL_SESSIONS = 1048576;
|
||||
|
||||
private final Context mContext;
|
||||
private final PackageManagerService mPm;
|
||||
@@ -410,9 +414,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
||||
final PackageInstallerSession session;
|
||||
synchronized (mSessions) {
|
||||
// Sanity check that installer isn't going crazy
|
||||
final int activeCount = getSessionCountLocked(callingUid);
|
||||
final int activeCount = getSessionCount(mSessions, callingUid);
|
||||
if (activeCount >= MAX_ACTIVE_SESSIONS) {
|
||||
throw new IllegalStateException("Too many active sessions for UID " + callingUid);
|
||||
throw new IllegalStateException(
|
||||
"Too many active sessions for UID " + callingUid);
|
||||
}
|
||||
final int historicalCount = getSessionCount(mHistoricalSessions, callingUid);
|
||||
if (historicalCount >= MAX_HISTORICAL_SESSIONS) {
|
||||
throw new IllegalStateException(
|
||||
"Too many historical sessions for UID " + callingUid);
|
||||
}
|
||||
|
||||
sessionId = allocateSessionIdLocked();
|
||||
@@ -452,8 +462,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
||||
int n = 0;
|
||||
int sessionId;
|
||||
do {
|
||||
sessionId = mRandom.nextInt(Integer.MAX_VALUE);
|
||||
if (mSessions.get(sessionId) == null) {
|
||||
sessionId = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
|
||||
if (mSessions.get(sessionId) == null && mHistoricalSessions.get(sessionId) == null) {
|
||||
return sessionId;
|
||||
}
|
||||
} while (n++ < 32);
|
||||
@@ -560,11 +570,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
|
||||
mCallbacks.unregister(callback);
|
||||
}
|
||||
|
||||
private int getSessionCountLocked(int installerUid) {
|
||||
private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
|
||||
int installerUid) {
|
||||
int count = 0;
|
||||
final int size = mSessions.size();
|
||||
final int size = sessions.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final PackageInstallerSession session = mSessions.valueAt(i);
|
||||
final PackageInstallerSession session = sessions.valueAt(i);
|
||||
if (session.installerUid == installerUid) {
|
||||
count++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user