Skip to content

Commit b70518c

Browse files
committed
Don't leak invalid pool before admin-permission
Avoids clients from learning if pools doesn't exist before they pass admin-permission event.
1 parent ccb5513 commit b70518c

1 file changed

Lines changed: 20 additions & 5 deletions

File tree

qubes/api/admin.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,9 +1590,14 @@ async def _vm_create(
15901590
invalid_template = True
15911591

15921592
invalid_label = False
1593-
for untrusted_param in untrusted_payload.decode(
1594-
"ascii", errors="strict"
1595-
).split(" "):
1593+
untrusted_invalid_pool_exc = False
1594+
try:
1595+
payload = untrusted_payload.decode("ascii", errors="strict")
1596+
except UnicodeDecodeError:
1597+
raise qubes.exc.ProtocolError(
1598+
"Parameters contains non-ASCII characters"
1599+
)
1600+
for untrusted_param in payload.split(" "):
15961601
untrusted_key, untrusted_value = untrusted_param.split("=", 1)
15971602
self.enforce(
15981603
untrusted_key not in kwargs, reason="Options must be unique"
@@ -1615,7 +1620,10 @@ async def _vm_create(
16151620
self.enforce(
16161621
pool is None, reason="Option 'pool' must be unique"
16171622
)
1618-
pool = self.app.get_pool(untrusted_value)
1623+
try:
1624+
pool = self.app.get_pool(untrusted_value)
1625+
except qubes.exc.QubesException as exc:
1626+
untrusted_invalid_pool_exc = exc
16191627

16201628
elif untrusted_key.startswith("pool:") and allow_pool:
16211629
untrusted_volume = untrusted_key.split(":", 1)[1]
@@ -1632,7 +1640,10 @@ async def _vm_create(
16321640
volume not in pools,
16331641
reason="Option 'pool:{}' must be unique".format(volume),
16341642
)
1635-
pools[volume] = self.app.get_pool(untrusted_value)
1643+
try:
1644+
pools[volume] = self.app.get_pool(untrusted_value)
1645+
except qubes.exc.QubesException as exc:
1646+
untrusted_invalid_pool_exc = exc
16361647

16371648
else:
16381649
if not allow_pool and (
@@ -1680,6 +1691,10 @@ async def _vm_create(
16801691
# logged.
16811692
raise qubes.exc.QubesLabelNotFoundError(label="untrusted label")
16821693

1694+
# Avoids leaking pool existence before admin-permission.
1695+
if untrusted_invalid_pool_exc:
1696+
raise untrusted_invalid_pool_exc
1697+
16831698
vm = self.app.add_new_vm(vm_class, **kwargs)
16841699
# TODO: move this to extension (in race-free fashion)
16851700
vm.tags.add("created-by-" + str(self.src))

0 commit comments

Comments
 (0)