qrexec: fix handling autostarting RPC target VM

Do not reimplement manual VM state checking in qrexec-policy.
`qubes.xml` is loaded anyway, so just use QubesVM object to check if
domain is running.

Fixes QubesOS/qubes-issues#1283
This commit is contained in:
Marek Marczykowski-Górecki 2015-10-11 01:52:40 +02:00
parent 63dffb48c5
commit 63e74a01d3
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724

View File

@ -4,7 +4,9 @@ import os
import os.path
import subprocess
from qubes.qubes import vmm
from qubes.qubes import QubesVmCollection
import qubes.guihelpers
import libvirt
from optparse import OptionParser
import fcntl
@ -82,45 +84,36 @@ def find_policy(policy, domain, target):
return iter
return get_default_policy()
def is_domain_running(target):
if target == "dom0":
return True
libvirt_dom = vmm.libvirt_conn.lookupByName(target)
if libvirt_dom:
return libvirt_dom.isActive()
else:
return False
def validate_target(target):
# special targets
if target in ['$dispvm', 'dom0']:
if target in ['$dispvm']:
return True
from qubes.qubes import QubesVmCollection
qc = QubesVmCollection()
qc.lock_db_for_reading()
qc.load()
qc.unlock_db()
return qc.get_vm_by_name(target) is not None
return qc.get_vm_by_name(target)
def spawn_target_if_necessary(target):
if is_domain_running(target):
def spawn_target_if_necessary(vm):
if vm.is_running():
return
# use qvm-run instead of vm.start() to make sure that nothing is written
# to stdout and nothing is read from stdin
null = open("/dev/null", "r+")
subprocess.call(["qvm-run", "-a", "-q", target, "true"], stdin=null, stdout=null)
subprocess.call(["qvm-run", "-a", "-q", vm.name, "true"],
stdin=null, stdout=null)
null.close()
def do_execute(domain, target, user, service_name, process_ident):
def do_execute(domain, target, user, service_name, process_ident, vm=None):
if target == "$dispvm":
cmd = "/usr/lib/qubes/qfile-daemon-dvm " + service_name + " " + domain + " " +user
os.execl(QREXEC_CLIENT, "qrexec-client",
"-d", "dom0", "-c", process_ident, cmd)
else:
# see the previous commit why "qvm-run -a" is broken and dangerous
# also, dangling "xl" would keep stderr open and may prevent closing connection
spawn_target_if_necessary(target)
if isinstance(vm, qubes.qubes.QubesVm):
spawn_target_if_necessary(vm)
if target == "dom0":
cmd = QUBES_RPC_MULTIPLEXER_PATH + " " + service_name + " " + domain
else:
@ -175,7 +168,8 @@ def main():
# connection
process_ident+=","+domain+","+domain_id
if not validate_target(target):
vm = validate_target(target)
if vm is None:
print >> sys.stderr, "Rpc failed (unknown domain):", domain, target, service_name
text = "Domain '%s' doesn't exist (service %s called by domain %s)." % (
target, service_name, domain)
@ -218,7 +212,7 @@ def main():
else:
user="DEFAULT"
print >> sys.stderr, "Rpc allowed:", domain, target, service_name
do_execute(domain, target, user, service_name, process_ident)
do_execute(domain, target, user, service_name, process_ident, vm=vm)
print >> sys.stderr, "Rpc denied:", domain, target, service_name
exit(1)