From 598a3740c654b784c7d0e3bfe222d6e3a21da5544339867119b9ba2f0fdf504c Mon Sep 17 00:00:00 2001 From: Charles Arnold Date: Tue, 22 Jan 2013 15:40:06 +0000 Subject: [PATCH] - bnc#797285 - VUL-0: Xen: XSA-34 (CVE-2013-0151) - nested virtualization on 32-bit exposes host crash CVE-2013-0151-xsa34.patch - bnc#797287 - VUL-0: Xen: XSA-35 (CVE-2013-0152) - Nested HVM exposes host to being driven out of memory by guest CVE-2013-0152-xsa35.patch - bnc#793717 - NetWare will not boot on Xen 4.2 xnloader.py domUloader.py pygrub-netware-xnloader.patch Removed reverse-24757-use-grant-references.patch - bnc#797523 - VUL-1: CVE-2012-6075: qemu / kvm-qemu: e1000 overflows under some conditions CVE-2012-6075-xsa41.patch - Mask the floating point exceptions for guests like NetWare on machines that support XSAVE. x86-fpu-context-conditional.patch - fate##313584: pass bios information to XEN HVM guest 26341-hvm-firmware-passthrough.patch 26342-hvm-firmware-passthrough.patch 26343-hvm-firmware-passthrough.patch 26344-hvm-firmware-passthrough.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=223 --- 26341-hvm-firmware-passthrough.patch | 99 ++++ 26342-hvm-firmware-passthrough.patch | 282 ++++++++++ 26343-hvm-firmware-passthrough.patch | 645 +++++++++++++++++++++++ 26344-hvm-firmware-passthrough.patch | 101 ++++ CVE-2012-6075-xsa41.patch | 88 ++++ CVE-2013-0151-xsa34.patch | 32 ++ CVE-2013-0152-xsa35.patch | 26 + domUloader.py | 2 + pygrub-netware-xnloader.patch | 21 + reverse-24757-use-grant-references.patch | 145 ----- x86-fpu-context-conditional.patch | 13 + xen.changes | 42 ++ xen.spec | 21 +- xnloader.py | 62 +++ 14 files changed, 1429 insertions(+), 150 deletions(-) create mode 100644 26341-hvm-firmware-passthrough.patch create mode 100644 26342-hvm-firmware-passthrough.patch create mode 100644 26343-hvm-firmware-passthrough.patch create mode 100644 26344-hvm-firmware-passthrough.patch create mode 100644 CVE-2012-6075-xsa41.patch create mode 100644 CVE-2013-0151-xsa34.patch create mode 100644 CVE-2013-0152-xsa35.patch create mode 100644 pygrub-netware-xnloader.patch delete mode 100644 reverse-24757-use-grant-references.patch create mode 100644 x86-fpu-context-conditional.patch create mode 100644 xnloader.py diff --git a/26341-hvm-firmware-passthrough.patch b/26341-hvm-firmware-passthrough.patch new file mode 100644 index 0000000..8669b76 --- /dev/null +++ b/26341-hvm-firmware-passthrough.patch @@ -0,0 +1,99 @@ +fate#313584: pass bios information to XEN HVM guest + +# HG changeset patch +# User Ross Philipson +# Date 1357838188 0 +# Node ID 07bf59a7ce837bd795e2df2f28166cfe41990d3d +# Parent 19fd1237ff0dfa3d97a896d6ed6fbbd33f816a9f +HVM xenstore strings and firmware passthrough header + +Add public HVM definitions header for xenstore strings used in +HVMLOADER. In addition this header describes the use of the firmware +passthrough values set using xenstore. + +Signed-off-by: Ross Philipson +Committed-by: Keir Fraser + +diff -r 19fd1237ff0d -r 07bf59a7ce83 xen/include/public/hvm/hvm_xs_strings.h +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/xen/include/public/hvm/hvm_xs_strings.h Thu Jan 10 17:16:28 2013 +0000 +@@ -0,0 +1,79 @@ ++/****************************************************************************** ++ * hvm/hvm_xs_strings.h ++ * ++ * HVM xenstore strings used in HVMLOADER. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to ++ * deal in the Software without restriction, including without limitation the ++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ ++#define __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ ++ ++#define HVM_XS_HVMLOADER "hvmloader" ++#define HVM_XS_BIOS "hvmloader/bios" ++#define HVM_XS_GENERATION_ID_ADDRESS "hvmloader/generation-id-address" ++ ++/* The following values allow additional ACPI tables to be added to the ++ * virtual ACPI BIOS that hvmloader constructs. The values specify the guest ++ * physical address and length of a block of ACPI tables to add. The format of ++ * the block is simply concatenated raw tables (which specify their own length ++ * in the ACPI header). ++ */ ++#define HVM_XS_ACPI_PT_ADDRESS "hvmloader/acpi/address" ++#define HVM_XS_ACPI_PT_LENGTH "hvmloader/acpi/length" ++ ++/* Any number of SMBIOS types can be passed through to an HVM guest using ++ * the following xenstore values. The values specify the guest physical ++ * address and length of a block of SMBIOS structures for hvmloader to use. ++ * The block is formatted in the following way: ++ * ++ * ... ++ * ++ * Each length separator is a 32b integer indicating the length of the next ++ * SMBIOS structure. For DMTF defined types (0 - 121), the passed in struct ++ * will replace the default structure in hvmloader. In addition, any ++ * OEM/vendortypes (128 - 255) will all be added. ++ */ ++#define HVM_XS_SMBIOS_PT_ADDRESS "hvmloader/smbios/address" ++#define HVM_XS_SMBIOS_PT_LENGTH "hvmloader/smbios/length" ++ ++/* Set to 1 to enable SMBIOS default portable battery (type 22) values. */ ++#define HVM_XS_SMBIOS_DEFAULT_BATTERY "hvmloader/smbios/default_battery" ++ ++/* The following xenstore values are used to override some of the default ++ * string values in the SMBIOS table constructed in hvmloader. ++ */ ++#define HVM_XS_BIOS_STRINGS "bios-strings" ++#define HVM_XS_BIOS_VENDOR "bios-strings/bios-vendor" ++#define HVM_XS_BIOS_VERSION "bios-strings/bios-version" ++#define HVM_XS_SYSTEM_MANUFACTURER "bios-strings/system-manufacturer" ++#define HVM_XS_SYSTEM_PRODUCT_NAME "bios-strings/system-product-name" ++#define HVM_XS_SYSTEM_VERSION "bios-strings/system-version" ++#define HVM_XS_SYSTEM_SERIAL_NUMBER "bios-strings/system-serial-number" ++#define HVM_XS_ENCLOSURE_MANUFACTURER "bios-strings/enclosure-manufacturer" ++#define HVM_XS_ENCLOSURE_SERIAL_NUMBER "bios-strings/enclosure-serial-number" ++#define HVM_XS_BATTERY_MANUFACTURER "bios-strings/battery-manufacturer" ++#define HVM_XS_BATTERY_DEVICE_NAME "bios-strings/battery-device-name" ++ ++/* 1 to 99 OEM strings can be set in xenstore using values of the form ++ * below. These strings will be loaded into the SMBIOS type 11 structure. ++ */ ++#define HVM_XS_OEM_STRINGS "bios-strings/oem-%02d" ++ ++#endif /* __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ */ diff --git a/26342-hvm-firmware-passthrough.patch b/26342-hvm-firmware-passthrough.patch new file mode 100644 index 0000000..2297749 --- /dev/null +++ b/26342-hvm-firmware-passthrough.patch @@ -0,0 +1,282 @@ +fate#313584: pass bios information to XEN HVM guest + +# HG changeset patch +# User Ross Philipson +# Date 1357838241 0 +# Node ID cabf395a6c849cc65e56f1640b18db0c3e0faf5d +# Parent 07bf59a7ce837bd795e2df2f28166cfe41990d3d +HVM firmware passthrough control tools support + +Xen control tools support for loading the firmware passthrough blocks +during domain construction. SMBIOS and ACPI blocks are passed in using +the new xc_hvm_build_args structure. Each block is read and loaded +into the new domain address space behind the HVMLOADER image. The base +address for the two blocks is returned as an out parameter to the +caller via the args structure. + +Signed-off-by: Ross Philipson +Committed-by: Keir Fraser + +diff -r 07bf59a7ce83 -r cabf395a6c84 tools/libxc/xc_hvm_build_arm.c +--- a/tools/libxc/xc_hvm_build_arm.c Thu Jan 10 17:16:28 2013 +0000 ++++ b/tools/libxc/xc_hvm_build_arm.c Thu Jan 10 17:17:21 2013 +0000 +@@ -22,7 +22,7 @@ + #include + + int xc_hvm_build(xc_interface *xch, uint32_t domid, +- const struct xc_hvm_build_args *hvm_args) ++ struct xc_hvm_build_args *hvm_args) + { + errno = ENOSYS; + return -1; +diff -r 07bf59a7ce83 -r cabf395a6c84 tools/libxc/xc_hvm_build_x86.c +--- a/tools/libxc/xc_hvm_build_x86.c Thu Jan 10 17:16:28 2013 +0000 ++++ b/tools/libxc/xc_hvm_build_x86.c Thu Jan 10 17:17:21 2013 +0000 +@@ -49,6 +49,40 @@ + #define NR_SPECIAL_PAGES 8 + #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x)) + ++static int modules_init(struct xc_hvm_build_args *args, ++ uint64_t vend, struct elf_binary *elf, ++ uint64_t *mstart_out, uint64_t *mend_out) ++{ ++#define MODULE_ALIGN 1UL << 7 ++#define MB_ALIGN 1UL << 20 ++#define MKALIGN(x, a) (((uint64_t)(x) + (a) - 1) & ~(uint64_t)((a) - 1)) ++ uint64_t total_len = 0, offset1 = 0; ++ ++ if ( (args->acpi_module.length == 0)&&(args->smbios_module.length == 0) ) ++ return 0; ++ ++ /* Find the total length for the firmware modules with a reasonable large ++ * alignment size to align each the modules. ++ */ ++ total_len = MKALIGN(args->acpi_module.length, MODULE_ALIGN); ++ offset1 = total_len; ++ total_len += MKALIGN(args->smbios_module.length, MODULE_ALIGN); ++ ++ /* Want to place the modules 1Mb+change behind the loader image. */ ++ *mstart_out = MKALIGN(elf->pend, MB_ALIGN) + (MB_ALIGN); ++ *mend_out = *mstart_out + total_len; ++ ++ if ( *mend_out > vend ) ++ return -1; ++ ++ if ( args->acpi_module.length != 0 ) ++ args->acpi_module.guest_addr_out = *mstart_out; ++ if ( args->smbios_module.length != 0 ) ++ args->smbios_module.guest_addr_out = *mstart_out + offset1; ++ ++ return 0; ++} ++ + static void build_hvm_info(void *hvm_info_page, uint64_t mem_size, + uint64_t mmio_start, uint64_t mmio_size) + { +@@ -86,9 +120,8 @@ static void build_hvm_info(void *hvm_inf + hvm_info->checksum = -sum; + } + +-static int loadelfimage( +- xc_interface *xch, +- struct elf_binary *elf, uint32_t dom, unsigned long *parray) ++static int loadelfimage(xc_interface *xch, struct elf_binary *elf, ++ uint32_t dom, unsigned long *parray) + { + privcmd_mmap_entry_t *entries = NULL; + unsigned long pfn_start = elf->pstart >> PAGE_SHIFT; +@@ -126,6 +159,66 @@ static int loadelfimage( + return rc; + } + ++static int loadmodules(xc_interface *xch, ++ struct xc_hvm_build_args *args, ++ uint64_t mstart, uint64_t mend, ++ uint32_t dom, unsigned long *parray) ++{ ++ privcmd_mmap_entry_t *entries = NULL; ++ unsigned long pfn_start; ++ unsigned long pfn_end; ++ size_t pages; ++ uint32_t i; ++ uint8_t *dest; ++ int rc = -1; ++ ++ if ( (mstart == 0)||(mend == 0) ) ++ return 0; ++ ++ pfn_start = (unsigned long)(mstart >> PAGE_SHIFT); ++ pfn_end = (unsigned long)((mend + PAGE_SIZE - 1) >> PAGE_SHIFT); ++ pages = pfn_end - pfn_start; ++ ++ /* Map address space for module list. */ ++ entries = calloc(pages, sizeof(privcmd_mmap_entry_t)); ++ if ( entries == NULL ) ++ goto error_out; ++ ++ for ( i = 0; i < pages; i++ ) ++ entries[i].mfn = parray[(mstart >> PAGE_SHIFT) + i]; ++ ++ dest = xc_map_foreign_ranges( ++ xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT, ++ entries, pages); ++ if ( dest == NULL ) ++ goto error_out; ++ ++ /* Zero the range so padding is clear between modules */ ++ memset(dest, 0, pages << PAGE_SHIFT); ++ ++ /* Load modules into range */ ++ if ( args->acpi_module.length != 0 ) ++ { ++ memcpy(dest, ++ args->acpi_module.data, ++ args->acpi_module.length); ++ } ++ if ( args->smbios_module.length != 0 ) ++ { ++ memcpy(dest + (args->smbios_module.guest_addr_out - mstart), ++ args->smbios_module.data, ++ args->smbios_module.length); ++ } ++ ++ munmap(dest, pages << PAGE_SHIFT); ++ rc = 0; ++ ++ error_out: ++ free(entries); ++ ++ return rc; ++} ++ + /* + * Check whether there exists mmio hole in the specified memory range. + * Returns 1 if exists, else returns 0. +@@ -140,7 +233,7 @@ static int check_mmio_hole(uint64_t star + } + + static int setup_guest(xc_interface *xch, +- uint32_t dom, const struct xc_hvm_build_args *args, ++ uint32_t dom, struct xc_hvm_build_args *args, + char *image, unsigned long image_size) + { + xen_pfn_t *page_array = NULL; +@@ -153,6 +246,7 @@ static int setup_guest(xc_interface *xch + uint32_t *ident_pt; + struct elf_binary elf; + uint64_t v_start, v_end; ++ uint64_t m_start = 0, m_end = 0; + int rc; + xen_capabilities_info_t caps; + unsigned long stat_normal_pages = 0, stat_2mb_pages = 0, +@@ -178,11 +272,19 @@ static int setup_guest(xc_interface *xch + goto error_out; + } + ++ if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 ) ++ { ++ ERROR("Insufficient space to load modules."); ++ goto error_out; ++ } ++ + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" + " Loader: %016"PRIx64"->%016"PRIx64"\n" ++ " Modules: %016"PRIx64"->%016"PRIx64"\n" + " TOTAL: %016"PRIx64"->%016"PRIx64"\n" + " ENTRY ADDRESS: %016"PRIx64"\n", + elf.pstart, elf.pend, ++ m_start, m_end, + v_start, v_end, + elf_uval(&elf, elf.ehdr, e_entry)); + +@@ -337,6 +439,9 @@ static int setup_guest(xc_interface *xch + if ( loadelfimage(xch, &elf, dom, page_array) != 0 ) + goto error_out; + ++ if ( loadmodules(xch, args, m_start, m_end, dom, page_array) != 0 ) ++ goto error_out; ++ + if ( (hvm_info_page = xc_map_foreign_range( + xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, + HVM_INFO_PFN)) == NULL ) +@@ -413,7 +518,7 @@ static int setup_guest(xc_interface *xch + * Create a domain for a virtualized Linux, using files/filenames. + */ + int xc_hvm_build(xc_interface *xch, uint32_t domid, +- const struct xc_hvm_build_args *hvm_args) ++ struct xc_hvm_build_args *hvm_args) + { + struct xc_hvm_build_args args = *hvm_args; + void *image; +@@ -441,6 +546,15 @@ int xc_hvm_build(xc_interface *xch, uint + + sts = setup_guest(xch, domid, &args, image, image_size); + ++ if (!sts) ++ { ++ /* Return module load addresses to caller */ ++ hvm_args->acpi_module.guest_addr_out = ++ args.acpi_module.guest_addr_out; ++ hvm_args->smbios_module.guest_addr_out = ++ args.smbios_module.guest_addr_out; ++ } ++ + free(image); + + return sts; +@@ -461,6 +575,7 @@ int xc_hvm_build_target_mem(xc_interface + { + struct xc_hvm_build_args args = {}; + ++ memset(&args, 0, sizeof(struct xc_hvm_build_args)); + args.mem_size = (uint64_t)memsize << 20; + args.mem_target = (uint64_t)target << 20; + args.image_file_name = image_name; +diff -r 07bf59a7ce83 -r cabf395a6c84 tools/libxc/xenguest.h +--- a/tools/libxc/xenguest.h Thu Jan 10 17:16:28 2013 +0000 ++++ b/tools/libxc/xenguest.h Thu Jan 10 17:17:21 2013 +0000 +@@ -211,11 +211,23 @@ int xc_linux_build_mem(xc_interface *xch + unsigned int console_evtchn, + unsigned long *console_mfn); + ++struct xc_hvm_firmware_module { ++ uint8_t *data; ++ uint32_t length; ++ uint64_t guest_addr_out; ++}; ++ + struct xc_hvm_build_args { + uint64_t mem_size; /* Memory size in bytes. */ + uint64_t mem_target; /* Memory target in bytes. */ + uint64_t mmio_size; /* Size of the MMIO hole in bytes. */ + const char *image_file_name; /* File name of the image to load. */ ++ ++ /* Extra ACPI tables passed to HVMLOADER */ ++ struct xc_hvm_firmware_module acpi_module; ++ ++ /* Extra SMBIOS structures passed to HVMLOADER */ ++ struct xc_hvm_firmware_module smbios_module; + }; + + /** +@@ -228,7 +240,7 @@ struct xc_hvm_build_args { + * are optional. + */ + int xc_hvm_build(xc_interface *xch, uint32_t domid, +- const struct xc_hvm_build_args *hvm_args); ++ struct xc_hvm_build_args *hvm_args); + + int xc_hvm_build_target_mem(xc_interface *xch, + uint32_t domid, +diff -r 07bf59a7ce83 -r cabf395a6c84 tools/libxc/xg_private.c +--- a/tools/libxc/xg_private.c Thu Jan 10 17:16:28 2013 +0000 ++++ b/tools/libxc/xg_private.c Thu Jan 10 17:17:21 2013 +0000 +@@ -192,7 +192,7 @@ unsigned long csum_page(void *page) + __attribute__((weak)) + int xc_hvm_build(xc_interface *xch, + uint32_t domid, +- const struct xc_hvm_build_args *hvm_args) ++ struct xc_hvm_build_args *hvm_args) + { + errno = ENOSYS; + return -1; diff --git a/26343-hvm-firmware-passthrough.patch b/26343-hvm-firmware-passthrough.patch new file mode 100644 index 0000000..c3001cd --- /dev/null +++ b/26343-hvm-firmware-passthrough.patch @@ -0,0 +1,645 @@ +fate#313584: pass bios information to XEN HVM guest + +# HG changeset patch +# User Ross Philipson +# Date 1357838290 0 +# Node ID a7ce196f40444fafbe8f13b2d80e4885d4321806 +# Parent cabf395a6c849cc65e56f1640b18db0c3e0faf5d +HVM firmware passthrough SMBIOS processing + +Passthrough support for the SMBIOS structures including three new DMTF +defined types and support for OEM defined tables. Passed in SMBIOS +types override the default internal values. Default values can be +enabled for the new type 22 portable battery using a xenstore +flag. All other new DMTF defined and OEM structures will only be added +to the SMBIOS table if passthrough values are present. + +Signed-off-by: Ross Philipson +Committed-by: Keir Fraser + +diff -r cabf395a6c84 -r a7ce196f4044 tools/firmware/hvmloader/smbios.c +--- a/tools/firmware/hvmloader/smbios.c Thu Jan 10 17:17:21 2013 +0000 ++++ b/tools/firmware/hvmloader/smbios.c Thu Jan 10 17:18:10 2013 +0000 +@@ -26,16 +26,38 @@ + #include "smbios_types.h" + #include "util.h" + #include "hypercall.h" ++#include + ++/* SBMIOS handle base values */ ++#define SMBIOS_HANDLE_TYPE0 0x0000 ++#define SMBIOS_HANDLE_TYPE1 0x0100 ++#define SMBIOS_HANDLE_TYPE2 0x0200 ++#define SMBIOS_HANDLE_TYPE3 0x0300 ++#define SMBIOS_HANDLE_TYPE4 0x0400 ++#define SMBIOS_HANDLE_TYPE11 0x0B00 ++#define SMBIOS_HANDLE_TYPE16 0x1000 ++#define SMBIOS_HANDLE_TYPE17 0x1100 ++#define SMBIOS_HANDLE_TYPE19 0x1300 ++#define SMBIOS_HANDLE_TYPE20 0x1400 ++#define SMBIOS_HANDLE_TYPE22 0x1600 ++#define SMBIOS_HANDLE_TYPE32 0x2000 ++#define SMBIOS_HANDLE_TYPE39 0x2700 ++#define SMBIOS_HANDLE_TYPE127 0x7f00 ++ ++static void ++smbios_pt_init(void); ++static void* ++get_smbios_pt_struct(uint8_t type, uint32_t *length_out); ++static void ++get_cpu_manufacturer(char *buf, int len); + static int + write_smbios_tables(void *ep, void *start, + uint32_t vcpus, uint64_t memsize, + uint8_t uuid[16], char *xen_version, + uint32_t xen_major_version, uint32_t xen_minor_version, + unsigned *nr_structs, unsigned *max_struct_size); +- +-static void +-get_cpu_manufacturer(char *buf, int len); ++static uint64_t ++get_memsize(void); + static void + smbios_entry_point_init(void *start, + uint16_t max_structure_size, +@@ -49,6 +71,8 @@ static void * + smbios_type_1_init(void *start, const char *xen_version, + uint8_t uuid[16]); + static void * ++smbios_type_2_init(void *start); ++static void * + smbios_type_3_init(void *start); + static void * + smbios_type_4_init(void *start, unsigned int cpu_number, +@@ -64,10 +88,73 @@ smbios_type_19_init(void *start, uint32_ + static void * + smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance); + static void * ++smbios_type_22_init(void *start); ++static void * + smbios_type_32_init(void *start); + static void * ++smbios_type_39_init(void *start); ++static void * ++smbios_type_vendor_oem_init(void *start); ++static void * + smbios_type_127_init(void *start); + ++static uint32_t *smbios_pt_addr = NULL; ++static uint32_t smbios_pt_length = 0; ++ ++static void ++smbios_pt_init(void) ++{ ++ const char *s; ++ ++ s = xenstore_read(HVM_XS_SMBIOS_PT_ADDRESS, NULL); ++ if ( s == NULL ) ++ goto reset; ++ ++ smbios_pt_addr = (uint32_t*)(uint32_t)strtoll(s, NULL, 0); ++ if ( smbios_pt_addr == NULL ) ++ goto reset; ++ ++ s = xenstore_read(HVM_XS_SMBIOS_PT_LENGTH, NULL); ++ if ( s == NULL ) ++ goto reset; ++ ++ smbios_pt_length = (uint32_t)strtoll(s, NULL, 0); ++ if ( smbios_pt_length == 0 ) ++ goto reset; ++ ++ return; ++ ++reset: ++ smbios_pt_addr = NULL; ++ smbios_pt_length = 0; ++} ++ ++static void* ++get_smbios_pt_struct(uint8_t type, uint32_t *length_out) ++{ ++ uint32_t *sep = smbios_pt_addr; ++ uint32_t total = 0; ++ uint8_t *ptr; ++ ++ if ( sep == NULL ) ++ return NULL; ++ ++ while ( total < smbios_pt_length ) ++ { ++ ptr = (uint8_t*)(sep + 1); ++ if ( ptr[0] == type ) ++ { ++ *length_out = *sep; ++ return ptr; ++ } ++ ++ total += (*sep + sizeof(uint32_t)); ++ sep = (uint32_t*)(ptr + *sep); ++ } ++ ++ return NULL; ++} ++ + static void + get_cpu_manufacturer(char *buf, int len) + { +@@ -97,6 +184,8 @@ write_smbios_tables(void *ep, void *star + char cpu_manufacturer[15]; + int i, nr_mem_devs; + ++ smbios_pt_init(); ++ + get_cpu_manufacturer(cpu_manufacturer, 15); + + p = (char *)start; +@@ -112,6 +201,7 @@ write_smbios_tables(void *ep, void *star + do_struct(smbios_type_0_init(p, xen_version, xen_major_version, + xen_minor_version)); + do_struct(smbios_type_1_init(p, xen_version, uuid)); ++ do_struct(smbios_type_2_init(p)); + do_struct(smbios_type_3_init(p)); + for ( cpu_num = 1; cpu_num <= vcpus; cpu_num++ ) + do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer)); +@@ -130,7 +220,10 @@ write_smbios_tables(void *ep, void *star + do_struct(smbios_type_20_init(p, dev_memsize, i)); + } + ++ do_struct(smbios_type_22_init(p)); + do_struct(smbios_type_32_init(p)); ++ do_struct(smbios_type_39_init(p)); ++ do_struct(smbios_type_vendor_oem_init(p)); + do_struct(smbios_type_127_init(p)); + + #undef do_struct +@@ -289,12 +382,22 @@ smbios_type_0_init(void *start, const ch + struct smbios_type_0 *p = (struct smbios_type_0 *)start; + static const char *smbios_release_date = __SMBIOS_DATE__; + const char *s; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(0, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE0; ++ return (start + length); ++ } + + memset(p, 0, sizeof(*p)); + + p->header.type = 0; + p->header.length = sizeof(struct smbios_type_0); +- p->header.handle = 0; ++ p->header.handle = SMBIOS_HANDLE_TYPE0; + + p->vendor_str = 1; + p->version_str = 2; +@@ -315,11 +418,11 @@ smbios_type_0_init(void *start, const ch + p->embedded_controller_minor = 0xff; + + start += sizeof(struct smbios_type_0); +- s = xenstore_read("bios-strings/bios-vendor", "Xen"); ++ s = xenstore_read(HVM_XS_BIOS_VENDOR, "Xen"); + strcpy((char *)start, s); + start += strlen(s) + 1; + +- s = xenstore_read("bios-strings/bios-version", xen_version); ++ s = xenstore_read(HVM_XS_BIOS_VERSION, xen_version); + strcpy((char *)start, s); + start += strlen(s) + 1; + +@@ -338,12 +441,22 @@ smbios_type_1_init(void *start, const ch + char uuid_str[37]; + struct smbios_type_1 *p = (struct smbios_type_1 *)start; + const char *s; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(1, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE1; ++ return (start + length); ++ } + + memset(p, 0, sizeof(*p)); + + p->header.type = 1; + p->header.length = sizeof(struct smbios_type_1); +- p->header.handle = 0x100; ++ p->header.handle = SMBIOS_HANDLE_TYPE1; + + p->manufacturer_str = 1; + p->product_name_str = 2; +@@ -358,20 +471,20 @@ smbios_type_1_init(void *start, const ch + + start += sizeof(struct smbios_type_1); + +- s = xenstore_read("bios-strings/system-manufacturer", "Xen"); ++ s = xenstore_read(HVM_XS_SYSTEM_MANUFACTURER, "Xen"); + strcpy((char *)start, s); + start += strlen(s) + 1; + +- s = xenstore_read("bios-strings/system-product-name", "HVM domU"); ++ s = xenstore_read(HVM_XS_SYSTEM_PRODUCT_NAME, "HVM domU"); + strcpy((char *)start, s); + start += strlen(s) + 1; + +- s = xenstore_read("bios-strings/system-version", xen_version); ++ s = xenstore_read(HVM_XS_SYSTEM_VERSION, xen_version); + strcpy((char *)start, s); + start += strlen(s) + 1; + + uuid_to_string(uuid_str, uuid); +- s = xenstore_read("bios-strings/system-serial-number", uuid_str); ++ s = xenstore_read(HVM_XS_SYSTEM_SERIAL_NUMBER, uuid_str); + strcpy((char *)start, s); + start += strlen(s) + 1; + +@@ -380,17 +493,58 @@ smbios_type_1_init(void *start, const ch + return start+1; + } + ++/* Type 2 -- System Board */ ++static void * ++smbios_type_2_init(void *start) ++{ ++ struct smbios_type_2 *p = (struct smbios_type_2 *)start; ++ uint8_t *ptr; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(2, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE2; ++ ++ /* Set current chassis handle if present */ ++ if ( p->header.length > 13 ) ++ { ++ ptr = ((uint8_t*)start) + 11; ++ if ( *((uint16_t*)ptr) != 0 ) ++ *((uint16_t*)ptr) = SMBIOS_HANDLE_TYPE3; ++ } ++ ++ return (start + length); ++ } ++ ++ /* Only present when passed in */ ++ return start; ++} ++ + /* Type 3 -- System Enclosure */ + static void * + smbios_type_3_init(void *start) + { + struct smbios_type_3 *p = (struct smbios_type_3 *)start; ++ const char *s; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(3, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE3; ++ return (start + length); ++ } + + memset(p, 0, sizeof(*p)); + + p->header.type = 3; + p->header.length = sizeof(struct smbios_type_3); +- p->header.handle = 0x300; ++ p->header.handle = SMBIOS_HANDLE_TYPE3; + + p->manufacturer_str = 1; + p->type = 0x01; /* other */ +@@ -404,8 +558,19 @@ smbios_type_3_init(void *start) + + start += sizeof(struct smbios_type_3); + +- strcpy((char *)start, "Xen"); +- start += strlen("Xen") + 1; ++ s = xenstore_read(HVM_XS_ENCLOSURE_MANUFACTURER, "Xen"); ++ strcpy((char *)start, s); ++ start += strlen(s) + 1; ++ ++ /* No internal defaults for this if the value is not set */ ++ s = xenstore_read(HVM_XS_ENCLOSURE_SERIAL_NUMBER, NULL); ++ if ( (s != NULL)&&(*s != '\0') ) ++ { ++ strcpy((char *)start, s); ++ start += strlen(s) + 1; ++ p->serial_number_str = 2; ++ } ++ + *((uint8_t *)start) = 0; + return start+1; + } +@@ -423,7 +588,7 @@ smbios_type_4_init( + + p->header.type = 4; + p->header.length = sizeof(struct smbios_type_4); +- p->header.handle = 0x400 + cpu_number; ++ p->header.handle = SMBIOS_HANDLE_TYPE4 + cpu_number; + + p->socket_designation_str = 1; + p->processor_type = 0x03; /* CPU */ +@@ -465,13 +630,23 @@ static void * + smbios_type_11_init(void *start) + { + struct smbios_type_11 *p = (struct smbios_type_11 *)start; +- char path[20] = "bios-strings/oem-XX"; ++ char path[20]; + const char *s; + int i; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(11, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE11; ++ return (start + length); ++ } + + p->header.type = 11; + p->header.length = sizeof(struct smbios_type_11); +- p->header.handle = 0xB00; ++ p->header.handle = SMBIOS_HANDLE_TYPE11; + + p->count = 0; + +@@ -480,8 +655,7 @@ smbios_type_11_init(void *start) + /* Pull out as many oem-* strings we find in xenstore */ + for ( i = 1; i < 100; i++ ) + { +- path[(sizeof path) - 3] = '0' + ((i < 10) ? i : i / 10); +- path[(sizeof path) - 2] = (i < 10) ? '\0' : '0' + (i % 10); ++ snprintf(path, sizeof(path), HVM_XS_OEM_STRINGS, i); + if ( ((s = xenstore_read(path, NULL)) == NULL) || (*s == '\0') ) + break; + strcpy((char *)start, s); +@@ -510,7 +684,7 @@ smbios_type_16_init(void *start, uint32_ + memset(p, 0, sizeof(*p)); + + p->header.type = 16; +- p->header.handle = 0x1000; ++ p->header.handle = SMBIOS_HANDLE_TYPE16; + p->header.length = sizeof(struct smbios_type_16); + + p->location = 0x01; /* other */ +@@ -536,7 +710,7 @@ smbios_type_17_init(void *start, uint32_ + + p->header.type = 17; + p->header.length = sizeof(struct smbios_type_17); +- p->header.handle = 0x1100 + instance; ++ p->header.handle = SMBIOS_HANDLE_TYPE17 + instance; + + p->physical_memory_array_handle = 0x1000; + p->total_width = 64; +@@ -571,7 +745,7 @@ smbios_type_19_init(void *start, uint32_ + + p->header.type = 19; + p->header.length = sizeof(struct smbios_type_19); +- p->header.handle = 0x1300 + instance; ++ p->header.handle = SMBIOS_HANDLE_TYPE19 + instance; + + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; +@@ -593,7 +767,7 @@ smbios_type_20_init(void *start, uint32_ + + p->header.type = 20; + p->header.length = sizeof(struct smbios_type_20); +- p->header.handle = 0x1400 + instance; ++ p->header.handle = SMBIOS_HANDLE_TYPE20 + instance; + + p->starting_address = instance << 24; + p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; +@@ -609,6 +783,71 @@ smbios_type_20_init(void *start, uint32_ + return start+2; + } + ++/* Type 22 -- Portable Battery */ ++static void * ++smbios_type_22_init(void *start) ++{ ++ struct smbios_type_22 *p = (struct smbios_type_22 *)start; ++ static const char *smbios_release_date = __SMBIOS_DATE__; ++ const char *s; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(22, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE22; ++ return (start + length); ++ } ++ ++ s = xenstore_read(HVM_XS_SMBIOS_DEFAULT_BATTERY, "0"); ++ if ( strncmp(s, "1", 1) != 0 ) ++ return start; ++ ++ memset(p, 0, sizeof(*p)); ++ ++ p->header.type = 22; ++ p->header.length = sizeof(struct smbios_type_22); ++ p->header.handle = SMBIOS_HANDLE_TYPE22; ++ ++ p->location_str = 1; ++ p->manufacturer_str = 2; ++ p->manufacturer_date_str = 3; ++ p->serial_number_str = 0; ++ p->device_name_str = 4; ++ p->device_chemistry = 0x2; /* unknown */ ++ p->device_capacity = 0; /* unknown */ ++ p->device_voltage = 0; /* unknown */ ++ p->sbds_version_number = 0; ++ p->max_error = 0xff; /* unknown */ ++ p->sbds_serial_number = 0; ++ p->sbds_manufacturer_date = 0; ++ p->sbds_device_chemistry = 0; ++ p->design_capacity_multiplier = 0; ++ p->oem_specific = 0; ++ ++ start += sizeof(struct smbios_type_22); ++ ++ strcpy((char *)start, "Primary"); ++ start += strlen("Primary") + 1; ++ ++ s = xenstore_read(HVM_XS_BATTERY_MANUFACTURER, "Xen"); ++ strcpy((char *)start, s); ++ start += strlen(s) + 1; ++ ++ strcpy((char *)start, smbios_release_date); ++ start += strlen(smbios_release_date) + 1; ++ ++ s = xenstore_read(HVM_XS_BATTERY_DEVICE_NAME, "XEN-VBAT"); ++ strcpy((char *)start, s); ++ start += strlen(s) + 1; ++ ++ *((uint8_t *)start) = 0; ++ ++ return start+1; ++} ++ + /* Type 32 -- System Boot Information */ + static void * + smbios_type_32_init(void *start) +@@ -619,7 +858,7 @@ smbios_type_32_init(void *start) + + p->header.type = 32; + p->header.length = sizeof(struct smbios_type_32); +- p->header.handle = 0x2000; ++ p->header.handle = SMBIOS_HANDLE_TYPE32; + memset(p->reserved, 0, 6); + p->boot_status = 0; /* no errors detected */ + +@@ -628,6 +867,58 @@ smbios_type_32_init(void *start) + return start+2; + } + ++/* Type 39 -- Power Supply */ ++static void * ++smbios_type_39_init(void *start) ++{ ++ struct smbios_type_39 *p = (struct smbios_type_39 *)start; ++ void *pts; ++ uint32_t length; ++ ++ pts = get_smbios_pt_struct(39, &length); ++ if ( (pts != NULL)&&(length > 0) ) ++ { ++ memcpy(start, pts, length); ++ p->header.handle = SMBIOS_HANDLE_TYPE39; ++ return (start + length); ++ } ++ ++ /* Only present when passed in */ ++ return start; ++} ++ ++static void * ++smbios_type_vendor_oem_init(void *start) ++{ ++ uint32_t *sep = smbios_pt_addr; ++ uint32_t total = 0; ++ uint8_t *ptr; ++ ++ if ( sep == NULL ) ++ return start; ++ ++ while ( total < smbios_pt_length ) ++ { ++ ptr = (uint8_t*)(sep + 1); ++ if ( ptr[0] >= 128 ) ++ { ++ /* Vendor/OEM table, copy it in. Note the handle values cannot ++ * be changed since it is unknown what is in each of these tables ++ * but they could contain handle references to other tables. This ++ * means a slight risk of collision with the tables above but that ++ * would have to be dealt with on a case by case basis. ++ */ ++ memcpy(start, ptr, *sep); ++ start += *sep; ++ } ++ ++ total += (*sep + sizeof(uint32_t)); ++ sep = (uint32_t*)(ptr + *sep); ++ } ++ ++ return start; ++} ++ + /* Type 127 -- End of Table */ + static void * + smbios_type_127_init(void *start) +@@ -638,7 +929,7 @@ smbios_type_127_init(void *start) + + p->header.type = 127; + p->header.length = sizeof(struct smbios_type_127); +- p->header.handle = 0x7f00; ++ p->header.handle = SMBIOS_HANDLE_TYPE127; + + start += sizeof(struct smbios_type_127); + *((uint16_t *)start) = 0; +diff -r cabf395a6c84 -r a7ce196f4044 tools/firmware/hvmloader/smbios_types.h +--- a/tools/firmware/hvmloader/smbios_types.h Thu Jan 10 17:17:21 2013 +0000 ++++ b/tools/firmware/hvmloader/smbios_types.h Thu Jan 10 17:18:10 2013 +0000 +@@ -84,6 +84,15 @@ struct smbios_type_1 { + uint8_t family_str; + } __attribute__ ((packed)); + ++/* SMBIOS type 2 - Base Board Information */ ++struct smbios_type_2 { ++ struct smbios_structure_header header; ++ uint8_t manufacturer_str; ++ uint8_t product_name_str; ++ uint8_t version_str; ++ uint8_t serial_number_str; ++} __attribute__ ((packed)); ++ + /* SMBIOS type 3 - System Enclosure */ + struct smbios_type_3 { + struct smbios_structure_header header; +@@ -173,6 +182,26 @@ struct smbios_type_20 { + uint8_t interleaved_data_depth; + } __attribute__ ((packed)); + ++/* SMBIOS type 22 - Portable battery */ ++struct smbios_type_22 { ++ struct smbios_structure_header header; ++ uint8_t location_str; ++ uint8_t manufacturer_str; ++ uint8_t manufacturer_date_str; ++ uint8_t serial_number_str; ++ uint8_t device_name_str; ++ uint8_t device_chemistry; ++ uint16_t device_capacity; ++ uint16_t device_voltage; ++ uint8_t sbds_version_number; ++ uint8_t max_error; ++ uint16_t sbds_serial_number; ++ uint16_t sbds_manufacturer_date; ++ uint8_t sbds_device_chemistry; ++ uint8_t design_capacity_multiplier; ++ uint32_t oem_specific; ++} __attribute__ ((packed)); ++ + /* SMBIOS type 32 - System Boot Information */ + struct smbios_type_32 { + struct smbios_structure_header header; +@@ -180,6 +209,24 @@ struct smbios_type_32 { + uint8_t boot_status; + } __attribute__ ((packed)); + ++/* SMBIOS type 39 - Power Supply */ ++struct smbios_type_39 { ++ struct smbios_structure_header header; ++ uint8_t power_unit_group; ++ uint8_t location_str; ++ uint8_t device_name_str; ++ uint8_t manufacturer_str; ++ uint8_t serial_number_str; ++ uint8_t asset_tag_number_str; ++ uint8_t model_part_number_str; ++ uint8_t revision_level_str; ++ uint16_t max_capacity; ++ uint16_t characteristics; ++ uint16_t input_voltage_probe_handle; ++ uint16_t cooling_device_handle; ++ uint16_t input_current_probe_handle; ++} __attribute__ ((packed)); ++ + /* SMBIOS type 127 -- End-of-table */ + struct smbios_type_127 { + struct smbios_structure_header header; diff --git a/26344-hvm-firmware-passthrough.patch b/26344-hvm-firmware-passthrough.patch new file mode 100644 index 0000000..e4c8a5b --- /dev/null +++ b/26344-hvm-firmware-passthrough.patch @@ -0,0 +1,101 @@ +fate#313584: pass bios information to XEN HVM guest + +# HG changeset patch +# User Ross Philipson +# Date 1357838323 0 +# Node ID b9c38bea15b117552ecb51809779c7cfef82dd44 +# Parent a7ce196f40444fafbe8f13b2d80e4885d4321806 +HVM firmware passthrough ACPI processing + +ACPI table passthrough support allowing additional static tables and +SSDTs (AML code) to be loaded. These additional tables are added at +the end of the secondary table list in the RSDT/XSDT tables. + +Signed-off-by: Ross Philipson +Committed-by: Keir Fraser + +diff -r a7ce196f4044 -r b9c38bea15b1 tools/firmware/hvmloader/acpi/build.c +--- a/tools/firmware/hvmloader/acpi/build.c Thu Jan 10 17:18:10 2013 +0000 ++++ b/tools/firmware/hvmloader/acpi/build.c Thu Jan 10 17:18:43 2013 +0000 +@@ -23,6 +23,9 @@ + #include "ssdt_pm.h" + #include "../config.h" + #include "../util.h" ++#include ++ ++#define ACPI_MAX_SECONDARY_TABLES 16 + + #define align16(sz) (((sz) + 15) & ~15) + #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d)) +@@ -198,6 +201,52 @@ static struct acpi_20_waet *construct_wa + return waet; + } + ++static int construct_passthrough_tables(unsigned long *table_ptrs, ++ int nr_tables) ++{ ++ const char *s; ++ uint8_t *acpi_pt_addr; ++ uint32_t acpi_pt_length; ++ struct acpi_header *header; ++ int nr_added; ++ int nr_max = (ACPI_MAX_SECONDARY_TABLES - nr_tables - 1); ++ uint32_t total = 0; ++ uint8_t *buffer; ++ ++ s = xenstore_read(HVM_XS_ACPI_PT_ADDRESS, NULL); ++ if ( s == NULL ) ++ return 0; ++ ++ acpi_pt_addr = (uint8_t*)(uint32_t)strtoll(s, NULL, 0); ++ if ( acpi_pt_addr == NULL ) ++ return 0; ++ ++ s = xenstore_read(HVM_XS_ACPI_PT_LENGTH, NULL); ++ if ( s == NULL ) ++ return 0; ++ ++ acpi_pt_length = (uint32_t)strtoll(s, NULL, 0); ++ ++ for ( nr_added = 0; nr_added < nr_max; nr_added++ ) ++ { ++ if ( (acpi_pt_length - total) < sizeof(struct acpi_header) ) ++ break; ++ ++ header = (struct acpi_header*)acpi_pt_addr; ++ ++ buffer = mem_alloc(header->length, 16); ++ if ( buffer == NULL ) ++ break; ++ memcpy(buffer, header, header->length); ++ ++ table_ptrs[nr_tables++] = (unsigned long)buffer; ++ total += header->length; ++ acpi_pt_addr += header->length; ++ } ++ ++ return nr_added; ++} ++ + static int construct_secondary_tables(unsigned long *table_ptrs, + struct acpi_info *info) + { +@@ -293,6 +342,9 @@ static int construct_secondary_tables(un + } + } + ++ /* Load any additional tables passed through. */ ++ nr_tables += construct_passthrough_tables(table_ptrs, nr_tables); ++ + table_ptrs[nr_tables] = 0; + return nr_tables; + } +@@ -327,7 +379,7 @@ void acpi_build_tables(struct acpi_confi + struct acpi_10_fadt *fadt_10; + struct acpi_20_facs *facs; + unsigned char *dsdt; +- unsigned long secondary_tables[16]; ++ unsigned long secondary_tables[ACPI_MAX_SECONDARY_TABLES]; + int nr_secondaries, i; + unsigned long vm_gid_addr; + diff --git a/CVE-2012-6075-xsa41.patch b/CVE-2012-6075-xsa41.patch new file mode 100644 index 0000000..389b76b --- /dev/null +++ b/CVE-2012-6075-xsa41.patch @@ -0,0 +1,88 @@ +Subject: e1000: Discard packets that are too long if !SBP and !LPE +From: Michael Contreras michael@inetric.com Sun Dec 2 20:11:22 2012 -0800 +Date: Wed Jan 16 14:12:40 2013 +0000: +Git: b4e9b8169dedc0bcf0d3abe07642f761ac70aeea + +The e1000_receive function for the e1000 needs to discard packets longer than +1522 bytes if the SBP and LPE flags are disabled. The linux driver assumes +this behavior and allocates memory based on this assumption. + +Signed-off-by: Michael Contreras +Signed-off-by: Anthony Liguori + +Subject: e1000: Discard oversized packets based on SBP|LPE +From: Michael Contreras +Date: Wed, 5 Dec 2012 18:31:30 +0000 (-0500) + +e1000: Discard oversized packets based on SBP|LPE + +Discard packets longer than 16384 when !SBP to match the hardware behavior. + +Signed-off-by: Michael Contreras +Signed-off-by: Stefan Hajnoczi + +[ This is a security vulnerability, CVE-2012-6075 / XSA-41. ] +(cherry picked from commit 4c2cae2a882db4d2a231b27b3b31a5bbec6dacbf) + +Index: xen-4.2.1-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c +=================================================================== +--- xen-4.2.1-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/e1000.c ++++ xen-4.2.1-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c +@@ -55,6 +55,11 @@ static int debugflags = DBGBIT(TXERR) | + #define REG_IOADDR 0x0 + #define REG_IODATA 0x4 + ++/* this is the size past which hardware will drop packets when setting LPE=0 */ ++#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 ++/* this is the size past which hardware will drop packets when setting LPE=1 */ ++#define MAXIMUM_ETHERNET_LPE_SIZE 16384 ++ + /* + * HW models: + * E1000_DEV_ID_82540EM works with Windows and Linux +@@ -628,6 +633,14 @@ e1000_receive(void *opaque, const uint8_ + return; + } + ++ /* Discard oversized packets if !LPE and !SBP. */ ++ if ((size > MAXIMUM_ETHERNET_LPE_SIZE || ++ (size > MAXIMUM_ETHERNET_VLAN_SIZE ++ && !(s->mac_reg[RCTL] & E1000_RCTL_LPE))) ++ && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) { ++ return; ++ } ++ + if (!receive_filter(s, buf, size)) + return; + +Index: xen-4.2.1-testing/tools/qemu-xen-dir-remote/hw/e1000.c +=================================================================== +--- xen-4.2.1-testing.orig/tools/qemu-xen-dir-remote/hw/e1000.c ++++ xen-4.2.1-testing/tools/qemu-xen-dir-remote/hw/e1000.c +@@ -59,6 +59,11 @@ static int debugflags = DBGBIT(TXERR) | + #define PNPMMIO_SIZE 0x20000 + #define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */ + ++/* this is the size past which hardware will drop packets when setting LPE=0 */ ++#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 ++/* this is the size past which hardware will drop packets when setting LPE=1 */ ++#define MAXIMUM_ETHERNET_LPE_SIZE 16384 ++ + /* + * HW models: + * E1000_DEV_ID_82540EM works with Windows and Linux +@@ -693,6 +698,14 @@ e1000_receive(VLANClientState *nc, const + size = sizeof(min_buf); + } + ++ /* Discard oversized packets if !LPE and !SBP. */ ++ if ((size > MAXIMUM_ETHERNET_LPE_SIZE || ++ (size > MAXIMUM_ETHERNET_VLAN_SIZE ++ && !(s->mac_reg[RCTL] & E1000_RCTL_LPE))) ++ && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) { ++ return size; ++ } ++ + if (!receive_filter(s, buf, size)) + return size; + diff --git a/CVE-2013-0151-xsa34.patch b/CVE-2013-0151-xsa34.patch new file mode 100644 index 0000000..e8fc8ff --- /dev/null +++ b/CVE-2013-0151-xsa34.patch @@ -0,0 +1,32 @@ +References: CVE-2013-0151 XSA-34 bnc#797285 + +x86_32: don't allow use of nested HVM + +There are (indirect) uses of map_domain_page() in the nested HVM code +that are unsafe when not just using the 1:1 mapping. + +This is XSA-34 / CVE-2013-0151. + +Signed-off-by: Jan Beulich + +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c +@@ -3930,6 +3930,10 @@ long do_hvm_op(unsigned long op, XEN_GUE + rc = -EINVAL; + break; + case HVM_PARAM_NESTEDHVM: ++#ifdef __i386__ ++ if ( a.value ) ++ rc = -EINVAL; ++#else + if ( a.value > 1 ) + rc = -EINVAL; + if ( !is_hvm_domain(d) ) +@@ -3944,6 +3948,7 @@ long do_hvm_op(unsigned long op, XEN_GUE + for_each_vcpu(d, v) + if ( rc == 0 ) + rc = nestedhvm_vcpu_initialise(v); ++#endif + break; + case HVM_PARAM_BUFIOREQ_EVTCHN: + rc = -EINVAL; diff --git a/CVE-2013-0152-xsa35.patch b/CVE-2013-0152-xsa35.patch new file mode 100644 index 0000000..743347f --- /dev/null +++ b/CVE-2013-0152-xsa35.patch @@ -0,0 +1,26 @@ +References: CVE-2013-0152 XSA-35 bnc#797287 + +xen: Do not allow guests to enable nested HVM on themselves + +There is no reason for this and doing so exposes a memory leak to +guests. Only toolstacks need write access to this HVM param. + +This is XSA-35 / CVE-2013-0152. + +Signed-off-by: Ian Campbell +Acked-by: Jan Beulich + +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c +@@ -3930,6 +3930,11 @@ long do_hvm_op(unsigned long op, XEN_GUE + rc = -EINVAL; + break; + case HVM_PARAM_NESTEDHVM: ++ if ( !IS_PRIV(current->domain) ) ++ { ++ rc = -EPERM; ++ break; ++ } + #ifdef __i386__ + if ( a.value ) + rc = -EINVAL; diff --git a/domUloader.py b/domUloader.py index 60fb82b..f8ea760 100644 --- a/domUloader.py +++ b/domUloader.py @@ -37,6 +37,7 @@ from stat import * from xen.xend import sxp import tempfile import time +import xnloader # Global options quiet = False @@ -447,6 +448,7 @@ def copyKernelAndRamdisk(disk, vdev, kernel, ramdisk): raise sxpr += "(ramdisk %s)" % inm part.umount() + xnloader.patch_netware_loader(knm) return sxpr def main(argv): diff --git a/pygrub-netware-xnloader.patch b/pygrub-netware-xnloader.patch new file mode 100644 index 0000000..4f89619 --- /dev/null +++ b/pygrub-netware-xnloader.patch @@ -0,0 +1,21 @@ +Index: xen-4.2.1-testing/tools/pygrub/src/pygrub +=================================================================== +--- xen-4.2.1-testing.orig/tools/pygrub/src/pygrub ++++ xen-4.2.1-testing/tools/pygrub/src/pygrub +@@ -26,6 +26,7 @@ import fsimage + import grub.GrubConf + import grub.LiloConf + import grub.ExtLinuxConf ++import xnloader + + PYGRUB_VER = 0.6 + FS_READ_MAX = 1024 * 1024 +@@ -734,6 +735,8 @@ if __name__ == "__main__": + if len(data) == 0: + os.close(tfd) + del datafile ++ if file_to_read == "/nwserver/xnloader.sys": ++ xnloader.patch_netware_loader(ret) + return ret + try: + os.write(tfd, data) diff --git a/reverse-24757-use-grant-references.patch b/reverse-24757-use-grant-references.patch deleted file mode 100644 index 96d000d..0000000 --- a/reverse-24757-use-grant-references.patch +++ /dev/null @@ -1,145 +0,0 @@ -Reverse c/s 24757. Breaks booting NetWare. - -# HG changeset patch -# User Alex Zeffertt -# Date 1328812412 0 -# Node ID aae516b78fce679f9c367231b7a3891814fcfdbb -# Parent 585caf50a9260d3fc6a4ece0450d10d34e73489f - -xenstored: use grant references instead of map_foreign_range - -make xenstored use grantref rather than map_foreign_range (which can -only be used by privileged domains) - -This patch modifies the xenstore daemon to use xc_gnttab_map_grant_ref -instead of xc_map_foreign_range where available. - -Previous versions of this patch have been sent to xen-devel. See -http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html -http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01492.html - -Signed-off-by: Diego Ongaro -Signed-off-by: Alex Zeffertt -Signed-off-by: Daniel De Graaf -Acked-by: Ian Campbell -Cc: Ian Jackson -Cc: Stefano Stabellini -Committed-by: Ian Jackson - -Index: xen-4.2.0-testing/tools/xenstore/xenstored_domain.c -=================================================================== ---- xen-4.2.0-testing.orig/tools/xenstore/xenstored_domain.c -+++ xen-4.2.0-testing/tools/xenstore/xenstored_domain.c -@@ -32,10 +32,8 @@ - #include "xenstored_watch.h" - - #include --#include - - static xc_interface **xc_handle; --xc_gnttab **xcg_handle; - static evtchn_port_t virq_port; - - xc_evtchn *xce_handle = NULL; -@@ -165,26 +163,6 @@ static int readchn(struct connection *co - return len; - } - --static void *map_interface(domid_t domid, unsigned long mfn) --{ -- if (*xcg_handle != NULL) { -- /* this is the preferred method */ -- return xc_gnttab_map_grant_ref(*xcg_handle, domid, -- GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); -- } else { -- return xc_map_foreign_range(*xc_handle, domid, -- getpagesize(), PROT_READ|PROT_WRITE, mfn); -- } --} -- --static void unmap_interface(void *interface) --{ -- if (*xcg_handle != NULL) -- xc_gnttab_munmap(*xcg_handle, interface, 1); -- else -- munmap(interface, getpagesize()); --} -- - static int destroy_domain(void *_domain) - { - struct domain *domain = _domain; -@@ -196,14 +174,8 @@ static int destroy_domain(void *_domain) - eprintf("> Unbinding port %i failed!\n", domain->port); - } - -- if (domain->interface) { -- /* Domain 0 was mapped by dom0_init, so it must be unmapped -- using munmap() and not the grant unmap call. */ -- if (domain->domid == 0) -- unmap_xenbus(domain->interface); -- else -- unmap_interface(domain->interface); -- } -+ if (domain->interface) -+ munmap(domain->interface, getpagesize()); - - fire_watches(NULL, "@releaseDomain", false); - -@@ -372,7 +344,9 @@ void do_introduce(struct connection *con - domain = find_domain_by_domid(domid); - - if (domain == NULL) { -- interface = map_interface(domid, mfn); -+ interface = xc_map_foreign_range( -+ *xc_handle, domid, -+ getpagesize(), PROT_READ|PROT_WRITE, mfn); - if (!interface) { - send_error(conn, errno); - return; -@@ -380,7 +354,7 @@ void do_introduce(struct connection *con - /* Hang domain off "in" until we're finished. */ - domain = new_domain(in, domid, port); - if (!domain) { -- unmap_interface(interface); -+ munmap(interface, getpagesize()); - send_error(conn, errno); - return; - } -@@ -572,18 +546,6 @@ void do_reset_watches(struct connection - send_ack(conn, XS_RESET_WATCHES); - } - --static int close_xc_handle(void *_handle) --{ -- xc_interface_close(*(xc_interface**)_handle); -- return 0; --} -- --static int close_xcg_handle(void *_handle) --{ -- xc_gnttab_close(*(xc_gnttab **)_handle); -- return 0; --} -- - /* Returns the implicit path of a connection (only domains have this) */ - const char *get_implicit_path(const struct connection *conn) - { -@@ -633,18 +595,6 @@ void domain_init(void) - if (!*xc_handle) - barf_perror("Failed to open connection to hypervisor"); - -- talloc_set_destructor(xc_handle, close_xc_handle); -- -- xcg_handle = talloc(talloc_autofree_context(), xc_gnttab*); -- if (!xcg_handle) -- barf_perror("Failed to allocate domain gnttab handle"); -- -- *xcg_handle = xc_gnttab_open(NULL, 0); -- if (*xcg_handle < 0) -- xprintf("WARNING: Failed to open connection to gnttab\n"); -- else -- talloc_set_destructor(xcg_handle, close_xcg_handle); -- - xce_handle = xc_evtchn_open(NULL, 0); - - if (xce_handle == NULL) diff --git a/x86-fpu-context-conditional.patch b/x86-fpu-context-conditional.patch new file mode 100644 index 0000000..2bbcca3 --- /dev/null +++ b/x86-fpu-context-conditional.patch @@ -0,0 +1,13 @@ +--- 2013-01-08.orig/xen/arch/x86/domain.c 2013-01-08 00:00:00.000000000 +0100 ++++ 2013-01-08/xen/arch/x86/domain.c 2013-01-15 15:46:17.000000000 +0100 +@@ -834,7 +834,9 @@ int arch_set_info_guest( + + v->arch.vgc_flags = flags; + +- memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt)); ++ if ( flags & VGCF_I387_VALID ) ++ memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt)); ++ + if ( !compat ) + { + memcpy(&v->arch.user_regs, &c.nat->user_regs, sizeof(c.nat->user_regs)); diff --git a/xen.changes b/xen.changes index 6731dba..da8dc8b 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,45 @@ +------------------------------------------------------------------- +Tue Jan 22 08:12:39 MST 2013 - carnold@novell.com + +- bnc#797285 - VUL-0: Xen: XSA-34 (CVE-2013-0151) - nested + virtualization on 32-bit exposes host crash + CVE-2013-0151-xsa34.patch +- bnc#797287 - VUL-0: Xen: XSA-35 (CVE-2013-0152) - Nested HVM + exposes host to being driven out of memory by guest + CVE-2013-0152-xsa35.patch + +------------------------------------------------------------------- +Thu Jan 17 14:13:52 MST 2013 - carnold@novell.com + +- bnc#793717 - NetWare will not boot on Xen 4.2 + xnloader.py + domUloader.py + pygrub-netware-xnloader.patch + Removed reverse-24757-use-grant-references.patch + +------------------------------------------------------------------- +Wed Jan 16 11:26:29 MST 2013 + +- bnc#797523 - VUL-1: CVE-2012-6075: qemu / kvm-qemu: e1000 + overflows under some conditions + CVE-2012-6075-xsa41.patch + +------------------------------------------------------------------- +Tue Jan 15 13:19:36 MST 2013 - carnold@novell.com + +- Mask the floating point exceptions for guests like NetWare on + machines that support XSAVE. + x86-fpu-context-conditional.patch + +------------------------------------------------------------------- +Mon Jan 14 12:01:33 MST 2013 - carnold@novell.com + +- fate##313584: pass bios information to XEN HVM guest + 26341-hvm-firmware-passthrough.patch + 26342-hvm-firmware-passthrough.patch + 26343-hvm-firmware-passthrough.patch + 26344-hvm-firmware-passthrough.patch + ------------------------------------------------------------------- Tue Jan 8 11:06:04 MST 2013 - carnold@novell.com diff --git a/xen.spec b/xen.spec index f7822c8..60602e2 100644 --- a/xen.spec +++ b/xen.spec @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - Name: xen ExclusiveArch: %ix86 x86_64 %define xvers 4.2 @@ -115,7 +114,7 @@ BuildRequires: kernel-syms BuildRequires: module-init-tools BuildRequires: xorg-x11 %endif -Version: 4.2.1_02 +Version: 4.2.1_03 Release: 0 PreReq: %insserv_prereq %fillup_prereq Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) @@ -217,7 +216,14 @@ Patch26330: 26330-VT-d-phantom-MSI.patch Patch26331: 26331-IOMMU-phantom-dev-quirk.patch Patch26332: 26332-x86-compat-show-guest-stack-mfn.patch Patch26333: 26333-x86-get_page_type-assert.patch +Patch26341: 26341-hvm-firmware-passthrough.patch +Patch26342: 26342-hvm-firmware-passthrough.patch +Patch26343: 26343-hvm-firmware-passthrough.patch +Patch26344: 26344-hvm-firmware-passthrough.patch Patch33: CVE-2012-5634-xsa33.patch +Patch34: CVE-2013-0151-xsa34.patch +Patch35: CVE-2013-0152-xsa35.patch +Patch41: CVE-2012-6075-xsa41.patch # Upstream qemu patches Patch100: VNC-Support-for-ExtendedKeyEvent-client-message.patch # Our patches @@ -311,8 +317,7 @@ Patch458: ipxe-enable-nics.patch Patch459: blktap-close-fifos.patch Patch460: blktap-disable-debug-printf.patch Patch461: xen-glibc217.patch -Patch462: reverse-24757-use-grant-references.patch -Patch463: xen-migration-bridge-check.patch +Patch462: xen-migration-bridge-check.patch # Jim's domain lock patch Patch480: xend-domain-lock.patch Patch481: xend-domain-lock-sfex.patch @@ -725,7 +730,14 @@ tar xfj %{SOURCE6} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch26331 -p1 %patch26332 -p1 %patch26333 -p1 +%patch26341 -p1 +%patch26342 -p1 +%patch26343 -p1 +%patch26344 -p1 %patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch41 -p1 # Qemu %patch100 -p1 # Our patches @@ -817,7 +829,6 @@ tar xfj %{SOURCE6} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch460 -p1 %patch461 -p1 %patch462 -p1 -%patch463 -p1 %patch480 -p1 %patch481 -p1 %patch500 -p1 diff --git a/xnloader.py b/xnloader.py new file mode 100644 index 0000000..ba2e568 --- /dev/null +++ b/xnloader.py @@ -0,0 +1,62 @@ +# NetWare-specific operations +# +# Copyright (c) 2013 Suse Linux Products. +# Author: Charles Arnold +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Binary patching of xnloader.sys +# For launching NetWare on Xen 4.2 and newer + +import os, sys, base64 + +CODE_OFFSET=0x49F5 +NUMBER_OF_CODE_BYTES=17 +ORIGINAL_CODE="BA00080000C786FC1F0000FFFFFFFF31C9" +PATCHED_CODE="BAF8070000834C961CFFB9080000009090" +XNLOADER_SYS_MD5SUM="eb76cce2a2d45928ea2bf26e01430af2" + +def patch_netware_loader(loader): + """Open the given xnloader.sys file and patch the relevant code hunk.""" + + # domUloader calls this with all kernels so perhaps this is not the NetWare loader + md5sum_cmd = 'md5sum ' + loader + p = os.popen(md5sum_cmd) + sum = p.read().split()[0] + p.close() + if sum != XNLOADER_SYS_MD5SUM: + return + + try: + fd = os.open(loader, os.O_RDWR) + except Exception, e: + print >>sys.stderr, e + raise + + # Validate minimum size for I/O + stat = os.fstat(fd) + if stat.st_size < CODE_OFFSET+NUMBER_OF_CODE_BYTES: + os.close(fd) + return + + # Seek to location of code hunk + os.lseek(fd, CODE_OFFSET, os.SEEK_SET) + + # Read code bytes at offset + buf = os.read(fd, NUMBER_OF_CODE_BYTES) + + code_as_hex = base64.b16encode(buf) + if code_as_hex == ORIGINAL_CODE: + # Seek back to start location of the code hunk + os.lseek(fd, CODE_OFFSET, os.SEEK_SET) + # Convert the PATCHED_CODE string to raw binary + code_as_bin = base64.b16decode(PATCHED_CODE) + # Write the patched code + os.write(fd, code_as_bin) + os.close(fd) +