Skip to content

Commit

Permalink
q-dev: fix detaching
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrbartman committed Oct 14, 2024
1 parent 540072f commit 63ae996
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 13 deletions.
22 changes: 10 additions & 12 deletions qubesusbproxy/core3ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,30 +658,28 @@ async def on_device_attach_usb(self, vm, event, device, options):
policy_line, False)

@qubes.ext.handler('device-pre-detach:usb')
async def on_device_detach_usb(self, vm, event, device):
async def on_device_detach_usb(self, vm, event, port):
# pylint: disable=unused-argument,no-self-use
if not vm.is_running() or vm.qid == 0:
return

if not isinstance(device, USBDevice):
return

connected_to = device.attachment
# detect race conditions; there is still race here, but much smaller
if connected_to is None or connected_to.qid != vm.qid:
for attached, options in self.on_device_list_attached(vm, event):
if attached.port == port:
break
else:
raise QubesUSBException(
"Device {!s} not connected to VM {}".format(
device, vm.name))
f"Device {port} not connected to VM {vm.name}")

# update the cache before the call, to avoid sending duplicated events
# (one on qubesdb watch and the other by the caller of this method)
self.devices_cache[device.backend_domain.name][device.port_id] = None
backend = attached
self.devices_cache[backend][attached.port_id] = None

try:
await device.backend_domain.run_service_for_stdio(
await backend.backend_domain.run_service_for_stdio(
'qubes.USBDetach',
user='root',
input='{}\n'.format(device.port_id).encode())
input='{}\n'.format(backend.port_id).encode())
except subprocess.CalledProcessError as e:
# TODO: sanitize and include stdout
raise QubesUSBException('Device detach failed')
Expand Down
2 changes: 1 addition & 1 deletion qubesusbproxy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def device_list_change(
for dev_id, front_vm in detached.items():
dev = device_class(vm, dev_id)
asyncio.ensure_future(front_vm.fire_event_async(
f'device-detach:{devclass}', device=dev))
f'device-detach:{devclass}', port=dev))
for dev_id in removed:
device = device_class(vm, dev_id)
vm.fire_event(f'device-removed:{devclass}', device=device)
Expand Down

0 comments on commit 63ae996

Please sign in to comment.