>From e7db25186de8cb278f2b5f5c51e965129defaa11 Mon Sep 17 00:00:00 2001 From: Daniel P. Berrange 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.8.1/src/qemu/libvirtd_qemu.aug =================================================================== --- libvirt-0.8.1.orig/src/qemu/libvirtd_qemu.aug +++ libvirt-0.8.1/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.8.1/src/qemu/qemu.conf =================================================================== --- libvirt-0.8.1.orig/src/qemu/qemu.conf +++ libvirt-0.8.1/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 elements to include +# elements instead of enabling this option. +# allow_disk_format_probing = 1 Index: libvirt-0.8.1/src/qemu/qemu_conf.c =================================================================== --- libvirt-0.8.1.orig/src/qemu/qemu_conf.c +++ libvirt-0.8.1/src/qemu/qemu_conf.c @@ -351,6 +351,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.8.1/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.8.1.orig/src/qemu/qemu_driver.c +++ libvirt-0.8.1/src/qemu/qemu_driver.c @@ -1289,7 +1289,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; @@ -9145,8 +9146,15 @@ static int qemuDomainGetBlockInfo(virDom goto cleanup; } } else { - if ((format = virStorageFileProbeFormat(disk->src)) < 0) + if (driver->allowDiskFormatProbing) { + if ((format = virStorageFileProbeFormat(disk->src)) < 0) + goto cleanup; + } else { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("no disk format for %s and probing is disabled"), + disk->src); goto cleanup; + } } if (virStorageFileGetMetadataFromFD(path, fd, Index: libvirt-0.8.1/src/qemu/qemu_security_dac.c =================================================================== --- libvirt-0.8.1.orig/src/qemu/qemu_security_dac.c +++ libvirt-0.8.1/src/qemu/qemu_security_dac.c @@ -118,7 +118,7 @@ qemuSecurityDACSetSecurityImageLabel(vir return 0; return virDomainDiskDefForeachPath(disk, - true, + driver->allowDiskFormatProbing, false, qemuSecurityDACSetSecurityFileLabel, NULL); Index: libvirt-0.8.1/src/qemu/test_libvirtd_qemu.aug =================================================================== --- libvirt-0.8.1.orig/src/qemu/test_libvirtd_qemu.aug +++ libvirt-0.8.1/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.8.1/src/security/security_apparmor.c =================================================================== --- libvirt-0.8.1.orig/src/security/security_apparmor.c +++ libvirt-0.8.1/src/security/security_apparmor.c @@ -157,6 +157,8 @@ load_profile(virSecurityDriverPtr drv, char *xml = NULL; int pipefd[2]; pid_t child; + const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv) + ? "1" : "0"; if (pipe(pipefd) < -1) { virReportSystemError(errno, "%s", _("unable to create pipe")); @@ -172,19 +174,19 @@ load_profile(virSecurityDriverPtr drv, if (create) { const char *const argv[] = { - VIRT_AA_HELPER, "-c", "-u", profile, NULL + VIRT_AA_HELPER, "-p", probe, "-c", "-u", profile, NULL }; ret = virExec(argv, NULL, NULL, &child, pipefd[0], NULL, NULL, VIR_EXEC_NONE); } 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(argv, NULL, NULL, &child, pipefd[0], NULL, NULL, VIR_EXEC_NONE); } else { const char *const argv[] = { - VIRT_AA_HELPER, "-r", "-u", profile, NULL + VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, NULL }; ret = virExec(argv, NULL, NULL, &child, pipefd[0], NULL, NULL, VIR_EXEC_NONE); @@ -312,9 +314,11 @@ AppArmorSecurityDriverProbe(void) * currently not used. */ static int -AppArmorSecurityDriverOpen(virSecurityDriverPtr drv) +AppArmorSecurityDriverOpen(virSecurityDriverPtr drv, + bool allowDiskFormatProbing) { virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI); + virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing); return 0; } Index: libvirt-0.8.1/src/security/security_driver.c =================================================================== --- libvirt-0.8.1.orig/src/security/security_driver.c +++ libvirt-0.8.1/src/security/security_driver.c @@ -56,7 +56,8 @@ virSecurityDriverVerify(virDomainDefPtr 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(tmp) == -1) { + if (tmp->open(tmp, allowDiskFormatProbing) == -1) { return -1; } else { *drv = tmp; @@ -125,3 +126,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.8.1/src/security/security_driver.h =================================================================== --- libvirt-0.8.1.orig/src/security/security_driver.h +++ libvirt-0.8.1/src/security/security_driver.h @@ -33,7 +33,8 @@ typedef struct _virSecurityDriverState v typedef virSecurityDriverState *virSecurityDriverStatePtr; typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void); -typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv); +typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv, + bool allowDiskFormatProbing); typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv, virDomainObjPtr vm, virDomainDiskDefPtr disk); @@ -94,12 +95,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(virDomainDefPtr def); @@ -112,7 +115,10 @@ virSecurityDriverVerify(virDomainDefPtr void virSecurityDriverInit(virSecurityDriverPtr drv); int virSecurityDriverSetDOI(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.8.1/src/security/security_selinux.c =================================================================== --- libvirt-0.8.1.orig/src/security/security_selinux.c +++ libvirt-0.8.1/src/security/security_selinux.c @@ -266,13 +266,15 @@ SELinuxSecurityDriverProbe(void) } static int -SELinuxSecurityDriverOpen(virSecurityDriverPtr drv) +SELinuxSecurityDriverOpen(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(drv, SECURITY_SELINUX_VOID_DOI); + virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing); return SELinuxInitialize(); } @@ -438,18 +440,19 @@ SELinuxSetSecurityFileLabel(virDomainDis } static int -SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, +SELinuxSetSecurityImageLabel(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(disk, - true, + allowDiskFormatProbing, false, SELinuxSetSecurityFileLabel, secdef); Index: libvirt-0.8.1/src/security/virt-aa-helper.c =================================================================== --- libvirt-0.8.1.orig/src/security/virt-aa-helper.c +++ libvirt-0.8.1/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 @@ -845,7 +846,7 @@ get_files(vahControl * ctl) for (i = 0; i < ctl->def->ndisks; i++) { int ret = virDomainDiskDefForeachPath(ctl->def->disks[i], - true, + ctl->allowDiskFormatProbing, false, add_file_path, &buf); @@ -944,6 +945,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'}, @@ -992,6 +994,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.8.1/tests/seclabeltest.c =================================================================== --- libvirt-0.8.1.orig/tests/seclabeltest.c +++ libvirt-0.8.1/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.8.1/src/qemu/qemu_conf.h =================================================================== --- libvirt-0.8.1.orig/src/qemu/qemu_conf.h +++ libvirt-0.8.1/src/qemu/qemu_conf.h @@ -137,6 +137,7 @@ struct qemud_driver { ebtablesContext *ebtables; unsigned int relaxedACS : 1; + unsigned int allowDiskFormatProbing : 1; virCapsPtr caps; Index: libvirt-0.8.1/tests/secaatest.c =================================================================== --- libvirt-0.8.1.orig/tests/secaatest.c +++ libvirt-0.8.1/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");