fix(interception): route oversized transactions to software gen

The 256KB native size guard skipped interception entirely for oversized
transactions, causing them to reach the real TEE which returns different
attestation values. This inconsistency is exactly what G10 detects.

Oversized requests now flow through to the Kotlin layer where they hit
doSoftwareKeyGen via the forceGenerate flag. Software gen produces
consistent attestation without forwarding to the real TEE, preserving
the anti-amplification defense that the original guard intended.
This commit is contained in:
Enginex0
2026-03-26 01:30:07 +01:00
parent 0b8985d8bd
commit 7a98b35666
2 changed files with 3 additions and 11 deletions
-6
View File
@@ -350,16 +350,10 @@ static sp<BinderStub> g_stub_instance = nullptr;
namespace {
constexpr binder_size_t kMaxInterceptableDataSize = 256 * 1024;
void inspectAndRewriteTransaction(binder_transaction_data *txn_data) {
if (!txn_data || txn_data->target.ptr == 0)
return;
// Bypass interception for oversized payloads to prevent thread starvation from flood attacks
if (txn_data->data_size > kMaxInterceptableDataSize)
return;
// AIDL methods use codes in [FIRST_CALL_TRANSACTION, LAST_CALL_TRANSACTION] (1..0x00ffffff).
// System transactions (PING, INTERFACE, DUMP, SHELL_COMMAND) use codes above that range.
// Skip those — intercepting a ping adds measurable latency that timing detectors flag.
@@ -403,10 +403,7 @@ class KeyMintSecurityLevelInterceptor(
}
private fun handleGenerateKey(txId: Long, callingUid: Int, callingPid: Int, data: Parcel): TransactionResult {
if (data.dataSize() > MAX_ALIAS_LENGTH) {
SystemLogger.warning("Skipping oversized transaction: ${data.dataSize()} bytes")
return TransactionResult.ContinueAndSkipPost
}
val oversized = data.dataSize() > MAX_ALIAS_LENGTH
return runCatching {
data.enforceInterface(IKeystoreSecurityLevel.DESCRIPTOR)
@@ -476,6 +473,7 @@ class KeyMintSecurityLevelInterceptor(
val isAttestKeyRequest = parsedParams.isAttestKey()
val forceGenerate =
oversized ||
ConfigurationManager.shouldGenerate(callingUid) ||
(ConfigurationManager.shouldPatch(callingUid) && isAttestKeyRequest) ||
(attestationKey != null &&