>From e7db25186de8cb278f2b5f5c51e965129defaa11 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 17:58:58 +0100
Subject: [PATCH 08/10] Disable all disk probing in QEMU driver & add config option to re-enable

Disk format probing is now disabled by default. A new config
option in /etc/qemu/qemu.conf will re-enable it for existing
deployments where this causes trouble
---
 src/qemu/libvirtd_qemu.aug       |    1 +
 src/qemu/qemu.conf               |   12 ++++++++++++
 src/qemu/qemu_conf.c             |    4 ++++
 src/qemu/qemu_conf.h             |    1 +
 src/qemu/qemu_driver.c           |   36 +++++++++++++++++++++++-------------
 src/qemu/qemu_security_dac.c     |    2 +-
 src/qemu/test_libvirtd_qemu.aug  |    4 ++++
 src/security/security_apparmor.c |   12 ++++++++----
 src/security/security_driver.c   |   16 ++++++++++++++--
 src/security/security_driver.h   |   10 ++++++++--
 src/security/security_selinux.c  |    9 ++++++---
 src/security/virt-aa-helper.c    |   10 +++++++++-
 tests/seclabeltest.c             |    2 +-
 13 files changed, 92 insertions(+), 27 deletions(-)

Index: libvirt-0.7.6/src/qemu/libvirtd_qemu.aug
===================================================================
--- libvirt-0.7.6.orig/src/qemu/libvirtd_qemu.aug
+++ libvirt-0.7.6/src/qemu/libvirtd_qemu.aug
@@ -38,6 +38,7 @@ module Libvirtd_qemu =
                  | str_entry "save_image_format"
                  | str_entry "hugetlbfs_mount"
                  | bool_entry "relaxed_acs_check"
+                 | bool_entry "allow_disk_format_probing"
 
    (* Each enty in the config is one of the following three ... *)
    let entry = vnc_entry
Index: libvirt-0.7.6/src/qemu/qemu.conf
===================================================================
--- libvirt-0.7.6.orig/src/qemu/qemu.conf
+++ libvirt-0.7.6/src/qemu/qemu.conf
@@ -168,3 +168,15 @@
 # be assigned to guests.
 #
 # relaxed_acs_check = 1
+
+
+
+# If allow_disk_format_probing is enabled, libvirt will probe disk
+# images to attempt to identify their format, when not otherwise
+# specified in the XML. This is disabled by default.
+#
+# WARNING: Enabling probing is a security hole in almost all
+# deployments. It is strongly recommended that users update their
+# guest XML <disk> elements to include  <driver type='XXXX'/>
+# elements instead of enabling this option.
+# allow_disk_format_probing = 1
Index: libvirt-0.7.6/src/qemu/qemu_conf.c
===================================================================
--- libvirt-0.7.6.orig/src/qemu/qemu_conf.c
+++ libvirt-0.7.6/src/qemu/qemu_conf.c
@@ -349,6 +349,10 @@ int qemudLoadDriverConfig(struct qemud_d
     CHECK_TYPE ("relaxed_acs_check", VIR_CONF_LONG);
     if (p) driver->relaxedACS = p->l;
 
+    p = virConfGetValue (conf, "allow_disk_format_probing");
+    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
+    if (p) driver->allowDiskFormatProbing = p->l;
+
     virConfFree (conf);
     return 0;
 }
