summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-11-12 05:36:39 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-11-12 05:36:39 +0000
commite9b725168c57cc542382e0796ac5c9ec76974b5d (patch)
tree938891084b74b2a80296b271a2f14f42a757362f
parent23b5774f9063cb0a17dfec2f4c1c222871d9a9c6 (diff)
parent4e9ea675434412180e95d24ac178c6130c616b18 (diff)
downloadbase-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
-rw-r--r--core/java/android/accounts/Account.java7
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java45
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3
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);