From c122ded7bf96eb566c355d4f4ddd623ce05dcec6 Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Wed, 11 Mar 2026 12:41:57 +0100 Subject: [PATCH] perf(daemon): add restart backoff, process priority, and map eviction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supervisor had zero-delay restart on crash loops — pins CPU core at 100% if daemon keeps dying. Add exponential backoff (500ms to 30s cap, resets after 30s stable). Set nice=10 on daemon child to yield CPU to foreground apps. Evict stale entries from fileLocks and rate limiter ConcurrentHashMaps that grew unbounded. Upload pre-built flashable zips in CI instead of unpacking and re-compressing loose files. --- .github/workflows/build.yml | 6 ++++-- app/src/main/cpp/supervisor.cpp | 21 ++++++++++++++++++- .../keystore/shim/GeneratedKeyPersistence.kt | 2 ++ .../shim/KeyMintSecurityLevelInterceptor.kt | 4 ++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7de98f5..2e7ade9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,8 +92,8 @@ jobs: cp "$RELEASE_FILE" "out/TEESimulator-${VER}-Release.zip" cp "$DEBUG_FILE" "out/TEESimulator-${VER}-Debug.zip" - echo "Release: $(basename "$RELEASE_FILE") -> TEESimulator-${VER}-Release.zip" - echo "Debug: $(basename "$DEBUG_FILE") -> TEESimulator-${VER}-Debug.zip" + echo "Release: $(basename "$RELEASE_FILE") -> TEESimulator-${VER}-Release.zip ($(du -h "$RELEASE_FILE" | cut -f1))" + echo "Debug: $(basename "$DEBUG_FILE") -> TEESimulator-${VER}-Debug.zip ($(du -h "$DEBUG_FILE" | cut -f1))" env: VER: ${{ steps.ver.outputs.version }} @@ -102,12 +102,14 @@ jobs: name: TEESimulator-release-zip path: out/TEESimulator-*-Release.zip retention-days: 30 + compression-level: 0 - uses: actions/upload-artifact@v4 with: name: TEESimulator-debug-zip path: out/TEESimulator-*-Debug.zip retention-days: 7 + compression-level: 0 - uses: actions/upload-artifact@v4 with: diff --git a/app/src/main/cpp/supervisor.cpp b/app/src/main/cpp/supervisor.cpp index ada8000..104c264 100644 --- a/app/src/main/cpp/supervisor.cpp +++ b/app/src/main/cpp/supervisor.cpp @@ -2,11 +2,13 @@ #include #include #include +#include #include #include #include #include #include +#include static volatile sig_atomic_t should_exit = 0; @@ -27,7 +29,12 @@ int main(int argc, char *argv[]) { const char *daemon_path = argv[1]; char **daemon_argv = &argv[1]; + int backoff_ms = 500; + while (!should_exit) { + struct timespec child_start; + clock_gettime(CLOCK_MONOTONIC, &child_start); + pid_t pid = fork(); if (pid < 0) { @@ -39,6 +46,7 @@ int main(int argc, char *argv[]) { if (pid == 0) { // Child: become the daemon prctl(PR_SET_PDEATHSIG, SIGKILL); // Die if parent dies + setpriority(PRIO_PROCESS, 0, 10); // lower CPU priority than foreground execv(daemon_path, daemon_argv); perror("execv failed"); _exit(127); @@ -50,7 +58,18 @@ int main(int argc, char *argv[]) { if (should_exit) break; - // Instant restart - no delay + // Exponential backoff on rapid crashes, reset if child was stable + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + long lived_ms = (now.tv_sec - child_start.tv_sec) * 1000 + + (now.tv_nsec - child_start.tv_nsec) / 1000000; + + if (lived_ms > 30000) { + backoff_ms = 500; + } else { + usleep(backoff_ms * 1000); + if (backoff_ms < 30000) backoff_ms *= 2; + } } return 0; diff --git a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/GeneratedKeyPersistence.kt b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/GeneratedKeyPersistence.kt index 7807190..07c57d8 100644 --- a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/GeneratedKeyPersistence.kt +++ b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/GeneratedKeyPersistence.kt @@ -129,6 +129,7 @@ object GeneratedKeyPersistence { val file = File(PERSISTENCE_DIR, keyFileName(keyId.uid, keyId.alias)) if (file.exists()) { if (file.delete()) { + fileLocks.remove(keyFileName(keyId.uid, keyId.alias)) SystemLogger.debug("Deleted persisted key: $keyId") } else { SystemLogger.warning("Failed to delete persisted key file: ${file.name}") @@ -158,6 +159,7 @@ object GeneratedKeyPersistence { if (file.delete()) count++ } } + fileLocks.clear() SystemLogger.info("Deleted $count persisted key files") }.onFailure { e -> SystemLogger.error("Failed to delete all persisted keys", e) diff --git a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt index aadcad8..7a99ba9 100644 --- a/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt +++ b/app/src/main/java/org/matrix/TEESimulator/interception/keystore/shim/KeyMintSecurityLevelInterceptor.kt @@ -546,6 +546,10 @@ class KeyMintSecurityLevelInterceptor( val timestamps = uidKeygenTimestamps.computeIfAbsent(uid) { mutableListOf() } synchronized(timestamps) { timestamps.removeAll { now - it > BURST_WINDOW_MS } + if (timestamps.isEmpty()) { + uidKeygenTimestamps.remove(uid, timestamps) + uidHardwareKeygenCount.remove(uid) + } return timestamps.size } }