Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pr/383'
Browse files Browse the repository at this point in the history
* origin/pr/383:
  winusb: bring back xen-hvm-stubdom-linux
  winusb: fix requires
  winusb: add optional parameter to lambda function
  winusb: remove whitespace
  winusb: check if qrexec running for the stubdom
  winusb: fix domain name for is_paused() message
  winusb: add test for run_service with stubdom arg
  winusb: explicitly use root on starting qrexec daemon in stubdom
  winusb: run qrexec agent in stubdom before the main qrexec daemon
  winusb: fix naming
  winusb: Replace minimal stubomain' kernel and ramdisk
  winusb: Redirect rpc calls to stub domain
  winusb: run qrexec daemon for stubdomain
  • Loading branch information
marmarek committed Jun 23, 2021
2 parents af15a89 + c3f7cb2 commit ab0b638
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 12 deletions.
20 changes: 16 additions & 4 deletions qubes/tests/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,7 @@ def test_700_run_service(self, mock_subprocess):
vm = self.get_vm(cls=qubes.vm.standalonevm.StandaloneVM,
name='vm')
vm.is_running = lambda: True
vm.is_qrexec_running = lambda: True
vm.is_qrexec_running = lambda stubdom=False: True
vm.start = start_mock
with self.subTest('running'):
self.loop.run_until_complete(vm.run_service('test.service'))
Expand Down Expand Up @@ -2053,7 +2053,7 @@ def test_700_run_service(self, mock_subprocess):
start_mock.reset_mock()
with self.subTest('no_qrexec'):
vm.is_running = lambda: True
vm.is_qrexec_running = lambda: False
vm.is_qrexec_running = lambda stubdom=False: False
with self.assertRaises(qubes.exc.QubesVMError):
self.loop.run_until_complete(vm.run_service('test.service'))
self.assertFalse(start_mock.called)
Expand All @@ -2063,7 +2063,7 @@ def test_700_run_service(self, mock_subprocess):
start_mock.reset_mock()
with self.subTest('other_user'):
vm.is_running = lambda: True
vm.is_qrexec_running = lambda: True
vm.is_qrexec_running = lambda stubdom=False: True
self.loop.run_until_complete(vm.run_service('test.service',
user='other'))
mock_subprocess.assert_called_once_with(
Expand All @@ -2075,14 +2075,26 @@ def test_700_run_service(self, mock_subprocess):
start_mock.reset_mock()
with self.subTest('other_source'):
vm.is_running = lambda: True
vm.is_qrexec_running = lambda: True
vm.is_qrexec_running = lambda stubdom=False: True
self.loop.run_until_complete(vm.run_service('test.service',
source='test-inst-vm'))
mock_subprocess.assert_called_once_with(
'/usr/bin/qrexec-client', '-d', 'test-inst-vm',
'user:QUBESRPC test.service test-inst-vm')
self.assertFalse(start_mock.called)

mock_subprocess.reset_mock()
start_mock.reset_mock()
with self.subTest('stubdom'):
vm.is_running = lambda: True
vm.is_qrexec_running = lambda stubdom=True: True
self.loop.run_until_complete(vm.run_service('test.service',
stubdom=True))
mock_subprocess.assert_called_once_with(
'/usr/bin/qrexec-client', '-d', 'test-inst-vm-dm',
'user:QUBESRPC test.service dom0')
self.assertFalse(start_mock.called)

@unittest.mock.patch('qubes.vm.qubesvm.QubesVM.run')
def test_710_run_for_stdio(self, mock_run):
vm = self.get_vm(cls=qubes.vm.standalonevm.StandaloneVM,
Expand Down
26 changes: 18 additions & 8 deletions qubes/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,9 @@ async def start(self, start_guid=True, notify_function=None,
self.log.warning('Activating the {} VM'.format(self.name))
self.libvirt_domain.resume()

if self.virt_mode == 'hvm' and \
self.features.check_with_template('stubdom-qrexec', False):
await self.start_qrexec_daemon(stubdom=True)
await self.start_qrexec_daemon()

await self.fire_event_async('domain-start',
Expand Down Expand Up @@ -1426,7 +1429,7 @@ def unpause(self):

return self

async def run_service(self, service, source=None, user=None,
async def run_service(self, service, source=None, user=None, stubdom=False,
filter_esc=False, autostart=False, gui=False, **kwargs):
"""Run service on this VM
Expand Down Expand Up @@ -1456,6 +1459,8 @@ async def run_service(self, service, source=None, user=None,

source = 'dom0' if source is None else self.app.domains[source].name

name = self.name + '-dm' if stubdom else self.name

if user is None:
user = self.default_user

Expand All @@ -1468,16 +1473,16 @@ async def run_service(self, service, source=None, user=None,
raise qubes.exc.QubesVMNotRunningError(self)
await self.start(start_guid=gui)

if not self.is_qrexec_running():
if not self.is_qrexec_running(stubdom=stubdom):
raise qubes.exc.QubesVMError(
self, 'Domain {!r}: qrexec not connected'.format(self.name))
self, 'Domain {!r}: qrexec not connected'.format(name))

await self.fire_event_async('domain-cmd-pre-run', pre_event=True,
start_guid=gui)

return await asyncio.create_subprocess_exec(
qubes.config.system_path['qrexec_client_path'],
'-d', str(self.name),
'-d', str(name),
*(('-t', '-T') if filter_esc else ()),
'{}:QUBESRPC {} {}'.format(user, service, source),
**kwargs)
Expand Down Expand Up @@ -1640,14 +1645,18 @@ def start_daemon(*command, input=None, **kwargs):
output=stdout, stderr=stderr)

@asyncio.coroutine
def start_qrexec_daemon(self):
def start_qrexec_daemon(self, stubdom=False):
"""Start qrexec daemon.
:raises OSError: when starting fails.
"""

self.log.debug('Starting the qrexec daemon')
qrexec_args = [str(self.xid), self.name, self.default_user]
if stubdom:
qrexec_args = [str(self.stubdom_xid), self.name + '-dm', 'root']
else:
qrexec_args = [str(self.xid), self.name, self.default_user]

if not self.debug:
qrexec_args.insert(0, "-q")

Expand Down Expand Up @@ -1976,7 +1985,7 @@ def is_paused(self):
return self.libvirt_domain \
and self.libvirt_domain.state()[0] == libvirt.VIR_DOMAIN_PAUSED

def is_qrexec_running(self):
def is_qrexec_running(self, stubdom=False):
"""Check whether qrexec for this domain is available.
:returns: :py:obj:`True` if qrexec is running, \
Expand All @@ -1985,7 +1994,8 @@ def is_qrexec_running(self):
"""
if self.xid < 0: # pylint: disable=comparison-with-callable
return False
return os.path.exists('/var/run/qubes/qrexec.%s' % self.name)
name = self.name + '-dm' if stubdom else self.name
return os.path.exists('/var/run/qubes/qrexec.%s' % name)

def is_fully_usable(self):
return all(self.fire_event('domain-is-fully-usable'))
Expand Down
1 change: 1 addition & 0 deletions rpm_spec/core-dom0.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Conflicts: qubes-gui-dom0 < 1.1.13
Requires: xen-runtime
Requires: xen-hvm
Requires: xen-hvm-stubdom-linux >= 1.0.13
Requires: xen-hvm-stubdom-linux-full >= 1.0.13
Requires: libvirt-daemon-xen >= 3.3.0-7
%endif
Requires: cronie
Expand Down
5 changes: 5 additions & 0 deletions templates/libvirt/xen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@
{% if vm.stubdom_mem %}
memory="{{ vm.stubdom_mem * 1024 -}}"
{% endif %}
{% if vm.features.check_with_template('audio-model', False)
or vm.features.check_with_template('stubdom-qrexec', False) %}
kernel="/usr/libexec/xen/boot/qemu-stubdom-linux-full-kernel"
ramdisk="/usr/libexec/xen/boot/qemu-stubdom-linux-full-rootfs"
{% endif %}
/>
<input type="tablet" bus="usb"/>
{% if vm.features.check_with_template('audio-model', False) %}
Expand Down

0 comments on commit ab0b638

Please sign in to comment.