Blob Blame History Raw
From d0712483981daf5a748c1cd083fe61d8d9ea8102 Mon Sep 17 00:00:00 2001
From: Ian Jackson <>
Date: Fri, 29 Apr 2016 16:19:28 +0100
Subject: [PATCH 01/21] libxl: Make copy of every xs backend in /libxl in

We want to stop libxl trustingly reading information from the backend
directory (since this is, of course, writeable by the backend, which
might be a semi-trusted driver domain).

In principle it is wrong in current libxl for anything to try to
divine virtual device configuration from xenstore: the JSON domain
config ought to supply that, and xenstore should only tell us which
devices actually exist.


Firstly, there are several existing places where configuration
information is retrieved from xenstore rather than JSON.  We do not
want to reen gineer this in a security patch.

Secondly, we want to make a security patch which can be backported to
versions of libxl without the JSON configuration machinery.

So we take the expedient approach of keeping a copy of the
configuration somewhere we trust, namely /libxl.  This is obviously
fairly low-risk, although it does write significantly more keys in

In this patch we make this change in libxl__device_generic_add.  This
is responsible for actually writing the vast majority of device
information to xenstore.  There are a few loose ends which will be
dealt with in a moment.

Likewise, changes to readers to use the new location will appear in
further patches.

This is part of XSA-178.

Signed-off-by: Ian Jackson <>
Reviewed-by: Wei Liu <>
 docs/misc/xenstore-paths.markdown |  4 ++++
 tools/libxl/libxl_device.c        | 23 +++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/docs/misc/xenstore-paths.markdown b/docs/misc/xenstore-paths.markdown
index 2f545c1..261ee42 100644
--- a/docs/misc/xenstore-paths.markdown
+++ b/docs/misc/xenstore-paths.markdown
@@ -549,6 +549,10 @@ Path in xenstore to the frontend, normally
 Path in xenstore to the backend, normally
+#### /libxl/$DOMID/device/$KIND/$DEVID/$NODE
+Trustworthy copy of /local/domain/$DOMID/backend/$KIND/$DEVID/$NODE.
 #### /libxl/$DOMID/dm-version ("qemu\_xen"|"qemu\_xen\_traditional") = [n,INTERNAL]
 The device model version for a domain.
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 16384f8..4b61b4c 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -185,6 +185,29 @@ retry_transaction:
         xs_write(ctx->xsh, t, GCSPRINTF("%s/frontend", backend_path),
                  frontend_path, strlen(frontend_path));
         libxl__xs_writev(gc, t, backend_path, bents);
+        /*
+         * We make a copy of everything for the backend in the libxl
+         * path as well.  This means we don't need to trust the
+         * backend.  Ideally this information would not be used and we
+         * would use the information from the json configuration
+         * instead.  But there are still places in libxl that try to
+         * reconstruct a config from xenstore.
+         *
+         * This duplication will typically produces duplicate keys
+         * which will go out of date, but that's OK because nothing
+         * reads those.  For example, there is usually
+         *   /libxl/$guest/device/$kind/$devid/state
+         * which starts out containing XenbusStateInitialising ("1")
+         * just like the copy in
+         *  /local/domain/$driverdom/backend/$guest/$kind/$devid/state
+         * but which won't ever be updated.
+         *
+         * This duplication is superfluous and messy but as discussed
+         * the proper fix is more intrusive than we want to do now.
+         */
+        rc = libxl__xs_writev(gc, t, libxl_path, bents);
+        if (rc) goto out;
     if (!create_transaction)