From 274bce922a2bff57e7342dcd01ba855da9da19b39568d0ed8029ab13418c9822 Mon Sep 17 00:00:00 2001 From: James Fehlig Date: Fri, 16 Jul 2010 22:40:42 +0000 Subject: [PATCH 1/4] VUL-0: multiple issues in libvirt OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=60 --- CVE-2010-223x-0001.patch | 339 ++++++++++++ CVE-2010-223x-0002.patch | 158 ++++++ CVE-2010-223x-0003.patch | 486 +++++++++++++++++ CVE-2010-223x-0004.patch | 218 ++++++++ CVE-2010-223x-0005.patch | 167 ++++++ CVE-2010-223x-0006.patch | 273 ++++++++++ CVE-2010-223x-0007.patch | 1058 ++++++++++++++++++++++++++++++++++++++ CVE-2010-223x-0008.patch | 385 ++++++++++++++ CVE-2010-223x-0009.patch | 110 ++++ CVE-2010-223x-0010.patch | 288 +++++++++++ CVE-2010-2242-nat.patch | 262 ++++++++++ libvirt.changes | 8 + libvirt.spec | 27 +- 13 files changed, 3778 insertions(+), 1 deletion(-) create mode 100644 CVE-2010-223x-0001.patch create mode 100644 CVE-2010-223x-0002.patch create mode 100644 CVE-2010-223x-0003.patch create mode 100644 CVE-2010-223x-0004.patch create mode 100644 CVE-2010-223x-0005.patch create mode 100644 CVE-2010-223x-0006.patch create mode 100644 CVE-2010-223x-0007.patch create mode 100644 CVE-2010-223x-0008.patch create mode 100644 CVE-2010-223x-0009.patch create mode 100644 CVE-2010-223x-0010.patch create mode 100644 CVE-2010-2242-nat.patch diff --git a/CVE-2010-223x-0001.patch b/CVE-2010-223x-0001.patch new file mode 100644 index 0000000..ac97a2f --- /dev/null +++ b/CVE-2010-223x-0001.patch @@ -0,0 +1,339 @@ +>From 7b91c43bef0348c8cc18037bec5aef668b51fc90 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 14 Jun 2010 15:53:59 +0100 +Subject: [PATCH 01/10] Extract the backing store format as well as name, if available + +When QEMU opens a backing store for a QCow2 file, it will +normally auto-probe for the format of the backing store, +rather than assuming it has the same format as the referencing +file. There is a QCow2 extension that allows an explicit format +for the backing store to be embedded in the referencing file. +This closes the auto-probing security hole in QEMU. + +This backing store format can be useful for libvirt users +of virStorageFileGetMetadata, so extract this data and report +it. + +QEMU does not require disk image backing store files to be in +the same format the file linkee. It will auto-probe the disk +format for the backing store when opening it. If the backing +store was intended to be a raw file this could be a security +hole, because a guest may have written data into its disk that +then makes the backing store look like a qcow2 file. If it can +trick QEMU into thinking the raw file is a qcow2 file, it can +access arbitrary files on the host by adding further backing +store links. + +To address this, callers of virStorageFileGetMeta need to be +told of the backing store format. If no format is declared, +they can make a decision whether to allow format probing or +not. +--- + src/util/storage_file.c | 192 ++++++++++++++++++++++++++++++++++++++++------ + src/util/storage_file.h | 2 + + 2 files changed, 169 insertions(+), 25 deletions(-) + +Index: libvirt-0.8.1/src/util/storage_file.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.c ++++ libvirt-0.8.1/src/util/storage_file.c +@@ -71,12 +71,18 @@ struct FileTypeInfo { + int qcowCryptOffset; /* Byte offset from start of file + * where to find encryption mode, + * -1 if encryption is not used */ +- int (*getBackingStore)(char **res, const unsigned char *buf, size_t buf_size); ++ int (*getBackingStore)(char **res, int *format, ++ const unsigned char *buf, size_t buf_size); + }; + +-static int cowGetBackingStore(char **, const unsigned char *, size_t); +-static int qcowXGetBackingStore(char **, const unsigned char *, size_t); +-static int vmdk4GetBackingStore(char **, const unsigned char *, size_t); ++static int cowGetBackingStore(char **, int *, ++ const unsigned char *, size_t); ++static int qcow1GetBackingStore(char **, int *, ++ const unsigned char *, size_t); ++static int qcow2GetBackingStore(char **, int *, ++ const unsigned char *, size_t); ++static int vmdk4GetBackingStore(char **, int *, ++ const unsigned char *, size_t); + + + static struct FileTypeInfo const fileTypeInfo[] = { +@@ -112,11 +118,11 @@ static struct FileTypeInfo const fileTyp + /* QCow */ + { VIR_STORAGE_FILE_QCOW, "QFI", NULL, + LV_BIG_ENDIAN, 4, 1, +- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore }, ++ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore }, + /* QCow 2 */ + { VIR_STORAGE_FILE_QCOW2, "QFI", NULL, + LV_BIG_ENDIAN, 4, 2, +- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore }, ++ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore }, + /* VMDK 3 */ + /* XXX Untested + { VIR_STORAGE_FILE_VMDK, "COWD", NULL, +@@ -137,11 +143,14 @@ static struct FileTypeInfo const fileTyp + + static int + cowGetBackingStore(char **res, ++ int *format, + const unsigned char *buf, + size_t buf_size) + { + #define COW_FILENAME_MAXLEN 1024 + *res = NULL; ++ *format = VIR_STORAGE_FILE_AUTO; ++ + if (buf_size < 4+4+ COW_FILENAME_MAXLEN) + return BACKING_STORE_INVALID; + if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */ +@@ -155,31 +164,101 @@ cowGetBackingStore(char **res, + return BACKING_STORE_OK; + } + ++ ++ ++#define QCOWX_HDR_BACKING_FILE_OFFSET 4+4 ++#define QCOWX_HDR_BACKING_FILE_SIZE 4+4+8 ++ ++#define QCOW2_HDR_TOTAL_SIZE 4+4+8+4+4+8+4+4+8+8+4+4+8 ++#define QCOW2_HDR_EXTENSION_END 0 ++#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA ++ ++static int ++qcow2GetBackingStoreFormat(int *format, ++ const unsigned char *buf, ++ size_t buf_size, ++ size_t extension_start, ++ size_t extension_end) ++{ ++ size_t offset = extension_start; ++ ++ /* ++ * The extensions take format of ++ * ++ * int32: magic ++ * int32: length ++ * byte[length]: payload ++ * ++ * Unknown extensions can be ignored by skipping ++ * over "length" bytes in the data stream. ++ */ ++ while (offset < (buf_size-8) && ++ offset < (extension_end-8)) { ++ int magic = (buf[offset] << 24) + ++ (buf[offset+1] << 16) + ++ (buf[offset+2] << 8) + ++ (buf[offset+3]); ++ int len = (buf[offset+4] << 24) + ++ (buf[offset+5] << 16) + ++ (buf[offset+6] << 8) + ++ (buf[offset+7]); ++ ++ offset += 8; ++ ++ if ((offset + len) > buf_size) ++ break; ++ ++ switch (magic) { ++ case QCOW2_HDR_EXTENSION_END: ++ goto done; ++ ++ case QCOW2_HDR_EXTENSION_BACKING_FORMAT: ++ if (buf[offset+len] != '\0') ++ break; ++ *format = virStorageFileFormatTypeFromString( ++ ((const char *)buf)+offset); ++ break; ++ } ++ ++ offset += len; ++ } ++ ++done: ++ ++ return 0; ++} ++ ++ + static int + qcowXGetBackingStore(char **res, ++ int *format, + const unsigned char *buf, +- size_t buf_size) ++ size_t buf_size, ++ bool isQCow2) + { + unsigned long long offset; + unsigned long size; + + *res = NULL; +- if (buf_size < 4+4+8+4) ++ if (format) ++ *format = VIR_STORAGE_FILE_AUTO; ++ ++ if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4) + return BACKING_STORE_INVALID; +- offset = (((unsigned long long)buf[4+4] << 56) +- | ((unsigned long long)buf[4+4+1] << 48) +- | ((unsigned long long)buf[4+4+2] << 40) +- | ((unsigned long long)buf[4+4+3] << 32) +- | ((unsigned long long)buf[4+4+4] << 24) +- | ((unsigned long long)buf[4+4+5] << 16) +- | ((unsigned long long)buf[4+4+6] << 8) +- | buf[4+4+7]); /* QCowHeader.backing_file_offset */ ++ offset = (((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET] << 56) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+1] << 48) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+2] << 40) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+3] << 32) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+4] << 24) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+5] << 16) ++ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+6] << 8) ++ | buf[QCOWX_HDR_BACKING_FILE_OFFSET+7]); /* QCowHeader.backing_file_offset */ + if (offset > buf_size) + return BACKING_STORE_INVALID; +- size = ((buf[4+4+8] << 24) +- | (buf[4+4+8+1] << 16) +- | (buf[4+4+8+2] << 8) +- | buf[4+4+8+3]); /* QCowHeader.backing_file_size */ ++ size = ((buf[QCOWX_HDR_BACKING_FILE_SIZE] << 24) ++ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16) ++ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8) ++ | buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */ + if (size == 0) + return BACKING_STORE_OK; + if (offset + size > buf_size || offset + size < offset) +@@ -192,12 +271,63 @@ qcowXGetBackingStore(char **res, + } + memcpy(*res, buf + offset, size); + (*res)[size] = '\0'; ++ ++ /* ++ * Traditionally QCow2 files had a layout of ++ * ++ * [header] ++ * [backingStoreName] ++ * ++ * Although the backingStoreName typically followed ++ * the header immediately, this was not required by ++ * the format. By specifying a higher byte offset for ++ * the backing file offset in the header, it was ++ * possible to leave space between the header and ++ * start of backingStore. ++ * ++ * This hack is now used to store extensions to the ++ * qcow2 format: ++ * ++ * [header] ++ * [extensions] ++ * [backingStoreName] ++ * ++ * Thus the file region to search for extensions is ++ * between the end of the header (QCOW2_HDR_TOTAL_SIZE) ++ * and the start of the backingStoreName (offset) ++ */ ++ if (isQCow2) ++ qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset); ++ + return BACKING_STORE_OK; + } + + + static int ++qcow1GetBackingStore(char **res, ++ int *format, ++ const unsigned char *buf, ++ size_t buf_size) ++{ ++ /* QCow1 doesn't have the extensions capability ++ * used to store backing format */ ++ *format = VIR_STORAGE_FILE_AUTO; ++ return qcowXGetBackingStore(res, NULL, buf, buf_size, false); ++} ++ ++static int ++qcow2GetBackingStore(char **res, ++ int *format, ++ const unsigned char *buf, ++ size_t buf_size) ++{ ++ return qcowXGetBackingStore(res, format, buf, buf_size, true); ++} ++ ++ ++static int + vmdk4GetBackingStore(char **res, ++ int *format, + const unsigned char *buf, + size_t buf_size) + { +@@ -207,6 +337,12 @@ vmdk4GetBackingStore(char **res, + size_t len; + + *res = NULL; ++ /* XXX should we set VMDK instead ? QEMU does auto ++ * probing, but this isn't in compliance with the ++ * VMDK spec/VMWare impl which presumes only VMDK ++ * backing format ++ */ ++ *format = VIR_STORAGE_FILE_AUTO; + + if (buf_size <= 0x200) + return BACKING_STORE_INVALID; +@@ -351,9 +487,12 @@ virStorageFileGetMetadataFromFD(const ch + /* Validation passed, we know the file format now */ + meta->format = fileTypeInfo[i].type; + if (fileTypeInfo[i].getBackingStore != NULL) { +- char *base; ++ char *backing; ++ int backingFormat; + +- switch (fileTypeInfo[i].getBackingStore(&base, head, len)) { ++ switch (fileTypeInfo[i].getBackingStore(&backing, ++ &backingFormat, ++ head, len)) { + case BACKING_STORE_OK: + break; + +@@ -363,13 +502,16 @@ virStorageFileGetMetadataFromFD(const ch + case BACKING_STORE_ERROR: + return -1; + } +- if (base != NULL) { +- meta->backingStore = absolutePathFromBaseFile(path, base); +- VIR_FREE(base); ++ if (backing != NULL) { ++ meta->backingStore = absolutePathFromBaseFile(path, backing); ++ VIR_FREE(backing); + if (meta->backingStore == NULL) { + virReportOOMError(); + return -1; + } ++ meta->backingStoreFormat = backingFormat; ++ } else { ++ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; + } + } + return 0; +Index: libvirt-0.8.1/src/util/storage_file.h +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.h ++++ libvirt-0.8.1/src/util/storage_file.h +@@ -28,6 +28,7 @@ + # include + + enum virStorageFileFormat { ++ VIR_STORAGE_FILE_AUTO = -1, + VIR_STORAGE_FILE_RAW = 0, + VIR_STORAGE_FILE_DIR, + VIR_STORAGE_FILE_BOCHS, +@@ -47,6 +48,7 @@ VIR_ENUM_DECL(virStorageFileFormat); + typedef struct _virStorageFileMetadata { + int format; + char *backingStore; ++ int backingStoreFormat; + unsigned long long capacity; + bool encrypted; + } virStorageFileMetadata; diff --git a/CVE-2010-223x-0002.patch b/CVE-2010-223x-0002.patch new file mode 100644 index 0000000..b2c4d17 --- /dev/null +++ b/CVE-2010-223x-0002.patch @@ -0,0 +1,158 @@ +>From 66c633413960e869a15062cee8667db51e6c817a Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 14 Jun 2010 16:39:32 +0100 +Subject: [PATCH 02/10] Remove 'type' field from FileTypeInfo struct + +Instead of including a field in FileTypeInfo struct for the +disk format, rely on the array index matching the format. +Use verify() to assert the correct number of elements in the +array. + +* src/util/storage_file.c: remove type field from FileTypeInfo +--- + src/util/storage_file.c | 108 +++++++++++++++++++++++----------------------- + 1 files changed, 54 insertions(+), 54 deletions(-) + +Index: libvirt-0.8.1/src/util/storage_file.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.c ++++ libvirt-0.8.1/src/util/storage_file.c +@@ -51,7 +51,6 @@ enum { + + /* Either 'magic' or 'extension' *must* be provided */ + struct FileTypeInfo { +- int type; /* One of the constants above */ + const char *magic; /* Optional string of file magic + * to check at head of file */ + const char *extension; /* Optional file extension to check */ +@@ -86,60 +85,59 @@ static int vmdk4GetBackingStore(char **, + + + static struct FileTypeInfo const fileTypeInfo[] = { +- /* Bochs */ +- /* XXX Untested +- { VIR_STORAGE_FILE_BOCHS, "Bochs Virtual HD Image", NULL, +- LV_LITTLE_ENDIAN, 64, 0x20000, +- 32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/ +- /* CLoop */ +- /* XXX Untested +- { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL, +- LV_LITTLE_ENDIAN, -1, 0, +- -1, 0, 0, -1, NULL }, */ +- /* Cow */ +- { VIR_STORAGE_FILE_COW, "OOOM", NULL, +- LV_BIG_ENDIAN, 4, 2, +- 4+4+1024+4, 8, 1, -1, cowGetBackingStore }, +- /* DMG */ +- /* XXX QEMU says there's no magic for dmg, but we should check... */ +- { VIR_STORAGE_FILE_DMG, NULL, ".dmg", +- 0, -1, 0, +- -1, 0, 0, -1, NULL }, +- /* XXX there's probably some magic for iso we can validate too... */ +- { VIR_STORAGE_FILE_ISO, NULL, ".iso", +- 0, -1, 0, +- -1, 0, 0, -1, NULL }, +- /* Parallels */ +- /* XXX Untested +- { VIR_STORAGE_FILE_PARALLELS, "WithoutFreeSpace", NULL, +- LV_LITTLE_ENDIAN, 16, 2, +- 16+4+4+4+4, 4, 512, -1, NULL }, +- */ +- /* QCow */ +- { VIR_STORAGE_FILE_QCOW, "QFI", NULL, +- LV_BIG_ENDIAN, 4, 1, +- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore }, +- /* QCow 2 */ +- { VIR_STORAGE_FILE_QCOW2, "QFI", NULL, +- LV_BIG_ENDIAN, 4, 2, +- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore }, +- /* VMDK 3 */ +- /* XXX Untested +- { VIR_STORAGE_FILE_VMDK, "COWD", NULL, +- LV_LITTLE_ENDIAN, 4, 1, +- 4+4+4, 4, 512, -1, NULL }, +- */ +- /* VMDK 4 */ +- { VIR_STORAGE_FILE_VMDK, "KDMV", NULL, +- LV_LITTLE_ENDIAN, 4, 1, +- 4+4+4, 8, 512, -1, vmdk4GetBackingStore }, +- /* Connectix / VirtualPC */ +- /* XXX Untested +- { VIR_STORAGE_FILE_VPC, "conectix", NULL, +- LV_BIG_ENDIAN, -1, 0, +- -1, 0, 0, -1, NULL}, +- */ ++ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, ++ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, ++ [VIR_STORAGE_FILE_BOCHS] = { ++ /*"Bochs Virtual HD Image", */ /* Untested */ NULL, ++ NULL, ++ LV_LITTLE_ENDIAN, 64, 0x20000, ++ 32+16+16+4+4+4+4+4, 8, 1, -1, NULL ++ }, ++ [VIR_STORAGE_FILE_CLOOP] = { ++ /*"#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", */ /* Untested */ NULL, ++ NULL, ++ LV_LITTLE_ENDIAN, -1, 0, ++ -1, 0, 0, -1, NULL ++ }, ++ [VIR_STORAGE_FILE_COW] = { ++ "OOOM", NULL, ++ LV_BIG_ENDIAN, 4, 2, ++ 4+4+1024+4, 8, 1, -1, cowGetBackingStore ++ }, ++ [VIR_STORAGE_FILE_DMG] = { ++ NULL, /* XXX QEMU says there's no magic for dmg, but we should check... */ ++ ".dmg", ++ 0, -1, 0, ++ -1, 0, 0, -1, NULL ++ }, ++ [VIR_STORAGE_FILE_ISO] = { ++ NULL, /* XXX there's probably some magic for iso we can validate too... */ ++ ".iso", ++ 0, -1, 0, ++ -1, 0, 0, -1, NULL ++ }, ++ [VIR_STORAGE_FILE_QCOW] = { ++ "QFI", NULL, ++ LV_BIG_ENDIAN, 4, 1, ++ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore ++ }, ++ [VIR_STORAGE_FILE_QCOW2] = { ++ "QFI", NULL, ++ LV_BIG_ENDIAN, 4, 2, ++ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore ++ }, ++ [VIR_STORAGE_FILE_VMDK] = { ++ "KDMV", NULL, ++ LV_LITTLE_ENDIAN, 4, 1, ++ 4+4+4, 8, 512, -1, vmdk4GetBackingStore ++ }, ++ [VIR_STORAGE_FILE_VPC] = { ++ "conectix", NULL, ++ LV_BIG_ENDIAN, 12, 0x10000, ++ 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL ++ }, + }; ++verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST); + + static int + cowGetBackingStore(char **res, +@@ -485,7 +483,7 @@ virStorageFileGetMetadataFromFD(const ch + } + + /* Validation passed, we know the file format now */ +- meta->format = fileTypeInfo[i].type; ++ meta->format = i; + if (fileTypeInfo[i].getBackingStore != NULL) { + char *backing; + int backingFormat; +@@ -525,7 +523,7 @@ virStorageFileGetMetadataFromFD(const ch + if (!virFileHasSuffix(path, fileTypeInfo[i].extension)) + continue; + +- meta->format = fileTypeInfo[i].type; ++ meta->format = i; + return 0; + } + diff --git a/CVE-2010-223x-0003.patch b/CVE-2010-223x-0003.patch new file mode 100644 index 0000000..ecfcc81 --- /dev/null +++ b/CVE-2010-223x-0003.patch @@ -0,0 +1,486 @@ +>From f8d3e740cee4903bd2eef1a072e8190f5e9e92b9 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 15 Jun 2010 14:58:10 +0100 +Subject: [PATCH 03/10] Refactor virStorageFileGetMetadataFromFD to separate functionality + +The virStorageFileGetMetadataFromFD did two jobs in one. First +it probed for storage type, then it extracted metadata for the +type. It is desirable to be able to separate these jobs, allowing +probing without querying metadata, and querying metadata without +probing. + +To prepare for this, split out probing code into a new pair of +methods + + virStorageFileProbeFormatFromFD + virStorageFileProbeFormat + +* src/util/storage_file.c, src/util/storage_file.h, + src/libvirt_private.syms: Introduce virStorageFileProbeFormat + and virStorageFileProbeFormatFromFD +--- + src/libvirt_private.syms | 2 + + src/util/storage_file.c | 393 ++++++++++++++++++++++++++++++++-------------- + src/util/storage_file.h | 4 + + 3 files changed, 281 insertions(+), 118 deletions(-) + +Index: libvirt-0.8.1/src/libvirt_private.syms +=================================================================== +--- libvirt-0.8.1.orig/src/libvirt_private.syms ++++ libvirt-0.8.1/src/libvirt_private.syms +@@ -619,6 +619,8 @@ virStorageGenerateQcowPassphrase; + # storage_file.h + virStorageFileFormatTypeToString; + virStorageFileFormatTypeFromString; ++virStorageFileProbeFormat; ++virStorageFileProbeFormatFromFD; + virStorageFileGetMetadata; + virStorageFileGetMetadataFromFD; + +Index: libvirt-0.8.1/src/util/storage_file.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.c ++++ libvirt-0.8.1/src/util/storage_file.c +@@ -85,8 +85,8 @@ static int vmdk4GetBackingStore(char **, + + + static struct FileTypeInfo const fileTypeInfo[] = { +- [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, +- [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, ++ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL }, ++ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL }, + [VIR_STORAGE_FILE_BOCHS] = { + /*"Bochs Virtual HD Image", */ /* Untested */ NULL, + NULL, +@@ -390,146 +390,302 @@ absolutePathFromBaseFile(const char *bas + return res; + } + ++static int ++virStorageFileMatchesMagic(int format, ++ unsigned char *buf, ++ size_t buflen) ++{ ++ int mlen; ++ ++ if (fileTypeInfo[format].magic == NULL) ++ return 0; ++ ++ /* Validate magic data */ ++ mlen = strlen(fileTypeInfo[format].magic); ++ if (mlen > buflen) ++ return 0; ++ ++ if (memcmp(buf, fileTypeInfo[format].magic, mlen) != 0) ++ return 0; ++ ++ return 1; ++} ++ ++ ++static int ++virStorageFileMatchesExtension(int format, ++ const char *path) ++{ ++ if (fileTypeInfo[format].extension == NULL) ++ return 0; ++ ++ if (virFileHasSuffix(path, fileTypeInfo[format].extension)) ++ return 1; ++ ++ return 0; ++} ++ ++ ++static int ++virStorageFileMatchesVersion(int format, ++ unsigned char *buf, ++ size_t buflen) ++{ ++ int version; ++ ++ /* Validate version number info */ ++ if (fileTypeInfo[format].versionOffset == -1) ++ return 0; ++ ++ if ((fileTypeInfo[format].versionOffset + 4) > buflen) ++ return 0; ++ ++ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) { ++ version = ++ (buf[fileTypeInfo[format].versionOffset+3] << 24) | ++ (buf[fileTypeInfo[format].versionOffset+2] << 16) | ++ (buf[fileTypeInfo[format].versionOffset+1] << 8) | ++ (buf[fileTypeInfo[format].versionOffset]); ++ } else { ++ version = ++ (buf[fileTypeInfo[format].versionOffset] << 24) | ++ (buf[fileTypeInfo[format].versionOffset+1] << 16) | ++ (buf[fileTypeInfo[format].versionOffset+2] << 8) | ++ (buf[fileTypeInfo[format].versionOffset+3]); ++ } ++ if (version != fileTypeInfo[format].versionNumber) ++ return 0; ++ ++ return 1; ++} ++ ++ ++static int ++virStorageFileGetMetadataFromBuf(int format, ++ const char *path, ++ unsigned char *buf, ++ size_t buflen, ++ virStorageFileMetadata *meta) ++{ ++ /* XXX we should consider moving virStorageBackendUpdateVolInfo ++ * code into this method, for non-magic files ++ */ ++ if (!fileTypeInfo[format].magic) { ++ return 0; ++ } ++ ++ /* Optionally extract capacity from file */ ++ if (fileTypeInfo[format].sizeOffset != -1) { ++ if ((fileTypeInfo[format].sizeOffset + 8) > buflen) ++ return 1; ++ ++ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) { ++ meta->capacity = ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7] << 56) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 48) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 40) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 32) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 24) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 16) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 8) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset]); ++ } else { ++ meta->capacity = ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset] << 56) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 48) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 40) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 32) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 24) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 16) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 8) | ++ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7]); ++ } ++ /* Avoid unlikely, but theoretically possible overflow */ ++ if (meta->capacity > (ULLONG_MAX / fileTypeInfo[format].sizeMultiplier)) ++ return 1; ++ meta->capacity *= fileTypeInfo[format].sizeMultiplier; ++ } ++ ++ if (fileTypeInfo[format].qcowCryptOffset != -1) { ++ int crypt_format; ++ ++ crypt_format = ++ (buf[fileTypeInfo[format].qcowCryptOffset] << 24) | ++ (buf[fileTypeInfo[format].qcowCryptOffset+1] << 16) | ++ (buf[fileTypeInfo[format].qcowCryptOffset+2] << 8) | ++ (buf[fileTypeInfo[format].qcowCryptOffset+3]); ++ meta->encrypted = crypt_format != 0; ++ } ++ ++ if (fileTypeInfo[format].getBackingStore != NULL) { ++ char *backing; ++ int backingFormat; ++ int ret = fileTypeInfo[format].getBackingStore(&backing, ++ &backingFormat, ++ buf, buflen); ++ if (ret == BACKING_STORE_INVALID) ++ return 1; ++ ++ if (ret == BACKING_STORE_ERROR) ++ return -1; ++ ++ if (backing != NULL) { ++ meta->backingStore = absolutePathFromBaseFile(path, backing); ++ VIR_FREE(backing); ++ if (meta->backingStore == NULL) { ++ virReportOOMError(); ++ return -1; ++ } ++ meta->backingStoreFormat = backingFormat; ++ } else { ++ meta->backingStore = NULL; ++ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virStorageFileProbeFormatFromBuf(const char *path, ++ unsigned char *buf, ++ size_t buflen) ++{ ++ int format = VIR_STORAGE_FILE_RAW; ++ int i; ++ ++ /* First check file magic */ ++ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) { ++ if (virStorageFileMatchesMagic(i, buf, buflen) && ++ virStorageFileMatchesVersion(i, buf, buflen)) { ++ format = i; ++ goto cleanup; ++ } ++ } ++ ++ /* No magic, so check file extension */ ++ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) { ++ if (virStorageFileMatchesExtension(i, path)) { ++ format = i; ++ goto cleanup; ++ } ++ } ++ ++cleanup: ++ return format; ++} ++ + /** +- * Probe the header of a file to determine what type of disk image +- * it is, and info about its capacity if available. ++ * virStorageFileProbeFormatFromFD: ++ * ++ * Probe for the format of 'fd' (which is an open file descriptor ++ * pointing to 'path'), returning the detected disk format. ++ * ++ * Callers are advised never to trust the returned 'format' ++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a ++ * malicious guest can turn a file into any other non-raw ++ * format at will. ++ * ++ * Best option: Don't use this function + */ + int +-virStorageFileGetMetadataFromFD(const char *path, +- int fd, +- virStorageFileMetadata *meta) ++virStorageFileProbeFormatFromFD(const char *path, int fd) + { + unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ +- int len, i; ++ int len; + +- /* If all else fails, call it a raw file */ +- meta->format = VIR_STORAGE_FILE_RAW; ++ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { ++ virReportSystemError(errno, _("cannot set to start of '%s'"), path); ++ return -1; ++ } + + if ((len = read(fd, head, sizeof(head))) < 0) { + virReportSystemError(errno, _("cannot read header '%s'"), path); + return -1; + } + +- /* First check file magic */ +- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { +- int mlen; ++ return virStorageFileProbeFormatFromBuf(path, head, len); ++} + +- if (fileTypeInfo[i].magic == NULL) +- continue; ++/** ++ * virStorageFileProbeFormat: ++ * ++ * Probe for the format of 'path', returning the detected ++ * disk format. ++ * ++ * Callers are advised never to trust the returned 'format' ++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a ++ * malicious guest can turn a file into any other non-raw ++ * format at will. ++ * ++ * Best option: Don't use this function ++ */ ++int ++virStorageFileProbeFormat(const char *path) ++{ ++ int fd, ret; + +- /* Validate magic data */ +- mlen = strlen(fileTypeInfo[i].magic); +- if (mlen > len) +- continue; +- if (memcmp(head, fileTypeInfo[i].magic, mlen) != 0) +- continue; +- +- /* Validate version number info */ +- if (fileTypeInfo[i].versionNumber != -1) { +- int version; +- +- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) { +- version = (head[fileTypeInfo[i].versionOffset+3] << 24) | +- (head[fileTypeInfo[i].versionOffset+2] << 16) | +- (head[fileTypeInfo[i].versionOffset+1] << 8) | +- head[fileTypeInfo[i].versionOffset]; +- } else { +- version = (head[fileTypeInfo[i].versionOffset] << 24) | +- (head[fileTypeInfo[i].versionOffset+1] << 16) | +- (head[fileTypeInfo[i].versionOffset+2] << 8) | +- head[fileTypeInfo[i].versionOffset+3]; +- } +- if (version != fileTypeInfo[i].versionNumber) +- continue; +- } ++ if ((fd = open(path, O_RDONLY)) < 0) { ++ virReportSystemError(errno, _("cannot open file '%s'"), path); ++ return -1; ++ } + +- /* Optionally extract capacity from file */ +- if (fileTypeInfo[i].sizeOffset != -1) { +- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) { +- meta->capacity = +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7] << 56) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 48) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 40) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 32) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 24) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 16) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 8) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset]); +- } else { +- meta->capacity = +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset] << 56) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 48) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 40) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 32) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 24) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 16) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 8) | +- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7]); +- } +- /* Avoid unlikely, but theoretically possible overflow */ +- if (meta->capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier)) +- continue; +- meta->capacity *= fileTypeInfo[i].sizeMultiplier; +- } ++ ret = virStorageFileProbeFormatFromFD(path, fd); + +- if (fileTypeInfo[i].qcowCryptOffset != -1) { +- int crypt_format; ++ close(fd); + +- crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) | +- (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) | +- (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) | +- head[fileTypeInfo[i].qcowCryptOffset+3]; +- meta->encrypted = crypt_format != 0; +- } ++ return ret; ++} + +- /* Validation passed, we know the file format now */ +- meta->format = i; +- if (fileTypeInfo[i].getBackingStore != NULL) { +- char *backing; +- int backingFormat; +- +- switch (fileTypeInfo[i].getBackingStore(&backing, +- &backingFormat, +- head, len)) { +- case BACKING_STORE_OK: +- break; ++/** ++ * virStorageFileGetMetadataFromFD: ++ * ++ * Probe for the format of 'fd' (which is an open file descriptor ++ * for the file 'path'), filling 'meta' with the detected ++ * format and other associated metadata. ++ * ++ * Callers are advised never to trust the returned 'meta->format' ++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a ++ * malicious guest can turn a file into any other non-raw ++ * format at will. ++ */ ++int ++virStorageFileGetMetadataFromFD(const char *path, ++ int fd, ++ virStorageFileMetadata *meta) ++{ ++ unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ ++ int len; + +- case BACKING_STORE_INVALID: +- continue; ++ memset(meta, 0, sizeof (*meta)); + +- case BACKING_STORE_ERROR: +- return -1; +- } +- if (backing != NULL) { +- meta->backingStore = absolutePathFromBaseFile(path, backing); +- VIR_FREE(backing); +- if (meta->backingStore == NULL) { +- virReportOOMError(); +- return -1; +- } +- meta->backingStoreFormat = backingFormat; +- } else { +- meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; +- } +- } +- return 0; ++ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { ++ virReportSystemError(errno, _("cannot set to start of '%s'"), path); ++ return -1; + } + +- /* No magic, so check file extension */ +- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { +- if (fileTypeInfo[i].extension == NULL) +- continue; +- +- if (!virFileHasSuffix(path, fileTypeInfo[i].extension)) +- continue; +- +- meta->format = i; +- return 0; ++ if ((len = read(fd, head, sizeof(head))) < 0) { ++ virReportSystemError(errno, _("cannot read header '%s'"), path); ++ return -1; + } + +- return 0; ++ meta->format = virStorageFileProbeFormatFromBuf(path, head, len); ++ ++ return virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta); + } + ++/** ++ * virStorageFileGetMetadata: ++ * ++ * Probe for the format of 'path', filling 'meta' with the detected ++ * format and other associated metadata. ++ * ++ * Callers are advised never to trust the returned 'meta->format' ++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a ++ * malicious guest can turn a file into any other non-raw ++ * format at will. ++ */ + int + virStorageFileGetMetadata(const char *path, + virStorageFileMetadata *meta) +Index: libvirt-0.8.1/src/util/storage_file.h +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.h ++++ libvirt-0.8.1/src/util/storage_file.h +@@ -57,6 +57,10 @@ typedef struct _virStorageFileMetadata { + # define DEV_BSIZE 512 + # endif + ++int virStorageFileProbeFormat(const char *path); ++int virStorageFileProbeFormatFromFD(const char *path, ++ int fd); ++ + int virStorageFileGetMetadata(const char *path, + virStorageFileMetadata *meta); + int virStorageFileGetMetadataFromFD(const char *path, diff --git a/CVE-2010-223x-0004.patch b/CVE-2010-223x-0004.patch new file mode 100644 index 0000000..bd0633c --- /dev/null +++ b/CVE-2010-223x-0004.patch @@ -0,0 +1,218 @@ +>From 7b2c30d0af7938df533b85e948918cfdff2e5f01 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 15 Jun 2010 16:15:51 +0100 +Subject: [PATCH 04/10] Require format to be passed into virStorageFileGetMetadata + +Require the disk image to be passed into virStorageFileGetMetadata. +If this is set to VIR_STORAGE_FILE_AUTO, then the format will be +resolved using probing. This makes it easier to control when +probing will be used + +* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c, + src/security/security_selinux.c, src/security/virt-aa-helper.c: + Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata. +* src/storage/storage_backend_fs.c: Probe for disk format before + caling virStorageFileGetMetadata. +* src/util/storage_file.h, src/util/storage_file.c: Remove format + from virStorageFileMeta struct & require it to be passed into + method. +--- + src/qemu/qemu_driver.c | 27 +++++++++++++++++++++++---- + src/qemu/qemu_security_dac.c | 4 +++- + src/security/security_selinux.c | 4 +++- + src/security/virt-aa-helper.c | 4 +++- + src/storage/storage_backend_fs.c | 11 ++++++++--- + src/util/storage_file.c | 15 ++++++++++++--- + src/util/storage_file.h | 3 ++- + 7 files changed, 54 insertions(+), 14 deletions(-) + +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 +@@ -9059,8 +9059,10 @@ static int qemuDomainGetBlockInfo(virDom + int fd = -1; + off_t end; + virStorageFileMetadata meta; ++ virDomainDiskDefPtr disk = NULL; + struct stat sb; + int i; ++ int format; + + virCheckFlags(0, -1); + +@@ -9086,6 +9088,7 @@ static int qemuDomainGetBlockInfo(virDom + if (vm->def->disks[i]->src != NULL && + STREQ (vm->def->disks[i]->src, path)) { + ret = 0; ++ disk = vm->def->disks[i]; + break; + } + } +@@ -9108,7 +9111,21 @@ static int qemuDomainGetBlockInfo(virDom + + /* Probe for magic formats */ + memset(&meta, 0, sizeof(meta)); +- if (virStorageFileGetMetadataFromFD(path, fd, &meta) < 0) ++ if (disk->driverType) { ++ if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) { ++ qemuReportError(VIR_ERR_INTERNAL_ERROR, ++ _("unknown disk format %s for %s"), ++ disk->driverType, disk->src); ++ goto cleanup; ++ } ++ } else { ++ if ((format = virStorageFileProbeFormat(disk->src)) < 0) ++ goto cleanup; ++ } ++ ++ if (virStorageFileGetMetadataFromFD(path, fd, ++ format, ++ &meta) < 0) + goto cleanup; + + /* Get info for normal formats */ +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,9 @@ qemuSecurityDACSetSecurityImageLabel(vir + + memset(&meta, 0, sizeof(meta)); + +- ret = virStorageFileGetMetadata(path, &meta); ++ ret = virStorageFileGetMetadata(path, ++ VIR_STORAGE_FILE_AUTO, ++ &meta); + + if (path != disk->src) + VIR_FREE(path); +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 +@@ -431,7 +431,9 @@ SELinuxSetSecurityImageLabel(virDomainOb + + memset(&meta, 0, sizeof(meta)); + +- ret = virStorageFileGetMetadata(path, &meta); ++ ret = virStorageFileGetMetadata(path, ++ VIR_STORAGE_FILE_AUTO, ++ &meta); + + if (path != disk->src) + VIR_FREE(path); +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 +@@ -833,7 +833,9 @@ get_files(vahControl * ctl) + + memset(&meta, 0, sizeof(meta)); + +- ret = virStorageFileGetMetadata(path, &meta); ++ ret = virStorageFileGetMetadata(path, ++ VIR_STORAGE_FILE_AUTO, ++ &meta); + + if (path != ctl->def->disks[i]->src) + VIR_FREE(path); +Index: libvirt-0.8.1/src/storage/storage_backend_fs.c +=================================================================== +--- libvirt-0.8.1.orig/src/storage/storage_backend_fs.c ++++ libvirt-0.8.1/src/storage/storage_backend_fs.c +@@ -77,14 +77,19 @@ virStorageBackendProbeTarget(virStorageV + + memset(&meta, 0, sizeof(meta)); + +- if (virStorageFileGetMetadataFromFD(target->path, fd, &meta) < 0) { ++ if ((target->format = virStorageFileProbeFormatFromFD(target->path, fd)) < 0) { + close(fd); + return -1; + } + +- close(fd); ++ if (virStorageFileGetMetadataFromFD(target->path, fd, ++ target->format, ++ &meta) < 0) { ++ close(fd); ++ return -1; ++ } + +- target->format = meta.format; ++ close(fd); + + if (backingStore) { + *backingStore = meta.backingStore; +Index: libvirt-0.8.1/src/util/storage_file.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.c ++++ libvirt-0.8.1/src/util/storage_file.c +@@ -653,6 +653,7 @@ virStorageFileProbeFormat(const char *pa + int + virStorageFileGetMetadataFromFD(const char *path, + int fd, ++ int format, + virStorageFileMetadata *meta) + { + unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ +@@ -670,9 +671,16 @@ virStorageFileGetMetadataFromFD(const ch + return -1; + } + +- meta->format = virStorageFileProbeFormatFromBuf(path, head, len); ++ if (format == VIR_STORAGE_FILE_AUTO) ++ format = virStorageFileProbeFormatFromBuf(path, head, len); + +- return virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta); ++ if (format < 0 || ++ format >= VIR_STORAGE_FILE_LAST) { ++ virReportSystemError(EINVAL, _("unknown storage file format %d"), format); ++ return -1; ++ } ++ ++ return virStorageFileGetMetadataFromBuf(format, path, head, len, meta); + } + + /** +@@ -688,6 +696,7 @@ virStorageFileGetMetadataFromFD(const ch + */ + int + virStorageFileGetMetadata(const char *path, ++ int format, + virStorageFileMetadata *meta) + { + int fd, ret; +@@ -697,7 +706,7 @@ virStorageFileGetMetadata(const char *pa + return -1; + } + +- ret = virStorageFileGetMetadataFromFD(path, fd, meta); ++ ret = virStorageFileGetMetadataFromFD(path, fd, format, meta); + + close(fd); + +Index: libvirt-0.8.1/src/util/storage_file.h +=================================================================== +--- libvirt-0.8.1.orig/src/util/storage_file.h ++++ libvirt-0.8.1/src/util/storage_file.h +@@ -46,7 +46,6 @@ enum virStorageFileFormat { + VIR_ENUM_DECL(virStorageFileFormat); + + typedef struct _virStorageFileMetadata { +- int format; + char *backingStore; + int backingStoreFormat; + unsigned long long capacity; +@@ -62,9 +61,11 @@ int virStorageFileProbeFormatFromFD(cons + int fd); + + int virStorageFileGetMetadata(const char *path, ++ int format, + virStorageFileMetadata *meta); + int virStorageFileGetMetadataFromFD(const char *path, + int fd, ++ int format, + virStorageFileMetadata *meta); + + #endif /* __VIR_STORAGE_FILE_H__ */ diff --git a/CVE-2010-223x-0005.patch b/CVE-2010-223x-0005.patch new file mode 100644 index 0000000..9523af8 --- /dev/null +++ b/CVE-2010-223x-0005.patch @@ -0,0 +1,167 @@ +>From 494b96317334716f846436a5ec485963411cb4a3 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 14 Jun 2010 18:09:15 +0100 +Subject: [PATCH 05/10] Add an API for iterating over disk paths + +There is duplicated code which iterates over disk backing stores +performing some action. Provide a convenient helper for doing +this to eliminate duplication & risk of mistakes with disk format +probing + +* src/conf/domain_conf.c, src/conf/domain_conf.h, + src/libvirt_private.syms: Add virDomainDiskDefForeachPath() +--- + src/conf/domain_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ + src/conf/domain_conf.h | 11 +++++ + src/libvirt_private.syms | 1 + + 3 files changed, 111 insertions(+), 0 deletions(-) + +Index: libvirt-0.8.1/src/conf/domain_conf.c +=================================================================== +--- libvirt-0.8.1.orig/src/conf/domain_conf.c ++++ libvirt-0.8.1/src/conf/domain_conf.c +@@ -45,6 +45,7 @@ + #include "macvtap.h" + #include "nwfilter_conf.h" + #include "ignore-value.h" ++#include "storage_file.h" + + #define VIR_FROM_THIS VIR_FROM_DOMAIN + +@@ -6928,4 +6929,102 @@ int virDomainSnapshotHasChildren(virDoma + } + + ++int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, ++ bool allowProbing, ++ bool ignoreOpenFailure, ++ virDomainDiskDefPathIterator iter, ++ void *opaque) ++{ ++ virHashTablePtr paths; ++ int format; ++ int ret = -1; ++ int depth = 0; ++ char *nextpath = NULL; ++ ++ if (!disk->src) ++ return 0; ++ ++ if (disk->driverType) { ++ const char *formatStr = disk->driverType; ++ if (STREQ(formatStr, "aio")) ++ formatStr = "raw"; /* Xen compat */ ++ ++ if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) { ++ virDomainReportError(VIR_ERR_INTERNAL_ERROR, ++ _("unknown disk format '%s' for %s"), ++ disk->driverType, disk->src); ++ return -1; ++ } ++ } else { ++ if (allowProbing) { ++ format = VIR_STORAGE_FILE_AUTO; ++ } else { ++ virDomainReportError(VIR_ERR_INTERNAL_ERROR, ++ _("no disk format for %s and probing is disabled"), ++ disk->src); ++ return -1; ++ } ++ } ++ ++ paths = virHashCreate(5); ++ ++ do { ++ virStorageFileMetadata meta; ++ const char *path = nextpath ? nextpath : disk->src; ++ int fd; ++ ++ if (iter(disk, path, depth, opaque) < 0) ++ goto cleanup; ++ ++ if (virHashLookup(paths, path)) { ++ virDomainReportError(VIR_ERR_INTERNAL_ERROR, ++ _("backing store for %s is self-referential"), ++ disk->src); ++ goto cleanup; ++ } ++ ++ if ((fd = open(path, O_RDONLY)) < 0) { ++ if (ignoreOpenFailure) { ++ char ebuf[1024]; ++ VIR_WARN("Ignoring open failure on %s: %s", path, ++ virStrerror(errno, ebuf, sizeof(ebuf))); ++ break; ++ } else { ++ virReportSystemError(errno, ++ _("unable to open disk path %s"), ++ path); ++ goto cleanup; ++ } ++ } ++ ++ if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) { ++ close(fd); ++ goto cleanup; ++ } ++ close(fd); ++ ++ if (virHashAddEntry(paths, path, (void*)0x1) < 0) { ++ virReportOOMError(); ++ goto cleanup; ++ } ++ ++ depth++; ++ nextpath = meta.backingStore; ++ ++ format = meta.backingStoreFormat; ++ ++ if (format == VIR_STORAGE_FILE_AUTO && ++ !allowProbing) ++ format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */ ++ } while (nextpath); ++ ++ ret = 0; ++ ++cleanup: ++ virHashFree(paths, NULL); ++ VIR_FREE(nextpath); ++ ++ return ret; ++} ++ + #endif /* ! PROXY */ +Index: libvirt-0.8.1/src/conf/domain_conf.h +=================================================================== +--- libvirt-0.8.1.orig/src/conf/domain_conf.h ++++ libvirt-0.8.1/src/conf/domain_conf.h +@@ -1057,6 +1057,17 @@ int virDomainObjListGetInactiveNames(vir + int maxnames); + + ++typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk, ++ const char *path, ++ unsigned int depth, ++ void *opaque); ++ ++int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, ++ bool allowProbing, ++ bool ignoreOpenFailure, ++ virDomainDiskDefPathIterator iter, ++ void *opaque); ++ + VIR_ENUM_DECL(virDomainVirt) + VIR_ENUM_DECL(virDomainBoot) + VIR_ENUM_DECL(virDomainFeature) +Index: libvirt-0.8.1/src/libvirt_private.syms +=================================================================== +--- libvirt-0.8.1.orig/src/libvirt_private.syms ++++ libvirt-0.8.1/src/libvirt_private.syms +@@ -223,6 +223,7 @@ virDomainSnapshotObjUnref; + virDomainSnapshotDefParseString; + virDomainSnapshotDefFormat; + virDomainSnapshotAssignDef; ++virDomainDiskDefForeachPath; + + + # domain_event.h diff --git a/CVE-2010-223x-0006.patch b/CVE-2010-223x-0006.patch new file mode 100644 index 0000000..50a3d63 --- /dev/null +++ b/CVE-2010-223x-0006.patch @@ -0,0 +1,273 @@ +>From e2ebe4b785eccb930f36f400a22940fa9660a24b Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 15 Jun 2010 16:40:47 +0100 +Subject: [PATCH 06/10] Convert all disk backing store loops to shared helper API + +Update the QEMU cgroups code, QEMU DAC security driver, SELinux +and AppArmour security drivers over to use the shared helper API +virDomainDiskDefForeachPath(). + +* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c, + src/security/security_selinux.c, src/security/virt-aa-helper.c: + Convert over to use virDomainDiskDefForeachPath() +--- + src/qemu/qemu_driver.c | 161 ++++++++++++++++---------------------- + src/qemu/qemu_security_dac.c | 47 ++++-------- + src/security/security_selinux.c | 67 +++++++---------- + src/security/virt-aa-helper.c | 71 ++++++++---------- + 4 files changed, 142 insertions(+), 204 deletions(-) + +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 +@@ -99,47 +99,28 @@ err: + + + static int ++qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED, ++ const char *path, ++ unsigned int depth ATTRIBUTE_UNUSED, ++ void *opaque ATTRIBUTE_UNUSED) ++{ ++ return qemuSecurityDACSetOwnership(path, driver->user, driver->group); ++} ++ ++ ++static int + qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk) + + { +- const char *path; +- + if (!driver->privileged || !driver->dynamicOwnership) + return 0; + +- if (!disk->src) +- return 0; +- +- path = disk->src; +- do { +- virStorageFileMetadata meta; +- int ret; +- +- memset(&meta, 0, sizeof(meta)); +- +- ret = virStorageFileGetMetadata(path, +- VIR_STORAGE_FILE_AUTO, +- &meta); +- +- if (path != disk->src) +- VIR_FREE(path); +- path = NULL; +- +- if (ret < 0) +- return -1; +- +- if (meta.backingStore != NULL && +- qemuSecurityDACSetOwnership(meta.backingStore, +- driver->user, driver->group) < 0) { +- VIR_FREE(meta.backingStore); +- return -1; +- } +- +- path = meta.backingStore; +- } while (path != NULL); +- +- return qemuSecurityDACSetOwnership(disk->src, driver->user, driver->group); ++ return virDomainDiskDefForeachPath(disk, ++ true, ++ false, ++ qemuSecurityDACSetSecurityFileLabel, ++ NULL); + } + + +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 +@@ -411,56 +411,43 @@ SELinuxRestoreSecurityImageLabel(virDoma + } + + static int ++SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk, ++ const char *path, ++ unsigned int depth, ++ void *opaque) ++{ ++ const virSecurityLabelDefPtr secdef = opaque; ++ ++ if (depth == 0) { ++ if (disk->shared) { ++ return SELinuxSetFilecon(path, default_image_context); ++ } else if (disk->readonly) { ++ return SELinuxSetFilecon(path, default_content_context); ++ } else if (secdef->imagelabel) { ++ return SELinuxSetFilecon(path, secdef->imagelabel); ++ } else { ++ return 0; ++ } ++ } else { ++ return SELinuxSetFilecon(path, default_content_context); ++ } ++} ++ ++static int + SELinuxSetSecurityImageLabel(virDomainObjPtr vm, + virDomainDiskDefPtr disk) + + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +- const char *path; + + if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) + return 0; + +- if (!disk->src) +- return 0; +- +- path = disk->src; +- do { +- virStorageFileMetadata meta; +- int ret; +- +- memset(&meta, 0, sizeof(meta)); +- +- ret = virStorageFileGetMetadata(path, +- VIR_STORAGE_FILE_AUTO, +- &meta); +- +- if (path != disk->src) +- VIR_FREE(path); +- path = NULL; +- +- if (ret < 0) +- break; +- +- if (meta.backingStore != NULL && +- SELinuxSetFilecon(meta.backingStore, +- default_content_context) < 0) { +- VIR_FREE(meta.backingStore); +- return -1; +- } +- +- path = meta.backingStore; +- } while (path != NULL); +- +- if (disk->shared) { +- return SELinuxSetFilecon(disk->src, default_image_context); +- } else if (disk->readonly) { +- return SELinuxSetFilecon(disk->src, default_content_context); +- } else if (secdef->imagelabel) { +- return SELinuxSetFilecon(disk->src, secdef->imagelabel); +- } +- +- return 0; ++ return virDomainDiskDefForeachPath(disk, ++ true, ++ 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 +@@ -36,7 +36,6 @@ + #include "uuid.h" + #include "hostusb.h" + #include "pci.h" +-#include "storage_file.h" + + static char *progname; + +@@ -802,6 +801,28 @@ file_iterate_pci_cb(pciDevice *dev ATTRI + } + + static int ++add_file_path(virDomainDiskDefPtr disk, ++ const char *path, ++ unsigned int depth, ++ void *opaque) ++{ ++ virBufferPtr buf = opaque; ++ int ret; ++ ++ if (depth == 0) { ++ if (disk->readonly) ++ ret = vah_add_file(buf, path, "r"); ++ else ++ ret = vah_add_file(buf, path, "rw"); ++ } else { ++ ret = vah_add_file(buf, path, "r"); ++ } ++ ++ return ret; ++} ++ ++ ++static int + get_files(vahControl * ctl) + { + virBuffer buf = VIR_BUFFER_INITIALIZER; +@@ -822,47 +843,15 @@ get_files(vahControl * ctl) + goto clean; + } + +- for (i = 0; i < ctl->def->ndisks; i++) +- if (ctl->def->disks[i] && ctl->def->disks[i]->src) { +- int ret; +- const char *path; +- +- path = ctl->def->disks[i]->src; +- do { +- virStorageFileMetadata meta; +- +- memset(&meta, 0, sizeof(meta)); +- +- ret = virStorageFileGetMetadata(path, +- VIR_STORAGE_FILE_AUTO, +- &meta); +- +- if (path != ctl->def->disks[i]->src) +- VIR_FREE(path); +- path = NULL; +- +- if (ret < 0) { +- vah_warning("could not open path, skipping"); +- continue; +- } +- +- if (meta.backingStore != NULL && +- (ret = vah_add_file(&buf, meta.backingStore, "rw")) != 0) { +- VIR_FREE(meta.backingStore); +- goto clean; +- } +- +- path = meta.backingStore; +- } while (path != NULL); +- +- if (ctl->def->disks[i]->readonly) +- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "r"); +- else +- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "rw"); +- +- if (ret != 0) +- goto clean; +- } ++ for (i = 0; i < ctl->def->ndisks; i++) { ++ int ret = virDomainDiskDefForeachPath(ctl->def->disks[i], ++ true, ++ false, ++ add_file_path, ++ &buf); ++ if (ret != 0) ++ goto clean; ++ } + + for (i = 0; i < ctl->def->nserials; i++) + if (ctl->def->serials[i] && ctl->def->serials[i]->data.file.path) diff --git a/CVE-2010-223x-0007.patch b/CVE-2010-223x-0007.patch new file mode 100644 index 0000000..386877a --- /dev/null +++ b/CVE-2010-223x-0007.patch @@ -0,0 +1,1058 @@ +>From 38d7c5a26e4c12a784619f1ed4fc993d9af82032 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 15 Jun 2010 17:44:19 +0100 +Subject: [PATCH 07/10] Security driver params + +--- + src/qemu/qemu_driver.c | 85 +++++++++++++++++++----------- + src/qemu/qemu_security_dac.c | 44 +++++++++++----- + src/qemu/qemu_security_stacked.c | 107 +++++++++++++++++++++++++------------- + src/security/security_apparmor.c | 57 +++++++++++++------- + src/security/security_driver.h | 40 ++++++++++---- + src/security/security_selinux.c | 56 +++++++++++++------ + 6 files changed, 258 insertions(+), 131 deletions(-) + +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 +@@ -1245,7 +1245,8 @@ qemuReconnectDomain(void *payload, const + + if (driver->securityDriver && + driver->securityDriver->domainReserveSecurityLabel && +- driver->securityDriver->domainReserveSecurityLabel(obj) < 0) ++ driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver, ++ obj) < 0) + goto error; + + if (obj->def->id >= driver->nextvmid) +@@ -3207,13 +3208,15 @@ static int qemudStartVMDaemon(virConnect + DEBUG0("Generating domain security label (if required)"); + if (driver->securityDriver && + driver->securityDriver->domainGenSecurityLabel && +- driver->securityDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securityDriver->domainGenSecurityLabel(driver->securityDriver, ++ vm) < 0) + return -1; + + DEBUG0("Generating setting domain security labels (if required)"); + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityAllLabel && +- driver->securityDriver->domainSetSecurityAllLabel(vm) < 0) ++ driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver, ++ vm) < 0) + goto cleanup; + + /* Ensure no historical cgroup for this VM is lying around bogus +@@ -3489,10 +3492,12 @@ cleanup: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityAllLabel) +- driver->securityDriver->domainRestoreSecurityAllLabel(vm); ++ driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver, ++ vm); + if (driver->securityDriver && + driver->securityDriver->domainReleaseSecurityLabel) +- driver->securityDriver->domainReleaseSecurityLabel(vm); ++ driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver, ++ vm); + qemuRemoveCgroup(driver, vm, 1); + if ((vm->def->ngraphics == 1) && + vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && +@@ -3585,10 +3590,12 @@ static void qemudShutdownVMDaemon(struct + /* Reset Security Labels */ + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityAllLabel) +- driver->securityDriver->domainRestoreSecurityAllLabel(vm); ++ driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver, ++ vm); + if (driver->securityDriver && + driver->securityDriver->domainReleaseSecurityLabel) +- driver->securityDriver->domainReleaseSecurityLabel(vm); ++ driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver, ++ vm); + + /* Clear out dynamically assigned labels */ + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { +@@ -4991,7 +4998,8 @@ static int qemudDomainSaveFlag(virDomain + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainSetSavedStateLabel && +- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + if (header.compressed == QEMUD_SAVE_FORMAT_RAW) { +@@ -5022,7 +5030,8 @@ static int qemudDomainSaveFlag(virDomain + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + VIR_WARN("failed to restore save state label on %s", path); + + if (cgroup != NULL) { +@@ -5069,7 +5078,8 @@ endjob: + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + VIR_WARN("failed to restore save state label on %s", path); + } + +@@ -5304,7 +5314,8 @@ static int qemudDomainCoreDump(virDomain + + if (driver->securityDriver && + driver->securityDriver->domainSetSavedStateLabel && +- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + /* Migrate will always stop the VM, so the resume condition is +@@ -5340,7 +5351,8 @@ static int qemudDomainCoreDump(virDomain + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + endjob: +@@ -5724,12 +5736,13 @@ static int qemudDomainGetSecurityLabel(v + * QEMU monitor hasn't seen SIGHUP/ERR on poll(). + */ + if (virDomainObjIsActive(vm)) { +- if (driver->securityDriver && driver->securityDriver->domainGetSecurityProcessLabel) { +- if (driver->securityDriver->domainGetSecurityProcessLabel(vm, seclabel) == -1) { +- qemuReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Failed to get security label")); +- goto cleanup; +- } ++ if (driver->securityDriver && ++ driver->securityDriver->domainGetSecurityProcessLabel && ++ driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver, ++ vm, seclabel) < 0) { ++ qemuReportError(VIR_ERR_INTERNAL_ERROR, ++ "%s", _("Failed to get security label")); ++ goto cleanup; + } + } + +@@ -6731,7 +6744,8 @@ static int qemudDomainChangeEjectableMed + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags))) +@@ -6760,7 +6774,8 @@ static int qemudDomainChangeEjectableMed + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, origdisk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, origdisk) < 0) + VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src); + + VIR_FREE(origdisk->src); +@@ -6778,7 +6793,8 @@ error: + VIR_FREE(driveAlias); + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on new media %s", disk->src); + return -1; + } +@@ -6805,7 +6821,8 @@ static int qemudDomainAttachPciDiskDevic + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { +@@ -6866,7 +6883,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -6998,7 +7016,8 @@ static int qemudDomainAttachSCSIDisk(str + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + /* We should have an address already, so make sure */ +@@ -7080,7 +7099,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -7107,7 +7127,8 @@ static int qemudDomainAttachUsbMassstora + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (!disk->src) { +@@ -7159,7 +7180,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -7503,7 +7525,8 @@ static int qemudDomainAttachHostDevice(s + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityHostdevLabel && +- driver->securityDriver->domainSetSecurityHostdevLabel(vm, hostdev) < 0) ++ driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver, ++ vm, hostdev) < 0) + return -1; + + switch (hostdev->source.subsys.type) { +@@ -7531,7 +7554,8 @@ static int qemudDomainAttachHostDevice(s + error: + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityHostdevLabel && +- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, hostdev) < 0) ++ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, ++ vm, hostdev) < 0) + VIR_WARN0("Unable to restore host device labelling on hotplug fail"); + + return -1; +@@ -7962,7 +7986,8 @@ static int qemudDomainDetachPciDiskDevic + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, dev->data.disk) < 0) + VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); + + ret = 0; +@@ -8367,7 +8392,8 @@ static int qemudDomainDetachHostDevice(s + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityHostdevLabel && +- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, dev->data.hostdev) < 0) ++ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, ++ vm, dev->data.hostdev) < 0) + VIR_WARN0("Failed to restore host device labelling"); + + return ret; +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 +@@ -109,7 +109,8 @@ qemuSecurityDACSetSecurityFileLabel(virD + + + static int +-qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk) + + { +@@ -125,7 +126,8 @@ qemuSecurityDACSetSecurityImageLabel(vir + + + static int +-qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk) + { + if (!driver->privileged || !driver->dynamicOwnership) +@@ -168,7 +170,8 @@ qemuSecurityDACSetSecurityUSBLabel(usbDe + + + static int +-qemuSecurityDACSetSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -237,7 +240,8 @@ qemuSecurityDACRestoreSecurityUSBLabel(u + + + static int +-qemuSecurityDACRestoreSecurityHostdevLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainHostdevDefPtr dev) + + { +@@ -289,7 +293,8 @@ done: + + + static int +-qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm) ++qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm) + { + int i; + int rc = 0; +@@ -300,12 +305,14 @@ qemuSecurityDACRestoreSecurityAllLabel(v + VIR_DEBUG("Restoring security label on %s", vm->def->name); + + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (qemuSecurityDACRestoreSecurityHostdevLabel(vm, ++ if (qemuSecurityDACRestoreSecurityHostdevLabel(drv, ++ vm, + vm->def->hostdevs[i]) < 0) + rc = -1; + } + for (i = 0 ; i < vm->def->ndisks ; i++) { +- if (qemuSecurityDACRestoreSecurityImageLabel(vm, ++ if (qemuSecurityDACRestoreSecurityImageLabel(drv, ++ vm, + vm->def->disks[i]) < 0) + rc = -1; + } +@@ -323,7 +330,8 @@ qemuSecurityDACRestoreSecurityAllLabel(v + + + static int +-qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm) ++qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm) + { + int i; + +@@ -334,11 +342,15 @@ qemuSecurityDACSetSecurityAllLabel(virDo + /* XXX fixme - we need to recursively label the entriy tree :-( */ + if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR) + continue; +- if (qemuSecurityDACSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) ++ if (qemuSecurityDACSetSecurityImageLabel(drv, ++ vm, ++ vm->def->disks[i]) < 0) + return -1; + } + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (qemuSecurityDACSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (qemuSecurityDACSetSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + return -1; + } + +@@ -359,7 +371,8 @@ qemuSecurityDACSetSecurityAllLabel(virDo + + + static int +-qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + const char *savefile) + { + if (!driver->privileged || !driver->dynamicOwnership) +@@ -370,7 +383,8 @@ qemuSecurityDACSetSavedStateLabel(virDom + + + static int +-qemuSecurityDACRestoreSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + const char *savefile) + { + if (!driver->privileged || !driver->dynamicOwnership) +Index: libvirt-0.8.1/src/qemu/qemu_security_stacked.c +=================================================================== +--- libvirt-0.8.1.orig/src/qemu/qemu_security_stacked.c ++++ libvirt-0.8.1/src/qemu/qemu_security_stacked.c +@@ -57,18 +57,21 @@ qemuSecurityStackedVerify(virDomainDefPt + + + static int +-qemuSecurityStackedGenLabel(virDomainObjPtr vm) ++qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainGenSecurityLabel && +- driver->securitySecondaryDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainGenSecurityLabel && +- driver->securityPrimaryDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -76,18 +79,21 @@ qemuSecurityStackedGenLabel(virDomainObj + + + static int +-qemuSecurityStackedReleaseLabel(virDomainObjPtr vm) ++qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainReleaseSecurityLabel && +- driver->securitySecondaryDriver->domainReleaseSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainReleaseSecurityLabel && +- driver->securityPrimaryDriver->domainReleaseSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -95,18 +101,21 @@ qemuSecurityStackedReleaseLabel(virDomai + + + static int +-qemuSecurityStackedReserveLabel(virDomainObjPtr vm) ++qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainReserveSecurityLabel && +- driver->securitySecondaryDriver->domainReserveSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainReserveSecurityLabel && +- driver->securityPrimaryDriver->domainReserveSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -114,19 +123,22 @@ qemuSecurityStackedReserveLabel(virDomai + + + static int +-qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityImageLabel && +- driver->securitySecondaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver, ++ vm, disk) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityImageLabel && +- driver->securityPrimaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver, ++ vm, disk) < 0) + rc = -1; + + return rc; +@@ -134,19 +146,22 @@ qemuSecurityStackedSetSecurityImageLabel + + + static int +-qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityImageLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver, ++ vm, disk) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityImageLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver, ++ vm, disk) < 0) + rc = -1; + + return rc; +@@ -154,7 +169,8 @@ qemuSecurityStackedRestoreSecurityImageL + + + static int +-qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -162,12 +178,14 @@ qemuSecurityStackedSetSecurityHostdevLab + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityHostdevLabel && +- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver, ++ vm, dev) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityHostdevLabel && +- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver, ++ vm, dev) < 0) + rc = -1; + + return rc; +@@ -175,20 +193,22 @@ qemuSecurityStackedSetSecurityHostdevLab + + + static int +-qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) +- + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver, ++ vm, dev) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver, ++ vm, dev) < 0) + rc = -1; + + return rc; +@@ -196,18 +216,21 @@ qemuSecurityStackedRestoreSecurityHostde + + + static int +-qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm) ++qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityAllLabel && +- driver->securitySecondaryDriver->domainSetSecurityAllLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityAllLabel && +- driver->securityPrimaryDriver->domainSetSecurityAllLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -215,18 +238,21 @@ qemuSecurityStackedSetSecurityAllLabel(v + + + static int +-qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm) ++qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityAllLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityAllLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -234,19 +260,22 @@ qemuSecurityStackedRestoreSecurityAllLab + + + static int +-qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSavedStateLabel && +- driver->securitySecondaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) ++ driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver, ++ vm, savefile) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSavedStateLabel && +- driver->securityPrimaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) ++ driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver, ++ vm, savefile) < 0) + rc = -1; + + return rc; +@@ -254,19 +283,22 @@ qemuSecurityStackedSetSavedStateLabel(vi + + + static int +-qemuSecurityStackedRestoreSavedStateLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSavedStateLabel && +- driver->securitySecondaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) ++ driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver, ++ vm, savefile) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSavedStateLabel && +- driver->securityPrimaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) ++ driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver, ++ vm, savefile) < 0) + rc = -1; + + return rc; +@@ -295,14 +327,16 @@ qemuSecurityStackedSetProcessLabel(virSe + } + + static int +-qemuSecurityStackedGetProcessLabel(virDomainObjPtr vm, ++qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virSecurityLabelPtr seclabel) + { + int rc = 0; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainGetSecurityProcessLabel && +- driver->securityPrimaryDriver->domainGetSecurityProcessLabel(vm, ++ driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver, ++ vm, + seclabel) < 0) + rc = -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 +@@ -148,7 +148,8 @@ profile_status_file(const char *str) + * load (add) a profile. Will create one if necessary + */ + static int +-load_profile(const char *profile, virDomainObjPtr vm, ++load_profile(virSecurityDriverPtr drv, ++ const char *profile, virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + int rc = -1, status, ret; +@@ -323,7 +324,8 @@ AppArmorSecurityDriverOpen(virSecurityDr + * called on shutdown. + */ + static int +-AppArmorGenSecurityLabel(virDomainObjPtr vm) ++AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = -1; + char *profile_name = NULL; +@@ -377,14 +379,15 @@ AppArmorGenSecurityLabel(virDomainObjPtr + } + + static int +-AppArmorSetSecurityAllLabel(virDomainObjPtr vm) ++AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm) + { + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) + return 0; + + /* if the profile is not already loaded, then load one */ + if (profile_loaded(vm->def->seclabel.label) < 0) { +- if (load_profile(vm->def->seclabel.label, vm, NULL) < 0) { ++ if (load_profile(drv, vm->def->seclabel.label, vm, NULL) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot generate AppArmor profile " + "\'%s\'"), vm->def->seclabel.label); +@@ -399,7 +402,9 @@ AppArmorSetSecurityAllLabel(virDomainObj + * running. + */ + static int +-AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec) ++AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, ++ virSecurityLabelPtr sec) + { + int rc = -1; + char *profile_name = NULL; +@@ -431,7 +436,8 @@ AppArmorGetSecurityProcessLabel(virDomai + * more details. Currently called via qemudShutdownVMDaemon. + */ + static int +-AppArmorReleaseSecurityLabel(virDomainObjPtr vm) ++AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + +@@ -444,7 +450,8 @@ AppArmorReleaseSecurityLabel(virDomainOb + + + static int +-AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm) ++AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int rc = 0; +@@ -498,7 +505,8 @@ AppArmorSetSecurityProcessLabel(virSecur + + /* Called when hotplugging */ + static int +-AppArmorRestoreSecurityImageLabel(virDomainObjPtr vm, ++AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk ATTRIBUTE_UNUSED) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -513,7 +521,7 @@ AppArmorRestoreSecurityImageLabel(virDom + + /* Update the profile only if it is loaded */ + if (profile_loaded(secdef->imagelabel) >= 0) { +- if (load_profile(secdef->imagelabel, vm, NULL) < 0) { ++ if (load_profile(drv, secdef->imagelabel, vm, NULL) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot update AppArmor profile " + "\'%s\'"), +@@ -531,7 +539,8 @@ AppArmorRestoreSecurityImageLabel(virDom + + /* Called when hotplugging */ + static int +-AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk) ++AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, virDomainDiskDefPtr disk) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int rc = -1; +@@ -556,7 +565,7 @@ AppArmorSetSecurityImageLabel(virDomainO + + /* update the profile only if it is loaded */ + if (profile_loaded(secdef->imagelabel) >= 0) { +- if (load_profile(secdef->imagelabel, vm, disk) < 0) { ++ if (load_profile(drv, secdef->imagelabel, vm, disk) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot update AppArmor profile " + "\'%s\'"), +@@ -590,14 +599,16 @@ AppArmorSecurityVerify(virDomainDefPtr d + } + + static int +-AppArmorReserveSecurityLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED) ++AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED) + { + /* NOOP. Nothing to reserve with AppArmor */ + return 0; + } + + static int +-AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm, ++AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) + + { +@@ -611,7 +622,8 @@ AppArmorSetSecurityHostdevLabel(virDomai + } + + static int +-AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) + + { +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 +@@ -28,26 +28,42 @@ typedef enum { + + typedef struct _virSecurityDriver virSecurityDriver; + typedef virSecurityDriver *virSecurityDriverPtr; ++ ++typedef struct _virSecurityDriverState virSecurityDriverState; ++typedef virSecurityDriverState *virSecurityDriverStatePtr; ++ + typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void); + typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv); +-typedef int (*virSecurityDomainRestoreImageLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk); +-typedef int (*virSecurityDomainSetImageLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk); +-typedef int (*virSecurityDomainRestoreHostdevLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev); +-typedef int (*virSecurityDomainSetHostdevLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev); +-typedef int (*virSecurityDomainSetSavedStateLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + const char *savefile); +-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + const char *savefile); +-typedef int (*virSecurityDomainGenLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainReserveLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainReleaseLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainSetAllLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm); +-typedef int (*virSecurityDomainGetProcessLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm); ++typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virSecurityLabelPtr sec); + typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv, + virDomainObjPtr vm); +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 +@@ -156,7 +156,8 @@ SELinuxInitialize(void) + } + + static int +-SELinuxGenSecurityLabel(virDomainObjPtr vm) ++SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = -1; + char mcs[1024]; +@@ -220,7 +221,8 @@ done: + } + + static int +-SELinuxReserveSecurityLabel(virDomainObjPtr vm) ++SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + security_context_t pctx; + context_t ctx = NULL; +@@ -275,7 +277,8 @@ SELinuxSecurityDriverOpen(virSecurityDri + } + + static int +-SELinuxGetSecurityProcessLabel(virDomainObjPtr vm, ++SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virSecurityLabelPtr sec) + { + security_context_t ctx; +@@ -385,7 +388,8 @@ err: + } + + static int +-SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm, ++SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -434,7 +438,8 @@ SELinuxSetSecurityFileLabel(virDomainDis + } + + static int +-SELinuxSetSecurityImageLabel(virDomainObjPtr vm, ++SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + + { +@@ -472,7 +477,8 @@ SELinuxSetSecurityUSBLabel(usbDevice *de + } + + static int +-SELinuxSetSecurityHostdevLabel(virDomainObjPtr vm, ++SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -540,7 +546,8 @@ SELinuxRestoreSecurityUSBLabel(usbDevice + } + + static int +-SELinuxRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -592,7 +599,8 @@ done: + } + + static int +-SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm) ++SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int i; +@@ -604,11 +612,14 @@ SELinuxRestoreSecurityAllLabel(virDomain + return 0; + + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (SELinuxRestoreSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (SELinuxRestoreSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + rc = -1; + } + for (i = 0 ; i < vm->def->ndisks ; i++) { +- if (SELinuxRestoreSecurityImageLabel(vm, ++ if (SELinuxRestoreSecurityImageLabel(drv, ++ vm, + vm->def->disks[i]) < 0) + rc = -1; + } +@@ -625,7 +636,8 @@ SELinuxRestoreSecurityAllLabel(virDomain + } + + static int +-SELinuxReleaseSecurityLabel(virDomainObjPtr vm) ++SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + +@@ -648,7 +660,8 @@ SELinuxReleaseSecurityLabel(virDomainObj + + + static int +-SELinuxSetSavedStateLabel(virDomainObjPtr vm, ++SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -661,7 +674,8 @@ SELinuxSetSavedStateLabel(virDomainObjPt + + + static int +-SELinuxRestoreSavedStateLabel(virDomainObjPtr vm, ++SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -719,7 +733,8 @@ SELinuxSetSecurityProcessLabel(virSecuri + } + + static int +-SELinuxSetSecurityAllLabel(virDomainObjPtr vm) ++SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int i; +@@ -734,11 +749,14 @@ SELinuxSetSecurityAllLabel(virDomainObjP + vm->def->disks[i]->src, vm->def->disks[i]->dst); + continue; + } +- if (SELinuxSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) ++ if (SELinuxSetSecurityImageLabel(drv, ++ vm, vm->def->disks[i]) < 0) + return -1; + } + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (SELinuxSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (SELinuxSetSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + return -1; + } + diff --git a/CVE-2010-223x-0008.patch b/CVE-2010-223x-0008.patch new file mode 100644 index 0000000..b432a05 --- /dev/null +++ b/CVE-2010-223x-0008.patch @@ -0,0 +1,385 @@ +>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"); diff --git a/CVE-2010-223x-0009.patch b/CVE-2010-223x-0009.patch new file mode 100644 index 0000000..33481fc --- /dev/null +++ b/CVE-2010-223x-0009.patch @@ -0,0 +1,110 @@ +>From f087f0656f882be305783e24d55921b57fbbcb97 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 14 Jun 2010 16:08:55 +0100 +Subject: [PATCH 09/10] Add ability to set a default driver name/type when parsing disks + +Record a default driver name/type in capabilities struct. Use this +when parsing disks if value is not set in XML config. + +* src/conf/capabilities.h: Record default driver name/type for disks +* src/conf/domain_conf.c: Fallback to default driver name/type + when parsing disks +* src/qemu/qemu_driver.c: Set default driver name/type to raw +--- + src/conf/capabilities.h | 2 ++ + src/conf/domain_conf.c | 21 ++++++++++++++++++--- + src/qemu/qemu_driver.c | 8 ++++++++ + 3 files changed, 28 insertions(+), 3 deletions(-) + +Index: libvirt-0.8.1/src/conf/capabilities.h +=================================================================== +--- libvirt-0.8.1.orig/src/conf/capabilities.h ++++ libvirt-0.8.1/src/conf/capabilities.h +@@ -120,6 +120,8 @@ struct _virCaps { + virCapsGuestPtr *guests; + unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN]; + unsigned int emulatorRequired : 1; ++ const char *defaultDiskDriverName; ++ const char *defaultDiskDriverType; + void *(*privateDataAllocFunc)(void); + void (*privateDataFreeFunc)(void *); + int (*privateDataXMLFormat)(virBufferPtr, void *); +Index: libvirt-0.8.1/src/conf/domain_conf.c +=================================================================== +--- libvirt-0.8.1.orig/src/conf/domain_conf.c ++++ libvirt-0.8.1/src/conf/domain_conf.c +@@ -1366,7 +1366,8 @@ virDomainDiskDefAssignAddress(virDomainD + * @param node XML nodeset to parse for disk definition + */ + static virDomainDiskDefPtr +-virDomainDiskDefParseXML(xmlNodePtr node, ++virDomainDiskDefParseXML(virCapsPtr caps, ++ xmlNodePtr node, + int flags) { + virDomainDiskDefPtr def; + xmlNodePtr cur; +@@ -1595,6 +1596,16 @@ virDomainDiskDefParseXML(xmlNodePtr node + def->serial = serial; + serial = NULL; + ++ if (!def->driverType && ++ caps->defaultDiskDriverType && ++ !(def->driverType = strdup(caps->defaultDiskDriverType))) ++ goto no_memory; ++ ++ if (!def->driverName && ++ caps->defaultDiskDriverName && ++ !(def->driverName = strdup(caps->defaultDiskDriverName))) ++ goto no_memory; ++ + if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE + && virDomainDiskDefAssignAddress(def) < 0) + goto error; +@@ -1615,6 +1626,9 @@ cleanup: + + return def; + ++no_memory: ++ virReportOOMError(); ++ + error: + virDomainDiskDefFree(def); + def = NULL; +@@ -3521,7 +3535,7 @@ virDomainDeviceDefPtr virDomainDeviceDef + + if (xmlStrEqual(node->name, BAD_CAST "disk")) { + dev->type = VIR_DOMAIN_DEVICE_DISK; +- if (!(dev->data.disk = virDomainDiskDefParseXML(node, flags))) ++ if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, flags))) + goto error; + } else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) { + dev->type = VIR_DOMAIN_DEVICE_FS; +@@ -4028,7 +4042,8 @@ static virDomainDefPtr virDomainDefParse + if (n && VIR_ALLOC_N(def->disks, n) < 0) + goto no_memory; + for (i = 0 ; i < n ; i++) { +- virDomainDiskDefPtr disk = virDomainDiskDefParseXML(nodes[i], ++ virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, ++ nodes[i], + flags); + if (!disk) + goto error; +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 +@@ -1324,6 +1324,14 @@ qemuCreateCapabilities(virCapsPtr oldcap + return NULL; + } + ++ if (driver->allowDiskFormatProbing) { ++ caps->defaultDiskDriverName = NULL; ++ caps->defaultDiskDriverType = NULL; ++ } else { ++ caps->defaultDiskDriverName = "qemu"; ++ caps->defaultDiskDriverType = "raw"; ++ } ++ + /* Domain XML parser hooks */ + caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc; + caps->privateDataFreeFunc = qemuDomainObjPrivateFree; diff --git a/CVE-2010-223x-0010.patch b/CVE-2010-223x-0010.patch new file mode 100644 index 0000000..02ab9e2 --- /dev/null +++ b/CVE-2010-223x-0010.patch @@ -0,0 +1,288 @@ +>From 6883117e3c6a6cabd760b6e6a468b69ad7b02839 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Wed, 16 Jun 2010 14:14:05 +0100 +Subject: [PATCH 10/10] Rewrite qemu-img backing store format handling + +When creating qcow2 files with a backing store, it is important +to set an explicit format to prevent QEMU probing. The storage +backend was only doing this if it found a 'kvm-img' binary. This +is wrong because plenty of kvm-img binaries don't support an +explicit format, and plenty of 'qemu-img' binaries do support +a format. The result was that most qcow2 files were not getting +a backing store format. + +This patch runs 'qemu-img -h' to check for the two support +argument formats + + '-o backing_format=raw' + '-F raw' + +and use whichever option it finds + +* src/storage/storage_backend.c: Query binary to determine + how to set the backing store format +--- + src/storage/storage_backend.c | 214 +++++++++++++++++++++++++++++------------ + 1 files changed, 152 insertions(+), 62 deletions(-) + +Index: libvirt-0.8.1/src/storage/storage_backend.c +=================================================================== +--- libvirt-0.8.1.orig/src/storage/storage_backend.c ++++ libvirt-0.8.1/src/storage/storage_backend.c +@@ -563,6 +563,69 @@ static int virStorageBackendCreateExecCo + return 0; + } + ++enum { ++ QEMU_IMG_BACKING_FORMAT_NONE = 0, ++ QEMU_IMG_BACKING_FORMAT_FLAG, ++ QEMU_IMG_BACKING_FORMAT_OPTIONS, ++}; ++ ++static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg) ++{ ++ const char *const qemuarg[] = { qemuimg, "-h", NULL }; ++ const char *const qemuenv[] = { "LC_ALL=C", NULL }; ++ pid_t child = 0; ++ int status; ++ int newstdout = -1; ++ char *help = NULL; ++ enum { MAX_HELP_OUTPUT_SIZE = 1024*8 }; ++ int len; ++ char *start; ++ char *end; ++ char *tmp; ++ int ret = -1; ++ ++ if (virExec(qemuarg, qemuenv, NULL, ++ &child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0) ++ goto cleanup; ++ ++ if ((len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help)) < 0) { ++ virReportSystemError(errno, ++ _("Unable to read '%s -h' output"), ++ qemuimg); ++ goto cleanup; ++ } ++ ++ start = strstr(help, " create "); ++ end = strstr(start, "\n"); ++ if ((tmp = strstr(start, "-F fmt")) && tmp < end) ++ ret = QEMU_IMG_BACKING_FORMAT_FLAG; ++ else if ((tmp = strstr(start, "[-o options]")) && tmp < end) ++ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS; ++ else ++ ret = QEMU_IMG_BACKING_FORMAT_NONE; ++ ++cleanup: ++ VIR_FREE(help); ++ close(newstdout); ++rewait: ++ if (child) { ++ if (waitpid(child, &status, 0) != child) { ++ if (errno == EINTR) ++ goto rewait; ++ ++ VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"), ++ WEXITSTATUS(status), (unsigned long)child); ++ } ++ if (WEXITSTATUS(status) != 0) { ++ VIR_WARN("Unexpected exit status '%d', qemu probably failed", ++ WEXITSTATUS(status)); ++ } ++ } ++ ++ return ret; ++} ++ ++ + static int + virStorageBackendCreateQemuImg(virConnectPtr conn, + virStoragePoolObjPtr pool, +@@ -570,10 +633,9 @@ virStorageBackendCreateQemuImg(virConnec + virStorageVolDefPtr inputvol, + unsigned int flags ATTRIBUTE_UNUSED) + { +- int ret; ++ int ret = -1; + char size[100]; + char *create_tool; +- short use_kvmimg; + + const char *type = virStorageFileFormatTypeToString(vol->target.format); + const char *backingType = vol->backingStore.path ? +@@ -584,41 +646,10 @@ virStorageBackendCreateQemuImg(virConnec + const char *inputPath = inputvol ? inputvol->target.path : NULL; + /* Treat input block devices as 'raw' format */ + const char *inputType = inputPath ? +- virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) : +- NULL; +- +- const char **imgargv; +- /* The extra NULL field is for indicating encryption (-e). */ +- const char *imgargvnormal[] = { +- NULL, "create", +- "-f", type, +- vol->target.path, +- size, +- NULL, +- NULL +- }; +- /* Extra NULL fields are for including "backingType" when using +- * kvm-img (-F backingType), and for indicating encryption (-e). +- */ +- const char *imgargvbacking[] = { +- NULL, "create", +- "-f", type, +- "-b", vol->backingStore.path, +- vol->target.path, +- size, +- NULL, +- NULL, +- NULL, +- NULL +- }; +- const char *convargv[] = { +- NULL, "convert", +- "-f", inputType, +- "-O", type, +- inputPath, +- vol->target.path, +- NULL, +- }; ++ virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? ++ VIR_STORAGE_FILE_RAW : ++ inputvol->target.format) : ++ NULL; + + if (type == NULL) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, +@@ -692,44 +723,103 @@ virStorageBackendCreateQemuImg(virConnec + } + } + +- if ((create_tool = virFindFileInPath("kvm-img")) != NULL) +- use_kvmimg = 1; +- else if ((create_tool = virFindFileInPath("qemu-img")) != NULL) +- use_kvmimg = 0; +- else { ++ /* Size in KB */ ++ snprintf(size, sizeof(size), "%lluK", vol->capacity/1024); ++ ++ /* KVM is usually ahead of qemu on features, so try that first */ ++ create_tool = virFindFileInPath("kvm-img"); ++ if (!create_tool) ++ create_tool = virFindFileInPath("qemu-img"); ++ ++ if (!create_tool) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unable to find kvm-img or qemu-img")); + return -1; + } + + if (inputvol) { +- convargv[0] = create_tool; +- imgargv = convargv; ++ const char *imgargv[] = { ++ create_tool, ++ "convert", ++ "-f", inputType, ++ "-O", type, ++ inputPath, ++ vol->target.path, ++ NULL, ++ }; ++ ++ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); + } else if (vol->backingStore.path) { +- imgargvbacking[0] = create_tool; +- if (use_kvmimg) { +- imgargvbacking[6] = "-F"; +- imgargvbacking[7] = backingType; +- imgargvbacking[8] = vol->target.path; +- imgargvbacking[9] = size; ++ const char *imgargv[] = { ++ create_tool, ++ "create", ++ "-f", type, ++ "-b", vol->backingStore.path, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL ++ }; ++ int imgformat = virStorageBackendQEMUImgBackingFormat(create_tool); ++ char *optflag = NULL; ++ if (imgformat < 0) ++ goto cleanup; ++ ++ switch (imgformat) { ++ case QEMU_IMG_BACKING_FORMAT_FLAG: ++ imgargv[6] = "-F"; ++ imgargv[7] = backingType; ++ imgargv[8] = vol->target.path; ++ imgargv[9] = size; ++ if (vol->target.encryption != NULL) ++ imgargv[10] = "-e"; ++ break; ++ ++ case QEMU_IMG_BACKING_FORMAT_OPTIONS: ++ if (virAsprintf(&optflag, "backing_fmt=%s", backingType) < 0) { ++ virReportOOMError(); ++ goto cleanup; ++ } ++ imgargv[6] = "-o"; ++ imgargv[7] = optflag; ++ imgargv[8] = vol->target.path; ++ imgargv[9] = size; ++ if (vol->target.encryption != NULL) ++ imgargv[10] = "-e"; ++ break; ++ ++ default: ++ VIR_INFO("Unable to set backing store format for %s with %s", ++ vol->target.path, create_tool); ++ imgargv[6] = vol->target.path; ++ imgargv[7] = size; + if (vol->target.encryption != NULL) +- imgargvbacking[10] = "-e"; +- } else if (vol->target.encryption != NULL) +- imgargvbacking[8] = "-e"; +- imgargv = imgargvbacking; ++ imgargv[8] = "-e"; ++ } ++ ++ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); ++ VIR_FREE(optflag); + } else { +- imgargvnormal[0] = create_tool; +- imgargv = imgargvnormal; ++ /* The extra NULL field is for indicating encryption (-e). */ ++ const char *imgargv[] = { ++ create_tool, ++ "create", ++ "-f", type, ++ vol->target.path, ++ size, ++ NULL, ++ NULL ++ }; + if (vol->target.encryption != NULL) + imgargv[6] = "-e"; +- } +- + +- /* Size in KB */ +- snprintf(size, sizeof(size), "%lluK", vol->capacity/1024); ++ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); ++ } + +- ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); +- VIR_FREE(imgargv[0]); ++ cleanup: ++ VIR_FREE(create_tool); + + return ret; + } diff --git a/CVE-2010-2242-nat.patch b/CVE-2010-2242-nat.patch new file mode 100644 index 0000000..f20e538 --- /dev/null +++ b/CVE-2010-2242-nat.patch @@ -0,0 +1,262 @@ +From 02318d5d46e1952294c20b41427dea124cbebb0a Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Thu, 10 Jun 2010 12:50:38 -0400 +Subject: [PATCH] Apply a source port mapping to virtual network masquerading + +IPtables will seek to preserve the source port unchanged when +doing masquerading, if possible. NFS has a pseudo-security +option where it checks for the source port <= 1023 before +allowing a mount request. If an admin has used this to make the +host OS trusted for mounts, the default iptables behaviour will +potentially allow NAT'd guests access too. This needs to be +stopped. + +With this change, the iptables -t nat -L -n -v rules for the +default network will be + +Chain POSTROUTING (policy ACCEPT 95 packets, 9163 bytes) + pkts bytes target prot opt in out source destination + 14 840 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 + 75 5752 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 + 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24 + +* src/network/bridge_driver.c: Add masquerade rules for TCP + and UDP protocols +* src/util/iptables.c, src/util/iptables.c: Add source port + mappings for TCP & UDP protocols when masquerading. +--- + src/network/bridge_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++-- + src/util/iptables.c | 70 +++++++++++++++++++++++++++++------------ + src/util/iptables.h | 6 ++- + 3 files changed, 122 insertions(+), 27 deletions(-) + +Index: libvirt-0.8.1/src/network/bridge_driver.c +=================================================================== +--- libvirt-0.8.1.orig/src/network/bridge_driver.c ++++ libvirt-0.8.1/src/network/bridge_driver.c +@@ -638,18 +638,75 @@ networkAddMasqueradingIptablesRules(stru + goto masqerr2; + } + ++ /* ++ * Enable masquerading. ++ * ++ * We need to end up with 3 rules in the table in this order ++ * ++ * 1. protocol=tcp with sport mapping restricton ++ * 2. protocol=udp with sport mapping restricton ++ * 3. generic any protocol ++ * ++ * The sport mappings are required, because default IPtables ++ * MASQUERADE is maintain port number unchanged where possible. ++ * ++ * NFS can be configured to only "trust" port numbers < 1023. ++ * ++ * Guests using NAT thus need to be prevented from having port ++ * numbers < 1023, otherwise they can bypass the NFS "security" ++ * check on the source port number. ++ * ++ * Since we use '--insert' to add rules to the header of the ++ * chain, we actually need to add them in the reverse of the ++ * order just mentioned ! ++ */ ++ ++ /* First the generic masquerade rule for other protocols */ + /* enable masquerading */ + if ((err = iptablesAddForwardMasquerade(driver->iptables, + network->def->network, +- network->def->forwardDev))) { ++ network->def->forwardDev, ++ NULL))) { + virReportSystemError(err, + _("failed to add iptables rule to enable masquerading to '%s'\n"), + network->def->forwardDev ? network->def->forwardDev : NULL); + goto masqerr3; + } + ++ /* UDP with a source port restriction */ ++ if ((err = iptablesAddForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ "udp"))) { ++ virReportSystemError(err, ++ _("failed to add iptables rule to enable UDP masquerading to '%s'"), ++ network->def->forwardDev ? network->def->forwardDev : NULL); ++ goto masqerr4; ++ } ++ ++ /* TCP with a source port restriction */ ++ if ((err = iptablesAddForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ "tcp"))) { ++ virReportSystemError(err, ++ _("failed to add iptables rule to enable TCP masquerading to '%s'"), ++ network->def->forwardDev ? network->def->forwardDev : NULL); ++ goto masqerr5; ++ } ++ + return 1; + ++ masqerr5: ++ iptablesRemoveForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ "udp"); ++ masqerr4: ++ iptablesRemoveForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ NULL); + masqerr3: + iptablesRemoveForwardAllowRelatedIn(driver->iptables, + network->def->network, +@@ -801,8 +858,17 @@ networkRemoveIptablesRules(struct networ + if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) { + if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { + iptablesRemoveForwardMasquerade(driver->iptables, +- network->def->network, +- network->def->forwardDev); ++ network->def->network, ++ network->def->forwardDev, ++ "tcp"); ++ iptablesRemoveForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ "udp"); ++ iptablesRemoveForwardMasquerade(driver->iptables, ++ network->def->network, ++ network->def->forwardDev, ++ NULL); + iptablesRemoveForwardAllowRelatedIn(driver->iptables, + network->def->network, + network->def->bridge, +Index: libvirt-0.8.1/src/util/iptables.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/iptables.c ++++ libvirt-0.8.1/src/util/iptables.c +@@ -692,25 +692,49 @@ iptablesRemoveForwardRejectIn(iptablesCo + */ + static int + iptablesForwardMasquerade(iptablesContext *ctx, +- const char *network, +- const char *physdev, +- int action) ++ const char *network, ++ const char *physdev, ++ const char *protocol, ++ int action) + { +- if (physdev && physdev[0]) { +- return iptablesAddRemoveRule(ctx->nat_postrouting, +- action, +- "--source", network, +- "!", "--destination", network, +- "--out-interface", physdev, +- "--jump", "MASQUERADE", +- NULL); ++ if (protocol && protocol[0]) { ++ if (physdev && physdev[0]) { ++ return iptablesAddRemoveRule(ctx->nat_postrouting, ++ action, ++ "--source", network, ++ "-p", protocol, ++ "!", "--destination", network, ++ "--out-interface", physdev, ++ "--jump", "MASQUERADE", ++ "--to-ports", "1024-65535", ++ NULL); ++ } else { ++ return iptablesAddRemoveRule(ctx->nat_postrouting, ++ action, ++ "--source", network, ++ "-p", protocol, ++ "!", "--destination", network, ++ "--jump", "MASQUERADE", ++ "--to-ports", "1024-65535", ++ NULL); ++ } + } else { +- return iptablesAddRemoveRule(ctx->nat_postrouting, +- action, +- "--source", network, +- "!", "--destination", network, +- "--jump", "MASQUERADE", +- NULL); ++ if (physdev && physdev[0]) { ++ return iptablesAddRemoveRule(ctx->nat_postrouting, ++ action, ++ "--source", network, ++ "!", "--destination", network, ++ "--out-interface", physdev, ++ "--jump", "MASQUERADE", ++ NULL); ++ } else { ++ return iptablesAddRemoveRule(ctx->nat_postrouting, ++ action, ++ "--source", network, ++ "!", "--destination", network, ++ "--jump", "MASQUERADE", ++ NULL); ++ } + } + } + +@@ -719,6 +743,7 @@ iptablesForwardMasquerade(iptablesContex + * @ctx: pointer to the IP table context + * @network: the source network name + * @physdev: the physical input device or NULL ++ * @protocol: the network protocol or NULL + * + * Add rules to the IP table context to allow masquerading + * network @network on @physdev. This allow the bridge to +@@ -729,9 +754,10 @@ iptablesForwardMasquerade(iptablesContex + int + iptablesAddForwardMasquerade(iptablesContext *ctx, + const char *network, +- const char *physdev) ++ const char *physdev, ++ const char *protocol) + { +- return iptablesForwardMasquerade(ctx, network, physdev, ADD); ++ return iptablesForwardMasquerade(ctx, network, physdev, protocol, ADD); + } + + /** +@@ -739,6 +765,7 @@ iptablesAddForwardMasquerade(iptablesCon + * @ctx: pointer to the IP table context + * @network: the source network name + * @physdev: the physical input device or NULL ++ * @protocol: the network protocol or NULL + * + * Remove rules from the IP table context to stop masquerading + * network @network on @physdev. This stops the bridge from +@@ -749,7 +776,8 @@ iptablesAddForwardMasquerade(iptablesCon + int + iptablesRemoveForwardMasquerade(iptablesContext *ctx, + const char *network, +- const char *physdev) ++ const char *physdev, ++ const char *protocol) + { +- return iptablesForwardMasquerade(ctx, network, physdev, REMOVE); ++ return iptablesForwardMasquerade(ctx, network, physdev, protocol, REMOVE); + } +Index: libvirt-0.8.1/src/util/iptables.h +=================================================================== +--- libvirt-0.8.1.orig/src/util/iptables.h ++++ libvirt-0.8.1/src/util/iptables.h +@@ -85,9 +85,11 @@ int iptablesRemoveForwardRe + + int iptablesAddForwardMasquerade (iptablesContext *ctx, + const char *network, +- const char *physdev); ++ const char *physdev, ++ const char *protocol); + int iptablesRemoveForwardMasquerade (iptablesContext *ctx, + const char *network, +- const char *physdev); ++ const char *physdev, ++ const char *protocol); + + #endif /* __QEMUD_IPTABLES_H__ */ diff --git a/libvirt.changes b/libvirt.changes index 195e9d8..0157921 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Fri Jul 9 14:35:04 MDT 2010 - jfehlig@novell.com + +- VUL-0: multiple issues in libvirt + CVE-2010-223x-000[1-0].patch, CVE-2010-223x-0010.patch, + CVE-2010-2242-nat.patch + bnc#618155 + ------------------------------------------------------------------- Fri Jun 25 09:02:38 MDT 2010 - jfehlig@novell.com diff --git a/libvirt.spec b/libvirt.spec index 5206d57..a62a1c1 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -96,6 +96,9 @@ BuildRequires: avahi-devel %if %{with_selinux} BuildRequires: libselinux-devel %endif +%if %{with_apparmor} +BuildRequires: libapparmor-devel +%endif %if %{with_numactl} BuildRequires: libnuma-devel %endif @@ -114,7 +117,7 @@ License: LGPLv2.1+ Group: Development/Libraries/C and C++ AutoReqProv: yes Version: 0.8.1 -Release: 3 +Release: 2 Summary: A C toolkit to interract with the virtualization capabilities of Linux # The client side, i.e. shared libs and virsh are in a subpackage Requires: %{name}-client = %{version}-%{release} @@ -146,6 +149,17 @@ Patch4: bitmap-alloc.patch Patch5: bitmap-fixes.patch Patch6: xend-content-buf.patch Patch7: xend-content-buf-fix.patch +Patch8: CVE-2010-223x-0001.patch +Patch9: CVE-2010-223x-0002.patch +Patch10: CVE-2010-223x-0003.patch +Patch11: CVE-2010-223x-0004.patch +Patch12: CVE-2010-223x-0005.patch +Patch13: CVE-2010-223x-0006.patch +Patch14: CVE-2010-223x-0007.patch +Patch15: CVE-2010-223x-0008.patch +Patch16: CVE-2010-223x-0009.patch +Patch17: CVE-2010-223x-0010.patch +Patch18: CVE-2010-2242-nat.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch102: clone.patch @@ -266,6 +280,17 @@ Authors: %patch5 -p1 %patch6 -p1 %patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 %patch100 -p1 %patch102 %patch103 -p1 From 8b4217ed93ef3218a451ee68dceae0324e8bed00389b7bf5d0301f948543e633 Mon Sep 17 00:00:00 2001 From: James Fehlig Date: Sat, 7 Aug 2010 04:24:13 +0000 Subject: [PATCH 2/4] update to libvirt 0.8.3 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=61 --- CVE-2010-223x-0001.patch | 339 ----------- CVE-2010-223x-0002.patch | 158 ----- CVE-2010-223x-0003.patch | 486 ---------------- CVE-2010-223x-0004.patch | 218 ------- CVE-2010-223x-0005.patch | 167 ------ CVE-2010-223x-0006.patch | 273 --------- CVE-2010-223x-0007.patch | 1058 ---------------------------------- CVE-2010-223x-0008.patch | 385 ------------- CVE-2010-223x-0009.patch | 110 ---- CVE-2010-223x-0010.patch | 288 --------- CVE-2010-2242-nat.patch | 262 --------- bitmap-alloc.patch | 29 - bitmap-fixes.patch | 59 -- libvirt-0.8.1.tar.bz2 | 3 - libvirt-0.8.3.tar.bz2 | 3 + libvirt.changes | 9 + libvirt.spec | 54 +- remote-rm-unused-field.patch | 50 -- vnc-race-1.patch | 281 --------- vnc-race-2.patch | 29 - vnc-race-3.patch | 130 ----- xend-content-buf-fix.patch | 79 --- xend-content-buf.patch | 244 -------- 23 files changed, 25 insertions(+), 4689 deletions(-) delete mode 100644 CVE-2010-223x-0001.patch delete mode 100644 CVE-2010-223x-0002.patch delete mode 100644 CVE-2010-223x-0003.patch delete mode 100644 CVE-2010-223x-0004.patch delete mode 100644 CVE-2010-223x-0005.patch delete mode 100644 CVE-2010-223x-0006.patch delete mode 100644 CVE-2010-223x-0007.patch delete mode 100644 CVE-2010-223x-0008.patch delete mode 100644 CVE-2010-223x-0009.patch delete mode 100644 CVE-2010-223x-0010.patch delete mode 100644 CVE-2010-2242-nat.patch delete mode 100644 bitmap-alloc.patch delete mode 100644 bitmap-fixes.patch delete mode 100644 libvirt-0.8.1.tar.bz2 create mode 100644 libvirt-0.8.3.tar.bz2 delete mode 100644 remote-rm-unused-field.patch delete mode 100644 vnc-race-1.patch delete mode 100644 vnc-race-2.patch delete mode 100644 vnc-race-3.patch delete mode 100644 xend-content-buf-fix.patch delete mode 100644 xend-content-buf.patch diff --git a/CVE-2010-223x-0001.patch b/CVE-2010-223x-0001.patch deleted file mode 100644 index ac97a2f..0000000 --- a/CVE-2010-223x-0001.patch +++ /dev/null @@ -1,339 +0,0 @@ ->From 7b91c43bef0348c8cc18037bec5aef668b51fc90 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Mon, 14 Jun 2010 15:53:59 +0100 -Subject: [PATCH 01/10] Extract the backing store format as well as name, if available - -When QEMU opens a backing store for a QCow2 file, it will -normally auto-probe for the format of the backing store, -rather than assuming it has the same format as the referencing -file. There is a QCow2 extension that allows an explicit format -for the backing store to be embedded in the referencing file. -This closes the auto-probing security hole in QEMU. - -This backing store format can be useful for libvirt users -of virStorageFileGetMetadata, so extract this data and report -it. - -QEMU does not require disk image backing store files to be in -the same format the file linkee. It will auto-probe the disk -format for the backing store when opening it. If the backing -store was intended to be a raw file this could be a security -hole, because a guest may have written data into its disk that -then makes the backing store look like a qcow2 file. If it can -trick QEMU into thinking the raw file is a qcow2 file, it can -access arbitrary files on the host by adding further backing -store links. - -To address this, callers of virStorageFileGetMeta need to be -told of the backing store format. If no format is declared, -they can make a decision whether to allow format probing or -not. ---- - src/util/storage_file.c | 192 ++++++++++++++++++++++++++++++++++++++++------ - src/util/storage_file.h | 2 + - 2 files changed, 169 insertions(+), 25 deletions(-) - -Index: libvirt-0.8.1/src/util/storage_file.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.c -+++ libvirt-0.8.1/src/util/storage_file.c -@@ -71,12 +71,18 @@ struct FileTypeInfo { - int qcowCryptOffset; /* Byte offset from start of file - * where to find encryption mode, - * -1 if encryption is not used */ -- int (*getBackingStore)(char **res, const unsigned char *buf, size_t buf_size); -+ int (*getBackingStore)(char **res, int *format, -+ const unsigned char *buf, size_t buf_size); - }; - --static int cowGetBackingStore(char **, const unsigned char *, size_t); --static int qcowXGetBackingStore(char **, const unsigned char *, size_t); --static int vmdk4GetBackingStore(char **, const unsigned char *, size_t); -+static int cowGetBackingStore(char **, int *, -+ const unsigned char *, size_t); -+static int qcow1GetBackingStore(char **, int *, -+ const unsigned char *, size_t); -+static int qcow2GetBackingStore(char **, int *, -+ const unsigned char *, size_t); -+static int vmdk4GetBackingStore(char **, int *, -+ const unsigned char *, size_t); - - - static struct FileTypeInfo const fileTypeInfo[] = { -@@ -112,11 +118,11 @@ static struct FileTypeInfo const fileTyp - /* QCow */ - { VIR_STORAGE_FILE_QCOW, "QFI", NULL, - LV_BIG_ENDIAN, 4, 1, -- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore }, -+ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore }, - /* QCow 2 */ - { VIR_STORAGE_FILE_QCOW2, "QFI", NULL, - LV_BIG_ENDIAN, 4, 2, -- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore }, -+ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore }, - /* VMDK 3 */ - /* XXX Untested - { VIR_STORAGE_FILE_VMDK, "COWD", NULL, -@@ -137,11 +143,14 @@ static struct FileTypeInfo const fileTyp - - static int - cowGetBackingStore(char **res, -+ int *format, - const unsigned char *buf, - size_t buf_size) - { - #define COW_FILENAME_MAXLEN 1024 - *res = NULL; -+ *format = VIR_STORAGE_FILE_AUTO; -+ - if (buf_size < 4+4+ COW_FILENAME_MAXLEN) - return BACKING_STORE_INVALID; - if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */ -@@ -155,31 +164,101 @@ cowGetBackingStore(char **res, - return BACKING_STORE_OK; - } - -+ -+ -+#define QCOWX_HDR_BACKING_FILE_OFFSET 4+4 -+#define QCOWX_HDR_BACKING_FILE_SIZE 4+4+8 -+ -+#define QCOW2_HDR_TOTAL_SIZE 4+4+8+4+4+8+4+4+8+8+4+4+8 -+#define QCOW2_HDR_EXTENSION_END 0 -+#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA -+ -+static int -+qcow2GetBackingStoreFormat(int *format, -+ const unsigned char *buf, -+ size_t buf_size, -+ size_t extension_start, -+ size_t extension_end) -+{ -+ size_t offset = extension_start; -+ -+ /* -+ * The extensions take format of -+ * -+ * int32: magic -+ * int32: length -+ * byte[length]: payload -+ * -+ * Unknown extensions can be ignored by skipping -+ * over "length" bytes in the data stream. -+ */ -+ while (offset < (buf_size-8) && -+ offset < (extension_end-8)) { -+ int magic = (buf[offset] << 24) + -+ (buf[offset+1] << 16) + -+ (buf[offset+2] << 8) + -+ (buf[offset+3]); -+ int len = (buf[offset+4] << 24) + -+ (buf[offset+5] << 16) + -+ (buf[offset+6] << 8) + -+ (buf[offset+7]); -+ -+ offset += 8; -+ -+ if ((offset + len) > buf_size) -+ break; -+ -+ switch (magic) { -+ case QCOW2_HDR_EXTENSION_END: -+ goto done; -+ -+ case QCOW2_HDR_EXTENSION_BACKING_FORMAT: -+ if (buf[offset+len] != '\0') -+ break; -+ *format = virStorageFileFormatTypeFromString( -+ ((const char *)buf)+offset); -+ break; -+ } -+ -+ offset += len; -+ } -+ -+done: -+ -+ return 0; -+} -+ -+ - static int - qcowXGetBackingStore(char **res, -+ int *format, - const unsigned char *buf, -- size_t buf_size) -+ size_t buf_size, -+ bool isQCow2) - { - unsigned long long offset; - unsigned long size; - - *res = NULL; -- if (buf_size < 4+4+8+4) -+ if (format) -+ *format = VIR_STORAGE_FILE_AUTO; -+ -+ if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4) - return BACKING_STORE_INVALID; -- offset = (((unsigned long long)buf[4+4] << 56) -- | ((unsigned long long)buf[4+4+1] << 48) -- | ((unsigned long long)buf[4+4+2] << 40) -- | ((unsigned long long)buf[4+4+3] << 32) -- | ((unsigned long long)buf[4+4+4] << 24) -- | ((unsigned long long)buf[4+4+5] << 16) -- | ((unsigned long long)buf[4+4+6] << 8) -- | buf[4+4+7]); /* QCowHeader.backing_file_offset */ -+ offset = (((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET] << 56) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+1] << 48) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+2] << 40) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+3] << 32) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+4] << 24) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+5] << 16) -+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+6] << 8) -+ | buf[QCOWX_HDR_BACKING_FILE_OFFSET+7]); /* QCowHeader.backing_file_offset */ - if (offset > buf_size) - return BACKING_STORE_INVALID; -- size = ((buf[4+4+8] << 24) -- | (buf[4+4+8+1] << 16) -- | (buf[4+4+8+2] << 8) -- | buf[4+4+8+3]); /* QCowHeader.backing_file_size */ -+ size = ((buf[QCOWX_HDR_BACKING_FILE_SIZE] << 24) -+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16) -+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8) -+ | buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */ - if (size == 0) - return BACKING_STORE_OK; - if (offset + size > buf_size || offset + size < offset) -@@ -192,12 +271,63 @@ qcowXGetBackingStore(char **res, - } - memcpy(*res, buf + offset, size); - (*res)[size] = '\0'; -+ -+ /* -+ * Traditionally QCow2 files had a layout of -+ * -+ * [header] -+ * [backingStoreName] -+ * -+ * Although the backingStoreName typically followed -+ * the header immediately, this was not required by -+ * the format. By specifying a higher byte offset for -+ * the backing file offset in the header, it was -+ * possible to leave space between the header and -+ * start of backingStore. -+ * -+ * This hack is now used to store extensions to the -+ * qcow2 format: -+ * -+ * [header] -+ * [extensions] -+ * [backingStoreName] -+ * -+ * Thus the file region to search for extensions is -+ * between the end of the header (QCOW2_HDR_TOTAL_SIZE) -+ * and the start of the backingStoreName (offset) -+ */ -+ if (isQCow2) -+ qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset); -+ - return BACKING_STORE_OK; - } - - - static int -+qcow1GetBackingStore(char **res, -+ int *format, -+ const unsigned char *buf, -+ size_t buf_size) -+{ -+ /* QCow1 doesn't have the extensions capability -+ * used to store backing format */ -+ *format = VIR_STORAGE_FILE_AUTO; -+ return qcowXGetBackingStore(res, NULL, buf, buf_size, false); -+} -+ -+static int -+qcow2GetBackingStore(char **res, -+ int *format, -+ const unsigned char *buf, -+ size_t buf_size) -+{ -+ return qcowXGetBackingStore(res, format, buf, buf_size, true); -+} -+ -+ -+static int - vmdk4GetBackingStore(char **res, -+ int *format, - const unsigned char *buf, - size_t buf_size) - { -@@ -207,6 +337,12 @@ vmdk4GetBackingStore(char **res, - size_t len; - - *res = NULL; -+ /* XXX should we set VMDK instead ? QEMU does auto -+ * probing, but this isn't in compliance with the -+ * VMDK spec/VMWare impl which presumes only VMDK -+ * backing format -+ */ -+ *format = VIR_STORAGE_FILE_AUTO; - - if (buf_size <= 0x200) - return BACKING_STORE_INVALID; -@@ -351,9 +487,12 @@ virStorageFileGetMetadataFromFD(const ch - /* Validation passed, we know the file format now */ - meta->format = fileTypeInfo[i].type; - if (fileTypeInfo[i].getBackingStore != NULL) { -- char *base; -+ char *backing; -+ int backingFormat; - -- switch (fileTypeInfo[i].getBackingStore(&base, head, len)) { -+ switch (fileTypeInfo[i].getBackingStore(&backing, -+ &backingFormat, -+ head, len)) { - case BACKING_STORE_OK: - break; - -@@ -363,13 +502,16 @@ virStorageFileGetMetadataFromFD(const ch - case BACKING_STORE_ERROR: - return -1; - } -- if (base != NULL) { -- meta->backingStore = absolutePathFromBaseFile(path, base); -- VIR_FREE(base); -+ if (backing != NULL) { -+ meta->backingStore = absolutePathFromBaseFile(path, backing); -+ VIR_FREE(backing); - if (meta->backingStore == NULL) { - virReportOOMError(); - return -1; - } -+ meta->backingStoreFormat = backingFormat; -+ } else { -+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; - } - } - return 0; -Index: libvirt-0.8.1/src/util/storage_file.h -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.h -+++ libvirt-0.8.1/src/util/storage_file.h -@@ -28,6 +28,7 @@ - # include - - enum virStorageFileFormat { -+ VIR_STORAGE_FILE_AUTO = -1, - VIR_STORAGE_FILE_RAW = 0, - VIR_STORAGE_FILE_DIR, - VIR_STORAGE_FILE_BOCHS, -@@ -47,6 +48,7 @@ VIR_ENUM_DECL(virStorageFileFormat); - typedef struct _virStorageFileMetadata { - int format; - char *backingStore; -+ int backingStoreFormat; - unsigned long long capacity; - bool encrypted; - } virStorageFileMetadata; diff --git a/CVE-2010-223x-0002.patch b/CVE-2010-223x-0002.patch deleted file mode 100644 index b2c4d17..0000000 --- a/CVE-2010-223x-0002.patch +++ /dev/null @@ -1,158 +0,0 @@ ->From 66c633413960e869a15062cee8667db51e6c817a Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Mon, 14 Jun 2010 16:39:32 +0100 -Subject: [PATCH 02/10] Remove 'type' field from FileTypeInfo struct - -Instead of including a field in FileTypeInfo struct for the -disk format, rely on the array index matching the format. -Use verify() to assert the correct number of elements in the -array. - -* src/util/storage_file.c: remove type field from FileTypeInfo ---- - src/util/storage_file.c | 108 +++++++++++++++++++++++----------------------- - 1 files changed, 54 insertions(+), 54 deletions(-) - -Index: libvirt-0.8.1/src/util/storage_file.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.c -+++ libvirt-0.8.1/src/util/storage_file.c -@@ -51,7 +51,6 @@ enum { - - /* Either 'magic' or 'extension' *must* be provided */ - struct FileTypeInfo { -- int type; /* One of the constants above */ - const char *magic; /* Optional string of file magic - * to check at head of file */ - const char *extension; /* Optional file extension to check */ -@@ -86,60 +85,59 @@ static int vmdk4GetBackingStore(char **, - - - static struct FileTypeInfo const fileTypeInfo[] = { -- /* Bochs */ -- /* XXX Untested -- { VIR_STORAGE_FILE_BOCHS, "Bochs Virtual HD Image", NULL, -- LV_LITTLE_ENDIAN, 64, 0x20000, -- 32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/ -- /* CLoop */ -- /* XXX Untested -- { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL, -- LV_LITTLE_ENDIAN, -1, 0, -- -1, 0, 0, -1, NULL }, */ -- /* Cow */ -- { VIR_STORAGE_FILE_COW, "OOOM", NULL, -- LV_BIG_ENDIAN, 4, 2, -- 4+4+1024+4, 8, 1, -1, cowGetBackingStore }, -- /* DMG */ -- /* XXX QEMU says there's no magic for dmg, but we should check... */ -- { VIR_STORAGE_FILE_DMG, NULL, ".dmg", -- 0, -1, 0, -- -1, 0, 0, -1, NULL }, -- /* XXX there's probably some magic for iso we can validate too... */ -- { VIR_STORAGE_FILE_ISO, NULL, ".iso", -- 0, -1, 0, -- -1, 0, 0, -1, NULL }, -- /* Parallels */ -- /* XXX Untested -- { VIR_STORAGE_FILE_PARALLELS, "WithoutFreeSpace", NULL, -- LV_LITTLE_ENDIAN, 16, 2, -- 16+4+4+4+4, 4, 512, -1, NULL }, -- */ -- /* QCow */ -- { VIR_STORAGE_FILE_QCOW, "QFI", NULL, -- LV_BIG_ENDIAN, 4, 1, -- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore }, -- /* QCow 2 */ -- { VIR_STORAGE_FILE_QCOW2, "QFI", NULL, -- LV_BIG_ENDIAN, 4, 2, -- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore }, -- /* VMDK 3 */ -- /* XXX Untested -- { VIR_STORAGE_FILE_VMDK, "COWD", NULL, -- LV_LITTLE_ENDIAN, 4, 1, -- 4+4+4, 4, 512, -1, NULL }, -- */ -- /* VMDK 4 */ -- { VIR_STORAGE_FILE_VMDK, "KDMV", NULL, -- LV_LITTLE_ENDIAN, 4, 1, -- 4+4+4, 8, 512, -1, vmdk4GetBackingStore }, -- /* Connectix / VirtualPC */ -- /* XXX Untested -- { VIR_STORAGE_FILE_VPC, "conectix", NULL, -- LV_BIG_ENDIAN, -1, 0, -- -1, 0, 0, -1, NULL}, -- */ -+ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, -+ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, -+ [VIR_STORAGE_FILE_BOCHS] = { -+ /*"Bochs Virtual HD Image", */ /* Untested */ NULL, -+ NULL, -+ LV_LITTLE_ENDIAN, 64, 0x20000, -+ 32+16+16+4+4+4+4+4, 8, 1, -1, NULL -+ }, -+ [VIR_STORAGE_FILE_CLOOP] = { -+ /*"#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", */ /* Untested */ NULL, -+ NULL, -+ LV_LITTLE_ENDIAN, -1, 0, -+ -1, 0, 0, -1, NULL -+ }, -+ [VIR_STORAGE_FILE_COW] = { -+ "OOOM", NULL, -+ LV_BIG_ENDIAN, 4, 2, -+ 4+4+1024+4, 8, 1, -1, cowGetBackingStore -+ }, -+ [VIR_STORAGE_FILE_DMG] = { -+ NULL, /* XXX QEMU says there's no magic for dmg, but we should check... */ -+ ".dmg", -+ 0, -1, 0, -+ -1, 0, 0, -1, NULL -+ }, -+ [VIR_STORAGE_FILE_ISO] = { -+ NULL, /* XXX there's probably some magic for iso we can validate too... */ -+ ".iso", -+ 0, -1, 0, -+ -1, 0, 0, -1, NULL -+ }, -+ [VIR_STORAGE_FILE_QCOW] = { -+ "QFI", NULL, -+ LV_BIG_ENDIAN, 4, 1, -+ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcow1GetBackingStore -+ }, -+ [VIR_STORAGE_FILE_QCOW2] = { -+ "QFI", NULL, -+ LV_BIG_ENDIAN, 4, 2, -+ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcow2GetBackingStore -+ }, -+ [VIR_STORAGE_FILE_VMDK] = { -+ "KDMV", NULL, -+ LV_LITTLE_ENDIAN, 4, 1, -+ 4+4+4, 8, 512, -1, vmdk4GetBackingStore -+ }, -+ [VIR_STORAGE_FILE_VPC] = { -+ "conectix", NULL, -+ LV_BIG_ENDIAN, 12, 0x10000, -+ 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL -+ }, - }; -+verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST); - - static int - cowGetBackingStore(char **res, -@@ -485,7 +483,7 @@ virStorageFileGetMetadataFromFD(const ch - } - - /* Validation passed, we know the file format now */ -- meta->format = fileTypeInfo[i].type; -+ meta->format = i; - if (fileTypeInfo[i].getBackingStore != NULL) { - char *backing; - int backingFormat; -@@ -525,7 +523,7 @@ virStorageFileGetMetadataFromFD(const ch - if (!virFileHasSuffix(path, fileTypeInfo[i].extension)) - continue; - -- meta->format = fileTypeInfo[i].type; -+ meta->format = i; - return 0; - } - diff --git a/CVE-2010-223x-0003.patch b/CVE-2010-223x-0003.patch deleted file mode 100644 index ecfcc81..0000000 --- a/CVE-2010-223x-0003.patch +++ /dev/null @@ -1,486 +0,0 @@ ->From f8d3e740cee4903bd2eef1a072e8190f5e9e92b9 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Tue, 15 Jun 2010 14:58:10 +0100 -Subject: [PATCH 03/10] Refactor virStorageFileGetMetadataFromFD to separate functionality - -The virStorageFileGetMetadataFromFD did two jobs in one. First -it probed for storage type, then it extracted metadata for the -type. It is desirable to be able to separate these jobs, allowing -probing without querying metadata, and querying metadata without -probing. - -To prepare for this, split out probing code into a new pair of -methods - - virStorageFileProbeFormatFromFD - virStorageFileProbeFormat - -* src/util/storage_file.c, src/util/storage_file.h, - src/libvirt_private.syms: Introduce virStorageFileProbeFormat - and virStorageFileProbeFormatFromFD ---- - src/libvirt_private.syms | 2 + - src/util/storage_file.c | 393 ++++++++++++++++++++++++++++++++-------------- - src/util/storage_file.h | 4 + - 3 files changed, 281 insertions(+), 118 deletions(-) - -Index: libvirt-0.8.1/src/libvirt_private.syms -=================================================================== ---- libvirt-0.8.1.orig/src/libvirt_private.syms -+++ libvirt-0.8.1/src/libvirt_private.syms -@@ -619,6 +619,8 @@ virStorageGenerateQcowPassphrase; - # storage_file.h - virStorageFileFormatTypeToString; - virStorageFileFormatTypeFromString; -+virStorageFileProbeFormat; -+virStorageFileProbeFormatFromFD; - virStorageFileGetMetadata; - virStorageFileGetMetadataFromFD; - -Index: libvirt-0.8.1/src/util/storage_file.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.c -+++ libvirt-0.8.1/src/util/storage_file.c -@@ -85,8 +85,8 @@ static int vmdk4GetBackingStore(char **, - - - static struct FileTypeInfo const fileTypeInfo[] = { -- [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, -- [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, 0, 0, 0, 0, 0, 0, NULL }, -+ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL }, -+ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL }, - [VIR_STORAGE_FILE_BOCHS] = { - /*"Bochs Virtual HD Image", */ /* Untested */ NULL, - NULL, -@@ -390,146 +390,302 @@ absolutePathFromBaseFile(const char *bas - return res; - } - -+static int -+virStorageFileMatchesMagic(int format, -+ unsigned char *buf, -+ size_t buflen) -+{ -+ int mlen; -+ -+ if (fileTypeInfo[format].magic == NULL) -+ return 0; -+ -+ /* Validate magic data */ -+ mlen = strlen(fileTypeInfo[format].magic); -+ if (mlen > buflen) -+ return 0; -+ -+ if (memcmp(buf, fileTypeInfo[format].magic, mlen) != 0) -+ return 0; -+ -+ return 1; -+} -+ -+ -+static int -+virStorageFileMatchesExtension(int format, -+ const char *path) -+{ -+ if (fileTypeInfo[format].extension == NULL) -+ return 0; -+ -+ if (virFileHasSuffix(path, fileTypeInfo[format].extension)) -+ return 1; -+ -+ return 0; -+} -+ -+ -+static int -+virStorageFileMatchesVersion(int format, -+ unsigned char *buf, -+ size_t buflen) -+{ -+ int version; -+ -+ /* Validate version number info */ -+ if (fileTypeInfo[format].versionOffset == -1) -+ return 0; -+ -+ if ((fileTypeInfo[format].versionOffset + 4) > buflen) -+ return 0; -+ -+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) { -+ version = -+ (buf[fileTypeInfo[format].versionOffset+3] << 24) | -+ (buf[fileTypeInfo[format].versionOffset+2] << 16) | -+ (buf[fileTypeInfo[format].versionOffset+1] << 8) | -+ (buf[fileTypeInfo[format].versionOffset]); -+ } else { -+ version = -+ (buf[fileTypeInfo[format].versionOffset] << 24) | -+ (buf[fileTypeInfo[format].versionOffset+1] << 16) | -+ (buf[fileTypeInfo[format].versionOffset+2] << 8) | -+ (buf[fileTypeInfo[format].versionOffset+3]); -+ } -+ if (version != fileTypeInfo[format].versionNumber) -+ return 0; -+ -+ return 1; -+} -+ -+ -+static int -+virStorageFileGetMetadataFromBuf(int format, -+ const char *path, -+ unsigned char *buf, -+ size_t buflen, -+ virStorageFileMetadata *meta) -+{ -+ /* XXX we should consider moving virStorageBackendUpdateVolInfo -+ * code into this method, for non-magic files -+ */ -+ if (!fileTypeInfo[format].magic) { -+ return 0; -+ } -+ -+ /* Optionally extract capacity from file */ -+ if (fileTypeInfo[format].sizeOffset != -1) { -+ if ((fileTypeInfo[format].sizeOffset + 8) > buflen) -+ return 1; -+ -+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) { -+ meta->capacity = -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7] << 56) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 48) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 40) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 32) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 24) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 16) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 8) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset]); -+ } else { -+ meta->capacity = -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset] << 56) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 48) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 40) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 32) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 24) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 16) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 8) | -+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7]); -+ } -+ /* Avoid unlikely, but theoretically possible overflow */ -+ if (meta->capacity > (ULLONG_MAX / fileTypeInfo[format].sizeMultiplier)) -+ return 1; -+ meta->capacity *= fileTypeInfo[format].sizeMultiplier; -+ } -+ -+ if (fileTypeInfo[format].qcowCryptOffset != -1) { -+ int crypt_format; -+ -+ crypt_format = -+ (buf[fileTypeInfo[format].qcowCryptOffset] << 24) | -+ (buf[fileTypeInfo[format].qcowCryptOffset+1] << 16) | -+ (buf[fileTypeInfo[format].qcowCryptOffset+2] << 8) | -+ (buf[fileTypeInfo[format].qcowCryptOffset+3]); -+ meta->encrypted = crypt_format != 0; -+ } -+ -+ if (fileTypeInfo[format].getBackingStore != NULL) { -+ char *backing; -+ int backingFormat; -+ int ret = fileTypeInfo[format].getBackingStore(&backing, -+ &backingFormat, -+ buf, buflen); -+ if (ret == BACKING_STORE_INVALID) -+ return 1; -+ -+ if (ret == BACKING_STORE_ERROR) -+ return -1; -+ -+ if (backing != NULL) { -+ meta->backingStore = absolutePathFromBaseFile(path, backing); -+ VIR_FREE(backing); -+ if (meta->backingStore == NULL) { -+ virReportOOMError(); -+ return -1; -+ } -+ meta->backingStoreFormat = backingFormat; -+ } else { -+ meta->backingStore = NULL; -+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; -+ } -+ } -+ -+ return 0; -+} -+ -+ -+static int -+virStorageFileProbeFormatFromBuf(const char *path, -+ unsigned char *buf, -+ size_t buflen) -+{ -+ int format = VIR_STORAGE_FILE_RAW; -+ int i; -+ -+ /* First check file magic */ -+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) { -+ if (virStorageFileMatchesMagic(i, buf, buflen) && -+ virStorageFileMatchesVersion(i, buf, buflen)) { -+ format = i; -+ goto cleanup; -+ } -+ } -+ -+ /* No magic, so check file extension */ -+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) { -+ if (virStorageFileMatchesExtension(i, path)) { -+ format = i; -+ goto cleanup; -+ } -+ } -+ -+cleanup: -+ return format; -+} -+ - /** -- * Probe the header of a file to determine what type of disk image -- * it is, and info about its capacity if available. -+ * virStorageFileProbeFormatFromFD: -+ * -+ * Probe for the format of 'fd' (which is an open file descriptor -+ * pointing to 'path'), returning the detected disk format. -+ * -+ * Callers are advised never to trust the returned 'format' -+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a -+ * malicious guest can turn a file into any other non-raw -+ * format at will. -+ * -+ * Best option: Don't use this function - */ - int --virStorageFileGetMetadataFromFD(const char *path, -- int fd, -- virStorageFileMetadata *meta) -+virStorageFileProbeFormatFromFD(const char *path, int fd) - { - unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ -- int len, i; -+ int len; - -- /* If all else fails, call it a raw file */ -- meta->format = VIR_STORAGE_FILE_RAW; -+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { -+ virReportSystemError(errno, _("cannot set to start of '%s'"), path); -+ return -1; -+ } - - if ((len = read(fd, head, sizeof(head))) < 0) { - virReportSystemError(errno, _("cannot read header '%s'"), path); - return -1; - } - -- /* First check file magic */ -- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { -- int mlen; -+ return virStorageFileProbeFormatFromBuf(path, head, len); -+} - -- if (fileTypeInfo[i].magic == NULL) -- continue; -+/** -+ * virStorageFileProbeFormat: -+ * -+ * Probe for the format of 'path', returning the detected -+ * disk format. -+ * -+ * Callers are advised never to trust the returned 'format' -+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a -+ * malicious guest can turn a file into any other non-raw -+ * format at will. -+ * -+ * Best option: Don't use this function -+ */ -+int -+virStorageFileProbeFormat(const char *path) -+{ -+ int fd, ret; - -- /* Validate magic data */ -- mlen = strlen(fileTypeInfo[i].magic); -- if (mlen > len) -- continue; -- if (memcmp(head, fileTypeInfo[i].magic, mlen) != 0) -- continue; -- -- /* Validate version number info */ -- if (fileTypeInfo[i].versionNumber != -1) { -- int version; -- -- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) { -- version = (head[fileTypeInfo[i].versionOffset+3] << 24) | -- (head[fileTypeInfo[i].versionOffset+2] << 16) | -- (head[fileTypeInfo[i].versionOffset+1] << 8) | -- head[fileTypeInfo[i].versionOffset]; -- } else { -- version = (head[fileTypeInfo[i].versionOffset] << 24) | -- (head[fileTypeInfo[i].versionOffset+1] << 16) | -- (head[fileTypeInfo[i].versionOffset+2] << 8) | -- head[fileTypeInfo[i].versionOffset+3]; -- } -- if (version != fileTypeInfo[i].versionNumber) -- continue; -- } -+ if ((fd = open(path, O_RDONLY)) < 0) { -+ virReportSystemError(errno, _("cannot open file '%s'"), path); -+ return -1; -+ } - -- /* Optionally extract capacity from file */ -- if (fileTypeInfo[i].sizeOffset != -1) { -- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) { -- meta->capacity = -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7] << 56) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 48) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 40) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 32) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 24) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 16) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 8) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset]); -- } else { -- meta->capacity = -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset] << 56) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 48) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 40) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 32) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 24) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 16) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 8) | -- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7]); -- } -- /* Avoid unlikely, but theoretically possible overflow */ -- if (meta->capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier)) -- continue; -- meta->capacity *= fileTypeInfo[i].sizeMultiplier; -- } -+ ret = virStorageFileProbeFormatFromFD(path, fd); - -- if (fileTypeInfo[i].qcowCryptOffset != -1) { -- int crypt_format; -+ close(fd); - -- crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) | -- (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) | -- (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) | -- head[fileTypeInfo[i].qcowCryptOffset+3]; -- meta->encrypted = crypt_format != 0; -- } -+ return ret; -+} - -- /* Validation passed, we know the file format now */ -- meta->format = i; -- if (fileTypeInfo[i].getBackingStore != NULL) { -- char *backing; -- int backingFormat; -- -- switch (fileTypeInfo[i].getBackingStore(&backing, -- &backingFormat, -- head, len)) { -- case BACKING_STORE_OK: -- break; -+/** -+ * virStorageFileGetMetadataFromFD: -+ * -+ * Probe for the format of 'fd' (which is an open file descriptor -+ * for the file 'path'), filling 'meta' with the detected -+ * format and other associated metadata. -+ * -+ * Callers are advised never to trust the returned 'meta->format' -+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a -+ * malicious guest can turn a file into any other non-raw -+ * format at will. -+ */ -+int -+virStorageFileGetMetadataFromFD(const char *path, -+ int fd, -+ virStorageFileMetadata *meta) -+{ -+ unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ -+ int len; - -- case BACKING_STORE_INVALID: -- continue; -+ memset(meta, 0, sizeof (*meta)); - -- case BACKING_STORE_ERROR: -- return -1; -- } -- if (backing != NULL) { -- meta->backingStore = absolutePathFromBaseFile(path, backing); -- VIR_FREE(backing); -- if (meta->backingStore == NULL) { -- virReportOOMError(); -- return -1; -- } -- meta->backingStoreFormat = backingFormat; -- } else { -- meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO; -- } -- } -- return 0; -+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { -+ virReportSystemError(errno, _("cannot set to start of '%s'"), path); -+ return -1; - } - -- /* No magic, so check file extension */ -- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { -- if (fileTypeInfo[i].extension == NULL) -- continue; -- -- if (!virFileHasSuffix(path, fileTypeInfo[i].extension)) -- continue; -- -- meta->format = i; -- return 0; -+ if ((len = read(fd, head, sizeof(head))) < 0) { -+ virReportSystemError(errno, _("cannot read header '%s'"), path); -+ return -1; - } - -- return 0; -+ meta->format = virStorageFileProbeFormatFromBuf(path, head, len); -+ -+ return virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta); - } - -+/** -+ * virStorageFileGetMetadata: -+ * -+ * Probe for the format of 'path', filling 'meta' with the detected -+ * format and other associated metadata. -+ * -+ * Callers are advised never to trust the returned 'meta->format' -+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a -+ * malicious guest can turn a file into any other non-raw -+ * format at will. -+ */ - int - virStorageFileGetMetadata(const char *path, - virStorageFileMetadata *meta) -Index: libvirt-0.8.1/src/util/storage_file.h -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.h -+++ libvirt-0.8.1/src/util/storage_file.h -@@ -57,6 +57,10 @@ typedef struct _virStorageFileMetadata { - # define DEV_BSIZE 512 - # endif - -+int virStorageFileProbeFormat(const char *path); -+int virStorageFileProbeFormatFromFD(const char *path, -+ int fd); -+ - int virStorageFileGetMetadata(const char *path, - virStorageFileMetadata *meta); - int virStorageFileGetMetadataFromFD(const char *path, diff --git a/CVE-2010-223x-0004.patch b/CVE-2010-223x-0004.patch deleted file mode 100644 index bd0633c..0000000 --- a/CVE-2010-223x-0004.patch +++ /dev/null @@ -1,218 +0,0 @@ ->From 7b2c30d0af7938df533b85e948918cfdff2e5f01 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Tue, 15 Jun 2010 16:15:51 +0100 -Subject: [PATCH 04/10] Require format to be passed into virStorageFileGetMetadata - -Require the disk image to be passed into virStorageFileGetMetadata. -If this is set to VIR_STORAGE_FILE_AUTO, then the format will be -resolved using probing. This makes it easier to control when -probing will be used - -* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c, - src/security/security_selinux.c, src/security/virt-aa-helper.c: - Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata. -* src/storage/storage_backend_fs.c: Probe for disk format before - caling virStorageFileGetMetadata. -* src/util/storage_file.h, src/util/storage_file.c: Remove format - from virStorageFileMeta struct & require it to be passed into - method. ---- - src/qemu/qemu_driver.c | 27 +++++++++++++++++++++++---- - src/qemu/qemu_security_dac.c | 4 +++- - src/security/security_selinux.c | 4 +++- - src/security/virt-aa-helper.c | 4 +++- - src/storage/storage_backend_fs.c | 11 ++++++++--- - src/util/storage_file.c | 15 ++++++++++++--- - src/util/storage_file.h | 3 ++- - 7 files changed, 54 insertions(+), 14 deletions(-) - -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 -@@ -9059,8 +9059,10 @@ static int qemuDomainGetBlockInfo(virDom - int fd = -1; - off_t end; - virStorageFileMetadata meta; -+ virDomainDiskDefPtr disk = NULL; - struct stat sb; - int i; -+ int format; - - virCheckFlags(0, -1); - -@@ -9086,6 +9088,7 @@ static int qemuDomainGetBlockInfo(virDom - if (vm->def->disks[i]->src != NULL && - STREQ (vm->def->disks[i]->src, path)) { - ret = 0; -+ disk = vm->def->disks[i]; - break; - } - } -@@ -9108,7 +9111,21 @@ static int qemuDomainGetBlockInfo(virDom - - /* Probe for magic formats */ - memset(&meta, 0, sizeof(meta)); -- if (virStorageFileGetMetadataFromFD(path, fd, &meta) < 0) -+ if (disk->driverType) { -+ if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) { -+ qemuReportError(VIR_ERR_INTERNAL_ERROR, -+ _("unknown disk format %s for %s"), -+ disk->driverType, disk->src); -+ goto cleanup; -+ } -+ } else { -+ if ((format = virStorageFileProbeFormat(disk->src)) < 0) -+ goto cleanup; -+ } -+ -+ if (virStorageFileGetMetadataFromFD(path, fd, -+ format, -+ &meta) < 0) - goto cleanup; - - /* Get info for normal formats */ -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,9 @@ qemuSecurityDACSetSecurityImageLabel(vir - - memset(&meta, 0, sizeof(meta)); - -- ret = virStorageFileGetMetadata(path, &meta); -+ ret = virStorageFileGetMetadata(path, -+ VIR_STORAGE_FILE_AUTO, -+ &meta); - - if (path != disk->src) - VIR_FREE(path); -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 -@@ -431,7 +431,9 @@ SELinuxSetSecurityImageLabel(virDomainOb - - memset(&meta, 0, sizeof(meta)); - -- ret = virStorageFileGetMetadata(path, &meta); -+ ret = virStorageFileGetMetadata(path, -+ VIR_STORAGE_FILE_AUTO, -+ &meta); - - if (path != disk->src) - VIR_FREE(path); -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 -@@ -833,7 +833,9 @@ get_files(vahControl * ctl) - - memset(&meta, 0, sizeof(meta)); - -- ret = virStorageFileGetMetadata(path, &meta); -+ ret = virStorageFileGetMetadata(path, -+ VIR_STORAGE_FILE_AUTO, -+ &meta); - - if (path != ctl->def->disks[i]->src) - VIR_FREE(path); -Index: libvirt-0.8.1/src/storage/storage_backend_fs.c -=================================================================== ---- libvirt-0.8.1.orig/src/storage/storage_backend_fs.c -+++ libvirt-0.8.1/src/storage/storage_backend_fs.c -@@ -77,14 +77,19 @@ virStorageBackendProbeTarget(virStorageV - - memset(&meta, 0, sizeof(meta)); - -- if (virStorageFileGetMetadataFromFD(target->path, fd, &meta) < 0) { -+ if ((target->format = virStorageFileProbeFormatFromFD(target->path, fd)) < 0) { - close(fd); - return -1; - } - -- close(fd); -+ if (virStorageFileGetMetadataFromFD(target->path, fd, -+ target->format, -+ &meta) < 0) { -+ close(fd); -+ return -1; -+ } - -- target->format = meta.format; -+ close(fd); - - if (backingStore) { - *backingStore = meta.backingStore; -Index: libvirt-0.8.1/src/util/storage_file.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.c -+++ libvirt-0.8.1/src/util/storage_file.c -@@ -653,6 +653,7 @@ virStorageFileProbeFormat(const char *pa - int - virStorageFileGetMetadataFromFD(const char *path, - int fd, -+ int format, - virStorageFileMetadata *meta) - { - unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ -@@ -670,9 +671,16 @@ virStorageFileGetMetadataFromFD(const ch - return -1; - } - -- meta->format = virStorageFileProbeFormatFromBuf(path, head, len); -+ if (format == VIR_STORAGE_FILE_AUTO) -+ format = virStorageFileProbeFormatFromBuf(path, head, len); - -- return virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta); -+ if (format < 0 || -+ format >= VIR_STORAGE_FILE_LAST) { -+ virReportSystemError(EINVAL, _("unknown storage file format %d"), format); -+ return -1; -+ } -+ -+ return virStorageFileGetMetadataFromBuf(format, path, head, len, meta); - } - - /** -@@ -688,6 +696,7 @@ virStorageFileGetMetadataFromFD(const ch - */ - int - virStorageFileGetMetadata(const char *path, -+ int format, - virStorageFileMetadata *meta) - { - int fd, ret; -@@ -697,7 +706,7 @@ virStorageFileGetMetadata(const char *pa - return -1; - } - -- ret = virStorageFileGetMetadataFromFD(path, fd, meta); -+ ret = virStorageFileGetMetadataFromFD(path, fd, format, meta); - - close(fd); - -Index: libvirt-0.8.1/src/util/storage_file.h -=================================================================== ---- libvirt-0.8.1.orig/src/util/storage_file.h -+++ libvirt-0.8.1/src/util/storage_file.h -@@ -46,7 +46,6 @@ enum virStorageFileFormat { - VIR_ENUM_DECL(virStorageFileFormat); - - typedef struct _virStorageFileMetadata { -- int format; - char *backingStore; - int backingStoreFormat; - unsigned long long capacity; -@@ -62,9 +61,11 @@ int virStorageFileProbeFormatFromFD(cons - int fd); - - int virStorageFileGetMetadata(const char *path, -+ int format, - virStorageFileMetadata *meta); - int virStorageFileGetMetadataFromFD(const char *path, - int fd, -+ int format, - virStorageFileMetadata *meta); - - #endif /* __VIR_STORAGE_FILE_H__ */ diff --git a/CVE-2010-223x-0005.patch b/CVE-2010-223x-0005.patch deleted file mode 100644 index 9523af8..0000000 --- a/CVE-2010-223x-0005.patch +++ /dev/null @@ -1,167 +0,0 @@ ->From 494b96317334716f846436a5ec485963411cb4a3 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Mon, 14 Jun 2010 18:09:15 +0100 -Subject: [PATCH 05/10] Add an API for iterating over disk paths - -There is duplicated code which iterates over disk backing stores -performing some action. Provide a convenient helper for doing -this to eliminate duplication & risk of mistakes with disk format -probing - -* src/conf/domain_conf.c, src/conf/domain_conf.h, - src/libvirt_private.syms: Add virDomainDiskDefForeachPath() ---- - src/conf/domain_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ - src/conf/domain_conf.h | 11 +++++ - src/libvirt_private.syms | 1 + - 3 files changed, 111 insertions(+), 0 deletions(-) - -Index: libvirt-0.8.1/src/conf/domain_conf.c -=================================================================== ---- libvirt-0.8.1.orig/src/conf/domain_conf.c -+++ libvirt-0.8.1/src/conf/domain_conf.c -@@ -45,6 +45,7 @@ - #include "macvtap.h" - #include "nwfilter_conf.h" - #include "ignore-value.h" -+#include "storage_file.h" - - #define VIR_FROM_THIS VIR_FROM_DOMAIN - -@@ -6928,4 +6929,102 @@ int virDomainSnapshotHasChildren(virDoma - } - - -+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, -+ bool allowProbing, -+ bool ignoreOpenFailure, -+ virDomainDiskDefPathIterator iter, -+ void *opaque) -+{ -+ virHashTablePtr paths; -+ int format; -+ int ret = -1; -+ int depth = 0; -+ char *nextpath = NULL; -+ -+ if (!disk->src) -+ return 0; -+ -+ if (disk->driverType) { -+ const char *formatStr = disk->driverType; -+ if (STREQ(formatStr, "aio")) -+ formatStr = "raw"; /* Xen compat */ -+ -+ if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) { -+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, -+ _("unknown disk format '%s' for %s"), -+ disk->driverType, disk->src); -+ return -1; -+ } -+ } else { -+ if (allowProbing) { -+ format = VIR_STORAGE_FILE_AUTO; -+ } else { -+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, -+ _("no disk format for %s and probing is disabled"), -+ disk->src); -+ return -1; -+ } -+ } -+ -+ paths = virHashCreate(5); -+ -+ do { -+ virStorageFileMetadata meta; -+ const char *path = nextpath ? nextpath : disk->src; -+ int fd; -+ -+ if (iter(disk, path, depth, opaque) < 0) -+ goto cleanup; -+ -+ if (virHashLookup(paths, path)) { -+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, -+ _("backing store for %s is self-referential"), -+ disk->src); -+ goto cleanup; -+ } -+ -+ if ((fd = open(path, O_RDONLY)) < 0) { -+ if (ignoreOpenFailure) { -+ char ebuf[1024]; -+ VIR_WARN("Ignoring open failure on %s: %s", path, -+ virStrerror(errno, ebuf, sizeof(ebuf))); -+ break; -+ } else { -+ virReportSystemError(errno, -+ _("unable to open disk path %s"), -+ path); -+ goto cleanup; -+ } -+ } -+ -+ if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) { -+ close(fd); -+ goto cleanup; -+ } -+ close(fd); -+ -+ if (virHashAddEntry(paths, path, (void*)0x1) < 0) { -+ virReportOOMError(); -+ goto cleanup; -+ } -+ -+ depth++; -+ nextpath = meta.backingStore; -+ -+ format = meta.backingStoreFormat; -+ -+ if (format == VIR_STORAGE_FILE_AUTO && -+ !allowProbing) -+ format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */ -+ } while (nextpath); -+ -+ ret = 0; -+ -+cleanup: -+ virHashFree(paths, NULL); -+ VIR_FREE(nextpath); -+ -+ return ret; -+} -+ - #endif /* ! PROXY */ -Index: libvirt-0.8.1/src/conf/domain_conf.h -=================================================================== ---- libvirt-0.8.1.orig/src/conf/domain_conf.h -+++ libvirt-0.8.1/src/conf/domain_conf.h -@@ -1057,6 +1057,17 @@ int virDomainObjListGetInactiveNames(vir - int maxnames); - - -+typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk, -+ const char *path, -+ unsigned int depth, -+ void *opaque); -+ -+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, -+ bool allowProbing, -+ bool ignoreOpenFailure, -+ virDomainDiskDefPathIterator iter, -+ void *opaque); -+ - VIR_ENUM_DECL(virDomainVirt) - VIR_ENUM_DECL(virDomainBoot) - VIR_ENUM_DECL(virDomainFeature) -Index: libvirt-0.8.1/src/libvirt_private.syms -=================================================================== ---- libvirt-0.8.1.orig/src/libvirt_private.syms -+++ libvirt-0.8.1/src/libvirt_private.syms -@@ -223,6 +223,7 @@ virDomainSnapshotObjUnref; - virDomainSnapshotDefParseString; - virDomainSnapshotDefFormat; - virDomainSnapshotAssignDef; -+virDomainDiskDefForeachPath; - - - # domain_event.h diff --git a/CVE-2010-223x-0006.patch b/CVE-2010-223x-0006.patch deleted file mode 100644 index 50a3d63..0000000 --- a/CVE-2010-223x-0006.patch +++ /dev/null @@ -1,273 +0,0 @@ ->From e2ebe4b785eccb930f36f400a22940fa9660a24b Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Tue, 15 Jun 2010 16:40:47 +0100 -Subject: [PATCH 06/10] Convert all disk backing store loops to shared helper API - -Update the QEMU cgroups code, QEMU DAC security driver, SELinux -and AppArmour security drivers over to use the shared helper API -virDomainDiskDefForeachPath(). - -* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c, - src/security/security_selinux.c, src/security/virt-aa-helper.c: - Convert over to use virDomainDiskDefForeachPath() ---- - src/qemu/qemu_driver.c | 161 ++++++++++++++++---------------------- - src/qemu/qemu_security_dac.c | 47 ++++-------- - src/security/security_selinux.c | 67 +++++++---------- - src/security/virt-aa-helper.c | 71 ++++++++---------- - 4 files changed, 142 insertions(+), 204 deletions(-) - -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 -@@ -99,47 +99,28 @@ err: - - - static int -+qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED, -+ const char *path, -+ unsigned int depth ATTRIBUTE_UNUSED, -+ void *opaque ATTRIBUTE_UNUSED) -+{ -+ return qemuSecurityDACSetOwnership(path, driver->user, driver->group); -+} -+ -+ -+static int - qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, - virDomainDiskDefPtr disk) - - { -- const char *path; -- - if (!driver->privileged || !driver->dynamicOwnership) - return 0; - -- if (!disk->src) -- return 0; -- -- path = disk->src; -- do { -- virStorageFileMetadata meta; -- int ret; -- -- memset(&meta, 0, sizeof(meta)); -- -- ret = virStorageFileGetMetadata(path, -- VIR_STORAGE_FILE_AUTO, -- &meta); -- -- if (path != disk->src) -- VIR_FREE(path); -- path = NULL; -- -- if (ret < 0) -- return -1; -- -- if (meta.backingStore != NULL && -- qemuSecurityDACSetOwnership(meta.backingStore, -- driver->user, driver->group) < 0) { -- VIR_FREE(meta.backingStore); -- return -1; -- } -- -- path = meta.backingStore; -- } while (path != NULL); -- -- return qemuSecurityDACSetOwnership(disk->src, driver->user, driver->group); -+ return virDomainDiskDefForeachPath(disk, -+ true, -+ false, -+ qemuSecurityDACSetSecurityFileLabel, -+ NULL); - } - - -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 -@@ -411,56 +411,43 @@ SELinuxRestoreSecurityImageLabel(virDoma - } - - static int -+SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk, -+ const char *path, -+ unsigned int depth, -+ void *opaque) -+{ -+ const virSecurityLabelDefPtr secdef = opaque; -+ -+ if (depth == 0) { -+ if (disk->shared) { -+ return SELinuxSetFilecon(path, default_image_context); -+ } else if (disk->readonly) { -+ return SELinuxSetFilecon(path, default_content_context); -+ } else if (secdef->imagelabel) { -+ return SELinuxSetFilecon(path, secdef->imagelabel); -+ } else { -+ return 0; -+ } -+ } else { -+ return SELinuxSetFilecon(path, default_content_context); -+ } -+} -+ -+static int - SELinuxSetSecurityImageLabel(virDomainObjPtr vm, - virDomainDiskDefPtr disk) - - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -- const char *path; - - if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) - return 0; - -- if (!disk->src) -- return 0; -- -- path = disk->src; -- do { -- virStorageFileMetadata meta; -- int ret; -- -- memset(&meta, 0, sizeof(meta)); -- -- ret = virStorageFileGetMetadata(path, -- VIR_STORAGE_FILE_AUTO, -- &meta); -- -- if (path != disk->src) -- VIR_FREE(path); -- path = NULL; -- -- if (ret < 0) -- break; -- -- if (meta.backingStore != NULL && -- SELinuxSetFilecon(meta.backingStore, -- default_content_context) < 0) { -- VIR_FREE(meta.backingStore); -- return -1; -- } -- -- path = meta.backingStore; -- } while (path != NULL); -- -- if (disk->shared) { -- return SELinuxSetFilecon(disk->src, default_image_context); -- } else if (disk->readonly) { -- return SELinuxSetFilecon(disk->src, default_content_context); -- } else if (secdef->imagelabel) { -- return SELinuxSetFilecon(disk->src, secdef->imagelabel); -- } -- -- return 0; -+ return virDomainDiskDefForeachPath(disk, -+ true, -+ 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 -@@ -36,7 +36,6 @@ - #include "uuid.h" - #include "hostusb.h" - #include "pci.h" --#include "storage_file.h" - - static char *progname; - -@@ -802,6 +801,28 @@ file_iterate_pci_cb(pciDevice *dev ATTRI - } - - static int -+add_file_path(virDomainDiskDefPtr disk, -+ const char *path, -+ unsigned int depth, -+ void *opaque) -+{ -+ virBufferPtr buf = opaque; -+ int ret; -+ -+ if (depth == 0) { -+ if (disk->readonly) -+ ret = vah_add_file(buf, path, "r"); -+ else -+ ret = vah_add_file(buf, path, "rw"); -+ } else { -+ ret = vah_add_file(buf, path, "r"); -+ } -+ -+ return ret; -+} -+ -+ -+static int - get_files(vahControl * ctl) - { - virBuffer buf = VIR_BUFFER_INITIALIZER; -@@ -822,47 +843,15 @@ get_files(vahControl * ctl) - goto clean; - } - -- for (i = 0; i < ctl->def->ndisks; i++) -- if (ctl->def->disks[i] && ctl->def->disks[i]->src) { -- int ret; -- const char *path; -- -- path = ctl->def->disks[i]->src; -- do { -- virStorageFileMetadata meta; -- -- memset(&meta, 0, sizeof(meta)); -- -- ret = virStorageFileGetMetadata(path, -- VIR_STORAGE_FILE_AUTO, -- &meta); -- -- if (path != ctl->def->disks[i]->src) -- VIR_FREE(path); -- path = NULL; -- -- if (ret < 0) { -- vah_warning("could not open path, skipping"); -- continue; -- } -- -- if (meta.backingStore != NULL && -- (ret = vah_add_file(&buf, meta.backingStore, "rw")) != 0) { -- VIR_FREE(meta.backingStore); -- goto clean; -- } -- -- path = meta.backingStore; -- } while (path != NULL); -- -- if (ctl->def->disks[i]->readonly) -- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "r"); -- else -- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "rw"); -- -- if (ret != 0) -- goto clean; -- } -+ for (i = 0; i < ctl->def->ndisks; i++) { -+ int ret = virDomainDiskDefForeachPath(ctl->def->disks[i], -+ true, -+ false, -+ add_file_path, -+ &buf); -+ if (ret != 0) -+ goto clean; -+ } - - for (i = 0; i < ctl->def->nserials; i++) - if (ctl->def->serials[i] && ctl->def->serials[i]->data.file.path) diff --git a/CVE-2010-223x-0007.patch b/CVE-2010-223x-0007.patch deleted file mode 100644 index 386877a..0000000 --- a/CVE-2010-223x-0007.patch +++ /dev/null @@ -1,1058 +0,0 @@ ->From 38d7c5a26e4c12a784619f1ed4fc993d9af82032 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Tue, 15 Jun 2010 17:44:19 +0100 -Subject: [PATCH 07/10] Security driver params - ---- - src/qemu/qemu_driver.c | 85 +++++++++++++++++++----------- - src/qemu/qemu_security_dac.c | 44 +++++++++++----- - src/qemu/qemu_security_stacked.c | 107 +++++++++++++++++++++++++------------- - src/security/security_apparmor.c | 57 +++++++++++++------- - src/security/security_driver.h | 40 ++++++++++---- - src/security/security_selinux.c | 56 +++++++++++++------ - 6 files changed, 258 insertions(+), 131 deletions(-) - -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 -@@ -1245,7 +1245,8 @@ qemuReconnectDomain(void *payload, const - - if (driver->securityDriver && - driver->securityDriver->domainReserveSecurityLabel && -- driver->securityDriver->domainReserveSecurityLabel(obj) < 0) -+ driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver, -+ obj) < 0) - goto error; - - if (obj->def->id >= driver->nextvmid) -@@ -3207,13 +3208,15 @@ static int qemudStartVMDaemon(virConnect - DEBUG0("Generating domain security label (if required)"); - if (driver->securityDriver && - driver->securityDriver->domainGenSecurityLabel && -- driver->securityDriver->domainGenSecurityLabel(vm) < 0) -+ driver->securityDriver->domainGenSecurityLabel(driver->securityDriver, -+ vm) < 0) - return -1; - - DEBUG0("Generating setting domain security labels (if required)"); - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityAllLabel && -- driver->securityDriver->domainSetSecurityAllLabel(vm) < 0) -+ driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver, -+ vm) < 0) - goto cleanup; - - /* Ensure no historical cgroup for this VM is lying around bogus -@@ -3489,10 +3492,12 @@ cleanup: - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityAllLabel) -- driver->securityDriver->domainRestoreSecurityAllLabel(vm); -+ driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver, -+ vm); - if (driver->securityDriver && - driver->securityDriver->domainReleaseSecurityLabel) -- driver->securityDriver->domainReleaseSecurityLabel(vm); -+ driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver, -+ vm); - qemuRemoveCgroup(driver, vm, 1); - if ((vm->def->ngraphics == 1) && - vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && -@@ -3585,10 +3590,12 @@ static void qemudShutdownVMDaemon(struct - /* Reset Security Labels */ - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityAllLabel) -- driver->securityDriver->domainRestoreSecurityAllLabel(vm); -+ driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver, -+ vm); - if (driver->securityDriver && - driver->securityDriver->domainReleaseSecurityLabel) -- driver->securityDriver->domainReleaseSecurityLabel(vm); -+ driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver, -+ vm); - - /* Clear out dynamically assigned labels */ - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { -@@ -4991,7 +4998,8 @@ static int qemudDomainSaveFlag(virDomain - if ((!bypassSecurityDriver) && - driver->securityDriver && - driver->securityDriver->domainSetSavedStateLabel && -- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) -+ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, -+ vm, path) == -1) - goto endjob; - - if (header.compressed == QEMUD_SAVE_FORMAT_RAW) { -@@ -5022,7 +5030,8 @@ static int qemudDomainSaveFlag(virDomain - if ((!bypassSecurityDriver) && - driver->securityDriver && - driver->securityDriver->domainRestoreSavedStateLabel && -- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) -+ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, -+ vm, path) == -1) - VIR_WARN("failed to restore save state label on %s", path); - - if (cgroup != NULL) { -@@ -5069,7 +5078,8 @@ endjob: - if ((!bypassSecurityDriver) && - driver->securityDriver && - driver->securityDriver->domainRestoreSavedStateLabel && -- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) -+ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, -+ vm, path) == -1) - VIR_WARN("failed to restore save state label on %s", path); - } - -@@ -5304,7 +5314,8 @@ static int qemudDomainCoreDump(virDomain - - if (driver->securityDriver && - driver->securityDriver->domainSetSavedStateLabel && -- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) -+ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, -+ vm, path) == -1) - goto endjob; - - /* Migrate will always stop the VM, so the resume condition is -@@ -5340,7 +5351,8 @@ static int qemudDomainCoreDump(virDomain - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSavedStateLabel && -- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) -+ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, -+ vm, path) == -1) - goto endjob; - - endjob: -@@ -5724,12 +5736,13 @@ static int qemudDomainGetSecurityLabel(v - * QEMU monitor hasn't seen SIGHUP/ERR on poll(). - */ - if (virDomainObjIsActive(vm)) { -- if (driver->securityDriver && driver->securityDriver->domainGetSecurityProcessLabel) { -- if (driver->securityDriver->domainGetSecurityProcessLabel(vm, seclabel) == -1) { -- qemuReportError(VIR_ERR_INTERNAL_ERROR, -- "%s", _("Failed to get security label")); -- goto cleanup; -- } -+ if (driver->securityDriver && -+ driver->securityDriver->domainGetSecurityProcessLabel && -+ driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver, -+ vm, seclabel) < 0) { -+ qemuReportError(VIR_ERR_INTERNAL_ERROR, -+ "%s", _("Failed to get security label")); -+ goto cleanup; - } - } - -@@ -6731,7 +6744,8 @@ static int qemudDomainChangeEjectableMed - - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityImageLabel && -- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - return -1; - - if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags))) -@@ -6760,7 +6774,8 @@ static int qemudDomainChangeEjectableMed - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, origdisk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, origdisk) < 0) - VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src); - - VIR_FREE(origdisk->src); -@@ -6778,7 +6793,8 @@ error: - VIR_FREE(driveAlias); - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - VIR_WARN("Unable to restore security label on new media %s", disk->src); - return -1; - } -@@ -6805,7 +6821,8 @@ static int qemudDomainAttachPciDiskDevic - - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityImageLabel && -- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - return -1; - - if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { -@@ -6866,7 +6883,8 @@ error: - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - VIR_WARN("Unable to restore security label on %s", disk->src); - - return -1; -@@ -6998,7 +7016,8 @@ static int qemudDomainAttachSCSIDisk(str - - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityImageLabel && -- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - return -1; - - /* We should have an address already, so make sure */ -@@ -7080,7 +7099,8 @@ error: - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - VIR_WARN("Unable to restore security label on %s", disk->src); - - return -1; -@@ -7107,7 +7127,8 @@ static int qemudDomainAttachUsbMassstora - - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityImageLabel && -- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - return -1; - - if (!disk->src) { -@@ -7159,7 +7180,8 @@ error: - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, disk) < 0) - VIR_WARN("Unable to restore security label on %s", disk->src); - - return -1; -@@ -7503,7 +7525,8 @@ static int qemudDomainAttachHostDevice(s - - if (driver->securityDriver && - driver->securityDriver->domainSetSecurityHostdevLabel && -- driver->securityDriver->domainSetSecurityHostdevLabel(vm, hostdev) < 0) -+ driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver, -+ vm, hostdev) < 0) - return -1; - - switch (hostdev->source.subsys.type) { -@@ -7531,7 +7554,8 @@ static int qemudDomainAttachHostDevice(s - error: - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityHostdevLabel && -- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, hostdev) < 0) -+ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, -+ vm, hostdev) < 0) - VIR_WARN0("Unable to restore host device labelling on hotplug fail"); - - return -1; -@@ -7962,7 +7986,8 @@ static int qemudDomainDetachPciDiskDevic - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityImageLabel && -- driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0) -+ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, -+ vm, dev->data.disk) < 0) - VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); - - ret = 0; -@@ -8367,7 +8392,8 @@ static int qemudDomainDetachHostDevice(s - - if (driver->securityDriver && - driver->securityDriver->domainRestoreSecurityHostdevLabel && -- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, dev->data.hostdev) < 0) -+ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, -+ vm, dev->data.hostdev) < 0) - VIR_WARN0("Failed to restore host device labelling"); - - return ret; -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 -@@ -109,7 +109,8 @@ qemuSecurityDACSetSecurityFileLabel(virD - - - static int --qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, -+qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED, - virDomainDiskDefPtr disk) - - { -@@ -125,7 +126,8 @@ qemuSecurityDACSetSecurityImageLabel(vir - - - static int --qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, -+qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED, - virDomainDiskDefPtr disk) - { - if (!driver->privileged || !driver->dynamicOwnership) -@@ -168,7 +170,8 @@ qemuSecurityDACSetSecurityUSBLabel(usbDe - - - static int --qemuSecurityDACSetSecurityHostdevLabel(virDomainObjPtr vm, -+qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev) - - { -@@ -237,7 +240,8 @@ qemuSecurityDACRestoreSecurityUSBLabel(u - - - static int --qemuSecurityDACRestoreSecurityHostdevLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, -+qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED, - virDomainHostdevDefPtr dev) - - { -@@ -289,7 +293,8 @@ done: - - - static int --qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm) -+qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm) - { - int i; - int rc = 0; -@@ -300,12 +305,14 @@ qemuSecurityDACRestoreSecurityAllLabel(v - VIR_DEBUG("Restoring security label on %s", vm->def->name); - - for (i = 0 ; i < vm->def->nhostdevs ; i++) { -- if (qemuSecurityDACRestoreSecurityHostdevLabel(vm, -+ if (qemuSecurityDACRestoreSecurityHostdevLabel(drv, -+ vm, - vm->def->hostdevs[i]) < 0) - rc = -1; - } - for (i = 0 ; i < vm->def->ndisks ; i++) { -- if (qemuSecurityDACRestoreSecurityImageLabel(vm, -+ if (qemuSecurityDACRestoreSecurityImageLabel(drv, -+ vm, - vm->def->disks[i]) < 0) - rc = -1; - } -@@ -323,7 +330,8 @@ qemuSecurityDACRestoreSecurityAllLabel(v - - - static int --qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm) -+qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm) - { - int i; - -@@ -334,11 +342,15 @@ qemuSecurityDACSetSecurityAllLabel(virDo - /* XXX fixme - we need to recursively label the entriy tree :-( */ - if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR) - continue; -- if (qemuSecurityDACSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) -+ if (qemuSecurityDACSetSecurityImageLabel(drv, -+ vm, -+ vm->def->disks[i]) < 0) - return -1; - } - for (i = 0 ; i < vm->def->nhostdevs ; i++) { -- if (qemuSecurityDACSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) -+ if (qemuSecurityDACSetSecurityHostdevLabel(drv, -+ vm, -+ vm->def->hostdevs[i]) < 0) - return -1; - } - -@@ -359,7 +371,8 @@ qemuSecurityDACSetSecurityAllLabel(virDo - - - static int --qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, -+qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED, - const char *savefile) - { - if (!driver->privileged || !driver->dynamicOwnership) -@@ -370,7 +383,8 @@ qemuSecurityDACSetSavedStateLabel(virDom - - - static int --qemuSecurityDACRestoreSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, -+qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED, - const char *savefile) - { - if (!driver->privileged || !driver->dynamicOwnership) -Index: libvirt-0.8.1/src/qemu/qemu_security_stacked.c -=================================================================== ---- libvirt-0.8.1.orig/src/qemu/qemu_security_stacked.c -+++ libvirt-0.8.1/src/qemu/qemu_security_stacked.c -@@ -57,18 +57,21 @@ qemuSecurityStackedVerify(virDomainDefPt - - - static int --qemuSecurityStackedGenLabel(virDomainObjPtr vm) -+qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainGenSecurityLabel && -- driver->securitySecondaryDriver->domainGenSecurityLabel(vm) < 0) -+ driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver, -+ vm) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainGenSecurityLabel && -- driver->securityPrimaryDriver->domainGenSecurityLabel(vm) < 0) -+ driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver, -+ vm) < 0) - rc = -1; - - return rc; -@@ -76,18 +79,21 @@ qemuSecurityStackedGenLabel(virDomainObj - - - static int --qemuSecurityStackedReleaseLabel(virDomainObjPtr vm) -+qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainReleaseSecurityLabel && -- driver->securitySecondaryDriver->domainReleaseSecurityLabel(vm) < 0) -+ driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver, -+ vm) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainReleaseSecurityLabel && -- driver->securityPrimaryDriver->domainReleaseSecurityLabel(vm) < 0) -+ driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver, -+ vm) < 0) - rc = -1; - - return rc; -@@ -95,18 +101,21 @@ qemuSecurityStackedReleaseLabel(virDomai - - - static int --qemuSecurityStackedReserveLabel(virDomainObjPtr vm) -+qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainReserveSecurityLabel && -- driver->securitySecondaryDriver->domainReserveSecurityLabel(vm) < 0) -+ driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver, -+ vm) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainReserveSecurityLabel && -- driver->securityPrimaryDriver->domainReserveSecurityLabel(vm) < 0) -+ driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver, -+ vm) < 0) - rc = -1; - - return rc; -@@ -114,19 +123,22 @@ qemuSecurityStackedReserveLabel(virDomai - - - static int --qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm, -+qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainSetSecurityImageLabel && -- driver->securitySecondaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver, -+ vm, disk) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainSetSecurityImageLabel && -- driver->securityPrimaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) -+ driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver, -+ vm, disk) < 0) - rc = -1; - - return rc; -@@ -134,19 +146,22 @@ qemuSecurityStackedSetSecurityImageLabel - - - static int --qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm, -+qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainRestoreSecurityImageLabel && -- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver, -+ vm, disk) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainRestoreSecurityImageLabel && -- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) -+ driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver, -+ vm, disk) < 0) - rc = -1; - - return rc; -@@ -154,7 +169,8 @@ qemuSecurityStackedRestoreSecurityImageL - - - static int --qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm, -+qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev) - - { -@@ -162,12 +178,14 @@ qemuSecurityStackedSetSecurityHostdevLab - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainSetSecurityHostdevLabel && -- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) -+ driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver, -+ vm, dev) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainSetSecurityHostdevLabel && -- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) -+ driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver, -+ vm, dev) < 0) - rc = -1; - - return rc; -@@ -175,20 +193,22 @@ qemuSecurityStackedSetSecurityHostdevLab - - - static int --qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm, -+qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev) -- - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel && -- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) -+ driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver, -+ vm, dev) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel && -- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) -+ driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver, -+ vm, dev) < 0) - rc = -1; - - return rc; -@@ -196,18 +216,21 @@ qemuSecurityStackedRestoreSecurityHostde - - - static int --qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm) -+qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainSetSecurityAllLabel && -- driver->securitySecondaryDriver->domainSetSecurityAllLabel(vm) < 0) -+ driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver, -+ vm) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainSetSecurityAllLabel && -- driver->securityPrimaryDriver->domainSetSecurityAllLabel(vm) < 0) -+ driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver, -+ vm) < 0) - rc = -1; - - return rc; -@@ -215,18 +238,21 @@ qemuSecurityStackedSetSecurityAllLabel(v - - - static int --qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm) -+qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainRestoreSecurityAllLabel && -- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm) < 0) -+ driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver, -+ vm) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainRestoreSecurityAllLabel && -- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm) < 0) -+ driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver, -+ vm) < 0) - rc = -1; - - return rc; -@@ -234,19 +260,22 @@ qemuSecurityStackedRestoreSecurityAllLab - - - static int --qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm, -+qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - const char *savefile) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainSetSavedStateLabel && -- driver->securitySecondaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) -+ driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver, -+ vm, savefile) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainSetSavedStateLabel && -- driver->securityPrimaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) -+ driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver, -+ vm, savefile) < 0) - rc = -1; - - return rc; -@@ -254,19 +283,22 @@ qemuSecurityStackedSetSavedStateLabel(vi - - - static int --qemuSecurityStackedRestoreSavedStateLabel(virDomainObjPtr vm, -+qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - const char *savefile) - { - int rc = 0; - - if (driver->securitySecondaryDriver && - driver->securitySecondaryDriver->domainRestoreSavedStateLabel && -- driver->securitySecondaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) -+ driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver, -+ vm, savefile) < 0) - rc = -1; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainRestoreSavedStateLabel && -- driver->securityPrimaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) -+ driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver, -+ vm, savefile) < 0) - rc = -1; - - return rc; -@@ -295,14 +327,16 @@ qemuSecurityStackedSetProcessLabel(virSe - } - - static int --qemuSecurityStackedGetProcessLabel(virDomainObjPtr vm, -+qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virSecurityLabelPtr seclabel) - { - int rc = 0; - - if (driver->securityPrimaryDriver && - driver->securityPrimaryDriver->domainGetSecurityProcessLabel && -- driver->securityPrimaryDriver->domainGetSecurityProcessLabel(vm, -+ driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver, -+ vm, - seclabel) < 0) - rc = -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 -@@ -148,7 +148,8 @@ profile_status_file(const char *str) - * load (add) a profile. Will create one if necessary - */ - static int --load_profile(const char *profile, virDomainObjPtr vm, -+load_profile(virSecurityDriverPtr drv, -+ const char *profile, virDomainObjPtr vm, - virDomainDiskDefPtr disk) - { - int rc = -1, status, ret; -@@ -323,7 +324,8 @@ AppArmorSecurityDriverOpen(virSecurityDr - * called on shutdown. - */ - static int --AppArmorGenSecurityLabel(virDomainObjPtr vm) -+AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = -1; - char *profile_name = NULL; -@@ -377,14 +379,15 @@ AppArmorGenSecurityLabel(virDomainObjPtr - } - - static int --AppArmorSetSecurityAllLabel(virDomainObjPtr vm) -+AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm) - { - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) - return 0; - - /* if the profile is not already loaded, then load one */ - if (profile_loaded(vm->def->seclabel.label) < 0) { -- if (load_profile(vm->def->seclabel.label, vm, NULL) < 0) { -+ if (load_profile(drv, vm->def->seclabel.label, vm, NULL) < 0) { - virSecurityReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot generate AppArmor profile " - "\'%s\'"), vm->def->seclabel.label); -@@ -399,7 +402,9 @@ AppArmorSetSecurityAllLabel(virDomainObj - * running. - */ - static int --AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec) -+AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, -+ virSecurityLabelPtr sec) - { - int rc = -1; - char *profile_name = NULL; -@@ -431,7 +436,8 @@ AppArmorGetSecurityProcessLabel(virDomai - * more details. Currently called via qemudShutdownVMDaemon. - */ - static int --AppArmorReleaseSecurityLabel(virDomainObjPtr vm) -+AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - -@@ -444,7 +450,8 @@ AppArmorReleaseSecurityLabel(virDomainOb - - - static int --AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm) -+AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - int rc = 0; -@@ -498,7 +505,8 @@ AppArmorSetSecurityProcessLabel(virSecur - - /* Called when hotplugging */ - static int --AppArmorRestoreSecurityImageLabel(virDomainObjPtr vm, -+AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk ATTRIBUTE_UNUSED) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -@@ -513,7 +521,7 @@ AppArmorRestoreSecurityImageLabel(virDom - - /* Update the profile only if it is loaded */ - if (profile_loaded(secdef->imagelabel) >= 0) { -- if (load_profile(secdef->imagelabel, vm, NULL) < 0) { -+ if (load_profile(drv, secdef->imagelabel, vm, NULL) < 0) { - virSecurityReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot update AppArmor profile " - "\'%s\'"), -@@ -531,7 +539,8 @@ AppArmorRestoreSecurityImageLabel(virDom - - /* Called when hotplugging */ - static int --AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk) -+AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm, virDomainDiskDefPtr disk) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - int rc = -1; -@@ -556,7 +565,7 @@ AppArmorSetSecurityImageLabel(virDomainO - - /* update the profile only if it is loaded */ - if (profile_loaded(secdef->imagelabel) >= 0) { -- if (load_profile(secdef->imagelabel, vm, disk) < 0) { -+ if (load_profile(drv, secdef->imagelabel, vm, disk) < 0) { - virSecurityReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot update AppArmor profile " - "\'%s\'"), -@@ -590,14 +599,16 @@ AppArmorSecurityVerify(virDomainDefPtr d - } - - static int --AppArmorReserveSecurityLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED) -+AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm ATTRIBUTE_UNUSED) - { - /* NOOP. Nothing to reserve with AppArmor */ - return 0; - } - - static int --AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm, -+AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) - - { -@@ -611,7 +622,8 @@ AppArmorSetSecurityHostdevLabel(virDomai - } - - static int --AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm, -+AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) - - { -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 -@@ -28,26 +28,42 @@ typedef enum { - - typedef struct _virSecurityDriver virSecurityDriver; - typedef virSecurityDriver *virSecurityDriverPtr; -+ -+typedef struct _virSecurityDriverState virSecurityDriverState; -+typedef virSecurityDriverState *virSecurityDriverStatePtr; -+ - typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void); - typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv); --typedef int (*virSecurityDomainRestoreImageLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk); --typedef int (*virSecurityDomainSetImageLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk); --typedef int (*virSecurityDomainRestoreHostdevLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev); --typedef int (*virSecurityDomainSetHostdevLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev); --typedef int (*virSecurityDomainSetSavedStateLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - const char *savefile); --typedef int (*virSecurityDomainRestoreSavedStateLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - const char *savefile); --typedef int (*virSecurityDomainGenLabel) (virDomainObjPtr sec); --typedef int (*virSecurityDomainReserveLabel) (virDomainObjPtr sec); --typedef int (*virSecurityDomainReleaseLabel) (virDomainObjPtr sec); --typedef int (*virSecurityDomainSetAllLabel) (virDomainObjPtr sec); --typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm); --typedef int (*virSecurityDomainGetProcessLabel) (virDomainObjPtr vm, -+typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr sec); -+typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr sec); -+typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr sec); -+typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr sec); -+typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm); -+typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv, -+ virDomainObjPtr vm, - virSecurityLabelPtr sec); - typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv, - virDomainObjPtr vm); -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 -@@ -156,7 +156,8 @@ SELinuxInitialize(void) - } - - static int --SELinuxGenSecurityLabel(virDomainObjPtr vm) -+SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - int rc = -1; - char mcs[1024]; -@@ -220,7 +221,8 @@ done: - } - - static int --SELinuxReserveSecurityLabel(virDomainObjPtr vm) -+SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - security_context_t pctx; - context_t ctx = NULL; -@@ -275,7 +277,8 @@ SELinuxSecurityDriverOpen(virSecurityDri - } - - static int --SELinuxGetSecurityProcessLabel(virDomainObjPtr vm, -+SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virSecurityLabelPtr sec) - { - security_context_t ctx; -@@ -385,7 +388,8 @@ err: - } - - static int --SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm, -+SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -@@ -434,7 +438,8 @@ SELinuxSetSecurityFileLabel(virDomainDis - } - - static int --SELinuxSetSecurityImageLabel(virDomainObjPtr vm, -+SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainDiskDefPtr disk) - - { -@@ -472,7 +477,8 @@ SELinuxSetSecurityUSBLabel(usbDevice *de - } - - static int --SELinuxSetSecurityHostdevLabel(virDomainObjPtr vm, -+SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev) - - { -@@ -540,7 +546,8 @@ SELinuxRestoreSecurityUSBLabel(usbDevice - } - - static int --SELinuxRestoreSecurityHostdevLabel(virDomainObjPtr vm, -+SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - virDomainHostdevDefPtr dev) - - { -@@ -592,7 +599,8 @@ done: - } - - static int --SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm) -+SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - int i; -@@ -604,11 +612,14 @@ SELinuxRestoreSecurityAllLabel(virDomain - return 0; - - for (i = 0 ; i < vm->def->nhostdevs ; i++) { -- if (SELinuxRestoreSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) -+ if (SELinuxRestoreSecurityHostdevLabel(drv, -+ vm, -+ vm->def->hostdevs[i]) < 0) - rc = -1; - } - for (i = 0 ; i < vm->def->ndisks ; i++) { -- if (SELinuxRestoreSecurityImageLabel(vm, -+ if (SELinuxRestoreSecurityImageLabel(drv, -+ vm, - vm->def->disks[i]) < 0) - rc = -1; - } -@@ -625,7 +636,8 @@ SELinuxRestoreSecurityAllLabel(virDomain - } - - static int --SELinuxReleaseSecurityLabel(virDomainObjPtr vm) -+SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - -@@ -648,7 +660,8 @@ SELinuxReleaseSecurityLabel(virDomainObj - - - static int --SELinuxSetSavedStateLabel(virDomainObjPtr vm, -+SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - const char *savefile) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -@@ -661,7 +674,8 @@ SELinuxSetSavedStateLabel(virDomainObjPt - - - static int --SELinuxRestoreSavedStateLabel(virDomainObjPtr vm, -+SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, -+ virDomainObjPtr vm, - const char *savefile) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -@@ -719,7 +733,8 @@ SELinuxSetSecurityProcessLabel(virSecuri - } - - static int --SELinuxSetSecurityAllLabel(virDomainObjPtr vm) -+SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv, -+ virDomainObjPtr vm) - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; - int i; -@@ -734,11 +749,14 @@ SELinuxSetSecurityAllLabel(virDomainObjP - vm->def->disks[i]->src, vm->def->disks[i]->dst); - continue; - } -- if (SELinuxSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) -+ if (SELinuxSetSecurityImageLabel(drv, -+ vm, vm->def->disks[i]) < 0) - return -1; - } - for (i = 0 ; i < vm->def->nhostdevs ; i++) { -- if (SELinuxSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) -+ if (SELinuxSetSecurityHostdevLabel(drv, -+ vm, -+ vm->def->hostdevs[i]) < 0) - return -1; - } - diff --git a/CVE-2010-223x-0008.patch b/CVE-2010-223x-0008.patch deleted file mode 100644 index b432a05..0000000 --- a/CVE-2010-223x-0008.patch +++ /dev/null @@ -1,385 +0,0 @@ ->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"); diff --git a/CVE-2010-223x-0009.patch b/CVE-2010-223x-0009.patch deleted file mode 100644 index 33481fc..0000000 --- a/CVE-2010-223x-0009.patch +++ /dev/null @@ -1,110 +0,0 @@ ->From f087f0656f882be305783e24d55921b57fbbcb97 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Mon, 14 Jun 2010 16:08:55 +0100 -Subject: [PATCH 09/10] Add ability to set a default driver name/type when parsing disks - -Record a default driver name/type in capabilities struct. Use this -when parsing disks if value is not set in XML config. - -* src/conf/capabilities.h: Record default driver name/type for disks -* src/conf/domain_conf.c: Fallback to default driver name/type - when parsing disks -* src/qemu/qemu_driver.c: Set default driver name/type to raw ---- - src/conf/capabilities.h | 2 ++ - src/conf/domain_conf.c | 21 ++++++++++++++++++--- - src/qemu/qemu_driver.c | 8 ++++++++ - 3 files changed, 28 insertions(+), 3 deletions(-) - -Index: libvirt-0.8.1/src/conf/capabilities.h -=================================================================== ---- libvirt-0.8.1.orig/src/conf/capabilities.h -+++ libvirt-0.8.1/src/conf/capabilities.h -@@ -120,6 +120,8 @@ struct _virCaps { - virCapsGuestPtr *guests; - unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN]; - unsigned int emulatorRequired : 1; -+ const char *defaultDiskDriverName; -+ const char *defaultDiskDriverType; - void *(*privateDataAllocFunc)(void); - void (*privateDataFreeFunc)(void *); - int (*privateDataXMLFormat)(virBufferPtr, void *); -Index: libvirt-0.8.1/src/conf/domain_conf.c -=================================================================== ---- libvirt-0.8.1.orig/src/conf/domain_conf.c -+++ libvirt-0.8.1/src/conf/domain_conf.c -@@ -1366,7 +1366,8 @@ virDomainDiskDefAssignAddress(virDomainD - * @param node XML nodeset to parse for disk definition - */ - static virDomainDiskDefPtr --virDomainDiskDefParseXML(xmlNodePtr node, -+virDomainDiskDefParseXML(virCapsPtr caps, -+ xmlNodePtr node, - int flags) { - virDomainDiskDefPtr def; - xmlNodePtr cur; -@@ -1595,6 +1596,16 @@ virDomainDiskDefParseXML(xmlNodePtr node - def->serial = serial; - serial = NULL; - -+ if (!def->driverType && -+ caps->defaultDiskDriverType && -+ !(def->driverType = strdup(caps->defaultDiskDriverType))) -+ goto no_memory; -+ -+ if (!def->driverName && -+ caps->defaultDiskDriverName && -+ !(def->driverName = strdup(caps->defaultDiskDriverName))) -+ goto no_memory; -+ - if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE - && virDomainDiskDefAssignAddress(def) < 0) - goto error; -@@ -1615,6 +1626,9 @@ cleanup: - - return def; - -+no_memory: -+ virReportOOMError(); -+ - error: - virDomainDiskDefFree(def); - def = NULL; -@@ -3521,7 +3535,7 @@ virDomainDeviceDefPtr virDomainDeviceDef - - if (xmlStrEqual(node->name, BAD_CAST "disk")) { - dev->type = VIR_DOMAIN_DEVICE_DISK; -- if (!(dev->data.disk = virDomainDiskDefParseXML(node, flags))) -+ if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, flags))) - goto error; - } else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) { - dev->type = VIR_DOMAIN_DEVICE_FS; -@@ -4028,7 +4042,8 @@ static virDomainDefPtr virDomainDefParse - if (n && VIR_ALLOC_N(def->disks, n) < 0) - goto no_memory; - for (i = 0 ; i < n ; i++) { -- virDomainDiskDefPtr disk = virDomainDiskDefParseXML(nodes[i], -+ virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, -+ nodes[i], - flags); - if (!disk) - goto error; -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 -@@ -1324,6 +1324,14 @@ qemuCreateCapabilities(virCapsPtr oldcap - return NULL; - } - -+ if (driver->allowDiskFormatProbing) { -+ caps->defaultDiskDriverName = NULL; -+ caps->defaultDiskDriverType = NULL; -+ } else { -+ caps->defaultDiskDriverName = "qemu"; -+ caps->defaultDiskDriverType = "raw"; -+ } -+ - /* Domain XML parser hooks */ - caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc; - caps->privateDataFreeFunc = qemuDomainObjPrivateFree; diff --git a/CVE-2010-223x-0010.patch b/CVE-2010-223x-0010.patch deleted file mode 100644 index 02ab9e2..0000000 --- a/CVE-2010-223x-0010.patch +++ /dev/null @@ -1,288 +0,0 @@ ->From 6883117e3c6a6cabd760b6e6a468b69ad7b02839 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Wed, 16 Jun 2010 14:14:05 +0100 -Subject: [PATCH 10/10] Rewrite qemu-img backing store format handling - -When creating qcow2 files with a backing store, it is important -to set an explicit format to prevent QEMU probing. The storage -backend was only doing this if it found a 'kvm-img' binary. This -is wrong because plenty of kvm-img binaries don't support an -explicit format, and plenty of 'qemu-img' binaries do support -a format. The result was that most qcow2 files were not getting -a backing store format. - -This patch runs 'qemu-img -h' to check for the two support -argument formats - - '-o backing_format=raw' - '-F raw' - -and use whichever option it finds - -* src/storage/storage_backend.c: Query binary to determine - how to set the backing store format ---- - src/storage/storage_backend.c | 214 +++++++++++++++++++++++++++++------------ - 1 files changed, 152 insertions(+), 62 deletions(-) - -Index: libvirt-0.8.1/src/storage/storage_backend.c -=================================================================== ---- libvirt-0.8.1.orig/src/storage/storage_backend.c -+++ libvirt-0.8.1/src/storage/storage_backend.c -@@ -563,6 +563,69 @@ static int virStorageBackendCreateExecCo - return 0; - } - -+enum { -+ QEMU_IMG_BACKING_FORMAT_NONE = 0, -+ QEMU_IMG_BACKING_FORMAT_FLAG, -+ QEMU_IMG_BACKING_FORMAT_OPTIONS, -+}; -+ -+static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg) -+{ -+ const char *const qemuarg[] = { qemuimg, "-h", NULL }; -+ const char *const qemuenv[] = { "LC_ALL=C", NULL }; -+ pid_t child = 0; -+ int status; -+ int newstdout = -1; -+ char *help = NULL; -+ enum { MAX_HELP_OUTPUT_SIZE = 1024*8 }; -+ int len; -+ char *start; -+ char *end; -+ char *tmp; -+ int ret = -1; -+ -+ if (virExec(qemuarg, qemuenv, NULL, -+ &child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0) -+ goto cleanup; -+ -+ if ((len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help)) < 0) { -+ virReportSystemError(errno, -+ _("Unable to read '%s -h' output"), -+ qemuimg); -+ goto cleanup; -+ } -+ -+ start = strstr(help, " create "); -+ end = strstr(start, "\n"); -+ if ((tmp = strstr(start, "-F fmt")) && tmp < end) -+ ret = QEMU_IMG_BACKING_FORMAT_FLAG; -+ else if ((tmp = strstr(start, "[-o options]")) && tmp < end) -+ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS; -+ else -+ ret = QEMU_IMG_BACKING_FORMAT_NONE; -+ -+cleanup: -+ VIR_FREE(help); -+ close(newstdout); -+rewait: -+ if (child) { -+ if (waitpid(child, &status, 0) != child) { -+ if (errno == EINTR) -+ goto rewait; -+ -+ VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"), -+ WEXITSTATUS(status), (unsigned long)child); -+ } -+ if (WEXITSTATUS(status) != 0) { -+ VIR_WARN("Unexpected exit status '%d', qemu probably failed", -+ WEXITSTATUS(status)); -+ } -+ } -+ -+ return ret; -+} -+ -+ - static int - virStorageBackendCreateQemuImg(virConnectPtr conn, - virStoragePoolObjPtr pool, -@@ -570,10 +633,9 @@ virStorageBackendCreateQemuImg(virConnec - virStorageVolDefPtr inputvol, - unsigned int flags ATTRIBUTE_UNUSED) - { -- int ret; -+ int ret = -1; - char size[100]; - char *create_tool; -- short use_kvmimg; - - const char *type = virStorageFileFormatTypeToString(vol->target.format); - const char *backingType = vol->backingStore.path ? -@@ -584,41 +646,10 @@ virStorageBackendCreateQemuImg(virConnec - const char *inputPath = inputvol ? inputvol->target.path : NULL; - /* Treat input block devices as 'raw' format */ - const char *inputType = inputPath ? -- virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) : -- NULL; -- -- const char **imgargv; -- /* The extra NULL field is for indicating encryption (-e). */ -- const char *imgargvnormal[] = { -- NULL, "create", -- "-f", type, -- vol->target.path, -- size, -- NULL, -- NULL -- }; -- /* Extra NULL fields are for including "backingType" when using -- * kvm-img (-F backingType), and for indicating encryption (-e). -- */ -- const char *imgargvbacking[] = { -- NULL, "create", -- "-f", type, -- "-b", vol->backingStore.path, -- vol->target.path, -- size, -- NULL, -- NULL, -- NULL, -- NULL -- }; -- const char *convargv[] = { -- NULL, "convert", -- "-f", inputType, -- "-O", type, -- inputPath, -- vol->target.path, -- NULL, -- }; -+ virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? -+ VIR_STORAGE_FILE_RAW : -+ inputvol->target.format) : -+ NULL; - - if (type == NULL) { - virStorageReportError(VIR_ERR_INTERNAL_ERROR, -@@ -692,44 +723,103 @@ virStorageBackendCreateQemuImg(virConnec - } - } - -- if ((create_tool = virFindFileInPath("kvm-img")) != NULL) -- use_kvmimg = 1; -- else if ((create_tool = virFindFileInPath("qemu-img")) != NULL) -- use_kvmimg = 0; -- else { -+ /* Size in KB */ -+ snprintf(size, sizeof(size), "%lluK", vol->capacity/1024); -+ -+ /* KVM is usually ahead of qemu on features, so try that first */ -+ create_tool = virFindFileInPath("kvm-img"); -+ if (!create_tool) -+ create_tool = virFindFileInPath("qemu-img"); -+ -+ if (!create_tool) { - virStorageReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("unable to find kvm-img or qemu-img")); - return -1; - } - - if (inputvol) { -- convargv[0] = create_tool; -- imgargv = convargv; -+ const char *imgargv[] = { -+ create_tool, -+ "convert", -+ "-f", inputType, -+ "-O", type, -+ inputPath, -+ vol->target.path, -+ NULL, -+ }; -+ -+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); - } else if (vol->backingStore.path) { -- imgargvbacking[0] = create_tool; -- if (use_kvmimg) { -- imgargvbacking[6] = "-F"; -- imgargvbacking[7] = backingType; -- imgargvbacking[8] = vol->target.path; -- imgargvbacking[9] = size; -+ const char *imgargv[] = { -+ create_tool, -+ "create", -+ "-f", type, -+ "-b", vol->backingStore.path, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL -+ }; -+ int imgformat = virStorageBackendQEMUImgBackingFormat(create_tool); -+ char *optflag = NULL; -+ if (imgformat < 0) -+ goto cleanup; -+ -+ switch (imgformat) { -+ case QEMU_IMG_BACKING_FORMAT_FLAG: -+ imgargv[6] = "-F"; -+ imgargv[7] = backingType; -+ imgargv[8] = vol->target.path; -+ imgargv[9] = size; -+ if (vol->target.encryption != NULL) -+ imgargv[10] = "-e"; -+ break; -+ -+ case QEMU_IMG_BACKING_FORMAT_OPTIONS: -+ if (virAsprintf(&optflag, "backing_fmt=%s", backingType) < 0) { -+ virReportOOMError(); -+ goto cleanup; -+ } -+ imgargv[6] = "-o"; -+ imgargv[7] = optflag; -+ imgargv[8] = vol->target.path; -+ imgargv[9] = size; -+ if (vol->target.encryption != NULL) -+ imgargv[10] = "-e"; -+ break; -+ -+ default: -+ VIR_INFO("Unable to set backing store format for %s with %s", -+ vol->target.path, create_tool); -+ imgargv[6] = vol->target.path; -+ imgargv[7] = size; - if (vol->target.encryption != NULL) -- imgargvbacking[10] = "-e"; -- } else if (vol->target.encryption != NULL) -- imgargvbacking[8] = "-e"; -- imgargv = imgargvbacking; -+ imgargv[8] = "-e"; -+ } -+ -+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); -+ VIR_FREE(optflag); - } else { -- imgargvnormal[0] = create_tool; -- imgargv = imgargvnormal; -+ /* The extra NULL field is for indicating encryption (-e). */ -+ const char *imgargv[] = { -+ create_tool, -+ "create", -+ "-f", type, -+ vol->target.path, -+ size, -+ NULL, -+ NULL -+ }; - if (vol->target.encryption != NULL) - imgargv[6] = "-e"; -- } -- - -- /* Size in KB */ -- snprintf(size, sizeof(size), "%lluK", vol->capacity/1024); -+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); -+ } - -- ret = virStorageBackendCreateExecCommand(pool, vol, imgargv); -- VIR_FREE(imgargv[0]); -+ cleanup: -+ VIR_FREE(create_tool); - - return ret; - } diff --git a/CVE-2010-2242-nat.patch b/CVE-2010-2242-nat.patch deleted file mode 100644 index f20e538..0000000 --- a/CVE-2010-2242-nat.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 02318d5d46e1952294c20b41427dea124cbebb0a Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -Date: Thu, 10 Jun 2010 12:50:38 -0400 -Subject: [PATCH] Apply a source port mapping to virtual network masquerading - -IPtables will seek to preserve the source port unchanged when -doing masquerading, if possible. NFS has a pseudo-security -option where it checks for the source port <= 1023 before -allowing a mount request. If an admin has used this to make the -host OS trusted for mounts, the default iptables behaviour will -potentially allow NAT'd guests access too. This needs to be -stopped. - -With this change, the iptables -t nat -L -n -v rules for the -default network will be - -Chain POSTROUTING (policy ACCEPT 95 packets, 9163 bytes) - pkts bytes target prot opt in out source destination - 14 840 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 - 75 5752 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 - 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24 - -* src/network/bridge_driver.c: Add masquerade rules for TCP - and UDP protocols -* src/util/iptables.c, src/util/iptables.c: Add source port - mappings for TCP & UDP protocols when masquerading. ---- - src/network/bridge_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++-- - src/util/iptables.c | 70 +++++++++++++++++++++++++++++------------ - src/util/iptables.h | 6 ++- - 3 files changed, 122 insertions(+), 27 deletions(-) - -Index: libvirt-0.8.1/src/network/bridge_driver.c -=================================================================== ---- libvirt-0.8.1.orig/src/network/bridge_driver.c -+++ libvirt-0.8.1/src/network/bridge_driver.c -@@ -638,18 +638,75 @@ networkAddMasqueradingIptablesRules(stru - goto masqerr2; - } - -+ /* -+ * Enable masquerading. -+ * -+ * We need to end up with 3 rules in the table in this order -+ * -+ * 1. protocol=tcp with sport mapping restricton -+ * 2. protocol=udp with sport mapping restricton -+ * 3. generic any protocol -+ * -+ * The sport mappings are required, because default IPtables -+ * MASQUERADE is maintain port number unchanged where possible. -+ * -+ * NFS can be configured to only "trust" port numbers < 1023. -+ * -+ * Guests using NAT thus need to be prevented from having port -+ * numbers < 1023, otherwise they can bypass the NFS "security" -+ * check on the source port number. -+ * -+ * Since we use '--insert' to add rules to the header of the -+ * chain, we actually need to add them in the reverse of the -+ * order just mentioned ! -+ */ -+ -+ /* First the generic masquerade rule for other protocols */ - /* enable masquerading */ - if ((err = iptablesAddForwardMasquerade(driver->iptables, - network->def->network, -- network->def->forwardDev))) { -+ network->def->forwardDev, -+ NULL))) { - virReportSystemError(err, - _("failed to add iptables rule to enable masquerading to '%s'\n"), - network->def->forwardDev ? network->def->forwardDev : NULL); - goto masqerr3; - } - -+ /* UDP with a source port restriction */ -+ if ((err = iptablesAddForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ "udp"))) { -+ virReportSystemError(err, -+ _("failed to add iptables rule to enable UDP masquerading to '%s'"), -+ network->def->forwardDev ? network->def->forwardDev : NULL); -+ goto masqerr4; -+ } -+ -+ /* TCP with a source port restriction */ -+ if ((err = iptablesAddForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ "tcp"))) { -+ virReportSystemError(err, -+ _("failed to add iptables rule to enable TCP masquerading to '%s'"), -+ network->def->forwardDev ? network->def->forwardDev : NULL); -+ goto masqerr5; -+ } -+ - return 1; - -+ masqerr5: -+ iptablesRemoveForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ "udp"); -+ masqerr4: -+ iptablesRemoveForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ NULL); - masqerr3: - iptablesRemoveForwardAllowRelatedIn(driver->iptables, - network->def->network, -@@ -801,8 +858,17 @@ networkRemoveIptablesRules(struct networ - if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) { - if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { - iptablesRemoveForwardMasquerade(driver->iptables, -- network->def->network, -- network->def->forwardDev); -+ network->def->network, -+ network->def->forwardDev, -+ "tcp"); -+ iptablesRemoveForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ "udp"); -+ iptablesRemoveForwardMasquerade(driver->iptables, -+ network->def->network, -+ network->def->forwardDev, -+ NULL); - iptablesRemoveForwardAllowRelatedIn(driver->iptables, - network->def->network, - network->def->bridge, -Index: libvirt-0.8.1/src/util/iptables.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/iptables.c -+++ libvirt-0.8.1/src/util/iptables.c -@@ -692,25 +692,49 @@ iptablesRemoveForwardRejectIn(iptablesCo - */ - static int - iptablesForwardMasquerade(iptablesContext *ctx, -- const char *network, -- const char *physdev, -- int action) -+ const char *network, -+ const char *physdev, -+ const char *protocol, -+ int action) - { -- if (physdev && physdev[0]) { -- return iptablesAddRemoveRule(ctx->nat_postrouting, -- action, -- "--source", network, -- "!", "--destination", network, -- "--out-interface", physdev, -- "--jump", "MASQUERADE", -- NULL); -+ if (protocol && protocol[0]) { -+ if (physdev && physdev[0]) { -+ return iptablesAddRemoveRule(ctx->nat_postrouting, -+ action, -+ "--source", network, -+ "-p", protocol, -+ "!", "--destination", network, -+ "--out-interface", physdev, -+ "--jump", "MASQUERADE", -+ "--to-ports", "1024-65535", -+ NULL); -+ } else { -+ return iptablesAddRemoveRule(ctx->nat_postrouting, -+ action, -+ "--source", network, -+ "-p", protocol, -+ "!", "--destination", network, -+ "--jump", "MASQUERADE", -+ "--to-ports", "1024-65535", -+ NULL); -+ } - } else { -- return iptablesAddRemoveRule(ctx->nat_postrouting, -- action, -- "--source", network, -- "!", "--destination", network, -- "--jump", "MASQUERADE", -- NULL); -+ if (physdev && physdev[0]) { -+ return iptablesAddRemoveRule(ctx->nat_postrouting, -+ action, -+ "--source", network, -+ "!", "--destination", network, -+ "--out-interface", physdev, -+ "--jump", "MASQUERADE", -+ NULL); -+ } else { -+ return iptablesAddRemoveRule(ctx->nat_postrouting, -+ action, -+ "--source", network, -+ "!", "--destination", network, -+ "--jump", "MASQUERADE", -+ NULL); -+ } - } - } - -@@ -719,6 +743,7 @@ iptablesForwardMasquerade(iptablesContex - * @ctx: pointer to the IP table context - * @network: the source network name - * @physdev: the physical input device or NULL -+ * @protocol: the network protocol or NULL - * - * Add rules to the IP table context to allow masquerading - * network @network on @physdev. This allow the bridge to -@@ -729,9 +754,10 @@ iptablesForwardMasquerade(iptablesContex - int - iptablesAddForwardMasquerade(iptablesContext *ctx, - const char *network, -- const char *physdev) -+ const char *physdev, -+ const char *protocol) - { -- return iptablesForwardMasquerade(ctx, network, physdev, ADD); -+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, ADD); - } - - /** -@@ -739,6 +765,7 @@ iptablesAddForwardMasquerade(iptablesCon - * @ctx: pointer to the IP table context - * @network: the source network name - * @physdev: the physical input device or NULL -+ * @protocol: the network protocol or NULL - * - * Remove rules from the IP table context to stop masquerading - * network @network on @physdev. This stops the bridge from -@@ -749,7 +776,8 @@ iptablesAddForwardMasquerade(iptablesCon - int - iptablesRemoveForwardMasquerade(iptablesContext *ctx, - const char *network, -- const char *physdev) -+ const char *physdev, -+ const char *protocol) - { -- return iptablesForwardMasquerade(ctx, network, physdev, REMOVE); -+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, REMOVE); - } -Index: libvirt-0.8.1/src/util/iptables.h -=================================================================== ---- libvirt-0.8.1.orig/src/util/iptables.h -+++ libvirt-0.8.1/src/util/iptables.h -@@ -85,9 +85,11 @@ int iptablesRemoveForwardRe - - int iptablesAddForwardMasquerade (iptablesContext *ctx, - const char *network, -- const char *physdev); -+ const char *physdev, -+ const char *protocol); - int iptablesRemoveForwardMasquerade (iptablesContext *ctx, - const char *network, -- const char *physdev); -+ const char *physdev, -+ const char *protocol); - - #endif /* __QEMUD_IPTABLES_H__ */ diff --git a/bitmap-alloc.patch b/bitmap-alloc.patch deleted file mode 100644 index 2a25011..0000000 --- a/bitmap-alloc.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit ce49cfb48ad5e9cac79819d0ccde4394c237af25 -Author: Eric Blake -Date: Wed Jun 2 09:03:57 2010 -0600 - - bitmap: reject zero-size bitmap - - * src/util/bitmap.c (virBitmapAlloc): Tighten sanity check. - -diff --git a/src/util/bitmap.c b/src/util/bitmap.c -index 69094a5..44edb49 100644 ---- a/src/util/bitmap.c -+++ b/src/util/bitmap.c -@@ -1,6 +1,7 @@ - /* - * bitmap.h: Simple bitmap operations - * -+ * Copyright (C) 2010 Red Hat, Inc. - * Copyright (C) 2010 Novell, Inc. - * - * This library is free software; you can redistribute it and/or -@@ -58,7 +59,7 @@ virBitmapPtr virBitmapAlloc(size_t size) - virBitmapPtr bitmap; - size_t sz; - -- if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) -+ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size || size == 0) - return NULL; - - sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / diff --git a/bitmap-fixes.patch b/bitmap-fixes.patch deleted file mode 100644 index 96d3bd4..0000000 --- a/bitmap-fixes.patch +++ /dev/null @@ -1,59 +0,0 @@ -If VM startup fails early enough (can't find a referenced USB device), -libvirtd will crash trying to clear the VNC port bit, since port = 0, -which overflows us out of the bitmap bounds. - -Fix this by being more defensive in the bitmap operations, and only -clearing a previously set VNC port. - -v2: Add safety check to all relevant bitmap ops. - -Signed-off-by: Cole Robinson ---- - src/qemu/qemu_driver.c | 2 +- - src/util/bitmap.c | 6 +++--- - 2 files changed, 4 insertions(+), 4 deletions(-) - -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 -@@ -3635,7 +3635,7 @@ retry: - if ((vm->def->ngraphics == 1) && - vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && - vm->def->graphics[0]->data.vnc.autoport && -- vm->def->graphics[0]->data.vnc.port != -1) { -+ vm->def->graphics[0]->data.vnc.port >= QEMU_VNC_PORT_MIN) { - if (virBitmapClearBit(driver->reservedVNCPorts, - vm->def->graphics[0]->data.vnc.port - \ - QEMU_VNC_PORT_MIN) < 0) { -Index: libvirt-0.8.1/src/util/bitmap.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/bitmap.c -+++ libvirt-0.8.1/src/util/bitmap.c -@@ -101,7 +101,7 @@ void virBitmapFree(virBitmapPtr bitmap) - */ - int virBitmapSetBit(virBitmapPtr bitmap, size_t b) - { -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); -@@ -119,7 +119,7 @@ int virBitmapSetBit(virBitmapPtr bitmap, - */ - int virBitmapClearBit(virBitmapPtr bitmap, size_t b) - { -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); -@@ -141,7 +141,7 @@ int virBitmapGetBit(virBitmapPtr bitmap, - { - uint32_t bit; - -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & diff --git a/libvirt-0.8.1.tar.bz2 b/libvirt-0.8.1.tar.bz2 deleted file mode 100644 index f77a719..0000000 --- a/libvirt-0.8.1.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:037256df745a96ba141dbfc4e4197e8bc16c51f21c834f4f89c599c379792698 -size 7706670 diff --git a/libvirt-0.8.3.tar.bz2 b/libvirt-0.8.3.tar.bz2 new file mode 100644 index 0000000..77c2193 --- /dev/null +++ b/libvirt-0.8.3.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:759f4957e6f2b905857897a84e36cbe73f7dc3a5150637430ff086c3e2b414b4 +size 8250164 diff --git a/libvirt.changes b/libvirt.changes index 0157921..d5dd114 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Fri Aug 6 21:53:21 MDT 2010 - jfehlig@novell.com + +- Update to libvirt 0.8.3 + - Support vSphere 4.1 + - Qemu arbitrary monitor commands + - Qemu Monitor API entry point + - lots of improvements and bug fixes + ------------------------------------------------------------------- Fri Jul 9 14:35:04 MDT 2010 - jfehlig@novell.com diff --git a/libvirt.spec b/libvirt.spec index a62a1c1..9428e71 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -1,5 +1,5 @@ # -# spec file for package libvirt (Version 0.8.1) +# spec file for package libvirt (Version 0.8.3) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -44,6 +44,7 @@ %define with_udev 0 %define with_hal 0 %define with_yajl 0 +%define with_macvtap 0 # Xen is available only on i386 x86_64 %ifnarch %ix86 x86_64 @@ -110,14 +111,17 @@ BuildRequires: PolicyKit-devel >= 0.6 %if %{with_phyp} BuildRequires: libssh2-devel %endif +%if %{with_macvtap} +BuildRequires: libnl-devel +%endif # Only for directory ownership: BuildRequires: gtk-doc Url: http://libvirt.org/ License: LGPLv2.1+ Group: Development/Libraries/C and C++ AutoReqProv: yes -Version: 0.8.1 -Release: 2 +Version: 0.8.3 +Release: 1 Summary: A C toolkit to interract with the virtualization capabilities of Linux # The client side, i.e. shared libs and virsh are in a subpackage Requires: %{name}-client = %{version}-%{release} @@ -141,25 +145,6 @@ Requires: PolicyKit >= 0.6 Source0: %{name}-%{version}.tar.bz2 Source1: libvirtd.init # Upstream patches -Patch0: remote-rm-unused-field.patch -Patch1: vnc-race-1.patch -Patch2: vnc-race-2.patch -Patch3: vnc-race-3.patch -Patch4: bitmap-alloc.patch -Patch5: bitmap-fixes.patch -Patch6: xend-content-buf.patch -Patch7: xend-content-buf-fix.patch -Patch8: CVE-2010-223x-0001.patch -Patch9: CVE-2010-223x-0002.patch -Patch10: CVE-2010-223x-0003.patch -Patch11: CVE-2010-223x-0004.patch -Patch12: CVE-2010-223x-0005.patch -Patch13: CVE-2010-223x-0006.patch -Patch14: CVE-2010-223x-0007.patch -Patch15: CVE-2010-223x-0008.patch -Patch16: CVE-2010-223x-0009.patch -Patch17: CVE-2010-223x-0010.patch -Patch18: CVE-2010-2242-nat.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch102: clone.patch @@ -272,25 +257,6 @@ Authors: %prep %setup -q -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 %patch100 -p1 %patch102 %patch103 -p1 @@ -351,6 +317,9 @@ Authors: %if ! %{with_yajl} %define _without_yajl --without-yajl %endif +%if ! %{with_macvtap} +%define _without_macvtap --without-macvtap +%endif autoreconf -f -i export CFLAGS="$RPM_OPT_FLAGS" %configure --disable-static --with-pic \ @@ -372,6 +341,7 @@ export CFLAGS="$RPM_OPT_FLAGS" %{?_without_hal} \ %{?_without_udev} \ %{?_without_yajl} \ + %{?_without_macvtap} \ --without-xen-proxy \ --libexecdir=%{_libdir}/%{name} \ --with-init-script=none \ @@ -497,6 +467,7 @@ rm -rf $RPM_BUILD_ROOT %if 0%{with_storage_disk} %{_libdir}/%{name}/libvirt_parthelper %endif +%doc %{_mandir}/man8/libvirtd.8* %files client -f %{name}.lang %defattr(-, root, root) @@ -525,6 +496,7 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/libvirt/schemas/storageencryption.rng %{_datadir}/libvirt/cpu_map.xml %{_datadir}/libvirt/schemas/nwfilter.rng +%{_datadir}/libvirt/schemas/domainsnapshot.rng %config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf %files devel diff --git a/remote-rm-unused-field.patch b/remote-rm-unused-field.patch deleted file mode 100644 index 0a5f271..0000000 --- a/remote-rm-unused-field.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit 34a7f3f6be9c63ac3d4c4604c1fb2482a4e5053b -Author: Matthew Booth -Date: Fri May 7 16:38:05 2010 +0200 - - Remove unused nwfilter field from struct remote_error - - Change 965466c1 added a new field to struct remote_error, which broke - the RPC protocol. Fortunately the new field is unused, so this change - simply removes it again. - - * src/remote/remote_protocol.(c|h|x): Remove remote_nwfilter from struct - remote_error - -diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c -index 187281d..972bf52 100644 ---- a/src/remote/remote_protocol.c -+++ b/src/remote/remote_protocol.c -@@ -227,8 +227,6 @@ xdr_remote_error (XDR *xdrs, remote_error *objp) - return FALSE; - if (!xdr_remote_network (xdrs, &objp->net)) - return FALSE; -- if (!xdr_remote_nwfilter (xdrs, &objp->nwfilter)) -- return FALSE; - return TRUE; - } - -diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h -index 6f01da7..a600af6 100644 ---- a/src/remote/remote_protocol.h -+++ b/src/remote/remote_protocol.h -@@ -143,7 +143,6 @@ struct remote_error { - int int1; - int int2; - remote_network net; -- remote_nwfilter nwfilter; - }; - typedef struct remote_error remote_error; - -diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x -index 8000ee0..1ce488c 100644 ---- a/src/remote/remote_protocol.x -+++ b/src/remote/remote_protocol.x -@@ -266,7 +266,6 @@ struct remote_error { - int int1; - int int2; - remote_network net; -- remote_nwfilter nwfilter; - }; - - /* Authentication types available thus far.... */ diff --git a/vnc-race-1.patch b/vnc-race-1.patch deleted file mode 100644 index 32d7aca..0000000 --- a/vnc-race-1.patch +++ /dev/null @@ -1,281 +0,0 @@ -commit 2f32d7afd5bd71f79c0e756c87813702065c6d1a -Author: Jim Fehlig -Date: Thu May 20 22:23:48 2010 -0600 - - Add simple bitmap operations to utils - - V2: - - Move bitmap impl to src/util/bitmap.[ch] - - Use CHAR_BIT instead of explicit '8' - - Use size_t instead of unsigned int - - Fix calculation of bitmap size in virBitmapAlloc - - Ensure bit is within range of map in the set, clear, and get - operations - - Use bool in virBitmapGetBit - - Add virBitmapFree to free-like funcs in cfg.mk - - V3: - - Check for overflow in virBitmapAlloc - - Fix copy and paste bug in virBitmapAlloc - - Use size_t in prototypes - - Add ATTRIBUTE_NONNULL in prototypes where appropriate - and remove NULL check from impl - - V4: - - Add ATTRIBUTE_RETURN_CHECK in prototypes where appropriate. - -Index: libvirt-0.8.1/src/Makefile.am -=================================================================== ---- libvirt-0.8.1.orig/src/Makefile.am -+++ libvirt-0.8.1/src/Makefile.am -@@ -50,6 +50,7 @@ augeastest_DATA = - # helper APIs for various purposes - UTIL_SOURCES = \ - util/authhelper.c util/authhelper.h \ -+ util/bitmap.c util/bitmap.h \ - util/bridge.c util/bridge.h \ - util/buf.c util/buf.h \ - util/conf.c util/conf.h \ -Index: libvirt-0.8.1/src/libvirt_private.syms -=================================================================== ---- libvirt-0.8.1.orig/src/libvirt_private.syms -+++ libvirt-0.8.1/src/libvirt_private.syms -@@ -4,6 +4,14 @@ - # - - -+# bitmap.h -+virBitmapAlloc; -+virBitmapFree; -+virBitmapSetBit; -+virBitmapClearBit; -+virBitmapGetBit; -+ -+ - # buf.h - virBufferVSprintf; - virBufferEscapeString; -Index: libvirt-0.8.1/src/util/bitmap.c -=================================================================== ---- /dev/null -+++ libvirt-0.8.1/src/util/bitmap.c -@@ -0,0 +1,151 @@ -+/* -+ * bitmap.h: Simple bitmap operations -+ * -+ * Copyright (C) 2010 Novell, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Jim Fehlig -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bitmap.h" -+#include "memory.h" -+ -+ -+struct _virBitmap { -+ size_t size; -+ uint32_t *map; -+}; -+ -+ -+#define VIR_BITMAP_BITS_PER_UNIT (sizeof(uint32_t) * CHAR_BIT) -+#define VIR_BITMAP_UNIT_OFFSET(b) ((b) / VIR_BITMAP_BITS_PER_UNIT) -+#define VIR_BITMAP_BIT_OFFSET(b) ((b) % VIR_BITMAP_BITS_PER_UNIT) -+ -+ -+/** -+ * virBitmapAlloc: -+ * @size: number of bits -+ * -+ * Allocate a bitmap capable of containing @size bits. -+ * -+ * Returns a pointer to the allocated bitmap or NULL if -+ * memory cannot be allocated. -+ */ -+virBitmapPtr virBitmapAlloc(size_t size) -+{ -+ virBitmapPtr bitmap; -+ size_t sz; -+ -+ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) -+ return NULL; -+ -+ sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / -+ VIR_BITMAP_BITS_PER_UNIT; -+ -+ if (VIR_ALLOC(bitmap) < 0) -+ return NULL; -+ -+ if (VIR_ALLOC_N(bitmap->map, sz) < 0) { -+ VIR_FREE(bitmap); -+ return NULL; -+ } -+ -+ return bitmap; -+} -+ -+/** -+ * virBitmapFree: -+ * @bitmap: previously allocated bitmap -+ * -+ * Free @bitmap previously allocated by virBitmapAlloc. -+ */ -+void virBitmapFree(virBitmapPtr bitmap) -+{ -+ if (bitmap) { -+ VIR_FREE(bitmap->map); -+ VIR_FREE(bitmap); -+ } -+} -+ -+/** -+ * virBitmapSetBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to set -+ * -+ * Set bit position @b in @bitmap -+ * -+ * Returns 0 on if bit is successfully set, -1 on error. -+ */ -+int virBitmapSetBit(virBitmapPtr bitmap, size_t b) -+{ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); -+ return 0; -+} -+ -+/** -+ * virBitmapClearBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to clear -+ * -+ * Clear bit position @b in @bitmap -+ * -+ * Returns 0 on if bit is successfully clear, -1 on error. -+ */ -+int virBitmapClearBit(virBitmapPtr bitmap, size_t b) -+{ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); -+ return 0; -+} -+ -+/** -+ * virBitmapGetBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to get -+ * @result: bool pointer to receive bit setting -+ * -+ * Get setting of bit position @b in @bitmap and store in @result -+ * -+ * On success, @result will contain the setting of @b and 0 is -+ * returned. On failure, -1 is returned and @result is unchanged. -+ */ -+int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) -+{ -+ uint32_t bit; -+ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & -+ (1 << VIR_BITMAP_BIT_OFFSET(b)); -+ -+ *result = bit != 0; -+ return 0; -+} -Index: libvirt-0.8.1/src/util/bitmap.h -=================================================================== ---- /dev/null -+++ libvirt-0.8.1/src/util/bitmap.h -@@ -0,0 +1,63 @@ -+/* -+ * bitmap.h: Simple bitmap operations -+ * -+ * Copyright (C) 2010 Novell, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Jim Fehlig -+ */ -+ -+#ifndef __BITMAP_H__ -+# define __BITMAP_H__ -+ -+#include "internal.h" -+ -+#include -+#include -+ -+ -+typedef struct _virBitmap virBitmap; -+typedef virBitmap *virBitmapPtr; -+ -+/* -+ * Allocate a bitmap capable of containing @size bits. -+ */ -+virBitmapPtr virBitmapAlloc(size_t size) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Free previously allocated bitmap -+ */ -+void virBitmapFree(virBitmapPtr bitmap); -+ -+/* -+ * Set bit position @b in @bitmap -+ */ -+int virBitmapSetBit(virBitmapPtr bitmap, size_t b) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Clear bit position @b in @bitmap -+ */ -+int virBitmapClearBit(virBitmapPtr bitmap, size_t b) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Get setting of bit position @b in @bitmap and store in @result -+ */ -+int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; -+ -+#endif diff --git a/vnc-race-2.patch b/vnc-race-2.patch deleted file mode 100644 index 67a9d16..0000000 --- a/vnc-race-2.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit c020f6203e3735a531135bc4321415ce5520fbde -Author: Jim Fehlig -Date: Thu May 20 22:25:16 2010 -0600 - - Add defines for QEMU_VNC_PORT_{MIN,MAX} and use them - -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 -@@ -89,6 +89,9 @@ - - #define VIR_FROM_THIS VIR_FROM_QEMU - -+#define QEMU_VNC_PORT_MIN 5900 -+#define QEMU_VNC_PORT_MAX 65535 -+ - /* Only 1 job is allowed at any time - * A job includes *all* monitor commands, even those just querying - * information, not merely actions */ -@@ -2607,7 +2610,7 @@ qemuInitPCIAddresses(struct qemud_driver - static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { - int i; - -- for (i = 5900 ; i < 65535 ; i++) { -+ for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { - int fd; - int reuse = 1; - struct sockaddr_in addr; diff --git a/vnc-race-3.patch b/vnc-race-3.patch deleted file mode 100644 index e083557..0000000 --- a/vnc-race-3.patch +++ /dev/null @@ -1,130 +0,0 @@ -commit ba196952f57f2cb22be75fa5a4f363035a111103 -Author: Jim Fehlig -Date: Fri May 21 07:52:09 2010 -0600 - - Fix race in finding available vnc port - - The qemu driver contains a subtle race in the logic to find next - available vnc port. Currently it iterates through all available ports - and returns the first for which bind(2) succeeds. However it is possible - that a previously issued port has not yet been bound by qemu, resulting - in the same port used for a subsequent domain. - - This patch addresses the race by using a simple bitmap to "reserve" the - ports allocated by libvirt. - - V2: - - Put port bitmap in struct qemud_driver - - Initialize bitmap in qemudStartup - - V3: - - Check for failure of virBitmapGetBit - - Additional check for port != -1 before calling virbitmapClearBit - - V4: - - Check for failure of virBitmap{Set,Clear}Bit - -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 -@@ -39,6 +39,7 @@ - # include "pci.h" - # include "cpu_conf.h" - # include "driver.h" -+# include "bitmap.h" - - # define qemudDebug(fmt, ...) do {} while(0) - -@@ -153,6 +154,8 @@ struct qemud_driver { - char *saveImageFormat; - - pciDeviceList *activePciHostdevs; -+ -+ virBitmapPtr reservedVNCPorts; - }; - - typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; -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 -@@ -1479,6 +1479,11 @@ qemudStartup(int privileged) { - virEventAddTimeout(-1, qemuDomainEventFlush, qemu_driver, NULL)) < 0) - goto error; - -+ /* Allocate bitmap for vnc port reservation */ -+ if ((qemu_driver->reservedVNCPorts = -+ virBitmapAlloc(QEMU_VNC_PORT_MAX - QEMU_VNC_PORT_MIN)) == NULL) -+ goto out_of_memory; -+ - if (privileged) { - if (virAsprintf(&qemu_driver->logDir, - "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1) -@@ -1775,6 +1780,7 @@ qemudShutdown(void) { - virCapabilitiesFree(qemu_driver->caps); - - virDomainObjListDeinit(&qemu_driver->domains); -+ virBitmapFree(qemu_driver->reservedVNCPorts); - - VIR_FREE(qemu_driver->securityDriverName); - VIR_FREE(qemu_driver->logDir); -@@ -2607,13 +2613,22 @@ qemuInitPCIAddresses(struct qemud_driver - return ret; - } - --static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { -+static int qemudNextFreeVNCPort(struct qemud_driver *driver) { - int i; - - for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { - int fd; - int reuse = 1; - struct sockaddr_in addr; -+ bool used = false; -+ -+ if (virBitmapGetBit(driver->reservedVNCPorts, -+ i - QEMU_VNC_PORT_MIN, &used) < 0) -+ VIR_DEBUG("virBitmapGetBit failed on bit %d", i - QEMU_VNC_PORT_MIN); -+ -+ if (used) -+ continue; -+ - addr.sin_family = AF_INET; - addr.sin_port = htons(i); - addr.sin_addr.s_addr = htonl(INADDR_ANY); -@@ -2629,6 +2644,12 @@ static int qemudNextFreeVNCPort(struct q - if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { - /* Not in use, lets grab it */ - close(fd); -+ /* Add port to bitmap of reserved ports */ -+ if (virBitmapSetBit(driver->reservedVNCPorts, -+ i - QEMU_VNC_PORT_MIN) < 0) { -+ VIR_DEBUG("virBitmapSetBit failed on bit %d", -+ i - QEMU_VNC_PORT_MIN); -+ } - return i; - } - close(fd); -@@ -3608,6 +3629,21 @@ retry: - - qemudRemoveDomainStatus(driver, vm); - -+ /* Remove VNC port from port reservation bitmap, but only if it was -+ reserved by the driver (autoport=yes) -+ */ -+ if ((vm->def->ngraphics == 1) && -+ vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && -+ vm->def->graphics[0]->data.vnc.autoport && -+ vm->def->graphics[0]->data.vnc.port != -1) { -+ if (virBitmapClearBit(driver->reservedVNCPorts, -+ vm->def->graphics[0]->data.vnc.port - \ -+ QEMU_VNC_PORT_MIN) < 0) { -+ VIR_DEBUG("virBitmapClearBit failed on bit %d", -+ vm->def->graphics[0]->data.vnc.port - QEMU_VNC_PORT_MIN); -+ } -+ } -+ - vm->pid = -1; - vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; diff --git a/xend-content-buf-fix.patch b/xend-content-buf-fix.patch deleted file mode 100644 index 784aecb..0000000 --- a/xend-content-buf-fix.patch +++ /dev/null @@ -1,79 +0,0 @@ -commit b1eb7f2e987d21b1711e86e5cb63a69abfce82f1 -Author: Jim Fehlig -Date: Fri Jun 4 10:04:03 2010 -0600 - - Fixes for commit 211dd1e9 - - Fixes for issues in commit 211dd1e9 noted by by Jim Meyering. - - 1. Allocate content buffer of size content_length + 1 to ensure - NUL-termination. - 2. Limit content buffer size to 64k - 3. Fix whitespace issue - - V2: - - Add comment to clarify allocation of content buffer - - Add ATTRIBUTE_NONNULL where appropriate - - User NULLSTR macro - -diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c -index 0c1a738..51cad92 100644 ---- a/src/xen/xend_internal.c -+++ b/src/xen/xend_internal.c -@@ -68,6 +68,7 @@ - # define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3 - #endif - -+#define XEND_RCV_BUF_MAX_LEN 65536 - - #ifndef PROXY - static int -@@ -310,7 +311,7 @@ istartswith(const char *haystack, const char *needle) - * Returns the HTTP return code and @content is set to the - * allocated memory containing HTTP content. - */ --static int -+static int ATTRIBUTE_NONNULL (2) - xend_req(int fd, char **content) - { - char buffer[4096]; -@@ -330,7 +331,19 @@ xend_req(int fd, char **content) - if (content_length > 0) { - ssize_t ret; - -- if (VIR_ALLOC_N(*content, content_length) < 0 ) { -+ if (content_length > XEND_RCV_BUF_MAX_LEN) { -+ virXendError(VIR_ERR_INTERNAL_ERROR, -+ _("Xend returned HTTP Content-Length of %d, " -+ "which exceeds maximum of %d"), -+ content_length, -+ XEND_RCV_BUF_MAX_LEN); -+ return -1; -+ } -+ -+ /* Allocate one byte beyond the end of the largest buffer we will read. -+ Combined with the fact that VIR_ALLOC_N zeros the returned buffer, -+ this guarantees that "content" will always be NUL-terminated. */ -+ if (VIR_ALLOC_N(*content, content_length + 1) < 0 ) { - virReportOOMError(); - return -1; - } -@@ -353,7 +366,7 @@ xend_req(int fd, char **content) - * - * Returns the HTTP return code or -1 in case or error. - */ --static int -+static int ATTRIBUTE_NONNULL(3) - xend_get(virConnectPtr xend, const char *path, - char **content) - { -@@ -379,8 +392,7 @@ xend_get(virConnectPtr xend, const char *path, - ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { - virXendError(VIR_ERR_GET_FAILED, - _("%d status from xen daemon: %s:%s"), -- ret, path, -- content ? *content: "NULL"); -+ ret, path, NULLSTR(*content)); - } - - return ret; diff --git a/xend-content-buf.patch b/xend-content-buf.patch deleted file mode 100644 index 70b887c..0000000 --- a/xend-content-buf.patch +++ /dev/null @@ -1,244 +0,0 @@ -commit 211dd1e9c54a9ba92e2e648acacbc18981374073 -Author: Jim Fehlig -Date: Wed Jun 2 18:07:17 2010 -0600 - - Allocate buffer to hold xend response - - There are cases when a response from xend can exceed 4096 bytes, in - which case anything beyond 4096 is ignored. This patch changes the - current fixed-size, stack-allocated buffer to a dynamically allocated - buffer based on Content-Length in HTTP header. - -diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c -index e763bad..0c1a738 100644 ---- a/src/xen/xend_internal.c -+++ b/src/xen/xend_internal.c -@@ -302,17 +302,19 @@ istartswith(const char *haystack, const char *needle) - * xend_req: - * @fd: the file descriptor - * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Read the HTTP response from a Xen Daemon request. -+ * If the response contains content, memory is allocated to -+ * hold the content. - * -- * Returns the HTTP return code. -+ * Returns the HTTP return code and @content is set to the -+ * allocated memory containing HTTP content. - */ - static int --xend_req(int fd, char *content, size_t n_content) -+xend_req(int fd, char **content) - { - char buffer[4096]; -- int content_length = -1; -+ int content_length = 0; - int retcode = 0; - - while (sreads(fd, buffer, sizeof(buffer)) > 0) { -@@ -325,19 +327,17 @@ xend_req(int fd, char *content, size_t n_content) - retcode = atoi(buffer + 9); - } - -- if (content_length > -1) { -+ if (content_length > 0) { - ssize_t ret; - -- if ((unsigned int) content_length > (n_content + 1)) -- content_length = n_content - 1; -+ if (VIR_ALLOC_N(*content, content_length) < 0 ) { -+ virReportOOMError(); -+ return -1; -+ } - -- ret = sread(fd, content, content_length); -+ ret = sread(fd, *content, content_length); - if (ret < 0) - return -1; -- -- content[ret] = 0; -- } else { -- content[0] = 0; - } - - return retcode; -@@ -348,7 +348,6 @@ xend_req(int fd, char *content, size_t n_content) - * @xend: pointer to the Xen Daemon structure - * @path: the path used for the HTTP request - * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Do an HTTP GET RPC with the Xen Daemon - * -@@ -356,7 +355,7 @@ xend_req(int fd, char *content, size_t n_content) - */ - static int - xend_get(virConnectPtr xend, const char *path, -- char *content, size_t n_content) -+ char **content) - { - int ret; - int s = do_connect(xend); -@@ -373,14 +372,15 @@ xend_get(virConnectPtr xend, const char *path, - "Accept-Encoding: identity\r\n" - "Content-Type: application/x-www-form-urlencoded\r\n" "\r\n"); - -- ret = xend_req(s, content, n_content); -+ ret = xend_req(s, content); - close(s); - - if (((ret < 0) || (ret >= 300)) && - ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { - virXendError(VIR_ERR_GET_FAILED, - _("%d status from xen daemon: %s:%s"), -- ret, path, content); -+ ret, path, -+ content ? *content: "NULL"); - } - - return ret; -@@ -392,8 +392,6 @@ xend_get(virConnectPtr xend, const char *path, - * @xend: pointer to the Xen Daemon structure - * @path: the path used for the HTTP request - * @ops: the information sent for the POST -- * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Do an HTTP POST RPC with the Xen Daemon, this usually makes changes at the - * Xen level. -@@ -401,10 +399,10 @@ xend_get(virConnectPtr xend, const char *path, - * Returns the HTTP return code or -1 in case or error. - */ - static int --xend_post(virConnectPtr xend, const char *path, const char *ops, -- char *content, size_t n_content) -+xend_post(virConnectPtr xend, const char *path, const char *ops) - { - char buffer[100]; -+ char *err_buf = NULL; - int ret; - int s = do_connect(xend); - -@@ -425,26 +423,28 @@ xend_post(virConnectPtr xend, const char *path, const char *ops, - swrites(s, "\r\n\r\n"); - swrites(s, ops); - -- ret = xend_req(s, content, n_content); -+ ret = xend_req(s, &err_buf); - close(s); - - if ((ret < 0) || (ret >= 300)) { - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -- } else if ((ret == 202) && (strstr(content, "failed") != NULL)) { -+ _("xend_post: error from xen daemon: %s"), err_buf); -+ } else if ((ret == 202) && err_buf && (strstr(err_buf, "failed") != NULL)) { - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -+ _("xend_post: error from xen daemon: %s"), err_buf); - ret = -1; -- } else if (((ret >= 200) && (ret <= 202)) && (strstr(content, "xend.err") != NULL)) { -+ } else if (((ret >= 200) && (ret <= 202)) && err_buf && -+ (strstr(err_buf, "xend.err") != NULL)) { - /* This is to catch case of things like 'virsh dump Domain-0 foo' - * which returns a success code, but the word 'xend.err' - * in body to indicate error :-( - */ - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -+ _("xend_post: error from xen daemon: %s"), err_buf); - ret = -1; - } - -+ VIR_FREE(err_buf); - return ret; - } - #endif /* ! PROXY */ -@@ -487,8 +487,6 @@ http2unix(int ret) - * xend_op_ext: - * @xend: pointer to the Xen Daemon structure - * @path: path for the object -- * @error: buffer for the error output -- * @n_error: size of @error - * @key: the key for the operation - * @ap: input values to pass to the operation - * -@@ -497,8 +495,7 @@ http2unix(int ret) - * Returns 0 in case of success, -1 in case of failure. - */ - static int --xend_op_ext(virConnectPtr xend, const char *path, char *error, -- size_t n_error, const char *key, va_list ap) -+xend_op_ext(virConnectPtr xend, const char *path, const char *key, va_list ap) - { - const char *k = key, *v; - virBuffer buf = VIR_BUFFER_INITIALIZER; -@@ -524,7 +521,7 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, - } - - content = virBufferContentAndReset(&buf); -- ret = http2unix(xend_post(xend, path, content, error, n_error)); -+ ret = http2unix(xend_post(xend, path, content)); - VIR_FREE(content); - - return ret; -@@ -535,8 +532,6 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, - * xend_op: - * @xend: pointer to the Xen Daemon structure - * @name: the domain name target of this operation -- * @error: buffer for the error output -- * @n_error: size of @error - * @key: the key for the operation - * @ap: input values to pass to the operation - * @...: input values to pass to the operation -@@ -550,14 +545,13 @@ static int ATTRIBUTE_SENTINEL - xend_op(virConnectPtr xend, const char *name, const char *key, ...) - { - char buffer[1024]; -- char error[1024]; - va_list ap; - int ret; - - snprintf(buffer, sizeof(buffer), "/xend/domain/%s", name); - - va_start(ap, key); -- ret = xend_op_ext(xend, buffer, error, sizeof(error), key, ap); -+ ret = xend_op_ext(xend, buffer, key, ap); - va_end(ap); - - return ret; -@@ -581,21 +575,29 @@ static struct sexpr *sexpr_get(virConnectPtr xend, const char *fmt, ...) - static struct sexpr * - sexpr_get(virConnectPtr xend, const char *fmt, ...) - { -- char buffer[4096]; -+ char *buffer = NULL; - char path[1024]; - va_list ap; - int ret; -+ struct sexpr *res = NULL; - - va_start(ap, fmt); - vsnprintf(path, sizeof(path), fmt, ap); - va_end(ap); - -- ret = xend_get(xend, path, buffer, sizeof(buffer)); -+ ret = xend_get(xend, path, &buffer); - ret = http2unix(ret); - if (ret == -1) -- return NULL; -+ goto cleanup; -+ -+ if (buffer == NULL) -+ goto cleanup; -+ -+ res = string2sexpr(buffer); - -- return string2sexpr(buffer); -+cleanup: -+ VIR_FREE(buffer); -+ return res; - } - - /** From 0068ec2b5dbf198b7208019cf70d2d6f46891d09ae0d8f434106a24e103ebca2 Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Mon, 9 Aug 2010 00:19:46 +0000 Subject: [PATCH 3/4] Accepting request 44796 from Virtualization checked in (request 44796) OBS-URL: https://build.opensuse.org/request/show/44796 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=62 --- bitmap-alloc.patch | 29 ++++ bitmap-fixes.patch | 59 ++++++++ libvirt-0.8.1.tar.bz2 | 3 + libvirt-0.8.3.tar.bz2 | 3 - libvirt.changes | 17 --- libvirt.spec | 35 +++-- remote-rm-unused-field.patch | 50 +++++++ vnc-race-1.patch | 281 +++++++++++++++++++++++++++++++++++ vnc-race-2.patch | 29 ++++ vnc-race-3.patch | 130 ++++++++++++++++ xend-content-buf-fix.patch | 79 ++++++++++ xend-content-buf.patch | 244 ++++++++++++++++++++++++++++++ 12 files changed, 923 insertions(+), 36 deletions(-) create mode 100644 bitmap-alloc.patch create mode 100644 bitmap-fixes.patch create mode 100644 libvirt-0.8.1.tar.bz2 delete mode 100644 libvirt-0.8.3.tar.bz2 create mode 100644 remote-rm-unused-field.patch create mode 100644 vnc-race-1.patch create mode 100644 vnc-race-2.patch create mode 100644 vnc-race-3.patch create mode 100644 xend-content-buf-fix.patch create mode 100644 xend-content-buf.patch diff --git a/bitmap-alloc.patch b/bitmap-alloc.patch new file mode 100644 index 0000000..2a25011 --- /dev/null +++ b/bitmap-alloc.patch @@ -0,0 +1,29 @@ +commit ce49cfb48ad5e9cac79819d0ccde4394c237af25 +Author: Eric Blake +Date: Wed Jun 2 09:03:57 2010 -0600 + + bitmap: reject zero-size bitmap + + * src/util/bitmap.c (virBitmapAlloc): Tighten sanity check. + +diff --git a/src/util/bitmap.c b/src/util/bitmap.c +index 69094a5..44edb49 100644 +--- a/src/util/bitmap.c ++++ b/src/util/bitmap.c +@@ -1,6 +1,7 @@ + /* + * bitmap.h: Simple bitmap operations + * ++ * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 Novell, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -58,7 +59,7 @@ virBitmapPtr virBitmapAlloc(size_t size) + virBitmapPtr bitmap; + size_t sz; + +- if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) ++ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size || size == 0) + return NULL; + + sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / diff --git a/bitmap-fixes.patch b/bitmap-fixes.patch new file mode 100644 index 0000000..96d3bd4 --- /dev/null +++ b/bitmap-fixes.patch @@ -0,0 +1,59 @@ +If VM startup fails early enough (can't find a referenced USB device), +libvirtd will crash trying to clear the VNC port bit, since port = 0, +which overflows us out of the bitmap bounds. + +Fix this by being more defensive in the bitmap operations, and only +clearing a previously set VNC port. + +v2: Add safety check to all relevant bitmap ops. + +Signed-off-by: Cole Robinson +--- + src/qemu/qemu_driver.c | 2 +- + src/util/bitmap.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +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 +@@ -3635,7 +3635,7 @@ retry: + if ((vm->def->ngraphics == 1) && + vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && + vm->def->graphics[0]->data.vnc.autoport && +- vm->def->graphics[0]->data.vnc.port != -1) { ++ vm->def->graphics[0]->data.vnc.port >= QEMU_VNC_PORT_MIN) { + if (virBitmapClearBit(driver->reservedVNCPorts, + vm->def->graphics[0]->data.vnc.port - \ + QEMU_VNC_PORT_MIN) < 0) { +Index: libvirt-0.8.1/src/util/bitmap.c +=================================================================== +--- libvirt-0.8.1.orig/src/util/bitmap.c ++++ libvirt-0.8.1/src/util/bitmap.c +@@ -101,7 +101,7 @@ void virBitmapFree(virBitmapPtr bitmap) + */ + int virBitmapSetBit(virBitmapPtr bitmap, size_t b) + { +- if (b > bitmap->size - 1) ++ if (bitmap->size <= b) + return -1; + + bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); +@@ -119,7 +119,7 @@ int virBitmapSetBit(virBitmapPtr bitmap, + */ + int virBitmapClearBit(virBitmapPtr bitmap, size_t b) + { +- if (b > bitmap->size - 1) ++ if (bitmap->size <= b) + return -1; + + bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); +@@ -141,7 +141,7 @@ int virBitmapGetBit(virBitmapPtr bitmap, + { + uint32_t bit; + +- if (b > bitmap->size - 1) ++ if (bitmap->size <= b) + return -1; + + bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & diff --git a/libvirt-0.8.1.tar.bz2 b/libvirt-0.8.1.tar.bz2 new file mode 100644 index 0000000..f77a719 --- /dev/null +++ b/libvirt-0.8.1.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:037256df745a96ba141dbfc4e4197e8bc16c51f21c834f4f89c599c379792698 +size 7706670 diff --git a/libvirt-0.8.3.tar.bz2 b/libvirt-0.8.3.tar.bz2 deleted file mode 100644 index 77c2193..0000000 --- a/libvirt-0.8.3.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:759f4957e6f2b905857897a84e36cbe73f7dc3a5150637430ff086c3e2b414b4 -size 8250164 diff --git a/libvirt.changes b/libvirt.changes index d5dd114..195e9d8 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,20 +1,3 @@ -------------------------------------------------------------------- -Fri Aug 6 21:53:21 MDT 2010 - jfehlig@novell.com - -- Update to libvirt 0.8.3 - - Support vSphere 4.1 - - Qemu arbitrary monitor commands - - Qemu Monitor API entry point - - lots of improvements and bug fixes - -------------------------------------------------------------------- -Fri Jul 9 14:35:04 MDT 2010 - jfehlig@novell.com - -- VUL-0: multiple issues in libvirt - CVE-2010-223x-000[1-0].patch, CVE-2010-223x-0010.patch, - CVE-2010-2242-nat.patch - bnc#618155 - ------------------------------------------------------------------- Fri Jun 25 09:02:38 MDT 2010 - jfehlig@novell.com diff --git a/libvirt.spec b/libvirt.spec index 9428e71..5206d57 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -1,5 +1,5 @@ # -# spec file for package libvirt (Version 0.8.3) +# spec file for package libvirt (Version 0.8.1) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -44,7 +44,6 @@ %define with_udev 0 %define with_hal 0 %define with_yajl 0 -%define with_macvtap 0 # Xen is available only on i386 x86_64 %ifnarch %ix86 x86_64 @@ -97,9 +96,6 @@ BuildRequires: avahi-devel %if %{with_selinux} BuildRequires: libselinux-devel %endif -%if %{with_apparmor} -BuildRequires: libapparmor-devel -%endif %if %{with_numactl} BuildRequires: libnuma-devel %endif @@ -111,17 +107,14 @@ BuildRequires: PolicyKit-devel >= 0.6 %if %{with_phyp} BuildRequires: libssh2-devel %endif -%if %{with_macvtap} -BuildRequires: libnl-devel -%endif # Only for directory ownership: BuildRequires: gtk-doc Url: http://libvirt.org/ License: LGPLv2.1+ Group: Development/Libraries/C and C++ AutoReqProv: yes -Version: 0.8.3 -Release: 1 +Version: 0.8.1 +Release: 3 Summary: A C toolkit to interract with the virtualization capabilities of Linux # The client side, i.e. shared libs and virsh are in a subpackage Requires: %{name}-client = %{version}-%{release} @@ -145,6 +138,14 @@ Requires: PolicyKit >= 0.6 Source0: %{name}-%{version}.tar.bz2 Source1: libvirtd.init # Upstream patches +Patch0: remote-rm-unused-field.patch +Patch1: vnc-race-1.patch +Patch2: vnc-race-2.patch +Patch3: vnc-race-3.patch +Patch4: bitmap-alloc.patch +Patch5: bitmap-fixes.patch +Patch6: xend-content-buf.patch +Patch7: xend-content-buf-fix.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch102: clone.patch @@ -257,6 +258,14 @@ Authors: %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %patch100 -p1 %patch102 %patch103 -p1 @@ -317,9 +326,6 @@ Authors: %if ! %{with_yajl} %define _without_yajl --without-yajl %endif -%if ! %{with_macvtap} -%define _without_macvtap --without-macvtap -%endif autoreconf -f -i export CFLAGS="$RPM_OPT_FLAGS" %configure --disable-static --with-pic \ @@ -341,7 +347,6 @@ export CFLAGS="$RPM_OPT_FLAGS" %{?_without_hal} \ %{?_without_udev} \ %{?_without_yajl} \ - %{?_without_macvtap} \ --without-xen-proxy \ --libexecdir=%{_libdir}/%{name} \ --with-init-script=none \ @@ -467,7 +472,6 @@ rm -rf $RPM_BUILD_ROOT %if 0%{with_storage_disk} %{_libdir}/%{name}/libvirt_parthelper %endif -%doc %{_mandir}/man8/libvirtd.8* %files client -f %{name}.lang %defattr(-, root, root) @@ -496,7 +500,6 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/libvirt/schemas/storageencryption.rng %{_datadir}/libvirt/cpu_map.xml %{_datadir}/libvirt/schemas/nwfilter.rng -%{_datadir}/libvirt/schemas/domainsnapshot.rng %config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf %files devel diff --git a/remote-rm-unused-field.patch b/remote-rm-unused-field.patch new file mode 100644 index 0000000..0a5f271 --- /dev/null +++ b/remote-rm-unused-field.patch @@ -0,0 +1,50 @@ +commit 34a7f3f6be9c63ac3d4c4604c1fb2482a4e5053b +Author: Matthew Booth +Date: Fri May 7 16:38:05 2010 +0200 + + Remove unused nwfilter field from struct remote_error + + Change 965466c1 added a new field to struct remote_error, which broke + the RPC protocol. Fortunately the new field is unused, so this change + simply removes it again. + + * src/remote/remote_protocol.(c|h|x): Remove remote_nwfilter from struct + remote_error + +diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c +index 187281d..972bf52 100644 +--- a/src/remote/remote_protocol.c ++++ b/src/remote/remote_protocol.c +@@ -227,8 +227,6 @@ xdr_remote_error (XDR *xdrs, remote_error *objp) + return FALSE; + if (!xdr_remote_network (xdrs, &objp->net)) + return FALSE; +- if (!xdr_remote_nwfilter (xdrs, &objp->nwfilter)) +- return FALSE; + return TRUE; + } + +diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h +index 6f01da7..a600af6 100644 +--- a/src/remote/remote_protocol.h ++++ b/src/remote/remote_protocol.h +@@ -143,7 +143,6 @@ struct remote_error { + int int1; + int int2; + remote_network net; +- remote_nwfilter nwfilter; + }; + typedef struct remote_error remote_error; + +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 8000ee0..1ce488c 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -266,7 +266,6 @@ struct remote_error { + int int1; + int int2; + remote_network net; +- remote_nwfilter nwfilter; + }; + + /* Authentication types available thus far.... */ diff --git a/vnc-race-1.patch b/vnc-race-1.patch new file mode 100644 index 0000000..32d7aca --- /dev/null +++ b/vnc-race-1.patch @@ -0,0 +1,281 @@ +commit 2f32d7afd5bd71f79c0e756c87813702065c6d1a +Author: Jim Fehlig +Date: Thu May 20 22:23:48 2010 -0600 + + Add simple bitmap operations to utils + + V2: + - Move bitmap impl to src/util/bitmap.[ch] + - Use CHAR_BIT instead of explicit '8' + - Use size_t instead of unsigned int + - Fix calculation of bitmap size in virBitmapAlloc + - Ensure bit is within range of map in the set, clear, and get + operations + - Use bool in virBitmapGetBit + - Add virBitmapFree to free-like funcs in cfg.mk + + V3: + - Check for overflow in virBitmapAlloc + - Fix copy and paste bug in virBitmapAlloc + - Use size_t in prototypes + - Add ATTRIBUTE_NONNULL in prototypes where appropriate + and remove NULL check from impl + + V4: + - Add ATTRIBUTE_RETURN_CHECK in prototypes where appropriate. + +Index: libvirt-0.8.1/src/Makefile.am +=================================================================== +--- libvirt-0.8.1.orig/src/Makefile.am ++++ libvirt-0.8.1/src/Makefile.am +@@ -50,6 +50,7 @@ augeastest_DATA = + # helper APIs for various purposes + UTIL_SOURCES = \ + util/authhelper.c util/authhelper.h \ ++ util/bitmap.c util/bitmap.h \ + util/bridge.c util/bridge.h \ + util/buf.c util/buf.h \ + util/conf.c util/conf.h \ +Index: libvirt-0.8.1/src/libvirt_private.syms +=================================================================== +--- libvirt-0.8.1.orig/src/libvirt_private.syms ++++ libvirt-0.8.1/src/libvirt_private.syms +@@ -4,6 +4,14 @@ + # + + ++# bitmap.h ++virBitmapAlloc; ++virBitmapFree; ++virBitmapSetBit; ++virBitmapClearBit; ++virBitmapGetBit; ++ ++ + # buf.h + virBufferVSprintf; + virBufferEscapeString; +Index: libvirt-0.8.1/src/util/bitmap.c +=================================================================== +--- /dev/null ++++ libvirt-0.8.1/src/util/bitmap.c +@@ -0,0 +1,151 @@ ++/* ++ * bitmap.h: Simple bitmap operations ++ * ++ * Copyright (C) 2010 Novell, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Jim Fehlig ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "bitmap.h" ++#include "memory.h" ++ ++ ++struct _virBitmap { ++ size_t size; ++ uint32_t *map; ++}; ++ ++ ++#define VIR_BITMAP_BITS_PER_UNIT (sizeof(uint32_t) * CHAR_BIT) ++#define VIR_BITMAP_UNIT_OFFSET(b) ((b) / VIR_BITMAP_BITS_PER_UNIT) ++#define VIR_BITMAP_BIT_OFFSET(b) ((b) % VIR_BITMAP_BITS_PER_UNIT) ++ ++ ++/** ++ * virBitmapAlloc: ++ * @size: number of bits ++ * ++ * Allocate a bitmap capable of containing @size bits. ++ * ++ * Returns a pointer to the allocated bitmap or NULL if ++ * memory cannot be allocated. ++ */ ++virBitmapPtr virBitmapAlloc(size_t size) ++{ ++ virBitmapPtr bitmap; ++ size_t sz; ++ ++ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) ++ return NULL; ++ ++ sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / ++ VIR_BITMAP_BITS_PER_UNIT; ++ ++ if (VIR_ALLOC(bitmap) < 0) ++ return NULL; ++ ++ if (VIR_ALLOC_N(bitmap->map, sz) < 0) { ++ VIR_FREE(bitmap); ++ return NULL; ++ } ++ ++ return bitmap; ++} ++ ++/** ++ * virBitmapFree: ++ * @bitmap: previously allocated bitmap ++ * ++ * Free @bitmap previously allocated by virBitmapAlloc. ++ */ ++void virBitmapFree(virBitmapPtr bitmap) ++{ ++ if (bitmap) { ++ VIR_FREE(bitmap->map); ++ VIR_FREE(bitmap); ++ } ++} ++ ++/** ++ * virBitmapSetBit: ++ * @bitmap: Pointer to bitmap ++ * @b: bit position to set ++ * ++ * Set bit position @b in @bitmap ++ * ++ * Returns 0 on if bit is successfully set, -1 on error. ++ */ ++int virBitmapSetBit(virBitmapPtr bitmap, size_t b) ++{ ++ if (b > bitmap->size - 1) ++ return -1; ++ ++ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); ++ return 0; ++} ++ ++/** ++ * virBitmapClearBit: ++ * @bitmap: Pointer to bitmap ++ * @b: bit position to clear ++ * ++ * Clear bit position @b in @bitmap ++ * ++ * Returns 0 on if bit is successfully clear, -1 on error. ++ */ ++int virBitmapClearBit(virBitmapPtr bitmap, size_t b) ++{ ++ if (b > bitmap->size - 1) ++ return -1; ++ ++ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); ++ return 0; ++} ++ ++/** ++ * virBitmapGetBit: ++ * @bitmap: Pointer to bitmap ++ * @b: bit position to get ++ * @result: bool pointer to receive bit setting ++ * ++ * Get setting of bit position @b in @bitmap and store in @result ++ * ++ * On success, @result will contain the setting of @b and 0 is ++ * returned. On failure, -1 is returned and @result is unchanged. ++ */ ++int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) ++{ ++ uint32_t bit; ++ ++ if (b > bitmap->size - 1) ++ return -1; ++ ++ bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & ++ (1 << VIR_BITMAP_BIT_OFFSET(b)); ++ ++ *result = bit != 0; ++ return 0; ++} +Index: libvirt-0.8.1/src/util/bitmap.h +=================================================================== +--- /dev/null ++++ libvirt-0.8.1/src/util/bitmap.h +@@ -0,0 +1,63 @@ ++/* ++ * bitmap.h: Simple bitmap operations ++ * ++ * Copyright (C) 2010 Novell, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Jim Fehlig ++ */ ++ ++#ifndef __BITMAP_H__ ++# define __BITMAP_H__ ++ ++#include "internal.h" ++ ++#include ++#include ++ ++ ++typedef struct _virBitmap virBitmap; ++typedef virBitmap *virBitmapPtr; ++ ++/* ++ * Allocate a bitmap capable of containing @size bits. ++ */ ++virBitmapPtr virBitmapAlloc(size_t size) ATTRIBUTE_RETURN_CHECK; ++ ++/* ++ * Free previously allocated bitmap ++ */ ++void virBitmapFree(virBitmapPtr bitmap); ++ ++/* ++ * Set bit position @b in @bitmap ++ */ ++int virBitmapSetBit(virBitmapPtr bitmap, size_t b) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++ ++/* ++ * Clear bit position @b in @bitmap ++ */ ++int virBitmapClearBit(virBitmapPtr bitmap, size_t b) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++ ++/* ++ * Get setting of bit position @b in @bitmap and store in @result ++ */ ++int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; ++ ++#endif diff --git a/vnc-race-2.patch b/vnc-race-2.patch new file mode 100644 index 0000000..67a9d16 --- /dev/null +++ b/vnc-race-2.patch @@ -0,0 +1,29 @@ +commit c020f6203e3735a531135bc4321415ce5520fbde +Author: Jim Fehlig +Date: Thu May 20 22:25:16 2010 -0600 + + Add defines for QEMU_VNC_PORT_{MIN,MAX} and use them + +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 +@@ -89,6 +89,9 @@ + + #define VIR_FROM_THIS VIR_FROM_QEMU + ++#define QEMU_VNC_PORT_MIN 5900 ++#define QEMU_VNC_PORT_MAX 65535 ++ + /* Only 1 job is allowed at any time + * A job includes *all* monitor commands, even those just querying + * information, not merely actions */ +@@ -2607,7 +2610,7 @@ qemuInitPCIAddresses(struct qemud_driver + static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { + int i; + +- for (i = 5900 ; i < 65535 ; i++) { ++ for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { + int fd; + int reuse = 1; + struct sockaddr_in addr; diff --git a/vnc-race-3.patch b/vnc-race-3.patch new file mode 100644 index 0000000..e083557 --- /dev/null +++ b/vnc-race-3.patch @@ -0,0 +1,130 @@ +commit ba196952f57f2cb22be75fa5a4f363035a111103 +Author: Jim Fehlig +Date: Fri May 21 07:52:09 2010 -0600 + + Fix race in finding available vnc port + + The qemu driver contains a subtle race in the logic to find next + available vnc port. Currently it iterates through all available ports + and returns the first for which bind(2) succeeds. However it is possible + that a previously issued port has not yet been bound by qemu, resulting + in the same port used for a subsequent domain. + + This patch addresses the race by using a simple bitmap to "reserve" the + ports allocated by libvirt. + + V2: + - Put port bitmap in struct qemud_driver + - Initialize bitmap in qemudStartup + + V3: + - Check for failure of virBitmapGetBit + - Additional check for port != -1 before calling virbitmapClearBit + + V4: + - Check for failure of virBitmap{Set,Clear}Bit + +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 +@@ -39,6 +39,7 @@ + # include "pci.h" + # include "cpu_conf.h" + # include "driver.h" ++# include "bitmap.h" + + # define qemudDebug(fmt, ...) do {} while(0) + +@@ -153,6 +154,8 @@ struct qemud_driver { + char *saveImageFormat; + + pciDeviceList *activePciHostdevs; ++ ++ virBitmapPtr reservedVNCPorts; + }; + + typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; +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 +@@ -1479,6 +1479,11 @@ qemudStartup(int privileged) { + virEventAddTimeout(-1, qemuDomainEventFlush, qemu_driver, NULL)) < 0) + goto error; + ++ /* Allocate bitmap for vnc port reservation */ ++ if ((qemu_driver->reservedVNCPorts = ++ virBitmapAlloc(QEMU_VNC_PORT_MAX - QEMU_VNC_PORT_MIN)) == NULL) ++ goto out_of_memory; ++ + if (privileged) { + if (virAsprintf(&qemu_driver->logDir, + "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1) +@@ -1775,6 +1780,7 @@ qemudShutdown(void) { + virCapabilitiesFree(qemu_driver->caps); + + virDomainObjListDeinit(&qemu_driver->domains); ++ virBitmapFree(qemu_driver->reservedVNCPorts); + + VIR_FREE(qemu_driver->securityDriverName); + VIR_FREE(qemu_driver->logDir); +@@ -2607,13 +2613,22 @@ qemuInitPCIAddresses(struct qemud_driver + return ret; + } + +-static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { ++static int qemudNextFreeVNCPort(struct qemud_driver *driver) { + int i; + + for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { + int fd; + int reuse = 1; + struct sockaddr_in addr; ++ bool used = false; ++ ++ if (virBitmapGetBit(driver->reservedVNCPorts, ++ i - QEMU_VNC_PORT_MIN, &used) < 0) ++ VIR_DEBUG("virBitmapGetBit failed on bit %d", i - QEMU_VNC_PORT_MIN); ++ ++ if (used) ++ continue; ++ + addr.sin_family = AF_INET; + addr.sin_port = htons(i); + addr.sin_addr.s_addr = htonl(INADDR_ANY); +@@ -2629,6 +2644,12 @@ static int qemudNextFreeVNCPort(struct q + if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { + /* Not in use, lets grab it */ + close(fd); ++ /* Add port to bitmap of reserved ports */ ++ if (virBitmapSetBit(driver->reservedVNCPorts, ++ i - QEMU_VNC_PORT_MIN) < 0) { ++ VIR_DEBUG("virBitmapSetBit failed on bit %d", ++ i - QEMU_VNC_PORT_MIN); ++ } + return i; + } + close(fd); +@@ -3608,6 +3629,21 @@ retry: + + qemudRemoveDomainStatus(driver, vm); + ++ /* Remove VNC port from port reservation bitmap, but only if it was ++ reserved by the driver (autoport=yes) ++ */ ++ if ((vm->def->ngraphics == 1) && ++ vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && ++ vm->def->graphics[0]->data.vnc.autoport && ++ vm->def->graphics[0]->data.vnc.port != -1) { ++ if (virBitmapClearBit(driver->reservedVNCPorts, ++ vm->def->graphics[0]->data.vnc.port - \ ++ QEMU_VNC_PORT_MIN) < 0) { ++ VIR_DEBUG("virBitmapClearBit failed on bit %d", ++ vm->def->graphics[0]->data.vnc.port - QEMU_VNC_PORT_MIN); ++ } ++ } ++ + vm->pid = -1; + vm->def->id = -1; + vm->state = VIR_DOMAIN_SHUTOFF; diff --git a/xend-content-buf-fix.patch b/xend-content-buf-fix.patch new file mode 100644 index 0000000..784aecb --- /dev/null +++ b/xend-content-buf-fix.patch @@ -0,0 +1,79 @@ +commit b1eb7f2e987d21b1711e86e5cb63a69abfce82f1 +Author: Jim Fehlig +Date: Fri Jun 4 10:04:03 2010 -0600 + + Fixes for commit 211dd1e9 + + Fixes for issues in commit 211dd1e9 noted by by Jim Meyering. + + 1. Allocate content buffer of size content_length + 1 to ensure + NUL-termination. + 2. Limit content buffer size to 64k + 3. Fix whitespace issue + + V2: + - Add comment to clarify allocation of content buffer + - Add ATTRIBUTE_NONNULL where appropriate + - User NULLSTR macro + +diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c +index 0c1a738..51cad92 100644 +--- a/src/xen/xend_internal.c ++++ b/src/xen/xend_internal.c +@@ -68,6 +68,7 @@ + # define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3 + #endif + ++#define XEND_RCV_BUF_MAX_LEN 65536 + + #ifndef PROXY + static int +@@ -310,7 +311,7 @@ istartswith(const char *haystack, const char *needle) + * Returns the HTTP return code and @content is set to the + * allocated memory containing HTTP content. + */ +-static int ++static int ATTRIBUTE_NONNULL (2) + xend_req(int fd, char **content) + { + char buffer[4096]; +@@ -330,7 +331,19 @@ xend_req(int fd, char **content) + if (content_length > 0) { + ssize_t ret; + +- if (VIR_ALLOC_N(*content, content_length) < 0 ) { ++ if (content_length > XEND_RCV_BUF_MAX_LEN) { ++ virXendError(VIR_ERR_INTERNAL_ERROR, ++ _("Xend returned HTTP Content-Length of %d, " ++ "which exceeds maximum of %d"), ++ content_length, ++ XEND_RCV_BUF_MAX_LEN); ++ return -1; ++ } ++ ++ /* Allocate one byte beyond the end of the largest buffer we will read. ++ Combined with the fact that VIR_ALLOC_N zeros the returned buffer, ++ this guarantees that "content" will always be NUL-terminated. */ ++ if (VIR_ALLOC_N(*content, content_length + 1) < 0 ) { + virReportOOMError(); + return -1; + } +@@ -353,7 +366,7 @@ xend_req(int fd, char **content) + * + * Returns the HTTP return code or -1 in case or error. + */ +-static int ++static int ATTRIBUTE_NONNULL(3) + xend_get(virConnectPtr xend, const char *path, + char **content) + { +@@ -379,8 +392,7 @@ xend_get(virConnectPtr xend, const char *path, + ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { + virXendError(VIR_ERR_GET_FAILED, + _("%d status from xen daemon: %s:%s"), +- ret, path, +- content ? *content: "NULL"); ++ ret, path, NULLSTR(*content)); + } + + return ret; diff --git a/xend-content-buf.patch b/xend-content-buf.patch new file mode 100644 index 0000000..70b887c --- /dev/null +++ b/xend-content-buf.patch @@ -0,0 +1,244 @@ +commit 211dd1e9c54a9ba92e2e648acacbc18981374073 +Author: Jim Fehlig +Date: Wed Jun 2 18:07:17 2010 -0600 + + Allocate buffer to hold xend response + + There are cases when a response from xend can exceed 4096 bytes, in + which case anything beyond 4096 is ignored. This patch changes the + current fixed-size, stack-allocated buffer to a dynamically allocated + buffer based on Content-Length in HTTP header. + +diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c +index e763bad..0c1a738 100644 +--- a/src/xen/xend_internal.c ++++ b/src/xen/xend_internal.c +@@ -302,17 +302,19 @@ istartswith(const char *haystack, const char *needle) + * xend_req: + * @fd: the file descriptor + * @content: the buffer to store the content +- * @n_content: the size of the buffer + * + * Read the HTTP response from a Xen Daemon request. ++ * If the response contains content, memory is allocated to ++ * hold the content. + * +- * Returns the HTTP return code. ++ * Returns the HTTP return code and @content is set to the ++ * allocated memory containing HTTP content. + */ + static int +-xend_req(int fd, char *content, size_t n_content) ++xend_req(int fd, char **content) + { + char buffer[4096]; +- int content_length = -1; ++ int content_length = 0; + int retcode = 0; + + while (sreads(fd, buffer, sizeof(buffer)) > 0) { +@@ -325,19 +327,17 @@ xend_req(int fd, char *content, size_t n_content) + retcode = atoi(buffer + 9); + } + +- if (content_length > -1) { ++ if (content_length > 0) { + ssize_t ret; + +- if ((unsigned int) content_length > (n_content + 1)) +- content_length = n_content - 1; ++ if (VIR_ALLOC_N(*content, content_length) < 0 ) { ++ virReportOOMError(); ++ return -1; ++ } + +- ret = sread(fd, content, content_length); ++ ret = sread(fd, *content, content_length); + if (ret < 0) + return -1; +- +- content[ret] = 0; +- } else { +- content[0] = 0; + } + + return retcode; +@@ -348,7 +348,6 @@ xend_req(int fd, char *content, size_t n_content) + * @xend: pointer to the Xen Daemon structure + * @path: the path used for the HTTP request + * @content: the buffer to store the content +- * @n_content: the size of the buffer + * + * Do an HTTP GET RPC with the Xen Daemon + * +@@ -356,7 +355,7 @@ xend_req(int fd, char *content, size_t n_content) + */ + static int + xend_get(virConnectPtr xend, const char *path, +- char *content, size_t n_content) ++ char **content) + { + int ret; + int s = do_connect(xend); +@@ -373,14 +372,15 @@ xend_get(virConnectPtr xend, const char *path, + "Accept-Encoding: identity\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" "\r\n"); + +- ret = xend_req(s, content, n_content); ++ ret = xend_req(s, content); + close(s); + + if (((ret < 0) || (ret >= 300)) && + ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { + virXendError(VIR_ERR_GET_FAILED, + _("%d status from xen daemon: %s:%s"), +- ret, path, content); ++ ret, path, ++ content ? *content: "NULL"); + } + + return ret; +@@ -392,8 +392,6 @@ xend_get(virConnectPtr xend, const char *path, + * @xend: pointer to the Xen Daemon structure + * @path: the path used for the HTTP request + * @ops: the information sent for the POST +- * @content: the buffer to store the content +- * @n_content: the size of the buffer + * + * Do an HTTP POST RPC with the Xen Daemon, this usually makes changes at the + * Xen level. +@@ -401,10 +399,10 @@ xend_get(virConnectPtr xend, const char *path, + * Returns the HTTP return code or -1 in case or error. + */ + static int +-xend_post(virConnectPtr xend, const char *path, const char *ops, +- char *content, size_t n_content) ++xend_post(virConnectPtr xend, const char *path, const char *ops) + { + char buffer[100]; ++ char *err_buf = NULL; + int ret; + int s = do_connect(xend); + +@@ -425,26 +423,28 @@ xend_post(virConnectPtr xend, const char *path, const char *ops, + swrites(s, "\r\n\r\n"); + swrites(s, ops); + +- ret = xend_req(s, content, n_content); ++ ret = xend_req(s, &err_buf); + close(s); + + if ((ret < 0) || (ret >= 300)) { + virXendError(VIR_ERR_POST_FAILED, +- _("xend_post: error from xen daemon: %s"), content); +- } else if ((ret == 202) && (strstr(content, "failed") != NULL)) { ++ _("xend_post: error from xen daemon: %s"), err_buf); ++ } else if ((ret == 202) && err_buf && (strstr(err_buf, "failed") != NULL)) { + virXendError(VIR_ERR_POST_FAILED, +- _("xend_post: error from xen daemon: %s"), content); ++ _("xend_post: error from xen daemon: %s"), err_buf); + ret = -1; +- } else if (((ret >= 200) && (ret <= 202)) && (strstr(content, "xend.err") != NULL)) { ++ } else if (((ret >= 200) && (ret <= 202)) && err_buf && ++ (strstr(err_buf, "xend.err") != NULL)) { + /* This is to catch case of things like 'virsh dump Domain-0 foo' + * which returns a success code, but the word 'xend.err' + * in body to indicate error :-( + */ + virXendError(VIR_ERR_POST_FAILED, +- _("xend_post: error from xen daemon: %s"), content); ++ _("xend_post: error from xen daemon: %s"), err_buf); + ret = -1; + } + ++ VIR_FREE(err_buf); + return ret; + } + #endif /* ! PROXY */ +@@ -487,8 +487,6 @@ http2unix(int ret) + * xend_op_ext: + * @xend: pointer to the Xen Daemon structure + * @path: path for the object +- * @error: buffer for the error output +- * @n_error: size of @error + * @key: the key for the operation + * @ap: input values to pass to the operation + * +@@ -497,8 +495,7 @@ http2unix(int ret) + * Returns 0 in case of success, -1 in case of failure. + */ + static int +-xend_op_ext(virConnectPtr xend, const char *path, char *error, +- size_t n_error, const char *key, va_list ap) ++xend_op_ext(virConnectPtr xend, const char *path, const char *key, va_list ap) + { + const char *k = key, *v; + virBuffer buf = VIR_BUFFER_INITIALIZER; +@@ -524,7 +521,7 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, + } + + content = virBufferContentAndReset(&buf); +- ret = http2unix(xend_post(xend, path, content, error, n_error)); ++ ret = http2unix(xend_post(xend, path, content)); + VIR_FREE(content); + + return ret; +@@ -535,8 +532,6 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, + * xend_op: + * @xend: pointer to the Xen Daemon structure + * @name: the domain name target of this operation +- * @error: buffer for the error output +- * @n_error: size of @error + * @key: the key for the operation + * @ap: input values to pass to the operation + * @...: input values to pass to the operation +@@ -550,14 +545,13 @@ static int ATTRIBUTE_SENTINEL + xend_op(virConnectPtr xend, const char *name, const char *key, ...) + { + char buffer[1024]; +- char error[1024]; + va_list ap; + int ret; + + snprintf(buffer, sizeof(buffer), "/xend/domain/%s", name); + + va_start(ap, key); +- ret = xend_op_ext(xend, buffer, error, sizeof(error), key, ap); ++ ret = xend_op_ext(xend, buffer, key, ap); + va_end(ap); + + return ret; +@@ -581,21 +575,29 @@ static struct sexpr *sexpr_get(virConnectPtr xend, const char *fmt, ...) + static struct sexpr * + sexpr_get(virConnectPtr xend, const char *fmt, ...) + { +- char buffer[4096]; ++ char *buffer = NULL; + char path[1024]; + va_list ap; + int ret; ++ struct sexpr *res = NULL; + + va_start(ap, fmt); + vsnprintf(path, sizeof(path), fmt, ap); + va_end(ap); + +- ret = xend_get(xend, path, buffer, sizeof(buffer)); ++ ret = xend_get(xend, path, &buffer); + ret = http2unix(ret); + if (ret == -1) +- return NULL; ++ goto cleanup; ++ ++ if (buffer == NULL) ++ goto cleanup; ++ ++ res = string2sexpr(buffer); + +- return string2sexpr(buffer); ++cleanup: ++ VIR_FREE(buffer); ++ return res; + } + + /** From 0f3d92179354b394801015a05dcf262c05271fa0c59afa4166fb98be0a0afb9e Mon Sep 17 00:00:00 2001 From: OBS User buildservice-autocommit Date: Mon, 9 Aug 2010 00:19:48 +0000 Subject: [PATCH 4/4] Updating link to change in openSUSE:Factory/libvirt revision 58.0 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=aacb9dc3314ae5fa758f19fc632ef971 --- bitmap-alloc.patch | 29 ---- bitmap-fixes.patch | 59 -------- libvirt-0.8.1.tar.bz2 | 3 - libvirt-0.8.3.tar.bz2 | 3 + libvirt.changes | 17 +++ libvirt.spec | 35 ++--- remote-rm-unused-field.patch | 50 ------- vnc-race-1.patch | 281 ----------------------------------- vnc-race-2.patch | 29 ---- vnc-race-3.patch | 130 ---------------- xend-content-buf-fix.patch | 79 ---------- xend-content-buf.patch | 244 ------------------------------ 12 files changed, 36 insertions(+), 923 deletions(-) delete mode 100644 bitmap-alloc.patch delete mode 100644 bitmap-fixes.patch delete mode 100644 libvirt-0.8.1.tar.bz2 create mode 100644 libvirt-0.8.3.tar.bz2 delete mode 100644 remote-rm-unused-field.patch delete mode 100644 vnc-race-1.patch delete mode 100644 vnc-race-2.patch delete mode 100644 vnc-race-3.patch delete mode 100644 xend-content-buf-fix.patch delete mode 100644 xend-content-buf.patch diff --git a/bitmap-alloc.patch b/bitmap-alloc.patch deleted file mode 100644 index 2a25011..0000000 --- a/bitmap-alloc.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit ce49cfb48ad5e9cac79819d0ccde4394c237af25 -Author: Eric Blake -Date: Wed Jun 2 09:03:57 2010 -0600 - - bitmap: reject zero-size bitmap - - * src/util/bitmap.c (virBitmapAlloc): Tighten sanity check. - -diff --git a/src/util/bitmap.c b/src/util/bitmap.c -index 69094a5..44edb49 100644 ---- a/src/util/bitmap.c -+++ b/src/util/bitmap.c -@@ -1,6 +1,7 @@ - /* - * bitmap.h: Simple bitmap operations - * -+ * Copyright (C) 2010 Red Hat, Inc. - * Copyright (C) 2010 Novell, Inc. - * - * This library is free software; you can redistribute it and/or -@@ -58,7 +59,7 @@ virBitmapPtr virBitmapAlloc(size_t size) - virBitmapPtr bitmap; - size_t sz; - -- if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) -+ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size || size == 0) - return NULL; - - sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / diff --git a/bitmap-fixes.patch b/bitmap-fixes.patch deleted file mode 100644 index 96d3bd4..0000000 --- a/bitmap-fixes.patch +++ /dev/null @@ -1,59 +0,0 @@ -If VM startup fails early enough (can't find a referenced USB device), -libvirtd will crash trying to clear the VNC port bit, since port = 0, -which overflows us out of the bitmap bounds. - -Fix this by being more defensive in the bitmap operations, and only -clearing a previously set VNC port. - -v2: Add safety check to all relevant bitmap ops. - -Signed-off-by: Cole Robinson ---- - src/qemu/qemu_driver.c | 2 +- - src/util/bitmap.c | 6 +++--- - 2 files changed, 4 insertions(+), 4 deletions(-) - -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 -@@ -3635,7 +3635,7 @@ retry: - if ((vm->def->ngraphics == 1) && - vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && - vm->def->graphics[0]->data.vnc.autoport && -- vm->def->graphics[0]->data.vnc.port != -1) { -+ vm->def->graphics[0]->data.vnc.port >= QEMU_VNC_PORT_MIN) { - if (virBitmapClearBit(driver->reservedVNCPorts, - vm->def->graphics[0]->data.vnc.port - \ - QEMU_VNC_PORT_MIN) < 0) { -Index: libvirt-0.8.1/src/util/bitmap.c -=================================================================== ---- libvirt-0.8.1.orig/src/util/bitmap.c -+++ libvirt-0.8.1/src/util/bitmap.c -@@ -101,7 +101,7 @@ void virBitmapFree(virBitmapPtr bitmap) - */ - int virBitmapSetBit(virBitmapPtr bitmap, size_t b) - { -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); -@@ -119,7 +119,7 @@ int virBitmapSetBit(virBitmapPtr bitmap, - */ - int virBitmapClearBit(virBitmapPtr bitmap, size_t b) - { -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); -@@ -141,7 +141,7 @@ int virBitmapGetBit(virBitmapPtr bitmap, - { - uint32_t bit; - -- if (b > bitmap->size - 1) -+ if (bitmap->size <= b) - return -1; - - bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & diff --git a/libvirt-0.8.1.tar.bz2 b/libvirt-0.8.1.tar.bz2 deleted file mode 100644 index f77a719..0000000 --- a/libvirt-0.8.1.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:037256df745a96ba141dbfc4e4197e8bc16c51f21c834f4f89c599c379792698 -size 7706670 diff --git a/libvirt-0.8.3.tar.bz2 b/libvirt-0.8.3.tar.bz2 new file mode 100644 index 0000000..77c2193 --- /dev/null +++ b/libvirt-0.8.3.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:759f4957e6f2b905857897a84e36cbe73f7dc3a5150637430ff086c3e2b414b4 +size 8250164 diff --git a/libvirt.changes b/libvirt.changes index 195e9d8..d5dd114 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Fri Aug 6 21:53:21 MDT 2010 - jfehlig@novell.com + +- Update to libvirt 0.8.3 + - Support vSphere 4.1 + - Qemu arbitrary monitor commands + - Qemu Monitor API entry point + - lots of improvements and bug fixes + +------------------------------------------------------------------- +Fri Jul 9 14:35:04 MDT 2010 - jfehlig@novell.com + +- VUL-0: multiple issues in libvirt + CVE-2010-223x-000[1-0].patch, CVE-2010-223x-0010.patch, + CVE-2010-2242-nat.patch + bnc#618155 + ------------------------------------------------------------------- Fri Jun 25 09:02:38 MDT 2010 - jfehlig@novell.com diff --git a/libvirt.spec b/libvirt.spec index 5206d57..9428e71 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -1,5 +1,5 @@ # -# spec file for package libvirt (Version 0.8.1) +# spec file for package libvirt (Version 0.8.3) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -44,6 +44,7 @@ %define with_udev 0 %define with_hal 0 %define with_yajl 0 +%define with_macvtap 0 # Xen is available only on i386 x86_64 %ifnarch %ix86 x86_64 @@ -96,6 +97,9 @@ BuildRequires: avahi-devel %if %{with_selinux} BuildRequires: libselinux-devel %endif +%if %{with_apparmor} +BuildRequires: libapparmor-devel +%endif %if %{with_numactl} BuildRequires: libnuma-devel %endif @@ -107,14 +111,17 @@ BuildRequires: PolicyKit-devel >= 0.6 %if %{with_phyp} BuildRequires: libssh2-devel %endif +%if %{with_macvtap} +BuildRequires: libnl-devel +%endif # Only for directory ownership: BuildRequires: gtk-doc Url: http://libvirt.org/ License: LGPLv2.1+ Group: Development/Libraries/C and C++ AutoReqProv: yes -Version: 0.8.1 -Release: 3 +Version: 0.8.3 +Release: 1 Summary: A C toolkit to interract with the virtualization capabilities of Linux # The client side, i.e. shared libs and virsh are in a subpackage Requires: %{name}-client = %{version}-%{release} @@ -138,14 +145,6 @@ Requires: PolicyKit >= 0.6 Source0: %{name}-%{version}.tar.bz2 Source1: libvirtd.init # Upstream patches -Patch0: remote-rm-unused-field.patch -Patch1: vnc-race-1.patch -Patch2: vnc-race-2.patch -Patch3: vnc-race-3.patch -Patch4: bitmap-alloc.patch -Patch5: bitmap-fixes.patch -Patch6: xend-content-buf.patch -Patch7: xend-content-buf-fix.patch # Need to go upstream Patch100: xen-name-for-devid.patch Patch102: clone.patch @@ -258,14 +257,6 @@ Authors: %prep %setup -q -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 %patch100 -p1 %patch102 %patch103 -p1 @@ -326,6 +317,9 @@ Authors: %if ! %{with_yajl} %define _without_yajl --without-yajl %endif +%if ! %{with_macvtap} +%define _without_macvtap --without-macvtap +%endif autoreconf -f -i export CFLAGS="$RPM_OPT_FLAGS" %configure --disable-static --with-pic \ @@ -347,6 +341,7 @@ export CFLAGS="$RPM_OPT_FLAGS" %{?_without_hal} \ %{?_without_udev} \ %{?_without_yajl} \ + %{?_without_macvtap} \ --without-xen-proxy \ --libexecdir=%{_libdir}/%{name} \ --with-init-script=none \ @@ -472,6 +467,7 @@ rm -rf $RPM_BUILD_ROOT %if 0%{with_storage_disk} %{_libdir}/%{name}/libvirt_parthelper %endif +%doc %{_mandir}/man8/libvirtd.8* %files client -f %{name}.lang %defattr(-, root, root) @@ -500,6 +496,7 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/libvirt/schemas/storageencryption.rng %{_datadir}/libvirt/cpu_map.xml %{_datadir}/libvirt/schemas/nwfilter.rng +%{_datadir}/libvirt/schemas/domainsnapshot.rng %config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf %files devel diff --git a/remote-rm-unused-field.patch b/remote-rm-unused-field.patch deleted file mode 100644 index 0a5f271..0000000 --- a/remote-rm-unused-field.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit 34a7f3f6be9c63ac3d4c4604c1fb2482a4e5053b -Author: Matthew Booth -Date: Fri May 7 16:38:05 2010 +0200 - - Remove unused nwfilter field from struct remote_error - - Change 965466c1 added a new field to struct remote_error, which broke - the RPC protocol. Fortunately the new field is unused, so this change - simply removes it again. - - * src/remote/remote_protocol.(c|h|x): Remove remote_nwfilter from struct - remote_error - -diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c -index 187281d..972bf52 100644 ---- a/src/remote/remote_protocol.c -+++ b/src/remote/remote_protocol.c -@@ -227,8 +227,6 @@ xdr_remote_error (XDR *xdrs, remote_error *objp) - return FALSE; - if (!xdr_remote_network (xdrs, &objp->net)) - return FALSE; -- if (!xdr_remote_nwfilter (xdrs, &objp->nwfilter)) -- return FALSE; - return TRUE; - } - -diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h -index 6f01da7..a600af6 100644 ---- a/src/remote/remote_protocol.h -+++ b/src/remote/remote_protocol.h -@@ -143,7 +143,6 @@ struct remote_error { - int int1; - int int2; - remote_network net; -- remote_nwfilter nwfilter; - }; - typedef struct remote_error remote_error; - -diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x -index 8000ee0..1ce488c 100644 ---- a/src/remote/remote_protocol.x -+++ b/src/remote/remote_protocol.x -@@ -266,7 +266,6 @@ struct remote_error { - int int1; - int int2; - remote_network net; -- remote_nwfilter nwfilter; - }; - - /* Authentication types available thus far.... */ diff --git a/vnc-race-1.patch b/vnc-race-1.patch deleted file mode 100644 index 32d7aca..0000000 --- a/vnc-race-1.patch +++ /dev/null @@ -1,281 +0,0 @@ -commit 2f32d7afd5bd71f79c0e756c87813702065c6d1a -Author: Jim Fehlig -Date: Thu May 20 22:23:48 2010 -0600 - - Add simple bitmap operations to utils - - V2: - - Move bitmap impl to src/util/bitmap.[ch] - - Use CHAR_BIT instead of explicit '8' - - Use size_t instead of unsigned int - - Fix calculation of bitmap size in virBitmapAlloc - - Ensure bit is within range of map in the set, clear, and get - operations - - Use bool in virBitmapGetBit - - Add virBitmapFree to free-like funcs in cfg.mk - - V3: - - Check for overflow in virBitmapAlloc - - Fix copy and paste bug in virBitmapAlloc - - Use size_t in prototypes - - Add ATTRIBUTE_NONNULL in prototypes where appropriate - and remove NULL check from impl - - V4: - - Add ATTRIBUTE_RETURN_CHECK in prototypes where appropriate. - -Index: libvirt-0.8.1/src/Makefile.am -=================================================================== ---- libvirt-0.8.1.orig/src/Makefile.am -+++ libvirt-0.8.1/src/Makefile.am -@@ -50,6 +50,7 @@ augeastest_DATA = - # helper APIs for various purposes - UTIL_SOURCES = \ - util/authhelper.c util/authhelper.h \ -+ util/bitmap.c util/bitmap.h \ - util/bridge.c util/bridge.h \ - util/buf.c util/buf.h \ - util/conf.c util/conf.h \ -Index: libvirt-0.8.1/src/libvirt_private.syms -=================================================================== ---- libvirt-0.8.1.orig/src/libvirt_private.syms -+++ libvirt-0.8.1/src/libvirt_private.syms -@@ -4,6 +4,14 @@ - # - - -+# bitmap.h -+virBitmapAlloc; -+virBitmapFree; -+virBitmapSetBit; -+virBitmapClearBit; -+virBitmapGetBit; -+ -+ - # buf.h - virBufferVSprintf; - virBufferEscapeString; -Index: libvirt-0.8.1/src/util/bitmap.c -=================================================================== ---- /dev/null -+++ libvirt-0.8.1/src/util/bitmap.c -@@ -0,0 +1,151 @@ -+/* -+ * bitmap.h: Simple bitmap operations -+ * -+ * Copyright (C) 2010 Novell, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Jim Fehlig -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bitmap.h" -+#include "memory.h" -+ -+ -+struct _virBitmap { -+ size_t size; -+ uint32_t *map; -+}; -+ -+ -+#define VIR_BITMAP_BITS_PER_UNIT (sizeof(uint32_t) * CHAR_BIT) -+#define VIR_BITMAP_UNIT_OFFSET(b) ((b) / VIR_BITMAP_BITS_PER_UNIT) -+#define VIR_BITMAP_BIT_OFFSET(b) ((b) % VIR_BITMAP_BITS_PER_UNIT) -+ -+ -+/** -+ * virBitmapAlloc: -+ * @size: number of bits -+ * -+ * Allocate a bitmap capable of containing @size bits. -+ * -+ * Returns a pointer to the allocated bitmap or NULL if -+ * memory cannot be allocated. -+ */ -+virBitmapPtr virBitmapAlloc(size_t size) -+{ -+ virBitmapPtr bitmap; -+ size_t sz; -+ -+ if (SIZE_MAX - VIR_BITMAP_BITS_PER_UNIT < size) -+ return NULL; -+ -+ sz = (size + VIR_BITMAP_BITS_PER_UNIT - 1) / -+ VIR_BITMAP_BITS_PER_UNIT; -+ -+ if (VIR_ALLOC(bitmap) < 0) -+ return NULL; -+ -+ if (VIR_ALLOC_N(bitmap->map, sz) < 0) { -+ VIR_FREE(bitmap); -+ return NULL; -+ } -+ -+ return bitmap; -+} -+ -+/** -+ * virBitmapFree: -+ * @bitmap: previously allocated bitmap -+ * -+ * Free @bitmap previously allocated by virBitmapAlloc. -+ */ -+void virBitmapFree(virBitmapPtr bitmap) -+{ -+ if (bitmap) { -+ VIR_FREE(bitmap->map); -+ VIR_FREE(bitmap); -+ } -+} -+ -+/** -+ * virBitmapSetBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to set -+ * -+ * Set bit position @b in @bitmap -+ * -+ * Returns 0 on if bit is successfully set, -1 on error. -+ */ -+int virBitmapSetBit(virBitmapPtr bitmap, size_t b) -+{ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] |= (1 << VIR_BITMAP_BIT_OFFSET(b)); -+ return 0; -+} -+ -+/** -+ * virBitmapClearBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to clear -+ * -+ * Clear bit position @b in @bitmap -+ * -+ * Returns 0 on if bit is successfully clear, -1 on error. -+ */ -+int virBitmapClearBit(virBitmapPtr bitmap, size_t b) -+{ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] &= ~(1 << VIR_BITMAP_BIT_OFFSET(b)); -+ return 0; -+} -+ -+/** -+ * virBitmapGetBit: -+ * @bitmap: Pointer to bitmap -+ * @b: bit position to get -+ * @result: bool pointer to receive bit setting -+ * -+ * Get setting of bit position @b in @bitmap and store in @result -+ * -+ * On success, @result will contain the setting of @b and 0 is -+ * returned. On failure, -1 is returned and @result is unchanged. -+ */ -+int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) -+{ -+ uint32_t bit; -+ -+ if (b > bitmap->size - 1) -+ return -1; -+ -+ bit = bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & -+ (1 << VIR_BITMAP_BIT_OFFSET(b)); -+ -+ *result = bit != 0; -+ return 0; -+} -Index: libvirt-0.8.1/src/util/bitmap.h -=================================================================== ---- /dev/null -+++ libvirt-0.8.1/src/util/bitmap.h -@@ -0,0 +1,63 @@ -+/* -+ * bitmap.h: Simple bitmap operations -+ * -+ * Copyright (C) 2010 Novell, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Jim Fehlig -+ */ -+ -+#ifndef __BITMAP_H__ -+# define __BITMAP_H__ -+ -+#include "internal.h" -+ -+#include -+#include -+ -+ -+typedef struct _virBitmap virBitmap; -+typedef virBitmap *virBitmapPtr; -+ -+/* -+ * Allocate a bitmap capable of containing @size bits. -+ */ -+virBitmapPtr virBitmapAlloc(size_t size) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Free previously allocated bitmap -+ */ -+void virBitmapFree(virBitmapPtr bitmap); -+ -+/* -+ * Set bit position @b in @bitmap -+ */ -+int virBitmapSetBit(virBitmapPtr bitmap, size_t b) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Clear bit position @b in @bitmap -+ */ -+int virBitmapClearBit(virBitmapPtr bitmap, size_t b) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -+ -+/* -+ * Get setting of bit position @b in @bitmap and store in @result -+ */ -+int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) -+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; -+ -+#endif diff --git a/vnc-race-2.patch b/vnc-race-2.patch deleted file mode 100644 index 67a9d16..0000000 --- a/vnc-race-2.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit c020f6203e3735a531135bc4321415ce5520fbde -Author: Jim Fehlig -Date: Thu May 20 22:25:16 2010 -0600 - - Add defines for QEMU_VNC_PORT_{MIN,MAX} and use them - -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 -@@ -89,6 +89,9 @@ - - #define VIR_FROM_THIS VIR_FROM_QEMU - -+#define QEMU_VNC_PORT_MIN 5900 -+#define QEMU_VNC_PORT_MAX 65535 -+ - /* Only 1 job is allowed at any time - * A job includes *all* monitor commands, even those just querying - * information, not merely actions */ -@@ -2607,7 +2610,7 @@ qemuInitPCIAddresses(struct qemud_driver - static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { - int i; - -- for (i = 5900 ; i < 65535 ; i++) { -+ for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { - int fd; - int reuse = 1; - struct sockaddr_in addr; diff --git a/vnc-race-3.patch b/vnc-race-3.patch deleted file mode 100644 index e083557..0000000 --- a/vnc-race-3.patch +++ /dev/null @@ -1,130 +0,0 @@ -commit ba196952f57f2cb22be75fa5a4f363035a111103 -Author: Jim Fehlig -Date: Fri May 21 07:52:09 2010 -0600 - - Fix race in finding available vnc port - - The qemu driver contains a subtle race in the logic to find next - available vnc port. Currently it iterates through all available ports - and returns the first for which bind(2) succeeds. However it is possible - that a previously issued port has not yet been bound by qemu, resulting - in the same port used for a subsequent domain. - - This patch addresses the race by using a simple bitmap to "reserve" the - ports allocated by libvirt. - - V2: - - Put port bitmap in struct qemud_driver - - Initialize bitmap in qemudStartup - - V3: - - Check for failure of virBitmapGetBit - - Additional check for port != -1 before calling virbitmapClearBit - - V4: - - Check for failure of virBitmap{Set,Clear}Bit - -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 -@@ -39,6 +39,7 @@ - # include "pci.h" - # include "cpu_conf.h" - # include "driver.h" -+# include "bitmap.h" - - # define qemudDebug(fmt, ...) do {} while(0) - -@@ -153,6 +154,8 @@ struct qemud_driver { - char *saveImageFormat; - - pciDeviceList *activePciHostdevs; -+ -+ virBitmapPtr reservedVNCPorts; - }; - - typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; -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 -@@ -1479,6 +1479,11 @@ qemudStartup(int privileged) { - virEventAddTimeout(-1, qemuDomainEventFlush, qemu_driver, NULL)) < 0) - goto error; - -+ /* Allocate bitmap for vnc port reservation */ -+ if ((qemu_driver->reservedVNCPorts = -+ virBitmapAlloc(QEMU_VNC_PORT_MAX - QEMU_VNC_PORT_MIN)) == NULL) -+ goto out_of_memory; -+ - if (privileged) { - if (virAsprintf(&qemu_driver->logDir, - "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1) -@@ -1775,6 +1780,7 @@ qemudShutdown(void) { - virCapabilitiesFree(qemu_driver->caps); - - virDomainObjListDeinit(&qemu_driver->domains); -+ virBitmapFree(qemu_driver->reservedVNCPorts); - - VIR_FREE(qemu_driver->securityDriverName); - VIR_FREE(qemu_driver->logDir); -@@ -2607,13 +2613,22 @@ qemuInitPCIAddresses(struct qemud_driver - return ret; - } - --static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { -+static int qemudNextFreeVNCPort(struct qemud_driver *driver) { - int i; - - for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { - int fd; - int reuse = 1; - struct sockaddr_in addr; -+ bool used = false; -+ -+ if (virBitmapGetBit(driver->reservedVNCPorts, -+ i - QEMU_VNC_PORT_MIN, &used) < 0) -+ VIR_DEBUG("virBitmapGetBit failed on bit %d", i - QEMU_VNC_PORT_MIN); -+ -+ if (used) -+ continue; -+ - addr.sin_family = AF_INET; - addr.sin_port = htons(i); - addr.sin_addr.s_addr = htonl(INADDR_ANY); -@@ -2629,6 +2644,12 @@ static int qemudNextFreeVNCPort(struct q - if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { - /* Not in use, lets grab it */ - close(fd); -+ /* Add port to bitmap of reserved ports */ -+ if (virBitmapSetBit(driver->reservedVNCPorts, -+ i - QEMU_VNC_PORT_MIN) < 0) { -+ VIR_DEBUG("virBitmapSetBit failed on bit %d", -+ i - QEMU_VNC_PORT_MIN); -+ } - return i; - } - close(fd); -@@ -3608,6 +3629,21 @@ retry: - - qemudRemoveDomainStatus(driver, vm); - -+ /* Remove VNC port from port reservation bitmap, but only if it was -+ reserved by the driver (autoport=yes) -+ */ -+ if ((vm->def->ngraphics == 1) && -+ vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && -+ vm->def->graphics[0]->data.vnc.autoport && -+ vm->def->graphics[0]->data.vnc.port != -1) { -+ if (virBitmapClearBit(driver->reservedVNCPorts, -+ vm->def->graphics[0]->data.vnc.port - \ -+ QEMU_VNC_PORT_MIN) < 0) { -+ VIR_DEBUG("virBitmapClearBit failed on bit %d", -+ vm->def->graphics[0]->data.vnc.port - QEMU_VNC_PORT_MIN); -+ } -+ } -+ - vm->pid = -1; - vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; diff --git a/xend-content-buf-fix.patch b/xend-content-buf-fix.patch deleted file mode 100644 index 784aecb..0000000 --- a/xend-content-buf-fix.patch +++ /dev/null @@ -1,79 +0,0 @@ -commit b1eb7f2e987d21b1711e86e5cb63a69abfce82f1 -Author: Jim Fehlig -Date: Fri Jun 4 10:04:03 2010 -0600 - - Fixes for commit 211dd1e9 - - Fixes for issues in commit 211dd1e9 noted by by Jim Meyering. - - 1. Allocate content buffer of size content_length + 1 to ensure - NUL-termination. - 2. Limit content buffer size to 64k - 3. Fix whitespace issue - - V2: - - Add comment to clarify allocation of content buffer - - Add ATTRIBUTE_NONNULL where appropriate - - User NULLSTR macro - -diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c -index 0c1a738..51cad92 100644 ---- a/src/xen/xend_internal.c -+++ b/src/xen/xend_internal.c -@@ -68,6 +68,7 @@ - # define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3 - #endif - -+#define XEND_RCV_BUF_MAX_LEN 65536 - - #ifndef PROXY - static int -@@ -310,7 +311,7 @@ istartswith(const char *haystack, const char *needle) - * Returns the HTTP return code and @content is set to the - * allocated memory containing HTTP content. - */ --static int -+static int ATTRIBUTE_NONNULL (2) - xend_req(int fd, char **content) - { - char buffer[4096]; -@@ -330,7 +331,19 @@ xend_req(int fd, char **content) - if (content_length > 0) { - ssize_t ret; - -- if (VIR_ALLOC_N(*content, content_length) < 0 ) { -+ if (content_length > XEND_RCV_BUF_MAX_LEN) { -+ virXendError(VIR_ERR_INTERNAL_ERROR, -+ _("Xend returned HTTP Content-Length of %d, " -+ "which exceeds maximum of %d"), -+ content_length, -+ XEND_RCV_BUF_MAX_LEN); -+ return -1; -+ } -+ -+ /* Allocate one byte beyond the end of the largest buffer we will read. -+ Combined with the fact that VIR_ALLOC_N zeros the returned buffer, -+ this guarantees that "content" will always be NUL-terminated. */ -+ if (VIR_ALLOC_N(*content, content_length + 1) < 0 ) { - virReportOOMError(); - return -1; - } -@@ -353,7 +366,7 @@ xend_req(int fd, char **content) - * - * Returns the HTTP return code or -1 in case or error. - */ --static int -+static int ATTRIBUTE_NONNULL(3) - xend_get(virConnectPtr xend, const char *path, - char **content) - { -@@ -379,8 +392,7 @@ xend_get(virConnectPtr xend, const char *path, - ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { - virXendError(VIR_ERR_GET_FAILED, - _("%d status from xen daemon: %s:%s"), -- ret, path, -- content ? *content: "NULL"); -+ ret, path, NULLSTR(*content)); - } - - return ret; diff --git a/xend-content-buf.patch b/xend-content-buf.patch deleted file mode 100644 index 70b887c..0000000 --- a/xend-content-buf.patch +++ /dev/null @@ -1,244 +0,0 @@ -commit 211dd1e9c54a9ba92e2e648acacbc18981374073 -Author: Jim Fehlig -Date: Wed Jun 2 18:07:17 2010 -0600 - - Allocate buffer to hold xend response - - There are cases when a response from xend can exceed 4096 bytes, in - which case anything beyond 4096 is ignored. This patch changes the - current fixed-size, stack-allocated buffer to a dynamically allocated - buffer based on Content-Length in HTTP header. - -diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c -index e763bad..0c1a738 100644 ---- a/src/xen/xend_internal.c -+++ b/src/xen/xend_internal.c -@@ -302,17 +302,19 @@ istartswith(const char *haystack, const char *needle) - * xend_req: - * @fd: the file descriptor - * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Read the HTTP response from a Xen Daemon request. -+ * If the response contains content, memory is allocated to -+ * hold the content. - * -- * Returns the HTTP return code. -+ * Returns the HTTP return code and @content is set to the -+ * allocated memory containing HTTP content. - */ - static int --xend_req(int fd, char *content, size_t n_content) -+xend_req(int fd, char **content) - { - char buffer[4096]; -- int content_length = -1; -+ int content_length = 0; - int retcode = 0; - - while (sreads(fd, buffer, sizeof(buffer)) > 0) { -@@ -325,19 +327,17 @@ xend_req(int fd, char *content, size_t n_content) - retcode = atoi(buffer + 9); - } - -- if (content_length > -1) { -+ if (content_length > 0) { - ssize_t ret; - -- if ((unsigned int) content_length > (n_content + 1)) -- content_length = n_content - 1; -+ if (VIR_ALLOC_N(*content, content_length) < 0 ) { -+ virReportOOMError(); -+ return -1; -+ } - -- ret = sread(fd, content, content_length); -+ ret = sread(fd, *content, content_length); - if (ret < 0) - return -1; -- -- content[ret] = 0; -- } else { -- content[0] = 0; - } - - return retcode; -@@ -348,7 +348,6 @@ xend_req(int fd, char *content, size_t n_content) - * @xend: pointer to the Xen Daemon structure - * @path: the path used for the HTTP request - * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Do an HTTP GET RPC with the Xen Daemon - * -@@ -356,7 +355,7 @@ xend_req(int fd, char *content, size_t n_content) - */ - static int - xend_get(virConnectPtr xend, const char *path, -- char *content, size_t n_content) -+ char **content) - { - int ret; - int s = do_connect(xend); -@@ -373,14 +372,15 @@ xend_get(virConnectPtr xend, const char *path, - "Accept-Encoding: identity\r\n" - "Content-Type: application/x-www-form-urlencoded\r\n" "\r\n"); - -- ret = xend_req(s, content, n_content); -+ ret = xend_req(s, content); - close(s); - - if (((ret < 0) || (ret >= 300)) && - ((ret != 404) || (!STRPREFIX(path, "/xend/domain/")))) { - virXendError(VIR_ERR_GET_FAILED, - _("%d status from xen daemon: %s:%s"), -- ret, path, content); -+ ret, path, -+ content ? *content: "NULL"); - } - - return ret; -@@ -392,8 +392,6 @@ xend_get(virConnectPtr xend, const char *path, - * @xend: pointer to the Xen Daemon structure - * @path: the path used for the HTTP request - * @ops: the information sent for the POST -- * @content: the buffer to store the content -- * @n_content: the size of the buffer - * - * Do an HTTP POST RPC with the Xen Daemon, this usually makes changes at the - * Xen level. -@@ -401,10 +399,10 @@ xend_get(virConnectPtr xend, const char *path, - * Returns the HTTP return code or -1 in case or error. - */ - static int --xend_post(virConnectPtr xend, const char *path, const char *ops, -- char *content, size_t n_content) -+xend_post(virConnectPtr xend, const char *path, const char *ops) - { - char buffer[100]; -+ char *err_buf = NULL; - int ret; - int s = do_connect(xend); - -@@ -425,26 +423,28 @@ xend_post(virConnectPtr xend, const char *path, const char *ops, - swrites(s, "\r\n\r\n"); - swrites(s, ops); - -- ret = xend_req(s, content, n_content); -+ ret = xend_req(s, &err_buf); - close(s); - - if ((ret < 0) || (ret >= 300)) { - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -- } else if ((ret == 202) && (strstr(content, "failed") != NULL)) { -+ _("xend_post: error from xen daemon: %s"), err_buf); -+ } else if ((ret == 202) && err_buf && (strstr(err_buf, "failed") != NULL)) { - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -+ _("xend_post: error from xen daemon: %s"), err_buf); - ret = -1; -- } else if (((ret >= 200) && (ret <= 202)) && (strstr(content, "xend.err") != NULL)) { -+ } else if (((ret >= 200) && (ret <= 202)) && err_buf && -+ (strstr(err_buf, "xend.err") != NULL)) { - /* This is to catch case of things like 'virsh dump Domain-0 foo' - * which returns a success code, but the word 'xend.err' - * in body to indicate error :-( - */ - virXendError(VIR_ERR_POST_FAILED, -- _("xend_post: error from xen daemon: %s"), content); -+ _("xend_post: error from xen daemon: %s"), err_buf); - ret = -1; - } - -+ VIR_FREE(err_buf); - return ret; - } - #endif /* ! PROXY */ -@@ -487,8 +487,6 @@ http2unix(int ret) - * xend_op_ext: - * @xend: pointer to the Xen Daemon structure - * @path: path for the object -- * @error: buffer for the error output -- * @n_error: size of @error - * @key: the key for the operation - * @ap: input values to pass to the operation - * -@@ -497,8 +495,7 @@ http2unix(int ret) - * Returns 0 in case of success, -1 in case of failure. - */ - static int --xend_op_ext(virConnectPtr xend, const char *path, char *error, -- size_t n_error, const char *key, va_list ap) -+xend_op_ext(virConnectPtr xend, const char *path, const char *key, va_list ap) - { - const char *k = key, *v; - virBuffer buf = VIR_BUFFER_INITIALIZER; -@@ -524,7 +521,7 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, - } - - content = virBufferContentAndReset(&buf); -- ret = http2unix(xend_post(xend, path, content, error, n_error)); -+ ret = http2unix(xend_post(xend, path, content)); - VIR_FREE(content); - - return ret; -@@ -535,8 +532,6 @@ xend_op_ext(virConnectPtr xend, const char *path, char *error, - * xend_op: - * @xend: pointer to the Xen Daemon structure - * @name: the domain name target of this operation -- * @error: buffer for the error output -- * @n_error: size of @error - * @key: the key for the operation - * @ap: input values to pass to the operation - * @...: input values to pass to the operation -@@ -550,14 +545,13 @@ static int ATTRIBUTE_SENTINEL - xend_op(virConnectPtr xend, const char *name, const char *key, ...) - { - char buffer[1024]; -- char error[1024]; - va_list ap; - int ret; - - snprintf(buffer, sizeof(buffer), "/xend/domain/%s", name); - - va_start(ap, key); -- ret = xend_op_ext(xend, buffer, error, sizeof(error), key, ap); -+ ret = xend_op_ext(xend, buffer, key, ap); - va_end(ap); - - return ret; -@@ -581,21 +575,29 @@ static struct sexpr *sexpr_get(virConnectPtr xend, const char *fmt, ...) - static struct sexpr * - sexpr_get(virConnectPtr xend, const char *fmt, ...) - { -- char buffer[4096]; -+ char *buffer = NULL; - char path[1024]; - va_list ap; - int ret; -+ struct sexpr *res = NULL; - - va_start(ap, fmt); - vsnprintf(path, sizeof(path), fmt, ap); - va_end(ap); - -- ret = xend_get(xend, path, buffer, sizeof(buffer)); -+ ret = xend_get(xend, path, &buffer); - ret = http2unix(ret); - if (ret == -1) -- return NULL; -+ goto cleanup; -+ -+ if (buffer == NULL) -+ goto cleanup; -+ -+ res = string2sexpr(buffer); - -- return string2sexpr(buffer); -+cleanup: -+ VIR_FREE(buffer); -+ return res; - } - - /**