Browse Source

qubespolicy: fix handling allow rule to '$dispvm'

When rule does not specify forced target (`target=...`), generic
`$dispvm` wasn't resolved to specific Disposable VM (based on
`default_dispvm` property).
Marek Marczykowski-Górecki 7 years ago
parent
commit
e8e30c8bdf
2 changed files with 22 additions and 0 deletions
  1. 9 0
      qubespolicy/__init__.py
  2. 13 0
      qubespolicy/tests/__init__.py

+ 9 - 0
qubespolicy/__init__.py

@@ -607,6 +607,15 @@ class Policy(object):
                     'policy define \'allow\' action at {}:{} but no target is '
                     'specified by caller or policy'.format(
                         rule.filename, rule.lineno))
+            if actual_target == '$dispvm':
+                if system_info['domains'][source]['default_dispvm'] is None:
+                    raise AccessDenied(
+                        'policy define \'allow\' action to $dispvm at {}:{} '
+                        'but no DispVM base is set for this VM'.format(
+                            rule.filename, rule.lineno))
+                actual_target = '$dispvm:' + \
+                    system_info['domains'][source]['default_dispvm']
+
             return PolicyAction(self.service, source,
                 actual_target, rule, target)
         else:

+ 13 - 0
qubespolicy/tests/__init__.py

@@ -725,6 +725,19 @@ class TC_20_Policy(qubes.tests.QubesTestCase):
                 'default-dvm', '$dispvm:default-dvm', 'test-invalid-dvm',
                 'test-no-dvm', 'test-template', 'test-standalone'])
 
+    def test_034_eval_resolve_dispvm(self):
+        with open(os.path.join(tmp_policy_dir, 'test.service'), 'w') as f:
+            f.write('test-vm3 $dispvm allow\n')
+
+        policy = qubespolicy.Policy('test.service', tmp_policy_dir)
+        action = policy.evaluate(system_info, 'test-vm3', '$dispvm')
+        self.assertEqual(action.rule, policy.policy_rules[0])
+        self.assertEqual(action.action, qubespolicy.Action.allow)
+        self.assertEqual(action.target, '$dispvm:default-dvm')
+        self.assertEqual(action.original_target, '$dispvm')
+        self.assertEqual(action.service, 'test.service')
+        self.assertIsNone(action.targets_for_ask)
+
 
 class TC_30_Misc(qubes.tests.QubesTestCase):
     @unittest.mock.patch('socket.socket')