Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qubes.OpenInVM * @anyvm @dispvm ask default_target=@dispvm:[...] causes AssertionError #7720

Closed
andrewdavidwong opened this issue Aug 29, 2022 · 9 comments
Labels
affects-4.1 This issue affects Qubes OS 4.1. C: core diagnosed Technical diagnosis has been performed (see issue comments). P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists.

Comments

@andrewdavidwong
Copy link
Member

andrewdavidwong commented Aug 29, 2022

How to file a helpful issue

Qubes OS release

4.1.1

Brief summary

Attempting to open a file in a non-global-default disposable with an ask default_target=[...] policy fails.

Steps to reproduce

  1. Create a disposable template named dvm-default.
  2. In Qubes Global Settings, set dvm-default as the default disposable template.
  3. Specify these policy rules in /etc/qubes/policy.d/30-user.policy in dom0:
    qubes.OpenInVM  *  @anyvm  @dispvm  ask default_target=@dispvm:dvm-default
    qubes.OpenInVM  *  @anyvm  @anyvm   deny
    
  4. Create another disposable template called dvm-other.
  5. Create an app qube called my-app-qube
  6. In my-app-qube's advanced settings, set "Default disposable template" to dvm-other.
  7. In my-app-qube, do qvm-open-in-dvm <some_file>.

Expected behavior

An "Operation execution" prompt is created in dom0 with the following:

Source: my-app-qube
Operation: qubes.OpenInVM
Target: Disposable VM (dvm-other)

(The target should be pre-filled.)

Actual behavior

No dom0 prompt is created. journalctl shows:

Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]: AssertionError
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:     assert default_target is None or default_target in targets_for_ask
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 619, in __init__
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:     return request.ask_resolution_type(self.rule, request,
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 922, in evaluate
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:     return rule.action.evaluate(request)
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 1307, in evaluate
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:     resolution = policy.evaluate(request)
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:   File "/usr/lib/python3.8/site-packages/qrexec/tools/qrexec_policy_exec.py", line 273, in handle_request
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:     result = await handle_request(**args, log=log,
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]:   File "/usr/lib/python3.8/site-packages/qrexec/tools/qrexec_policy_daemon.py", line 100, in handle_client_connection
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]: Traceback (most recent call last):
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]: future: <Task finished name='Task-35552' coro=<handle_client_connection() done, defined at /usr/lib/python3.8/site-packages/qrexec/tools/qre>
Aug 29 04:26:15 dom0 qrexec-policy-daemon[4452]: Task exception was never retrieved
@andrewdavidwong andrewdavidwong added T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists. C: core P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. needs diagnosis Requires technical diagnosis from developer. Replace with "diagnosed" or remove if otherwise closed. labels Aug 29, 2022
@andrewdavidwong andrewdavidwong added this to the Release 4.1 updates milestone Aug 29, 2022
@unman
Copy link
Member

unman commented Aug 29, 2022 via email

@marmarek
Copy link
Member

Those rules, with the current policy semantic, does not allow the call. The default_target selects default target from targets allowed (ask or allow) by other rules already. This is different from target, which overrides target regardless of whether it is otherwise allowed or not. See https://github.com/QubesOS/qubes-core-qrexec/blob/master/doc/qubes-policy.rst (hmm, it seems we don't have this rendered anywhere else).
And indeed no other rule allows calls to @dispvm:dvm-default (@dispvm means @dispvm:dvm-other when it has dvm-other set as default_dispvm).

So, we have few points here:

  1. Error handling - it should be clear message what really happened, not AssertionError
  2. Confusing difference between target= and default_target= - the later requires another rule that would allow/ask the call, while the former does not
  3. Setting just ask target= does not select that target as default, even though it makes it the only allowed choice. You'd need to specify both target= and default_target= for that.

The first point is an obvious bug. The second is intended semantics, but I can be persuaded to change it. The third one was intentional choice, but when looking at it now, I think it was a wrong one and should be changed.

@andrewdavidwong
Copy link
Member Author

andrewdavidwong commented Aug 30, 2022

should your expectation not be - "A dialog appears with @dispvm:dvm-default preselected" rather than "a disposable is created based on dvm-other" ?

Yes, I caught my mistake and edited the issue description between the time when GitHub emailed a copy of it to you and the time when you replied.

Those rules, with the current policy semantic, does not allow the call. The default_target selects default target from targets allowed (ask or allow) by other rules already. This is different from target, which overrides target regardless of whether it is otherwise allowed or not. See https://github.com/QubesOS/qubes-core-qrexec/blob/master/doc/qubes-policy.rst (hmm, it seems we don't have this rendered anywhere else). And indeed no other rule allows calls to @dispvm:dvm-default (@dispvm means @dispvm:dvm-other when it has dvm-other set as default_dispvm).

So, we have few points here:

  1. Error handling - it should be clear message what really happened, not AssertionError

Ok, let's keep this issue for that.

  1. Confusing difference between target= and default_target= - the later requires another rule that would allow/ask the call, while the former does not

Opened a separate issue for this: #7723

  1. Setting just ask target= does not select that target as default, even though it makes it the only allowed choice. You'd need to specify both target= and default_target= for that.

Reopened #5510 for this.

The first point is an obvious bug. The second is intended semantics, but I can be persuaded to change it. The third one was intentional choice, but when looking at it now, I think it was a wrong one and should be changed.

Summary:

