Skip to content

Commit cb49d11

Browse files
committed
Use serialization for qrexec argument
qrexec argument cannot have ':' nor '*'. Use function that avoids them. Fixes QubesOS/qubes-issues#10040
1 parent 64cbd8e commit cb49d11

File tree

6 files changed

+56
-54
lines changed

6 files changed

+56
-54
lines changed

qubesadmin/devices.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def _add(self, assignment: DeviceAssignment, action: str) -> None:
154154
self._vm.qubesd_call(
155155
None,
156156
f"admin.vm.device.{self._class}.{action.capitalize()}",
157-
repr(assignment),
157+
assignment.repr_for_qarg,
158158
assignment.serialize(),
159159
)
160160

@@ -179,7 +179,7 @@ def _remove(self, assignment: DeviceAssignment, action: str) -> None:
179179
self._vm.qubesd_call(
180180
None,
181181
f"admin.vm.device.{self._class}.{action.capitalize()}",
182-
repr(assignment),
182+
assignment.repr_for_qarg,
183183
)
184184

185185
def get_dedicated_devices(self) -> Iterable[DeviceAssignment]:
@@ -266,7 +266,9 @@ def get_exposed_devices(self) -> Iterable[DeviceInfo]:
266266
expected_devclass=self._class,
267267
)
268268

