From 5de215d54e9268bf1b7087fbd6114c1ecf91e616 Mon Sep 17 00:00:00 2001 From: Ali Mirjamali Date: Tue, 18 Feb 2025 01:20:21 +0330 Subject: [PATCH] Add the feature to prohibit starting of a qube fixes: https://github.com/QubesOS/qubes-issues/issues/9622 --- qubes/tests/integ/basic.py | 16 ++++++++++++++++ qubes/vm/qubesvm.py | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/qubes/tests/integ/basic.py b/qubes/tests/integ/basic.py index b798fd5c5..f39e01054 100644 --- a/qubes/tests/integ/basic.py +++ b/qubes/tests/integ/basic.py @@ -466,6 +466,22 @@ def test_206_shutdown_paused(self): self.loop.run_until_complete(self.vm.start()) self.shutdown_paused(self.vm) + def test_207_domain_start_prohibition(self): + vmname = self.make_vm_name("compromised_vm") + self.vm = self.app.add_new_vm( + qubes.vm.appvm.AppVM, + name=vmname, + template=self.app.default_template, + label="red", + ) + self.loop.run_until_complete(self.vm.create_on_disk()) + with self.assertRaises(qubes.exc.QubesException): + self.vm.features["prohibit-start"] = ( + "The qube is compromised and awaits forensic analysis" + ) + self.loop.run_until_complete(self.vm.start()) + self.assertFalse(self.vm.is_running()) + class TC_01_Properties(qubes.tests.SystemTestCase): # pylint: disable=attribute-defined-outside-init diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 8ce481d73..4375d7121 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -369,6 +369,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): .. event:: domain-start-failed (subject, event, reason) Fired when :py:meth:`start` method fails. + or if domain has a `prohibit-start` feature. *reason* argument is a textual error message. Handler for this event may be asynchronous. @@ -1302,6 +1303,17 @@ async def start( await self._ensure_shutdown_handled() + prohibit_rationale: str = self.features.get("prohibit-start", False) + if prohibit_rationale: + await self.fire_event_async( + "domain-start-failed", + reason="Qube start is prohibited. " + f"Rationale: {prohibit_rationale}", + ) + raise qubes.exc.QubesException( + f"Qube start is prohibited. Rationale: {prohibit_rationale}" + ) + self.log.info("Starting {}".format(self.name)) try: