frida / frida-rust

Frida Rust bindings
Other
188 stars 53 forks source link

`DeviceManager` is not being dropped properly #164

Closed Xoffio closed 1 month ago

Xoffio commented 1 month ago

I have a function like the next one:

#[tauri::command(async)]
fn get_pids() -> Result<Vec<(u32, String)>, String> {
    let device_manager = frida::DeviceManager::obtain(&FRIDA);
    let local_device = match device_manager.get_device_by_type(frida::DeviceType::Local) {
        Ok(device) => device,
        Err(err) => {
            return Err(format!("{}", err));
        }
    };

    let processes: Vec<(u32, String)> = local_device
        .enumerate_processes()
        .iter()
        .map(|process| (process.get_pid(), process.get_name().to_string()))
        .collect();

    Ok(processes)
}

If I execute that function multiple times I get the error shared memfd open() failed: Too many open files and my app crashes.

I decided to check the open files with lsof -u <USER> 2>/dev/null | grep -E "<APP_NAME>" | wc -l) and noticed that around 4 FIFO files gets open and they never get deleted until it reaches the maximum number of file descriptor in the system.

I noticed that frida-node calls frida_device_manager_close when dropping DeviceManager ref here, and here. We are currently not calling frida_device_manager_close in rust.

The next code seems to be working.

impl<'a> Drop for DeviceManager<'a> {
    fn drop(&mut self) {
        let mut error: *mut frida_sys::GError = std::ptr::null_mut();
        unsafe {
            frida_sys::frida_device_manager_close_sync(
                self.manager_ptr,
                std::ptr::null_mut(),
                &mut error,
            );

            frida_sys::frida_unref(self.manager_ptr as _)
        }
    }
}

I will be creating a PR for this.