269-
def update_assignment(self, device: Port, required: AssignmentMode):
269+
def update_assignment(
270+
self, device: VirtualDevice, required: AssignmentMode
271+
):
270272
"""
271273
Update assignment of already attached device.
272274
@@ -279,7 +281,7 @@ def update_assignment(self, device: Port, required: AssignmentMode):
279281
self._vm.qubesd_call(
280282
None,
281283
"admin.vm.device.{}.Set.assignment".format(self._class),
282-
repr(device),
284+
device.repr_for_qarg,
283285
required.value.encode("utf-8"),
284286
)
285287
self._assignment_cache = None

qubesadmin/tests/app.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,13 @@ def test_043_clone_devices(self):
751751
b"backend_domain='test-vm3' mode='required'\n")
752752

753753
self.app.expected_calls[
754-
('new-name', 'admin.vm.device.pci.Assign', 'test-vm2+dev1:*',
754+
('new-name', 'admin.vm.device.pci.Assign', 'test-vm2+dev1+_',
755755
b"device_id='*' port_id='dev1' "
756756
b"devclass='pci' backend_domain='test-vm2' mode='required' "
757757
b"frontend_domain='new-name' _ro='yes'")] = b'0\0'
758758

759759
self.app.expected_calls[
760-
('new-name', 'admin.vm.device.pci.Assign', 'test-vm3+dev2:*',
760+
('new-name', 'admin.vm.device.pci.Assign', 'test-vm3+dev2+_',
761761
b"device_id='*' port_id='dev2' "
762762
b"devclass='pci' backend_domain='test-vm3' mode='required' "
763763
b"frontend_domain='new-name'")] = b'0\0'
@@ -798,13 +798,13 @@ def test_044_clone_devices_fail(self):
798798
b"backend_domain='test-vm3' mode='required'\n")
799799

800800
self.app.expected_calls[
801-
('new-name', 'admin.vm.device.pci.Assign', 'test-vm2+dev1:*',
801+
('new-name', 'admin.vm.device.pci.Assign', 'test-vm2+dev1+_',
802802
b"device_id='*' port_id='dev1' "
803803
b"devclass='pci' backend_domain='test-vm2' mode='required' "
804804
b"frontend_domain='new-name' _ro='yes'")] = b'0\0'
805805

806806
self.app.expected_calls[
807-
('new-name', 'admin.vm.device.pci.Assign', 'test-vm3+dev2:*',
807+
('new-name', 'admin.vm.device.pci.Assign', 'test-vm3+dev2+_',
808808
b"device_id='*' port_id='dev2' "
809809
b"devclass='pci' backend_domain='test-vm3' mode='required' "
810810
b"frontend_domain='new-name'")] = \

qubesadmin/tests/backup/backupcompatibility.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,7 +1480,7 @@ def setup_expected_calls(self, parsed_qubes_xml, templates_map=None):
14801480
f"frontend_domain='{name}'".encode())
14811481
self.app.expected_calls[
14821482
(name, 'admin.vm.device.{}.Assign'.format(bus),
1483-
'{}+{}:*'.format(backend_domain, port_id),
1483+
'{}+{}+_'.format(backend_domain, port_id),
14841484
encoded_options)] = b'0\0'
14851485

14861486
for feature, value in vm['features'].items():

qubesadmin/tests/devices.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def test_011_getitem_missing(self):
117117

118118
def test_020_attach(self):
119119
self.app.expected_calls[
120-
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1:*',
120+
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1+_',
121121
b"device_id='*' port_id='dev1' devclass='test' "
122122
b"backend_domain='test-vm2' mode='manual' "
123123
b"frontend_domain='test-vm'")] = \
@@ -129,7 +129,7 @@ def test_020_attach(self):
129129

130130
def test_021_attach_options(self):
131131
self.app.expected_calls[
132-
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1:*',
132+
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1+_',
133133
b"device_id='*' port_id='dev1' devclass='test' "
134134
b"backend_domain='test-vm2' mode='manual' "
135135
b"frontend_domain='test-vm' _ro='True' "
@@ -143,7 +143,7 @@ def test_021_attach_options(self):
143143

144144
def test_022_attach_required(self):
145145
self.app.expected_calls[
146-
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1:*',
146+
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1+_',
147147
b"device_id='*' port_id='dev1' devclass='test' "
148148
b"backend_domain='test-vm2' mode='required' "
149149
b"frontend_domain='test-vm'")] = b'0\0'
@@ -155,7 +155,7 @@ def test_022_attach_required(self):
155155

156156
def test_023_attach_required_options(self):
157157
self.app.expected_calls[
158-
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1:*',
158+
('test-vm', 'admin.vm.device.test.Attach', 'test-vm2+dev1+_',
159159
b"device_id='*' port_id='dev1' devclass='test' "
160160
b"backend_domain='test-vm2' mode='required' "
161161
b"frontend_domain='test-vm' _ro='True'")] = b'0\0'
@@ -168,7 +168,7 @@ def test_023_attach_required_options(self):
168168

169169
def test_030_detach(self):
170170
self.app.expected_calls[
171-
('test-vm', 'admin.vm.device.test.Detach', 'test-vm2+dev1:*',
171+
('test-vm', 'admin.vm.device.test.Detach', 'test-vm2+dev1+_',
172172
None)] = b'0\0'
173173
assign = DeviceAssignment.new(
174174
self.app.domains['test-vm2'], 'dev1', devclass='test')
@@ -333,7 +333,7 @@ def test_060_attached(self):
333333
def test_070_update_assignment_required(self):
334334
self.app.expected_calls[
335335
('test-vm', 'admin.vm.device.test.Set.assignment',
336-
'test-vm2+dev1:*', b'required')] = b'0\0'
336+
'test-vm2+dev1+_', b'required')] = b'0\0'
337337
dev = DeviceAssignment.new(
338338
self.app.domains['test-vm2'], devclass='test', port_id='dev1')
339339
self.vm.devices['test'].update_assignment(dev, AssignmentMode.REQUIRED)
@@ -342,7 +342,7 @@ def test_070_update_assignment_required(self):
342342
def test_071_update_assignment_ask(self):
343343
self.app.expected_calls[
344344
('test-vm', 'admin.vm.device.test.Set.assignment',
345-
'test-vm2+dev1:*', b'ask-to-attach')] = b'0\0'
345+
'test-vm2+dev1+_', b'ask-to-attach')] = b'0\0'
346346
dev = DeviceAssignment.new(
347347
self.app.domains['test-vm2'], devclass='test', port_id='dev1')
348348
self.vm.devices['test'].update_assignment(dev, AssignmentMode.ASK)
@@ -351,7 +351,7 @@ def test_071_update_assignment_ask(self):
351351
def test_072_update_assignment_auto(self):
352352
self.app.expected_calls[
353353
('test-vm', 'admin.vm.device.test.Set.assignment',
354-
'test-vm2+dev1:*', b'auto-attach')] = b'0\0'
354+
'test-vm2+dev1+_', b'auto-attach')] = b'0\0'
355355
dev = DeviceAssignment.new(
356356
self.app.domains['test-vm2'], devclass='test', port_id='dev1')
357357
self.vm.devices['test'].update_assignment(dev, AssignmentMode.AUTO)

qubesadmin/tests/tools/qvm_device.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def test_010_attach(self):
215215
""" Test attach action """
216216
self.app.expected_calls[(
217217
'test-vm2', 'admin.vm.device.testclass.Attach',
218-
'test-vm1+dev1:dead:beef:babe:u012345',
218+
'test-vm1+dev1+dead+beef+babe+u012345',
219219
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
220220
b"devclass='testclass' backend_domain='test-vm1' mode='manual' "
221221
b"frontend_domain='test-vm2'")] = b'0\0'
@@ -227,7 +227,7 @@ def test_011_attach_options(self):
227227
""" Test `read-only` attach option """
228228
self.app.expected_calls[(
229229
'test-vm2', 'admin.vm.device.testclass.Attach',
230-
'test-vm1+dev1:dead:beef:babe:u012345',
230+
'test-vm1+dev1+dead+beef+babe+u012345',
231231
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
232232
b"devclass='testclass' backend_domain='test-vm1' mode='manual' "
233233
b"frontend_domain='test-vm2' _read-only='yes'")] = b'0\0'
@@ -277,7 +277,7 @@ def test_020_detach(self):
277277
""" Test detach action """
278278
self.app.expected_calls[
279279
('test-vm2', 'admin.vm.device.testclass.Detach',
280-
'test-vm1+dev1:dead:beef:babe:u012345', None)] = b'0\0'
280+
'test-vm1+dev1+dead+beef+babe+u012345', None)] = b'0\0'
281281
qubesadmin.tools.qvm_device.main(
282282
['testclass', 'detach', 'test-vm2', 'test-vm1:dev1'], app=self.app)
283283
self.assertAllCalled()
@@ -286,7 +286,7 @@ def test_021_detach_unknown(self):
286286
""" Test detach action """
287287
self.app.expected_calls[
288288
('test-vm2', 'admin.vm.device.testclass.Detach',
289-
'test-vm1+dev7:0000:0000::?******', None)] = b'0\0'
289+
'test-vm1+dev7+0000+0000++_______', None)] = b'0\0'
290290
qubesadmin.tools.qvm_device.main(
291291
['testclass', 'detach', 'test-vm2', 'test-vm1:dev7'], app=self.app)
292292
self.assertAllCalled()
@@ -298,10 +298,10 @@ def test_022_detach_all(self):
298298
b'0\0test-vm1+dev1\ntest-vm1+dev2\n'
299299
self.app.expected_calls[
300300
('test-vm2', 'admin.vm.device.testclass.Detach',
301-
'test-vm1+dev1:*', None)] = b'0\0'
301+
'test-vm1+dev1+_', None)] = b'0\0'
302302
self.app.expected_calls[
303303
('test-vm2', 'admin.vm.device.testclass.Detach',
304-
'test-vm1+dev2:*', None)] = b'0\0'
304+
'test-vm1+dev2+_', None)] = b'0\0'
305305
qubesadmin.tools.qvm_device.main(
306306
['testclass', 'detach', 'test-vm2'], app=self.app)
307307
self.assertAllCalled()
@@ -311,7 +311,7 @@ def test_030_assign(self):
311311
self.app.domains['test-vm2'].is_running = lambda: True
312312
self.app.expected_calls[(
313313
'test-vm2', 'admin.vm.device.testclass.Assign',
314-
'test-vm1+dev1:dead:beef:babe:u012345',
314+
'test-vm1+dev1+dead+beef+babe+u012345',
315315
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
316316
b"devclass='testclass' backend_domain='test-vm1' "
317317
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -334,7 +334,7 @@ def test_031_assign_required(self):
334334
self.app.domains['test-vm2'].is_running = lambda: True
335335
self.app.expected_calls[(
336336
'test-vm2', 'admin.vm.device.testclass.Assign',
337-
'test-vm1+dev1:dead:beef:babe:u012345',
337+
'test-vm1+dev1+dead+beef+babe+u012345',
338338
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
339339
b"devclass='testclass' backend_domain='test-vm1' mode='required' "
340340
b"frontend_domain='test-vm2'"
@@ -358,7 +358,7 @@ def test_032_assign_ask_and_options(self):
358358
self.app.domains['test-vm2'].is_running = lambda: True
359359
self.app.expected_calls[(
360360
'test-vm2', 'admin.vm.device.testclass.Assign',
361-
'test-vm1+dev1:dead:beef:babe:u012345',
361+
'test-vm1+dev1+dead+beef+babe+u012345',
362362
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
363363
b"devclass='testclass' backend_domain='test-vm1' "
364364
b"mode='ask-to-attach' frontend_domain='test-vm2' _read-only='yes'"
@@ -418,7 +418,7 @@ def test_036_assign_port(self):
418418
self.app.domains['test-vm2'].is_running = lambda: True
419419
self.app.expected_calls[(
420420
'test-vm2', 'admin.vm.device.testclass.Assign',
421-
'test-vm1+dev1:*',
421+
'test-vm1+dev1+_',
422422
b"device_id='*' port_id='dev1' "
423423
b"devclass='testclass' backend_domain='test-vm1' "
424424
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -442,7 +442,7 @@ def test_037_assign_port_asterisk(self):
442442
self.app.domains['test-vm2'].is_running = lambda: True
443443
self.app.expected_calls[(
444444
'test-vm2', 'admin.vm.device.testclass.Assign',
445-
'test-vm1+dev1:*',
445+
'test-vm1+dev1+_',
446446
b"device_id='*' port_id='dev1' "
447447
b"devclass='testclass' backend_domain='test-vm1' "
448448
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -466,7 +466,7 @@ def test_038_assign_device_from_port(self):
466466
self.app.domains['test-vm2'].is_running = lambda: True
467467
self.app.expected_calls[(
468468
'test-vm2', 'admin.vm.device.testclass.Assign',
469-
'test-vm1+*:dead:beef:babe:u012345',
469+
'test-vm1+_+dead+beef+babe+u012345',
470470
b"device_id='dead:beef:babe:u012345' port_id='*' "
471471
b"devclass='testclass' backend_domain='test-vm1' "
472472
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -490,7 +490,7 @@ def test_039_assign_explicit_device(self):
490490
self.app.domains['test-vm2'].is_running = lambda: True
491491
self.app.expected_calls[(
492492
'test-vm2', 'admin.vm.device.testclass.Assign',
493-
'test-vm1+dev1:cafe:cafe::0123456u654321',
493+
'test-vm1+dev1+cafe+cafe++0123456u654321',
494494
b"device_id='cafe:cafe::0123456u654321' port_id='dev1' "
495495
b"devclass='testclass' backend_domain='test-vm1' "
496496
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -511,7 +511,7 @@ def test_040_assign_explicit_device_device_id(self):
511511
self.app.domains['test-vm2'].is_running = lambda: True
512512
self.app.expected_calls[(
513513
'test-vm2', 'admin.vm.device.testclass.Assign',
514-
'test-vm1+*:cafe:cafe::0123456u654321',
514+
'test-vm1+_+cafe+cafe++0123456u654321',
515515
b"device_id='cafe:cafe::0123456u654321' port_id='*' "
516516
b"devclass='testclass' backend_domain='test-vm1' "
517517
b"mode='auto-attach' frontend_domain='test-vm2'"
@@ -533,7 +533,7 @@ def test_041_assign_denied_device(self):
533533
self.app.domains['test-vm2'].is_running = lambda: False
534534
self.app.expected_calls[(
535535
'test-vm2', 'admin.vm.device.testclass.Assign',
536-
'test-vm1+dev1:dead:beef:babe:u012345',
536+
'test-vm1+dev1+dead+beef+babe+u012345',
537537
b"device_id='dead:beef:babe:u012345' port_id='dev1' "
538538
b"devclass='testclass' backend_domain='test-vm1' "
539539
b"mode='ask-to-attach' frontend_domain='test-vm2'"
@@ -555,7 +555,7 @@ def test_050_unassign(self):
555555
""" Test unassign action """
556556
self.app.expected_calls[
557557
('test-vm2', 'admin.vm.device.testclass.Unassign',
558-
'test-vm1+dev1:dead:beef:babe:u012345', None)] = b'0\0'
558+
'test-vm1+dev1+dead+beef+babe+u012345', None)] = b'0\0'
559559
self.app.expected_calls[(
560560
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
561561
)] = b'0\0'
@@ -568,7 +568,7 @@ def test_051_unassign_unknown(self):
568568
""" Test unassign action """
569569
self.app.expected_calls[
570570
('test-vm2', 'admin.vm.device.testclass.Unassign',
571-
'test-vm1+dev7:0000:0000::?******', None)] = b'0\0'
571+
'test-vm1+dev7+0000+0000++_______', None)] = b'0\0'
572572
self.app.expected_calls[(
573573
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
574574
)] = b'0\0'
@@ -581,7 +581,7 @@ def test_052_unassign_port(self):
581581
""" Test unassign action """
582582
self.app.expected_calls[
583583
('test-vm2', 'admin.vm.device.testclass.Unassign',
584-
'test-vm1+dev1:*', None)] = b'0\0'
584+
'test-vm1+dev1+_', None)] = b'0\0'
585585
self.app.expected_calls[(
586586
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
587587
)] = b'0\0'
@@ -594,7 +594,7 @@ def test_053_unassign_device_from_port(self):
594594
""" Test unassign action """
595595
self.app.expected_calls[
596596
('test-vm2', 'admin.vm.device.testclass.Unassign',
597-
'test-vm1+*:dead:beef:babe:u012345', None)] = b'0\0'
597+
'test-vm1+_+dead+beef+babe+u012345', None)] = b'0\0'
598598
self.app.expected_calls[(
599599
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
600600
)] = b'0\0'
@@ -607,7 +607,7 @@ def test_054_unassign_explicit_device(self):
607607
""" Test unassign action """
608608
self.app.expected_calls[
609609
('test-vm2', 'admin.vm.device.testclass.Unassign',
610-
'test-vm1+dev1:dead:beef:babe:u0123456', None)] = b'0\0'
610+
'test-vm1+dev1+dead+beef+babe+u0123456', None)] = b'0\0'
611611
qubesadmin.tools.qvm_device.main(
612612
['testclass', 'unassign', 'test-vm2',
613613
'test-vm1:dev1:dead:beef:babe:u0123456'], app=self.app)
@@ -617,7 +617,7 @@ def test_055_unassign_explicit_device_port(self):
617617
""" Test unassign action """
618618
self.app.expected_calls[
619619
('test-vm2', 'admin.vm.device.testclass.Unassign',
620-
'test-vm1+dev1:*', None)] = b'0\0'
620+
'test-vm1+dev1+_', None)] = b'0\0'
621621
self.app.expected_calls[(
622622
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
623623
)] = b'0\0'
@@ -630,7 +630,7 @@ def test_056_unassign_explicit_device_id(self):
630630
""" Test unassign action """
631631
self.app.expected_calls[
632632
('test-vm2', 'admin.vm.device.testclass.Unassign',
633-
'test-vm1+*:cafe:cafe::0123456u654321', None)] = b'0\0'
633+
'test-vm1+_+cafe+cafe++0123456u654321', None)] = b'0\0'
634634
qubesadmin.tools.qvm_device.main(
635635
['testclass', 'unassign', 'test-vm2',
636636
'test-vm1:dev1:cafe:cafe::0123456u654321', '--device'],
@@ -645,10 +645,10 @@ def test_057_unassign_all(self):
645645
b"test-vm1+dev2 devclass='testclass'\n")
646646
self.app.expected_calls[
647647
('test-vm2', 'admin.vm.device.testclass.Unassign',
648-
'test-vm1+dev1:*', None)] = b'0\0'
648+
'test-vm1+dev1+_', None)] = b'0\0'
649649
self.app.expected_calls[
650650
('test-vm2', 'admin.vm.device.testclass.Unassign',
651-
'test-vm1+dev2:*', None)] = b'0\0'
651+
'test-vm1+dev2+_', None)] = b'0\0'
652652
self.app.expected_calls[(
653653
'test-vm2', 'admin.vm.device.testclass.Attached', None, None
654654
)] = b'0\0'

0 commit comments

Comments
 (0)