Prevent recursion when configured to intercept system UID (#100)
When the TEESimulator is configured to intercept UID 1000, accessing the `lazy` `bootKey` property causes a StackOverflowError. The property's initializer sends a key generation request (UID 0) to probe real hardware. Previously, the C++ layer hijacked this request and spoofed it to UID 1000. This sent the request back to the Kotlin interceptor (if configured so), which attempted to access `bootKey` again to build the response, creating an infinite loop. This change spoofs UID 0 requests to 1000 (to pass Keystore permissions) but explicitly bypasses hijacking, ensuring the probe request hits the real hardware.
This commit is contained in:
@@ -359,9 +359,15 @@ void inspectAndRewriteTransaction(binder_transaction_data *txn_data) {
|
|||||||
info.transaction_code = intercept::kBackdoorCode;
|
info.transaction_code = intercept::kBackdoorCode;
|
||||||
info.target_binder = nullptr;
|
info.target_binder = nullptr;
|
||||||
hijack = true;
|
hijack = true;
|
||||||
}
|
// Check 2: Spoof uid of KeyStore requests from the daemon to bypass permission check
|
||||||
// Check 2: Normal interception based on registry of monitored binders
|
} else if (txn_data->sender_euid == 0) {
|
||||||
else {
|
// The kernel driver fills sender_euid.
|
||||||
|
// libbinder.so trusts this value to populate IPCThreadState.
|
||||||
|
txn_data->sender_euid = 1000;
|
||||||
|
LOGV("[Hook] Spoofing UID for transaction: 0 -> %d", txn_data->sender_euid);
|
||||||
|
hijack = false; // Never hijack to avoid recursion
|
||||||
|
// Check 3: Normal interception based on registry of monitored binders
|
||||||
|
} else {
|
||||||
// Safe casting based on Binder driver ABI
|
// Safe casting based on Binder driver ABI
|
||||||
RefBase::weakref_type *weak_ref = reinterpret_cast<RefBase::weakref_type *>(txn_data->target.ptr);
|
RefBase::weakref_type *weak_ref = reinterpret_cast<RefBase::weakref_type *>(txn_data->target.ptr);
|
||||||
|
|
||||||
@@ -386,15 +392,6 @@ void inspectAndRewriteTransaction(binder_transaction_data *txn_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hijack) {
|
if (hijack) {
|
||||||
// The kernel driver fills sender_euid. libbinder trusts this value
|
|
||||||
// to populate IPCThreadState. By changing it here, we fool the
|
|
||||||
// entire process (including the TEE implementation) into thinking
|
|
||||||
// the call came from system (1000).
|
|
||||||
if (txn_data->sender_euid == 0) {
|
|
||||||
LOGV("[Hook] Spoofing UID for transaction: 0 -> 1000");
|
|
||||||
txn_data->sender_euid = 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t tx_id = ++g_transaction_id_counter;
|
uint64_t tx_id = ++g_transaction_id_counter;
|
||||||
info.transaction_id = tx_id;
|
info.transaction_id = tx_id;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user