Index: libvirt-0.7.6/src/qemu/qemu_driver.c
===================================================================
--- libvirt-0.7.6.orig/src/qemu/qemu_driver.c
+++ libvirt-0.7.6/src/qemu/qemu_driver.c
@@ -915,7 +915,8 @@ qemudSecurityInit(struct qemud_driver *q
     qemuSecurityDACSetDriver(qemud_drv);
 
     ret = virSecurityDriverStartup(&security_drv,
-                                   qemud_drv->securityDriverName);
+                                   qemud_drv->securityDriverName,
+                                   qemud_drv->allowDiskFormatProbing);
     if (ret == -1) {
         VIR_ERROR0(_("Failed to start security driver"));
         return -1;
Index: libvirt-0.7.6/src/qemu/qemu_security_dac.c
===================================================================
--- libvirt-0.7.6.orig/src/qemu/qemu_security_dac.c
+++ libvirt-0.7.6/src/qemu/qemu_security_dac.c
@@ -127,7 +127,7 @@ qemuSecurityDACSetSecurityImageLabel(vir
 
     return virDomainDiskDefForeachPath(conn,
                                        disk,
-                                       true,
+                                       driver->allowDiskFormatProbing,
                                        false,
                                        qemuSecurityDACSetSecurityFileLabel,
                                        NULL);
Index: libvirt-0.7.6/src/qemu/test_libvirtd_qemu.aug
===================================================================
--- libvirt-0.7.6.orig/src/qemu/test_libvirtd_qemu.aug
+++ libvirt-0.7.6/src/qemu/test_libvirtd_qemu.aug
@@ -97,6 +97,8 @@ save_image_format = \"gzip\"
 hugetlbfs_mount = \"/dev/hugepages\"
 
 relaxed_acs_check = 1
+
+allow_disk_format_probing = 1
 "
 
    test Libvirtd_qemu.lns get conf =
@@ -204,3 +206,5 @@ relaxed_acs_check = 1
 { "hugetlbfs_mount" = "/dev/hugepages" }
 { "#empty" }
 { "relaxed_acs_check" = "1" }
+{ "#empty" }
+{ "allow_disk_format_probing" = "1" }
Index: libvirt-0.7.6/src/security/security_apparmor.c
===================================================================
--- libvirt-0.7.6.orig/src/security/security_apparmor.c
+++ libvirt-0.7.6/src/security/security_apparmor.c
@@ -159,6 +159,8 @@ load_profile(virConnectPtr conn,
     char *xml = NULL;
     int pipefd[2];
     pid_t child;
+    const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+        ? "1" : "0";
 
     if (pipe(pipefd) < -1) {
         virReportSystemError(conn, errno, "%s", _("unable to create pipe"));
@@ -174,19 +176,19 @@ load_profile(virConnectPtr conn,
 
     if (create) {
         const char *const argv[] = {
-            VIRT_AA_HELPER, "-c", "-u", profile, NULL
+            VIRT_AA_HELPER, "-p", probe, "-c", "-u", profile, NULL
         };
         ret = virExec(conn, argv, NULL, NULL, &child,
                       pipefd[0], NULL, NULL, VIR_EXEC_CLEAR_CAPS);
     } else if (disk && disk->src) {
         const char *const argv[] = {
-            VIRT_AA_HELPER, "-r", "-u", profile, "-f", disk->src, NULL
+            VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, "-f", disk->src, NULL
         };
         ret = virExec(conn, argv, NULL, NULL, &child,
                       pipefd[0], NULL, NULL, VIR_EXEC_CLEAR_CAPS);
     } else {
         const char *const argv[] = {
-            VIRT_AA_HELPER, "-r", "-u", profile, NULL
+            VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, NULL
         };
         ret = virExec(conn, argv, NULL, NULL, &child,
                       pipefd[0], NULL, NULL, VIR_EXEC_CLEAR_CAPS);
@@ -314,9 +316,12 @@ AppArmorSecurityDriverProbe(void)
  * currently not used.
  */
 static int
-AppArmorSecurityDriverOpen(virConnectPtr conn, virSecurityDriverPtr drv)
+AppArmorSecurityDriverOpen(virConnectPtr conn,
+                           virSecurityDriverPtr drv,
+                           bool allowDiskFormatProbing)
 {
     virSecurityDriverSetDOI(conn, drv, SECURITY_APPARMOR_VOID_DOI);
+    virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
     return 0;
 }
 
Index: libvirt-0.7.6/src/security/security_driver.c
===================================================================
--- libvirt-0.7.6.orig/src/security/security_driver.c
+++ libvirt-0.7.6/src/security/security_driver.c
@@ -56,7 +56,8 @@ virSecurityDriverVerify(virConnectPtr co
 
 int
 virSecurityDriverStartup(virSecurityDriverPtr *drv,
-                         const char *name)
+                         const char *name,
+                         bool allowDiskFormatProbing)
 {
     unsigned int i;
 
@@ -72,7 +73,7 @@ virSecurityDriverStartup(virSecurityDriv
         switch (tmp->probe()) {
         case SECURITY_DRIVER_ENABLE:
             virSecurityDriverInit(tmp);
-            if (tmp->open(NULL, tmp) == -1) {
+            if (tmp->open(NULL, tmp, allowDiskFormatProbing) == -1) {
                 return -1;
             } else {
                 *drv = tmp;
@@ -144,3 +145,14 @@ virSecurityDriverGetModel(virSecurityDri
 {
     return drv->name;
 }
+
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+                                                bool allowDiskFormatProbing)
+{
+    drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
+}
+
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
+{
+    return drv->_private.allowDiskFormatProbing;
+}
Index: libvirt-0.7.6/src/security/security_driver.h
===================================================================
--- libvirt-0.7.6.orig/src/security/security_driver.h
+++ libvirt-0.7.6/src/security/security_driver.h
@@ -30,7 +30,8 @@ typedef struct _virSecurityDriver virSec
 typedef virSecurityDriver *virSecurityDriverPtr;
 typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
 typedef int (*virSecurityDriverOpen) (virConnectPtr conn,
-                                      virSecurityDriverPtr drv);
+                                      virSecurityDriverPtr drv,
+                                      bool allowDiskFormatProbing);
 typedef int (*virSecurityDomainRestoreImageLabel) (virConnectPtr conn,
                                                    virSecurityDriverPtr drv,
                                                    virDomainObjPtr vm,
@@ -105,12 +106,14 @@ struct _virSecurityDriver {
      */
     struct {
         char doi[VIR_SECURITY_DOI_BUFLEN];
+        bool allowDiskFormatProbing;
     } _private;
 };
 
 /* Global methods */
 int virSecurityDriverStartup(virSecurityDriverPtr *drv,
-                             const char *name);
+                             const char *name,
+                             bool allowDiskFormatProbing);
 
 int
 virSecurityDriverVerify(virConnectPtr conn, virDomainDefPtr def);
@@ -124,7 +127,10 @@ void virSecurityDriverInit(virSecurityDr
 int virSecurityDriverSetDOI(virConnectPtr conn,
                             virSecurityDriverPtr drv,
                             const char *doi);
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+                                                bool allowDiskFormatProbing);
 const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
 const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
 
 #endif /* __VIR_SECURITY_H__ */
Index: libvirt-0.7.6/src/security/security_selinux.c
===================================================================
--- libvirt-0.7.6.orig/src/security/security_selinux.c
+++ libvirt-0.7.6/src/security/security_selinux.c
@@ -268,13 +268,16 @@ SELinuxSecurityDriverProbe(void)
 }
 
 static int
-SELinuxSecurityDriverOpen(virConnectPtr conn, virSecurityDriverPtr drv)
+SELinuxSecurityDriverOpen(virConnectPtr conn,
+                          virSecurityDriverPtr drv,
+                          bool allowDiskFormatProbing )
 {
     /*
      * Where will the DOI come from?  SELinux configuration, or qemu
      * configuration? For the moment, we'll just set it to "0".
      */
     virSecurityDriverSetDOI(conn, drv, SECURITY_SELINUX_VOID_DOI);
+    virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
     return SELinuxInitialize(conn);
 }
 
@@ -436,19 +439,20 @@ SELinuxSetSecurityFileLabel(virDomainDis
 
 static int
 SELinuxSetSecurityImageLabel(virConnectPtr conn,
-                             virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+                             virSecurityDriverPtr drv,
                              virDomainObjPtr vm,
                              virDomainDiskDefPtr disk)
 
 {
     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+    bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
 
     if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
         return 0;
 
     return virDomainDiskDefForeachPath(conn,
                                        disk,
-                                       true,
+                                       allowDiskFormatProbing,
                                        false,
                                        SELinuxSetSecurityFileLabel,
                                        secdef);
Index: libvirt-0.7.6/src/security/virt-aa-helper.c
===================================================================
--- libvirt-0.7.6.orig/src/security/virt-aa-helper.c
+++ libvirt-0.7.6/src/security/virt-aa-helper.c
@@ -40,6 +40,7 @@
 static char *progname;
 
 typedef struct {
+    bool allowDiskFormatProbing;
     char uuid[PROFILE_NAME_SIZE];       /* UUID of vm */
     bool dryrun;                /* dry run */
     char cmd;                   /* 'c'   create
@@ -821,7 +822,7 @@ get_files(vahControl * ctl)
     for (i = 0; i < ctl->def->ndisks; i++) {
         int ret = virDomainDiskDefForeachPath(NULL,
                                               ctl->def->disks[i],
-                                              true,
+                                              ctl->allowDiskFormatProbing,
                                               false,
                                               add_file_path,
                                               &buf);
@@ -918,6 +919,7 @@ vahParseArgv(vahControl * ctl, int argc,
 {
     int arg, idx = 0;
     struct option opt[] = {
+        {"probing", 1, 0, 'p' },
         {"add", 0, 0, 'a'},
         {"create", 0, 0, 'c'},
         {"dryrun", 0, 0, 'd'},
@@ -966,6 +968,12 @@ vahParseArgv(vahControl * ctl, int argc,
                     PROFILE_NAME_SIZE) == NULL)
                     vah_error(ctl, 1, "error copying UUID");
                 break;
+            case 'p':
+                if (STREQ(optarg, "1"))
+                    ctl->allowDiskFormatProbing = true;
+                else
+                    ctl->allowDiskFormatProbing = false;
+                break;
             default:
                 vah_error(ctl, 1, "unsupported option");
                 break;
Index: libvirt-0.7.6/tests/seclabeltest.c
===================================================================
--- libvirt-0.7.6.orig/tests/seclabeltest.c
+++ libvirt-0.7.6/tests/seclabeltest.c
@@ -15,7 +15,7 @@ main (int argc ATTRIBUTE_UNUSED, char **
     const char *doi, *model;
     virSecurityDriverPtr security_drv;
 
-    ret = virSecurityDriverStartup (&security_drv, "selinux");
+    ret = virSecurityDriverStartup (&security_drv, "selinux", false);
     if (ret == -1)
     {
         fprintf (stderr, "Failed to start security driver");
Index: libvirt-0.7.6/src/qemu/qemu_conf.h
===================================================================
--- libvirt-0.7.6.orig/src/qemu/qemu_conf.h
+++ libvirt-0.7.6/src/qemu/qemu_conf.h
@@ -129,6 +129,7 @@ struct qemud_driver {
     ebtablesContext *ebtables;
 
     unsigned int relaxedACS : 1;
+    unsigned int allowDiskFormatProbing : 1;
 
     virCapsPtr caps;
 
Index: libvirt-0.7.6/tests/secaatest.c
===================================================================
--- libvirt-0.7.6.orig/tests/secaatest.c
+++ libvirt-0.7.6/tests/secaatest.c
@@ -15,7 +15,7 @@ main (int argc ATTRIBUTE_UNUSED, char **
     const char *doi, *model;
     virSecurityDriverPtr security_drv;
 
-    ret = virSecurityDriverStartup (&security_drv, "apparmor");
+    ret = virSecurityDriverStartup (&security_drv, "apparmor", false);
     if (ret == -1)
     {
         fprintf (stderr, "Failed to start security driver");
