fix: intercept BYO request under any caller UID

Shizuku-routed key attestation calls reach keystore2 with callingUid
set to shell (2000) or root (0) instead of the originating app's uid.
target.txt has no entry for those uids so shouldSkipUid returned true
in onPreTransact, and handleGenerateKey was never entered. The
transaction reached the real KeyMint HAL, which on older Keymaster 4.x
HALs rejects Tag::ATTEST_KEY with -49 UNSUPPORTED_TAG.

Move the shouldSkipUid gate from onPreTransact into handleGenerateKey
itself, evaluated after attestationKey and isAttestKeyRequest are
parsed. Skip only when the request is neither BYO nor attest-key-
purpose. CREATE_OPERATION keeps its outer-level gate (not part of the
BYO flow).

After this change, Shizuku-routed BYO requests enter dispatch, hit
forceGenerate=true via the prior simplification, and route to
doSoftwareKeyGen. Non-BYO non-attest calls from shell/root uids
still fall through to HAL unchanged.

D3 (option 2B) from /home/rootdev/.claude/plans/breezy-seeking-wozniak.md.
This commit is contained in:
Enginex0
2026-05-20 03:47:16 +01:00
parent f384871f5a
commit 76e033700c
@@ -70,18 +70,16 @@ class KeyMintSecurityLevelInterceptor(
callingPid: Int,
data: Parcel,
): TransactionResult {
val shouldSkip = ConfigurationManager.shouldSkipUid(callingUid)
when (code) {
GENERATE_KEY_TRANSACTION -> {
logTransaction(txId, transactionNames[code]!!, callingUid, callingPid)
if (!shouldSkip) return handleGenerateKey(txId, callingUid, callingPid, data)
return handleGenerateKey(txId, callingUid, callingPid, data)
}
CREATE_OPERATION_TRANSACTION -> {
logTransaction(txId, transactionNames[code]!!, callingUid, callingPid)
if (!shouldSkip) return handleCreateOperation(txId, callingUid, data)
if (!ConfigurationManager.shouldSkipUid(callingUid)) return handleCreateOperation(txId, callingUid, data)
}
IMPORT_KEY_TRANSACTION -> {
logTransaction(txId, transactionNames[code]!!, callingUid, callingPid)
@@ -430,6 +428,12 @@ class KeyMintSecurityLevelInterceptor(
)
val params = data.createTypedArray(KeyParameter.CREATOR)!!
val parsedParams = KeyMintAttestation(params)
val isAttestKeyRequest = parsedParams.isAttestKey()
if (ConfigurationManager.shouldSkipUid(callingUid)
&& attestationKey == null && !isAttestKeyRequest) {
return TransactionResult.ContinueAndSkipPost
}
SystemLogger.trace { "[TRACE-$txId] generateKey alias=${keyDescriptor.alias} algo=${parsedParams.algorithm} challenge=${parsedParams.attestationChallenge?.size ?: "null"} serial=${parsedParams.serial != null} imei=${parsedParams.imei != null} noAuth=${parsedParams.noAuthRequired} purposes=${parsedParams.purpose}" }
if (SystemLogger.isDebugBuild) params.forEach { p ->
@@ -490,7 +494,6 @@ class KeyMintSecurityLevelInterceptor(
}
val keyId = KeyIdentifier(callingUid, keyDescriptor.alias)
val isAttestKeyRequest = parsedParams.isAttestKey()
val forceGenerate =
oversized ||