Don't accidentially free provider when connecting to installation proxy

This commit is contained in:
Jackson Coxson
2025-03-24 19:09:24 -06:00
parent 3dd920cd4d
commit 715e777f72
3 changed files with 35 additions and 16 deletions

View File

@@ -26,7 +26,6 @@ int main() {
fprintf(stderr, "Failed to read pairing file: %d\n", err); fprintf(stderr, "Failed to read pairing file: %d\n", err);
return 1; return 1;
} }
printf("Read the pairing file");
// Create TCP provider // Create TCP provider
TcpProviderHandle *provider = NULL; TcpProviderHandle *provider = NULL;
@@ -62,11 +61,9 @@ int main() {
return 1; return 1;
} }
// Cast the result to plist_t array (assuming the binding returns plist_t) // Cast the result to plist_t array
plist_t *app_list = (plist_t *)apps; plist_t *app_list = (plist_t *)apps;
// Iterate through apps (this is a simplified example - you'd need proper
// plist handling)
printf("Found %zu apps:\n", apps_len); printf("Found %zu apps:\n", apps_len);
for (size_t i = 0; i < apps_len; i++) { for (size_t i = 0; i < apps_len; i++) {
plist_t app = app_list[i]; plist_t app = app_list[i];
@@ -82,7 +79,6 @@ int main() {
} }
// Cleanup // Cleanup
// Note: You'd need to properly free the plist array here
installation_proxy_client_free(client); installation_proxy_client_free(client);
tcp_provider_free(provider); tcp_provider_free(provider);

View File

@@ -31,16 +31,24 @@ pub unsafe extern "C" fn installation_proxy_connect_tcp(
provider: *mut TcpProviderHandle, provider: *mut TcpProviderHandle,
client: *mut *mut InstallationProxyClientHandle, client: *mut *mut InstallationProxyClientHandle,
) -> IdeviceErrorCode { ) -> IdeviceErrorCode {
if provider.is_null() { if provider.is_null() || client.is_null() {
log::error!("Provider is null"); log::error!("Null pointer provided");
return IdeviceErrorCode::InvalidArg; return IdeviceErrorCode::InvalidArg;
} }
let provider = unsafe { Box::from_raw(provider) }.0;
let res: Result<InstallationProxyClient, IdeviceError> = RUNTIME.block_on(async move { let res: Result<InstallationProxyClient, IdeviceError> = RUNTIME.block_on(async move {
let res = InstallationProxyClient::connect(&provider).await; // Take ownership of the provider (without immediately dropping it)
std::mem::forget(provider); let provider_box = unsafe { Box::from_raw(provider) };
res
// Get a reference to the inner value
let provider_ref = &provider_box.0;
// Connect using the reference
let result = InstallationProxyClient::connect(provider_ref).await;
// Explicitly keep the provider_box alive until after connect completes
std::mem::forget(provider_box);
result
}); });
match res { match res {
@@ -49,7 +57,12 @@ pub unsafe extern "C" fn installation_proxy_connect_tcp(
unsafe { *client = Box::into_raw(boxed) }; unsafe { *client = Box::into_raw(boxed) };
IdeviceErrorCode::IdeviceSuccess IdeviceErrorCode::IdeviceSuccess
} }
Err(e) => e.into(), Err(e) => {
// If connection failed, the provider_box was already forgotten,
// so we need to reconstruct it to avoid leak
let _ = unsafe { Box::from_raw(provider) };
e.into()
}
} }
} }
@@ -74,12 +87,20 @@ pub unsafe extern "C" fn installation_proxy_connect_usbmuxd(
log::error!("Provider is null"); log::error!("Provider is null");
return IdeviceErrorCode::InvalidArg; return IdeviceErrorCode::InvalidArg;
} }
let provider = unsafe { Box::from_raw(provider) }.0;
let res: Result<InstallationProxyClient, IdeviceError> = RUNTIME.block_on(async move { let res: Result<InstallationProxyClient, IdeviceError> = RUNTIME.block_on(async move {
let res = InstallationProxyClient::connect(&provider).await; // Take ownership of the provider (without immediately dropping it)
std::mem::forget(provider); let provider_box = unsafe { Box::from_raw(provider) };
res
// Get a reference to the inner value
let provider_ref = &provider_box.0;
// Connect using the reference
let result = InstallationProxyClient::connect(provider_ref).await;
// Explicitly keep the provider_box alive until after connect completes
std::mem::forget(provider_box);
result
}); });
match res { match res {
@@ -211,6 +232,7 @@ pub unsafe extern "C" fn installation_proxy_client_free(
handle: *mut InstallationProxyClientHandle, handle: *mut InstallationProxyClientHandle,
) { ) {
if !handle.is_null() { if !handle.is_null() {
log::debug!("Freeing installation_proxy_client");
let _ = unsafe { Box::from_raw(handle) }; let _ = unsafe { Box::from_raw(handle) };
} }
} }

View File

@@ -69,6 +69,7 @@ pub unsafe extern "C" fn idevice_tcp_provider_new(
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn tcp_provider_free(provider: *mut TcpProviderHandle) { pub unsafe extern "C" fn tcp_provider_free(provider: *mut TcpProviderHandle) {
if !provider.is_null() { if !provider.is_null() {
log::debug!("Freeing TCP provider");
unsafe { drop(Box::from_raw(provider)) }; unsafe { drop(Box::from_raw(provider)) };
} }
} }