diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-11-12 05:36:39 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-11-12 05:36:39 +0000 |
commit | e9b725168c57cc542382e0796ac5c9ec76974b5d (patch) | |
tree | 938891084b74b2a80296b271a2f14f42a757362f | |
parent | 23b5774f9063cb0a17dfec2f4c1c222871d9a9c6 (diff) | |
parent | 4e9ea675434412180e95d24ac178c6130c616b18 (diff) | |
download | base-pie-security-release.tar.gz |
Merge cherrypicks of [15405290, 16058207, 16094504] into security-aosp-pi-release.android-security-9.0.0_r76pie-security-release
Change-Id: Idfc9a60f6a24b6f545b31df366f95e0aa776acf2
5 files changed, 76 insertions, 5 deletions
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java index 3f90f36fb2a1..1546ae14862d 100644 --- a/core/java/android/accounts/Account.java +++ b/core/java/android/accounts/Account.java @@ -28,6 +28,7 @@ import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.GuardedBy; +import java.util.Objects; import java.util.Set; /** @@ -80,6 +81,12 @@ public class Account implements Parcelable { if (TextUtils.isEmpty(type)) { throw new IllegalArgumentException("the type must not be empty: " + type); } + if (name.length() > 200) { + throw new IllegalArgumentException("account name is longer than 200 characters"); + } + if (type.length() > 200) { + throw new IllegalArgumentException("account type is longer than 200 characters"); + } this.name = name; this.type = type; this.accessId = accessId; diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index ce0b68418f06..9e8464728b9b 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -46,6 +46,7 @@ import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.BroadcastReceiver; +import android.content.ClipData; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -1790,6 +1791,11 @@ public class AccountManagerService + ", skipping since the account already exists"); return false; } + if (accounts.accountsDb.findAllDeAccounts().size() > 100) { + Log.w(TAG, "insertAccountIntoDatabase: " + account + + ", skipping since more than 50 accounts on device exist"); + return false; + } long accountId = accounts.accountsDb.insertCeAccount(account, password); if (accountId < 0) { Log.w(TAG, "insertAccountIntoDatabase: " + account @@ -4754,6 +4760,11 @@ public class AccountManagerService * supplied entries in the system Settings app. */ protected boolean checkKeyIntent(int authUid, Intent intent) { + // Explicitly set an empty ClipData to ensure that we don't offer to + // promote any Uris contained inside for granting purposes + if (intent.getClipData() == null) { + intent.setClipData(ClipData.newPlainText(null, null)); + } intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 000627cc884e..5df53551b84f 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -125,6 +125,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { 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; + /** Destroy sessions older than this on storage free request */ + private static final long MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS = 8 * DateUtils.HOUR_IN_MILLIS; private final Context mContext; private final PackageManagerService mPm; @@ -228,23 +230,58 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @GuardedBy("mSessions") private void reconcileStagesLocked(String volumeUuid, boolean isEphemeral) { - final File stagingDir = buildStagingDir(volumeUuid, isEphemeral); - final ArraySet<File> unclaimedStages = newArraySet( - stagingDir.listFiles(sStageFilter)); + final ArraySet<File> unclaimedStages = getStagingDirsOnVolume(volumeUuid, isEphemeral); // Ignore stages claimed by active sessions for (int i = 0; i < mSessions.size(); i++) { final PackageInstallerSession session = mSessions.valueAt(i); unclaimedStages.remove(session.stageDir); } + removeStagingDirs(unclaimedStages); + } + private ArraySet<File> getStagingDirsOnVolume(String volumeUuid, boolean isEphemeral) { + final File stagingDir = buildStagingDir(volumeUuid, isEphemeral); + final ArraySet<File> stagingDirs = newArraySet( + stagingDir.listFiles(sStageFilter)); + return stagingDirs; + } + + private void removeStagingDirs(ArraySet<File> stagingDirsToRemove) { // Clean up orphaned staging directories - for (File stage : unclaimedStages) { + for (File stage : stagingDirsToRemove) { Slog.w(TAG, "Deleting orphan stage " + stage); synchronized (mPm.mInstallLock) { mPm.removeCodePathLI(stage); + } + } + } + + /** + * Called to free up some storage space from obsolete installation files + */ + public void freeStageDirs(String volumeUuid, boolean internalVolume) { + final ArraySet<File> unclaimedStagingDirsOnVolume = getStagingDirsOnVolume(volumeUuid, internalVolume); + final long currentTimeMillis = System.currentTimeMillis(); + synchronized (mSessions) { + for (int i = 0; i < mSessions.size(); i++) { + final PackageInstallerSession session = mSessions.valueAt(i); + if (!unclaimedStagingDirsOnVolume.contains(session.stageDir)) { + // Only handles sessions stored on the target volume + continue; + } + final long age = currentTimeMillis - session.createdMillis; + if (age >= MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS) { + // Aggressively close old sessions because we are running low on storage + // Their staging dirs will be removed too + session.abandon(); + } else { + // Session is new enough, so it deserves to be kept even on low storage + unclaimedStagingDirsOnVolume.remove(session.stageDir); + } } } + removeStagingDirs(unclaimedStagingDirsOnVolume); } public void onPrivateVolumeMounted(String volumeUuid) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 4c44b7b8027f..edada326ee12 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -794,6 +794,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } /** + * Check if the caller is the owner of this session. Otherwise throw a + * {@link SecurityException}. + */ + @GuardedBy("mLock") + private void assertCallerIsOwnerOrRootOrSystemLocked() { + final int callingUid = Binder.getCallingUid(); + if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid + && callingUid != Process.SYSTEM_UID) { + throw new SecurityException("Session does not belong to uid " + callingUid); + } + } + + /** * If anybody is reading or writing data of the session, throw an {@link SecurityException}. */ @GuardedBy("mLock") @@ -1564,7 +1577,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void abandon() { synchronized (mLock) { - assertCallerIsOwnerOrRootLocked(); + assertCallerIsOwnerOrRootOrSystemLocked(); if (mRelinquished) { Slog.d(TAG, "Ignoring abandon after commit relinquished control"); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2433df96ddd6..5306b7a9e8c5 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4694,6 +4694,9 @@ public class PackageManagerService extends IPackageManager.Stub InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) { return; } + + // 11. Clear temp install session files + mInstallerService.freeStageDirs(volumeUuid, internalVolume); } else { try { mInstaller.freeCache(volumeUuid, bytes, 0, 0); |