@andrewdavidwong andrewdavidwong added the affects-4.1 This issue affects Qubes OS 4.1. label Aug 8, 2023
@andrewdavidwong andrewdavidwong removed this from the Release 4.1 updates milestone Aug 13, 2023
@UndeadDevel
Copy link

I've found another case where this happens; I'll report just to cover this edge case, as it's error is slightly different and the trigger / use case is different:

When specifying a named DVM as default_target, e.g. default_target=named in the otherwise same scheme used above, then it will correctly ask for the file or URL to be opened in a prompt window, with the specified named DVM being pre-selected, even when its dvm-template is not the default. However, when trying to use e.g. qvm-open-in-dvm from that named DVM, which is itself the default_target, the reported assertion error happens:

dom0 qrexec-policy-daemon[2771]: Task exception was never retrieved 
dom0 qrexec-policy-daemon[2771]: future: <Task finished name='Task-22002' coro=<handle_client_connection() done, defined at /usr/lib/python3.8/site-packages/qrexec/tools/qrexec_policy_daemon.py:75> exception=AssertionError()>
dom0 qrexec-policy-daemon[2771]: Traceback (most recent call last):
dom0 qrexec-policy-daemon[2771]:   File "/usr/lib/python3.8/site-packages/qrexec/tools/qrexec_policy_daemon.py", line 120, in handle_client_connection
dom0 qrexec-policy-daemon[2771]:     result = await handle_request( 
dom0 qrexec-policy-daemon[2771]:   File "/usr/lib/python3.8/site-packages/qrexec/tools/qrexec_policy_exec.py", line 326, in handle_request
dom0 qrexec-policy-daemon[2771]:     resolution = policy.evaluate(request)
dom0 qrexec-policy-daemon[2771]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 1553, in evaluate
dom0 qrexec-policy-daemon[2771]:     return rule.action.evaluate(request)
dom0 qrexec-policy-daemon[2771]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 1058, in evaluate
dom0 qrexec-policy-daemon[2771]:     return request.ask_resolution_type(
dom0 qrexec-policy-daemon[2771]:   File "/usr/lib/python3.8/site-packages/qrexec/policy/parser.py", line 708, in __init__
dom0 qrexec-policy-daemon[2771]:     assert default_target is None or default_target in targets_for_ask 
dom0 qrexec-policy-daemon[2771]: AssertionError

The order of error messages is reversed and the line numbers are different, but I think it still fits the case described in this issue.

If I should post this also in one of the other two related issues, let me know...

@marmarek
Copy link
Member

The corner case here is that loopback calls are refused, so named cannot do a call back to named. It should be handled better (likely call refused with more appropriate message).

@UndeadDevel
Copy link

UndeadDevel commented Oct 19, 2023

Would it be possible to actually allow it if the policy is ask?

My (more detailed) use case is as follows: I have two cached, named DVMs, one with and one without networking. This is why I often open files in them, but also do other tasks, such as mount another VM's volume in them, because they're basically immediately available, so it's very convenient to use them. But it can happen that, e.g. I am looking through a volume and want to open some files in it, but without exposing that volume to risk and so I call qvm-open-in-dvm from this named DVM that I mounted the volume in, but then the error occurs.

So I have to either mount things that could have multiple files in a non-cached DVM to then use the standard functionality defined via policy, or start a non-cached DVM, manually copy the files over and then open there. It would be nice if I could just call qvm-open-in-dvm from there and have the prompt come up.

Edit: I retract this post, as I've made a mistake while trying to correct this issue via an additional policy (I thought that dvm-default will "autofill" the default DVM template, but that's not the case). I solved this by adding "higher" policy rules with the named DVM as source and specifying @dispvm as default_target.

@ben-grande
Copy link

Those rules, with the current policy semantic, does not allow the call. The default_target selects default target from targets allowed (ask or allow) by other rules already.
...
2. Confusing difference between target= and default_target= - the later requires another rule that would allow/ask the call, while the former does not

Summary of the problem: an ask rule with default_target= requires target=. If no target= is used, exception is thrown`, if it is used, only one qube can be selected.

Instead of handling the exception, I would like to propose for the target= to not be necessary before the GUI dialog is presented to the user. This would allow for the user to pre-select a default target but not force it to be the only one.

If this proposal is not accepted, I will try to PR handling the exception.

@andrewdavidwong andrewdavidwong added eol-4.1 Closed because Qubes 4.1 has reached end-of-life (EOL) and removed needs diagnosis Requires technical diagnosis from developer. Replace with "diagnosed" or remove if otherwise closed. labels Dec 7, 2024

This comment was marked as outdated.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 7, 2024
@ben-grande
Copy link

This issue was fixed. Qubes 4.2.3 and qubes-core-qrexec 4.2.21-1.

Used rule on non-existent service to try:

qubes.Test * dev @default ask default_target=dom0
qrexec: qubes.Test: dev -> : denied: policy define 'ask' action at /etc/qubes/policy.d/30-user.policy:7 but no target is available to choose from

@andrewdavidwong andrewdavidwong added diagnosed Technical diagnosis has been performed (see issue comments). and removed eol-4.1 Closed because Qubes 4.1 has reached end-of-life (EOL) labels Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-4.1 This issue affects Qubes OS 4.1. C: core diagnosed Technical diagnosis has been performed (see issue comments). P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists.
Projects
None yet
Development

No branches or pull requests

5 participants