From 4971f7b4a5069dc891b2dbd328ad5348d679145e Mon Sep 17 00:00:00 2001 From: Enginex0 Date: Fri, 6 Feb 2026 21:10:31 +0100 Subject: [PATCH] Derive boot and vendor patch levels from system prop when system=prop TrickyAddon fetches Pixel bulletin dates for boot/vendor but system=prop resolves to the real device prop, creating a cross-component date mismatch on non-Pixel devices. Force all three through the same prop resolution path. --- .../TEESimulator/attestation/AttestationBuilder.kt | 1 + .../matrix/TEESimulator/config/ConfigurationManager.kt | 9 ++++++++- .../org/matrix/TEESimulator/util/AndroidDeviceUtils.kt | 7 ++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationBuilder.kt b/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationBuilder.kt index 277100a..06027cd 100644 --- a/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationBuilder.kt +++ b/app/src/main/java/org/matrix/TEESimulator/attestation/AttestationBuilder.kt @@ -112,6 +112,7 @@ object AttestationBuilder { } val bootPatch = AndroidDeviceUtils.getBootPatchLevelLong(uid) + SystemLogger.info("Attestation patch levels for uid=$uid: os=$osPatch, vendor=$vendorPatch, boot=$bootPatch") properties[AttestationConstants.TAG_BOOT_PATCHLEVEL] = if (bootPatch != DO_NOT_REPORT) { DERTaggedObject( diff --git a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt index adea22a..8d73e11 100644 --- a/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt +++ b/app/src/main/java/org/matrix/TEESimulator/config/ConfigurationManager.kt @@ -253,7 +253,14 @@ object ConfigurationManager { } // Parse global and per-package configurations. - val newGlobalLevel = parseLines(contextLines[""]) + var newGlobalLevel = parseLines(contextLines[""]) + // TrickyAddon writes Pixel bulletin dates for boot/vendor but system=prop + // resolves to the real device prop — force boot/vendor through the same path + // to prevent cross-component date mismatches on non-Pixel devices. + if (newGlobalLevel?.system.equals("prop", ignoreCase = true)) { + SystemLogger.info("system=prop: forcing boot/vendor to derive from device props (were: boot=${newGlobalLevel?.boot}, vendor=${newGlobalLevel?.vendor})") + newGlobalLevel = newGlobalLevel?.copy(boot = "prop", vendor = "prop") + } contextLines.remove("") // Remove global context to iterate over packages next for ((pkg, lines) in contextLines) { diff --git a/app/src/main/java/org/matrix/TEESimulator/util/AndroidDeviceUtils.kt b/app/src/main/java/org/matrix/TEESimulator/util/AndroidDeviceUtils.kt index 3874db3..e9a5e62 100644 --- a/app/src/main/java/org/matrix/TEESimulator/util/AndroidDeviceUtils.kt +++ b/app/src/main/java/org/matrix/TEESimulator/util/AndroidDeviceUtils.kt @@ -239,11 +239,12 @@ object AndroidDeviceUtils { val resolvedValue = resolveDateKeywords(value) return when { - // "device_default" indicates falling back to the system property. resolvedValue.equals("device_default", ignoreCase = true) -> null - // "no" indicates this value should not be reported. + // Resolve from live system prop — matches what detectors see via getprop, + // even when PIF has spoofed ro.build.version.security_patch via resetprop + resolvedValue.equals("prop", ignoreCase = true) -> + parsePatchLevelValue(SystemProperties.get("ro.build.version.security_patch", ""), isLong) resolvedValue.equals("no", ignoreCase = true) -> DO_NOT_REPORT - // Otherwise, parse the resolved date string. else -> parsePatchLevelValue(resolvedValue, isLong) } }