Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6935755f authored by Christopher Tate's avatar Christopher Tate
Browse files

Ensure backup doesn't reuse ack tokens nearby in time

We've seen at least one incident in the field that suggests we
used the same identifying token in back to back operations, which
breaks certain invariants in the asynchronous-completion bookkeeping.
Harden against this by making sure that we don't reuse tokens in
nearby proximity.  This is done by making the low 8 bits a sequence
count, i.e. guaranteed unique within the last 256 operations, while
keeping the upper bits random so that apps can't guess at correct
tokens.

Fix 63691912
Fix 63553575
Test: CTS backup pass to completion plus manual inspection

Change-Id: I321c3a2b3f4203836800bb72db7332bd82e54aaf
parent f99ac67b
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -123,8 +123,8 @@ import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
import com.android.server.power.BatterySaverPolicy.ServiceType;
import libcore.io.IoUtils;
import java.io.BufferedInputStream;
@@ -691,6 +691,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>();
    final Object mCurrentOpLock = new Object();
    final Random mTokenGenerator = new Random();
    final AtomicInteger mNextToken = new AtomicInteger();
    final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<AdbParams>();
@@ -763,15 +764,13 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    @GuardedBy("mQueueLock")
    ArrayList<FullBackupEntry> mFullBackupQueue;
    // Utility: build a new random integer token
    // Utility: build a new random integer token.  The low bits are the ordinal of the
    // operation for near-time uniqueness, and the upper bits are random for app-
    // side unpredictability.
    @Override
    public int generateRandomIntegerToken() {
        int token;
        do {
            synchronized (mTokenGenerator) {
                token = mTokenGenerator.nextInt();
            }
        } while (token < 0);
        int token = mTokenGenerator.nextInt() & ~0xFF;
        token |= (mNextToken.incrementAndGet() & 0xFF);
        return token;
    }