]> xenbits.xensource.com Git - people/aperard/centos-package-xen.git/commitdiff
import xen-4.2.2-22.el6.centos.alt
authorKaranbir Singh <kbsingh@centos.org>
Tue, 7 Oct 2014 14:26:56 +0000 (14:26 +0000)
committerKaranbir Singh <kbsingh@centos.org>
Tue, 7 Oct 2014 14:26:56 +0000 (14:26 +0000)
81 files changed:
.xen.metadata [new file with mode: 0644]
README.md [deleted file]
SOURCES/blktapctrl.service [new file with mode: 0644]
SOURCES/init.blktapctrl [new file with mode: 0755]
SOURCES/init.xenconsoled [new file with mode: 0755]
SOURCES/init.xend [new file with mode: 0755]
SOURCES/init.xenstored [new file with mode: 0755]
SOURCES/libexec.xendomains [new file with mode: 0755]
SOURCES/proc-xen.mount [new file with mode: 0644]
SOURCES/pygrubfix.patch [new file with mode: 0644]
SOURCES/qemu-xen.trad.buildfix.patch [new file with mode: 0644]
SOURCES/sysconfig.blktapctrl [new file with mode: 0755]
SOURCES/sysconfig.xenconsoled [new file with mode: 0755]
SOURCES/sysconfig.xend [new file with mode: 0755]
SOURCES/sysconfig.xenstored [new file with mode: 0755]
SOURCES/tmpfiles.d.xen.conf [new file with mode: 0644]
SOURCES/var-lib-xenstored.mount [new file with mode: 0644]
SOURCES/xen-centos-blktap25-ctl-ipc-restart.patch [new file with mode: 0644]
SOURCES/xen-centos-disable-CFLAGS-for-qemu.patch [new file with mode: 0644]
SOURCES/xen-centos-disableWerror-blktap25.patch [new file with mode: 0644]
SOURCES/xen-centos-libxl-with-blktap25.patch [new file with mode: 0644]
SOURCES/xen-configure-xend.patch [new file with mode: 0644]
SOURCES/xen-dumpdir.patch [new file with mode: 0644]
SOURCES/xen-initscript.patch [new file with mode: 0644]
SOURCES/xen-net-disable-iptables-on-bridge.patch [new file with mode: 0644]
SOURCES/xen-watchdog.service [new file with mode: 0644]
SOURCES/xen-xl-autoballon-with-auto-option.patch [new file with mode: 0644]
SOURCES/xen-xl-set-autoballon-default-auto.patch [new file with mode: 0644]
SOURCES/xen.fedora.efi.build.patch [new file with mode: 0644]
SOURCES/xen.fedora19.buildfix.patch [new file with mode: 0644]
SOURCES/xen.git-9c23a1d0eb7a6b5e3273d527cfd7960838fbfee6.patch [new file with mode: 0644]
SOURCES/xen.logrotate [new file with mode: 0644]
SOURCES/xen.modules [new file with mode: 0644]
SOURCES/xen.use.fedora.ipxe.patch [new file with mode: 0644]
SOURCES/xen.use.fedora.seabios.patch [new file with mode: 0644]
SOURCES/xenconsoled.service [new file with mode: 0644]
SOURCES/xend-pci-loop.patch [new file with mode: 0644]
SOURCES/xend.catchbt.patch [new file with mode: 0644]
SOURCES/xend.selinux.fixes.patch [new file with mode: 0644]
SOURCES/xend.service [new file with mode: 0644]
SOURCES/xendomains.service [new file with mode: 0644]
SOURCES/xenstored.service [new file with mode: 0644]
SOURCES/xl.list.-l.format.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-01-vcpu-destroy-pagetables-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-02-new-guest-cr3-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-03-new-user-base-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-04-vcpu-reset-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-05-set-info-guest-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-06-unpin-preemptible.patch [new file with mode: 0644]
SOURCES/xsa45-4.2-07-mm-error-paths-preemptible.patch [new file with mode: 0644]
SOURCES/xsa46-regression-xend-xm.patch [new file with mode: 0644]
SOURCES/xsa48-4.2.patch [new file with mode: 0644]
SOURCES/xsa49-4.2.patch [new file with mode: 0644]
SOURCES/xsa52-4.2-unstable.patch [new file with mode: 0644]
SOURCES/xsa53-4.2.patch [new file with mode: 0644]
SOURCES/xsa54.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0001-libelf-abolish-libelf-relocate.c.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0002-libxc-introduce-xc_dom_seg_to_ptr_pages.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0003-libxc-Fix-range-checking-in-xc_dom_pfn_to_ptr-etc.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0004-libelf-add-struct-elf_binary-parameter-to-elf_load_i.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0005-libelf-abolish-elf_sval-and-elf_access_signed.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0006-libelf-move-include-of-asm-guest_access.h-to-top-of-.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0007-libelf-xc_dom_load_elf_symtab-Do-not-use-syms-uninit.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0008-libelf-introduce-macros-for-memory-access-and-pointe.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0009-tools-xcutils-readnotes-adjust-print_l1_mfn_valid_no.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0010-libelf-check-nul-terminated-strings-properly.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0011-libelf-check-all-pointer-accesses.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0012-libelf-Check-pointer-references-in-elf_is_elfbinary.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0013-libelf-Make-all-callers-call-elf_check_broken.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0014-libelf-use-C99-bool-for-booleans.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0015-libelf-use-only-unsigned-integers.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0016-libelf-check-loops-for-running-away.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0017-libelf-abolish-obsolete-macros.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0018-libxc-Add-range-checking-to-xc_dom_binloader.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0019-libxc-check-failure-of-xc_dom_-_to_ptr-xc_map_foreig.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0020-libxc-check-return-values-from-malloc.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0021-libxc-range-checks-in-xc_dom_p2m_host-and-_guest.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0022-libxc-check-blob-size-before-proceeding-in-xc_dom_ch.patch [new file with mode: 0644]
SOURCES/xsa55-4.2-0023-libxc-Better-range-check-in-xc_dom_alloc_segment.patch [new file with mode: 0644]
SOURCES/xsa56.patch [new file with mode: 0644]
SPECS/xen.spec [new file with mode: 0644]

diff --git a/.xen.metadata b/.xen.metadata
new file mode 100644 (file)
index 0000000..dcd28ac
--- /dev/null
@@ -0,0 +1,8 @@
+3411652615b89bc2c7fa7fb72a4fee1415936eb943ce27eff700278f1f26f50c SOURCES/blktap-9960138790b9d3610b12acd153bba20235efa4f5.tar.gz
+4e1d15d12dbd3e9208111d6b806ad5a9857ca8850c47877d36575b904559260b SOURCES/grub-0.97.tar.gz
+772e4d550e07826665ed0528c071dd5404ef7dbe1825a38c8adbc2a00bca948f SOURCES/lwip-1.3.0.tar.gz
+db426394965c48c1d29023e1cc6d965ea6b9a9035d8a849be2750ca4659a3d07 SOURCES/newlib-1.16.0.tar.gz
+f60ae61cfbd5da1d849d0beaa21f593c38dac9359f0b3ddc612f447408265b24 SOURCES/pciutils-2.2.9.tar.bz2
+d424c5ad5ef1ed6c3f0877752f82d4b240d42ce7ae770ae2b317d2881299575e SOURCES/qemu-xen-4.2.2.tar.gz
+1795c7d067a43174113fdf03447532f373e1c6c57c08d61d9e4e9be5e244b05e SOURCES/zlib-1.2.3.tar.gz
+c9bfe91a5e72f8545acebad9889d64368020359bfe18044c0e683133e55ae005 SOURCES/xen-4.2.2.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index 5231011..0000000
--- a/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-The master branch has no content
-
-Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch
-for CentOS-4, 5 or 6. If you find this file in a distro specific branch, it 
-means that no content has been checked in yet
-
-More information on how these git repositories are setup, is available at 
-http://wiki.centos.org/Sources
diff --git a/SOURCES/blktapctrl.service b/SOURCES/blktapctrl.service
new file mode 100644 (file)
index 0000000..b5c7c2c
--- /dev/null
@@ -0,0 +1,16 @@
+[Unit]
+Description=blktapctrl daemon
+Requires=proc-xen.mount
+After=proc-xen.mount
+RefuseManualStop=true
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=forking
+Environment=BLKTAPCTRL_ARGS=
+EnvironmentFile=-/etc/sysconfig/blktapctrl
+ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
+ExecStart=/usr/sbin/blktapctrl $BLKTAPCTRL_ARGS
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/init.blktapctrl b/SOURCES/init.blktapctrl
new file mode 100755 (executable)
index 0000000..c67713e
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# blktapctrl   Script to start the Xen blktapctrl daemon
+#
+# Author:       Daniel Berrange <berrange@redhat.com>
+#
+# chkconfig: 2345 97 01
+# description: Starts and stops the Xen blktapctrl daemon.
+### BEGIN INIT INFO
+# Provides:          blktapctrl
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop blktapctrl
+# Description:       Starts and stops the Xen blktapctrl daemon
+### END INIT INFO
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+if [ ! -d /proc/xen ]; then
+       exit 0
+fi
+if ! grep -q "control_d" /proc/xen/capabilities ; then
+       exit 0
+fi
+
+# Default config params
+BLKTAPCTRL_ARGS=
+
+# User customized params
+test -f /etc/sysconfig/blktapctrl && . /etc/sysconfig/blktapctrl
+
+start() {
+       echo -n $"Starting xen blktapctrl daemon: "
+        /usr/sbin/blktapctrl $BLKTAPCTRL_ARGS
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/blktapctrl
+}
+
+stop() {
+       echo -n $"Stoping xen blktapctrl daemon: "
+       # blktapctrl is not restartable.  So we refuse to stop it
+       # unless the machine is being shutdown or rebooted anyway.
+       if test "$runlevel" = "0" -o "$runlevel" = "6"; then
+               killproc xenstored > /dev/null
+               RETVAL=$?
+       else
+               RETVAL=1
+       fi
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/blktapctrl
+}
+
+rcstatus() {
+        status blktapctrl
+        RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+       echo
+}
+
+
+RETVAL=0
+case "$1" in
+  start)
+        start
+       ;;
+  stop)
+        stop
+       ;;
+  status)
+        rcstatus
+       ;;
+  *)
+       echo $"Usage: $0 {start|stop|status}"
+       exit 1
+esac
+
+exit $RETVAL
+
diff --git a/SOURCES/init.xenconsoled b/SOURCES/init.xenconsoled
new file mode 100755 (executable)
index 0000000..fe0defd
--- /dev/null
@@ -0,0 +1,121 @@
+#!/bin/bash
+#
+# xenconsoled  Script to start and stop the Xen xenconsoled daemon
+#
+# Author:       Daniel P. Berrange <berrange@redhat.com>
+#
+# chkconfig: 2345 97 01
+# description: Starts and stops the Xen control daemon.
+### BEGIN INIT INFO
+# Provides:          xenconsoled
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs xenstored
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop xenconsoled
+# Description:       Starts and stops the Xen xenconsoled daemon.
+### END INIT INFO
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+if [ ! -d /proc/xen ]; then
+       exit 0
+fi
+if ! grep -q "control_d" /proc/xen/capabilities ; then
+       exit 0
+fi
+
+# Default config params
+XENCONSOLED_LOG_HYPERVISOR=no
+XENCONSOLED_LOG_GUESTS=no
+XENCONSOLED_LOG_DIR=/var/log/xen/console
+XENCONSOLED_ARGS=
+
+# User customized params
+test -f /etc/sysconfig/xenconsoled && . /etc/sysconfig/xenconsoled
+
+XENCONSOLED_LOG=none
+if [ "$XENCONSOLED_LOG_HYPERVISOR" = "yes" ]
+then
+        if [ "$XENCONSOLED_LOG_GUESTS" = "yes" ]
+        then
+                XENCONSOLED_LOG=all
+        else
+                XENCONSOLED_LOG=hv
+        fi
+else
+        if [ "$XENCONSOLED_LOG_GUESTS" = "yes" ]
+        then
+                XENCONSOLED_LOG=guest
+        fi
+fi
+
+start() {
+       echo -n $"Starting xenconsoled daemon: "
+        /usr/sbin/xenconsoled --log=$XENCONSOLED_LOG --log-dir=$XENCONSOLED_LOG_DIR $XENCONSOLED_ARGS
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/xenconsoled
+}
+
+stop() {
+       echo -n $"Stopping xenconsoled daemon: "
+       killproc xenconsoled > /dev/null
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/xenconsoled
+}
+
+rcstatus() {
+        status xenconsoled
+        RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+       echo
+}
+
+reload() {
+       echo -n $"Reloading xenconsoled daemon: "
+       killproc xenconsoled -HUP > /dev/null
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+}
+
+RETVAL=0
+case "$1" in
+  start)
+        start
+       ;;
+  stop)
+        stop
+       ;;
+  status)
+        rcstatus
+       ;;
+  reload)
+       reload
+        ;;
+  restart|force-reload)
+       stop
+        start
+       ;;
+  condrestart)
+        if [ -f /var/lock/subsys/xenconsoled ]
+        then
+                stop
+                start
+        fi
+        ;;
+  *)
+       echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
+       exit 1
+esac
+
+exit $RETVAL
+
diff --git a/SOURCES/init.xend b/SOURCES/init.xend
new file mode 100755 (executable)
index 0000000..9d09df5
--- /dev/null
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# xend         Script to start and stop the Xen control daemon.
+#
+# Author:       Keir Fraser <keir.fraser@cl.cam.ac.uk>
+#
+# chkconfig: 2345 98 01
+# description: Starts and stops the Xen control daemon.
+### BEGIN INIT INFO
+# Provides:          xend
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop xend
+# Description:       Starts and stops the Xen control daemon.
+### END INIT INFO
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+if [ -e /etc/sysconfig/xend ]; then
+  . /etc/sysconfig/xend
+fi
+
+if [ ! -d /proc/xen ]; then
+       exit 0
+fi
+if ! grep -q "control_d" /proc/xen/capabilities ; then
+       exit 0
+fi
+
+# Default config params
+start() {
+       #set selinux to permissive to run xend
+       selinux_is="$(/usr/sbin/getenforce)"
+       if [ "$selinux_is" = "Enforcing" ]; then
+         /usr/sbin/setenforce 0
+       fi
+       # remove the blktap interface when starting xen
+       blktap_is="$(/sbin/lsmod | /bin/grep '^blktap ' | /bin/awk {'print $1'} )"
+       RMMOD_BLKTAP="$(echo ${RMMOD_BLKTAP,,})"
+       if [ "$blktap_is" == "blktap" ]; then
+         if [ "$RMMOD_BLKTAP" == "yes" ]; then
+           /sbin/rmmod blktap
+         fi
+       fi
+       #begin normal script
+       echo -n $"Starting xend daemon: "
+       /usr/sbin/xend
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/xend
+}
+
+stop() {
+       echo -n $"Stopping xend daemon: "
+       killproc xend > /dev/null
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/xend
+}
+
+rcstatus() {
+        status xend
+        RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+       echo
+}
+
+reload() {
+       echo -n $"Reloading xend daemon: "
+       killproc xend -HUP > /dev/null
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+}
+
+RETVAL=0
+case "$1" in
+  start)
+        start
+       ;;
+  stop)
+        stop
+       ;;
+  status)
+        rcstatus
+       ;;
+  reload)
+       reload
+        ;;
+  restart|force-reload)
+       stop
+        start
+       ;;
+  condrestart)
+        if [ -f /var/lock/subsys/xend ]
+        then
+                stop
+                start
+        fi
+        ;;
+  *)
+       echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
+       exit 1
+esac
+
+exit $RETVAL
+
diff --git a/SOURCES/init.xenstored b/SOURCES/init.xenstored
new file mode 100755 (executable)
index 0000000..328870d
--- /dev/null
@@ -0,0 +1,95 @@
+#!/bin/bash
+#
+# xenstored    Script to start and stop the Xen control daemon.
+#
+# Author:       Daniel Berrange <berrange@redhat.com
+#
+# chkconfig: 2345 96 01
+# description: Starts and stops the Xen xenstored daemon.
+### BEGIN INIT INFO
+# Provides:          xenstored
+# Required-Start:    $syslog $remote_fs
+# Should-Start:
+# Required-Stop:     $syslog $remote_fs
+# Should-Stop:
+# Default-Start:     3 4 5
+# Default-Stop:      0 1 2 6
+# Default-Enabled:   yes
+# Short-Description: Start/stop xenstored
+# Description:       Starts and stops the Xen xenstored daemon.
+### END INIT INFO
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+if [ ! -d /proc/xen ]; then
+       exit 0
+fi
+if [ ! -f /proc/xen/capabilities ]; then
+       mount -t xenfs xen /proc/xen
+fi
+if ! grep -q "control_d" /proc/xen/capabilities ; then
+       exit 0
+fi
+
+# Default config params
+XENSTORED_PID="/var/run/xenstored.pid"
+XENSTORED_ARGS=
+
+# User customized params
+test -f /etc/sysconfig/xenstored && . /etc/sysconfig/xenstored
+
+start() {
+       echo -n $"Starting xenstored daemon: "
+       grep -q '/var/lib/xenstored' /proc/mounts
+       if test "$?" = "1"; then
+               mount -t tmpfs xenstore /var/lib/xenstored
+               restorecon -R /var/lib/xenstored
+       fi
+        /usr/sbin/xenstored --pid-file $XENSTORED_PID $XENSTORED_ARGS
+       RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/xenstored
+}
+
+stop() {
+       echo -n $"Stopping xenstored daemon: "
+       # xenstored is not restartable.  So we refuse to stop it
+       # unless the machine is being shutdown or rebooted anyway.
+       if test "$runlevel" = "0" -o "$runlevel" = "6"; then
+               killproc xenstored > /dev/null
+               RETVAL=$?
+       else
+               RETVAL=1
+       fi
+       test $RETVAL = 0 && echo_success || echo_failure
+        echo
+        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/xenstored
+}
+
+rcstatus() {
+        status xenstored
+        RETVAL=$?
+       test $RETVAL = 0 && echo_success || echo_failure
+       echo
+}
+
+RETVAL=0
+case "$1" in
+  start)
+        start
+       ;;
+  stop)
+        stop
+       ;;
+  status)
+        rcstatus
+       ;;
+  *)
+       echo $"Usage: $0 {start|stop|status}"
+       exit 1
+esac
+
+exit $RETVAL
+
diff --git a/SOURCES/libexec.xendomains b/SOURCES/libexec.xendomains
new file mode 100755 (executable)
index 0000000..9e69d21
--- /dev/null
@@ -0,0 +1,569 @@
+#!/bin/bash
+#
+# /etc/init.d/xendomains
+# Start / stop domains automatically when domain 0 boots / shuts down.
+#
+# chkconfig: 345 99 00
+# description: Start / stop Xen domains.
+#
+# This script offers fairly basic functionality.  It should work on Redhat
+# but also on LSB-compliant SuSE releases and on Debian with the LSB package
+# installed.  (LSB is the Linux Standard Base)
+#
+# Based on the example in the "Designing High Quality Integrated Linux
+# Applications HOWTO" by Avi Alkalay
+# <http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/>
+#
+### BEGIN INIT INFO
+# Provides:          xendomains
+# Required-Start:    $syslog $remote_fs xenstored xenconsoled
+# Should-Start:      xend
+# Required-Stop:     $syslog $remote_fs xenstored xenconsoled
+# Should-Stop:       xend
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Start/stop secondary xen domains
+# Description:       Start / stop domains automatically when domain 0 
+#                    boots / shuts down.
+### END INIT INFO
+
+CMD=xl
+$CMD list &> /dev/null
+if test $? -ne 0
+then
+       CMD=xm
+fi
+
+$CMD list &> /dev/null
+if test $? -ne 0
+then
+       exit 0;
+fi
+
+# Correct exit code would probably be 5, but it's enough 
+# if xend complains if we're not running as privileged domain
+if ! [ -e /proc/xen/privcmd ]; then
+       exit 0
+fi
+
+# See docs/misc/distro_mapping.txt
+if [ -d /var/lock/subsys ]; then
+       LOCKFILE=/var/lock/subsys/xendomains
+else
+       LOCKFILE=/var/lock/xendomains
+fi
+
+if [ -d /etc/sysconfig ]; then
+       XENDOM_CONFIG=/etc/sysconfig/xendomains
+else
+       XENDOM_CONFIG=/etc/default/xendomains
+fi
+
+test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
+       if [ "$1" = "stop" ]; then exit 0;
+       else exit 6; fi; }
+
+. $XENDOM_CONFIG
+
+# Use the SUSE rc_ init script functions;
+# emulate them on LSB, RH and other systems
+if test -e /etc/rc.status; then
+    # SUSE rc script library
+    . /etc/rc.status
+else    
+    _cmd=$1
+    declare -a _SMSG
+    if test "${_cmd}" = "status"; then
+       _SMSG=(running dead dead unused unknown)
+       _RC_UNUSED=3
+    else
+       _SMSG=(done failed failed missed failed skipped unused failed failed)
+       _RC_UNUSED=6
+    fi
+    if test -e /lib/lsb/init-functions; then
+       # LSB    
+       . /lib/lsb/init-functions
+        if alias log_success_msg >/dev/null 2>/dev/null; then
+         echo_rc()
+         {
+              echo "  [${_SMSG[${_RC_RV}]}] "
+         }
+        else
+         echo_rc()
+         {
+           if test ${_RC_RV} = 0; then
+               log_success_msg "  [${_SMSG[${_RC_RV}]}] "
+           else
+               log_failure_msg "  [${_SMSG[${_RC_RV}]}] "
+           fi
+         }
+        fi
+    else    
+       # emulate it
+       echo_rc()
+       {
+           echo "  [${_SMSG[${_RC_RV}]}] "
+       }
+    fi
+    rc_reset() { _RC_RV=0; }
+    rc_failed()
+    {
+       if test -z "$1"; then 
+           _RC_RV=1;
+       elif test "$1" != "0"; then 
+           _RC_RV=$1; 
+       fi
+       return ${_RC_RV}
+    }
+    rc_check()
+    {
+       return rc_failed $?
+    }  
+    rc_status()
+    {
+       rc_failed $?
+       if test "$1" = "-r"; then _RC_RV=0; shift; fi
+       if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
+       if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed 3; shift; fi
+       if test "$1" = "-v"; then echo_rc; shift; fi
+       if test "$1" = "-r"; then _RC_RV=0; shift; fi
+       return ${_RC_RV}
+    }
+    rc_exit() { exit ${_RC_RV}; }
+    rc_active() 
+    {
+       if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi
+       if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi
+       return 1
+    }
+fi
+
+if ! which usleep >&/dev/null
+then
+  usleep()
+  {
+    if [ -n "$1" ]
+    then
+      sleep $(( $1 / 1000000 ))
+    fi
+  }
+fi
+
+# Reset status of this service
+rc_reset
+
+##
+# Returns 0 (success) if the given parameter names a directory, and that
+# directory is not empty.
+#
+contains_something()
+{
+  if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
+  then
+    return 0
+  else
+    return 1
+  fi
+}
+
+# read name from xen config file
+rdname()
+{
+    NM=$($CMD create --quiet --dryrun --defconfig "$1" |
+         sed -n 's/^.*(name \(.*\))$/\1/p')
+}
+
+rdnames()
+{
+    NAMES=
+    if ! contains_something "$XENDOMAINS_AUTO"
+    then 
+       return
+    fi
+    for dom in $XENDOMAINS_AUTO/*; do
+       rdname $dom
+       if test -z $NAMES; then 
+           NAMES=$NM; 
+       else
+           NAMES="$NAMES|$NM"
+       fi
+    done
+}
+
+LIST_GREP='((domain\|(domid\|(name\|^{$\|"name":\|"domid":'
+parseln()
+{
+    if [[ "$1" =~ '(domain' ]] || [[ "$1" = "{" ]]; then
+        name=;id=
+    elif [[ "$1" =~ '(name' ]]; then
+        name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/')
+    elif [[ "$1" =~ '(domid' ]]; then
+        id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/')
+    elif [[ "$1" =~ '"name":' ]]; then
+        name=$(echo $1 | sed -e 's/^.*"name": "\(.*\)",$/\1/')
+    elif [[ "$1" =~ '"domid":' ]]; then
+        id=$(echo $1 | sed -e 's/^.*"domid": \(.*\),$/\1/')
+    fi
+
+    [ -n "$name" -a -n "$id" ] && return 0 || return 1
+}
+
+is_running()
+{
+    rdname $1
+    RC=1
+    name=;id=
+    while read LN; do
+       parseln "$LN" || continue
+       if test $id = 0; then continue; fi
+       case $name in 
+           ($NM)
+               RC=0
+               ;;
+       esac
+    done < <($CMD list -l | grep $LIST_GREP)
+    return $RC
+}
+
+start() 
+{
+    if [ -f $LOCKFILE ]; then 
+       echo -e "xendomains already running (lockfile exists)"
+       return; 
+    fi
+
+    saved_domains=" "
+    if [ "$XENDOMAINS_RESTORE" = "true" ] &&
+       contains_something "$XENDOMAINS_SAVE"
+    then
+       mkdir -p $(dirname "$LOCKFILE")
+       touch $LOCKFILE
+       echo -n "Restoring Xen domains:"
+       saved_domains=`ls $XENDOMAINS_SAVE`
+        for dom in $XENDOMAINS_SAVE/*; do
+            if [ -f $dom ] ; then
+                HEADER=`head -c 16 $dom | head -n 1 2> /dev/null`
+                if [ "$HEADER" = "LinuxGuestRecord" -o "$HEADER" = "Xen saved domain" ]; then
+                    echo -n " ${dom##*/}"
+                    XMR=`$CMD restore $dom 2>&1 1>/dev/null`
+                    #$CMD restore $dom
+                    if [ $? -ne 0 ]; then
+                        echo -e "\nAn error occurred while restoring domain ${dom##*/}:\n$XMR"
+                        rc_failed $?
+                        echo -e '!'
+                    else
+                        # mv $dom ${dom%/*}/.${dom##*/}
+                        rm $dom
+                    fi
+                fi
+            fi
+        done
+       echo -e
+    fi
+
+    if contains_something "$XENDOMAINS_AUTO"
+    then
+       touch $LOCKFILE
+       echo -n "Starting auto Xen domains:"
+       # We expect config scripts for auto starting domains to be in
+       # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
+
+       # Create all domains with config files in XENDOMAINS_AUTO.
+       # TODO: We should record which domain name belongs 
+       # so we have the option to selectively shut down / migrate later
+       # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
+       # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't 
+       # restore correctly it requires administrative attention.
+       for dom in $XENDOMAINS_AUTO/*; do
+           echo -n " ${dom##*/}"
+           shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
+           echo $saved_domains | grep -w $shortdom > /dev/null
+           if [ $? -eq 0 ] || is_running $dom; then
+               echo -n "(skip)"
+           else
+               XMC=`$CMD create --quiet --defconfig $dom`
+               if [ $? -ne 0 ]; then
+                   echo -e "\nAn error occurred while creating domain ${dom##*/}: $XMC\n"
+                   rc_failed $?
+                   echo -e '!'
+               else
+                   usleep $XENDOMAINS_CREATE_USLEEP
+               fi
+           fi
+       done
+    fi
+}
+
+all_zombies()
+{
+    name=;id=
+    while read LN; do
+       parseln "$LN" || continue
+       if test $id = 0; then continue; fi
+       if test "$state" != "-b---d" -a "$state" != "-----d"; then
+           return 1;
+       fi
+    done < <($CMD list -l | grep $LIST_GREP)
+    return 0
+}
+
+# Wait for max $XENDOMAINS_STOP_MAXWAIT for $CMD $1 to finish;
+# if it has not exited by that time kill it, so the init script will
+# succeed within a finite amount of time; if $2 is nonnull, it will
+# kill the command as well as soon as no domain (except for zombies)
+# are left (used for shutdown --all). Third parameter, if any, suppresses
+# output of dots per working state (formatting issues)
+watchdog_xencmd()
+{
+    if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
+       exit
+    fi
+
+    usleep 20000
+    for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
+       # exit if $CMD save/migrate/shutdown is finished
+       PSAX=`ps axlw | grep "$CMD $1" | grep -v grep`
+       if test -z "$PSAX"; then exit; fi
+       if ! test -n "$3"; then echo -n '.'; fi
+       sleep 1
+       # go to kill immediately if there's only zombies left
+       if all_zombies && test -n "$2"; then break; fi
+    done
+    sleep 1
+    read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
+    # kill $CMD $1
+    kill $PSPID >/dev/null 2>&1
+    
+    echo -e .
+}
+
+stop()
+{
+    exec 3>&2 2> /dev/null
+    
+    # Collect list of domains to shut down
+    if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
+       rdnames
+    fi
+    echo -n "Shutting down Xen domains:"
+    name=;id=
+    while read LN; do
+       parseln "$LN" || continue
+       if test $id = 0; then continue; fi
+       echo -n " $name"
+       if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
+           eval "
+           case \"\$name\" in
+               ($NAMES)
+                   # nothing
+                   ;;
+               (*)
+                   echo -e '(skip)'
+                   continue
+                   ;;
+           esac
+           "
+       fi
+       # XENDOMAINS_SYSRQ chould be something like just "s" 
+       # or "s e i u" or even "s e s i u o"
+       # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
+       if test -n "$XENDOMAINS_SYSRQ"; then
+           for sysrq in $XENDOMAINS_SYSRQ; do
+               echo -n "(SR-$sysrq)"
+               XMR=`$CMD sysrq $id $sysrq 2>&1 1>/dev/null`
+               if test $? -ne 0; then
+                   echo -e "\nAn error occurred while doing sysrq on domain:\n$XMR\n"
+                   rc_failed $?
+                   echo -n '!'
+               fi
+               # usleep just ignores empty arg
+               usleep $XENDOMAINS_USLEEP
+           done
+       fi
+       if test "$state" = "-b---d" -o "$state" = "-----d"; then
+           echo -n "(zomb)"
+           continue
+       fi
+       if test -n "$XENDOMAINS_MIGRATE"; then
+           echo -n "(migr)"
+           watchdog_xencmd migrate &
+           WDOG_PID=$!
+           XMR=`$CMD migrate $id $XENDOMAINS_MIGRATE 2>&1 1>/dev/null`
+           if test $? -ne 0; then
+               echo -e "\nAn error occurred while migrating domain:\n$XMR\n"
+               rc_failed $?
+               echo -e '!'
+
+               kill $WDOG_PID >/dev/null 2>&1
+           else
+               kill $WDOG_PID >/dev/null 2>&1
+               
+               echo -e .
+               usleep 1000
+               continue
+           fi
+       fi
+       if test -n "$XENDOMAINS_SAVE"; then
+           echo -n "(save)"
+           watchdog_xencmd save &
+           WDOG_PID=$!
+           mkdir -p "$XENDOMAINS_SAVE"
+           XMR=`$CMD save $id $XENDOMAINS_SAVE/$name 2>&1 1>/dev/null`
+           if test $? -ne 0; then
+               echo -e "\nAn error occurred while saving domain:\n$XMR\n"
+               rc_failed $?
+               echo -e '!'
+               kill $WDOG_PID >/dev/null 2>&1
+           else
+               kill $WDOG_PID >/dev/null 2>&1
+               echo -e .
+               usleep 1000
+               continue
+           fi
+       fi
+       if test -n "$XENDOMAINS_SHUTDOWN"; then
+           # XENDOMAINS_SHUTDOWN should be "--halt --wait"
+           echo -n "(shut)"
+           watchdog_xencmd shutdown &
+           WDOG_PID=$!
+           XMR=`$CMD shutdown $XENDOMAINS_SHUTDOWN $id 2>&1 1>/dev/null`
+           if test $? -ne 0; then
+               echo -e "\nAn error occurred while shutting down domain:\n$XMR\n"
+               rc_failed $?
+               echo -e '!'
+           fi
+           kill $WDOG_PID >/dev/null 2>&1
+       fi
+    done < <($CMD list -l | grep $LIST_GREP)
+
+    # NB. this shuts down ALL Xen domains (politely), not just the ones in
+    # AUTODIR/*
+    # This is because it's easier to do ;-) but arguably if this script is run
+    # on system shutdown then it's also the right thing to do.
+    if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
+       # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
+       echo -n " SHUTDOWN_ALL "
+       watchdog_xencmd shutdown 1 false &
+       WDOG_PID=$!
+       XMR=`$CMD shutdown $XENDOMAINS_SHUTDOWN_ALL 2>&1 1>/dev/null`
+       if test $? -ne 0; then
+           echo -e "\nAn error occurred while shutting down all domains: $XMR\n"
+           rc_failed $?
+           echo -e '!'
+       fi
+       kill $WDOG_PID >/dev/null 2>&1
+    fi
+
+    # Unconditionally delete lock file
+    rm -f $LOCKFILE
+    
+    exec 2>&3
+}
+
+check_domain_up()
+{
+    name=;id=
+    while read LN; do
+       parseln "$LN" || continue
+       if test $id = 0; then continue; fi
+       case $name in 
+           ($1)
+               return 0
+               ;;
+       esac
+    done < <($CMD list -l | grep $LIST_GREP)
+    return 1
+}
+
+check_all_auto_domains_up()
+{
+    if ! contains_something "$XENDOMAINS_AUTO"
+    then
+      return 0
+    fi
+    missing=
+    for nm in $XENDOMAINS_AUTO/*; do
+       rdname $nm
+       found=0
+       if check_domain_up "$NM"; then 
+           echo -n " $name"
+       else 
+           missing="$missing $NM"
+       fi
+    done
+    if test -n "$missing"; then
+       echo -n " MISS AUTO:$missing"
+       return 1
+    fi
+    return 0
+}
+
+check_all_saved_domains_up()
+{
+    if ! contains_something "$XENDOMAINS_SAVE" 
+    then
+      return 0
+    fi
+    missing=`/bin/ls $XENDOMAINS_SAVE`
+    echo -n " MISS SAVED: " $missing
+    return 1
+}
+
+# This does NOT necessarily restart all running domains: instead it
+# stops all running domains and then boots all the domains specified in
+# AUTODIR.  If other domains have been started manually then they will
+# not get restarted.
+# Commented out to avoid confusion!
+
+restart()
+{
+    stop
+    start
+}
+
+reload()
+{
+    restart
+}
+
+
+case "$1" in
+    start)
+       start
+       rc_status
+       if test -f $LOCKFILE; then rc_status -v; fi
+       ;;
+
+    stop)
+       stop
+       rc_status -v
+       ;;
+
+    restart)
+       restart
+       ;;
+    reload)
+       reload
+       ;;
+
+    status)
+       echo -n "Checking for xendomains:" 
+       if test ! -f $LOCKFILE; then 
+           rc_failed 3
+       else
+           check_all_auto_domains_up
+           rc_status
+           check_all_saved_domains_up
+           rc_status
+       fi
+       rc_status -v
+       ;;
+
+    *)
+       echo "Usage: $0 {start|stop|restart|reload|status}"
+       rc_failed 3
+       rc_status -v
+       ;;
+esac
+
+rc_exit
diff --git a/SOURCES/proc-xen.mount b/SOURCES/proc-xen.mount
new file mode 100644 (file)
index 0000000..0eaa59c
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Mount /proc/xen files
+ConditionPathExists=/proc/xen
+RefuseManualStop=true
+
+[Mount]
+What=xenfs
+Where=/proc/xen
+Type=xenfs
diff --git a/SOURCES/pygrubfix.patch b/SOURCES/pygrubfix.patch
new file mode 100644 (file)
index 0000000..2caa7ca
--- /dev/null
@@ -0,0 +1,28 @@
+--- xen-4.1.0/tools/pygrub/src/pygrub.orig     2010-12-31 15:24:11.000000000 +0000
++++ xen-4.1.0/tools/pygrub/src/pygrub  2011-01-30 18:58:17.000000000 +0000
+@@ -97,6 +97,7 @@
+     fd = os.open(file, os.O_RDONLY)
+     buf = os.read(fd, 512)
+     os.close(fd)
++    offzerocount = 0
+     for poff in (446, 462, 478, 494): # partition offsets
+         # MBR contains a 16 byte descriptor per partition
+@@ -105,6 +106,7 @@
+         
+         # offset == 0 implies this partition is not enabled
+         if offset == 0:
++            offzerocount += 1
+             continue
+         if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
+@@ -123,6 +125,9 @@
+         else:
+             part_offs.append(offset)
++    if offzerocount == 4:
++        # Might be a grub boot sector pretending to be an MBR
++        part_offs.append(0)
+     return part_offs
+ class GrubLineEditor(curses.textpad.Textbox):
diff --git a/SOURCES/qemu-xen.trad.buildfix.patch b/SOURCES/qemu-xen.trad.buildfix.patch
new file mode 100644 (file)
index 0000000..791ec65
--- /dev/null
@@ -0,0 +1,14 @@
+--- xen-4.2.1/tools/qemu-xen-traditional/configure.orig        2010-12-05 18:48:29.000000000 +0000
++++ xen-4.2.1/tools/qemu-xen-traditional/configure     2012-11-15 23:59:12.453547657 +0000
+@@ -1097,7 +1097,10 @@
+ cat > $TMPC <<EOF
+ #include <signal.h>
+ #include <time.h>
+-int main(void) { clockid_t id; return clock_gettime(id, NULL); }
++int main(void) {
++  timer_create(CLOCK_REALTIME, NULL, NULL);
++  return clock_gettime(CLOCK_REALTIME, NULL);
++}
+ EOF
+ rt=no
diff --git a/SOURCES/sysconfig.blktapctrl b/SOURCES/sysconfig.blktapctrl
new file mode 100755 (executable)
index 0000000..bb6c09d
--- /dev/null
@@ -0,0 +1 @@
+#BLKTAPCTRL_ARGS=
diff --git a/SOURCES/sysconfig.xenconsoled b/SOURCES/sysconfig.xenconsoled
new file mode 100755 (executable)
index 0000000..4a00056
--- /dev/null
@@ -0,0 +1,22 @@
+# init.d only settings
+# Log all hypervisor messages (cf xm dmesg)
+#XENCONSOLED_LOG_HYPERVISOR=no
+# Log all guest console output (cf xm console)
+#XENCONSOLED_LOG_GUESTS=no
+
+# systemd only settings
+# No logging (default)
+#XENCONSOLED_LOG=none
+# Log guest console output only
+#XENCONSOLED_LOG=guest
+# Log hypervisor messages only
+#XENCONSOLED_LOG=hv
+# Log both guest console output and hypervisor messages
+#XENCONSOLED_LOG=all
+
+# setting for both init.d and systemd
+# Location to store guest & hypervisor logs
+#XENCONSOLED_LOG_DIR=/var/log/xen/console
+
+#XENCONSOLED_ARGS=
+
diff --git a/SOURCES/sysconfig.xend b/SOURCES/sysconfig.xend
new file mode 100755 (executable)
index 0000000..d5127a2
--- /dev/null
@@ -0,0 +1,6 @@
+# blktap seems not to work with virt-manager
+# the variable RMMOD_BLKTAP, if set to yes will remove the blktap module
+# if set to no it will not remove the module
+
+RMMOD_BLKTAP=no
+
diff --git a/SOURCES/sysconfig.xenstored b/SOURCES/sysconfig.xenstored
new file mode 100755 (executable)
index 0000000..0583132
--- /dev/null
@@ -0,0 +1,4 @@
+
+#XENSTORED_PID="/var/run/xenstored.pid"
+#XENSTORED_ARGS=
+
diff --git a/SOURCES/tmpfiles.d.xen.conf b/SOURCES/tmpfiles.d.xen.conf
new file mode 100644 (file)
index 0000000..5041017
--- /dev/null
@@ -0,0 +1 @@
+d /run/xen 0755 root root -
diff --git a/SOURCES/var-lib-xenstored.mount b/SOURCES/var-lib-xenstored.mount
new file mode 100644 (file)
index 0000000..49e0695
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=mount xenstore file system
+ConditionPathExists=/proc/xen
+RefuseManualStop=true
+
+[Mount]
+What=xenstore
+Where=/var/lib/xenstored
+Type=tmpfs
+Options=mode=755,context="system_u:object_r:xenstored_var_lib_t:s0"
diff --git a/SOURCES/xen-centos-blktap25-ctl-ipc-restart.patch b/SOURCES/xen-centos-blktap25-ctl-ipc-restart.patch
new file mode 100644 (file)
index 0000000..2087a83
--- /dev/null
@@ -0,0 +1,29 @@
+diff -uNrp xen-4.2.1.orig/tools/blktap2/control/tap-ctl-ipc.c xen-4.2.1/tools/blktap2/control/tap-ctl-ipc.c
+--- xen-4.2.1.orig/tools/blktap2/control/tap-ctl-ipc.c 2013-01-22 11:43:54.000000000 -0600
++++ xen-4.2.1/tools/blktap2/control/tap-ctl-ipc.c      2013-03-27 00:07:21.521475110 -0500
+@@ -58,8 +58,11 @@ tap_ctl_read_raw(int fd, void *buf, size
+               FD_SET(fd, &readfds);
+               ret = select(fd + 1, &readfds, NULL, NULL, timeout);
+-              if (ret == -1)
+-                      break;
++                if (ret == -1) {
++                        if (errno == EINTR)
++                                continue;
++                        break;
++                }
+               else if (FD_ISSET(fd, &readfds)) {
+                       ret = read(fd, buf + offset, size - offset);
+                       if (ret <= 0)
+@@ -114,6 +117,11 @@ tap_ctl_write_message(int fd, tapdisk_me
+                * bit more time than expected. */
+               ret = select(fd + 1, NULL, &writefds, NULL, timeout);
++               if (ret == -1) {
++                        if (errno == EINTR)
++                                continue;
++                        break;
++                }
+               if (ret == -1)
+                       break;
+               else if (FD_ISSET(fd, &writefds)) {
diff --git a/SOURCES/xen-centos-disable-CFLAGS-for-qemu.patch b/SOURCES/xen-centos-disable-CFLAGS-for-qemu.patch
new file mode 100644 (file)
index 0000000..2594a92
--- /dev/null
@@ -0,0 +1,11 @@
+diff -uNr xen-4.2.1__orig/tools/Makefile xen-4.2.1/tools/Makefile
+--- xen-4.2.1__orig/tools/Makefile     2012-12-17 10:00:09.000000000 -0500
++++ xen-4.2.1/tools/Makefile   2013-01-17 08:34:52.786982288 -0500
+@@ -187,6 +187,7 @@
+               source=.; \
+       fi; \
+       cd qemu-xen-dir; \
++      env -u CFLAGS \
+       $$source/configure --enable-xen --target-list=i386-softmmu \
+               --source-path=$$source \
+               --extra-cflags="-I$(XEN_ROOT)/tools/include \
diff --git a/SOURCES/xen-centos-disableWerror-blktap25.patch b/SOURCES/xen-centos-disableWerror-blktap25.patch
new file mode 100644 (file)
index 0000000..8369664
--- /dev/null
@@ -0,0 +1,35 @@
+diff -uNr xen-4.2.1__orig/tools/blktap2/drivers/Makefile xen-4.2.1/tools/blktap2/drivers/Makefile
+--- xen-4.2.1__orig/tools/blktap2/drivers/Makefile     2013-01-22 14:21:13.643741669 -0500
++++ xen-4.2.1/tools/blktap2/drivers/Makefile   2013-01-22 14:21:44.347092274 -0500
+@@ -207,7 +207,7 @@
+ top_build_prefix = ../
+ top_builddir = ..
+ top_srcdir = ..
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall 
+ AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/include
+ tapdisk_SOURCES = tapdisk2.c
+ tapdisk_LDADD = libtapdisk.la
+diff -uNr xen-4.2.1__orig/tools/blktap2/drivers/Makefile.am xen-4.2.1/tools/blktap2/drivers/Makefile.am
+--- xen-4.2.1__orig/tools/blktap2/drivers/Makefile.am  2013-01-22 12:43:54.000000000 -0500
++++ xen-4.2.1/tools/blktap2/drivers/Makefile.am        2013-01-22 14:21:44.347732663 -0500
+@@ -1,6 +1,6 @@
+ AM_CFLAGS  = -Wall
+-AM_CFLAGS += -Werror
++AM_CFLAGS += 
+ AM_CPPFLAGS  = -D_GNU_SOURCE
+ AM_CPPFLAGS += -I$(top_srcdir)/include
+diff -uNr xen-4.2.1__orig/tools/blktap2/drivers/Makefile.in xen-4.2.1/tools/blktap2/drivers/Makefile.in
+--- xen-4.2.1__orig/tools/blktap2/drivers/Makefile.in  2013-01-22 14:21:09.878842722 -0500
++++ xen-4.2.1/tools/blktap2/drivers/Makefile.in        2013-01-22 14:21:44.349092631 -0500
+@@ -207,7 +207,7 @@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall 
+ AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/include
+ tapdisk_SOURCES = tapdisk2.c
+ tapdisk_LDADD = libtapdisk.la
diff --git a/SOURCES/xen-centos-libxl-with-blktap25.patch b/SOURCES/xen-centos-libxl-with-blktap25.patch
new file mode 100644 (file)
index 0000000..cf6a087
--- /dev/null
@@ -0,0 +1,109 @@
+diff --git a/tools/Rules.mk b/tools/Rules.mk
+index f4e84c1..45f782d 100644
+--- a/tools/Rules.mk
++++ b/tools/Rules.mk
+@@ -46,9 +46,9 @@ LIBXL_BLKTAP ?= n
+ endif
+ ifeq ($(LIBXL_BLKTAP),y)
+-CFLAGS_libblktapctl = -I$(XEN_BLKTAP2)/control -I$(XEN_BLKTAP2)/include $(CFLAGS_xeninclude)
+-LDLIBS_libblktapctl = -L$(XEN_BLKTAP2)/control -lblktapctl
+-SHLIB_libblktapctl  = -Wl,-rpath-link=$(XEN_BLKTAP2)/control
++CFLAGS_libblktapctl = -I$(XEN_BLKTAP2)/include $(CFLAGS_xeninclude)
++LDLIBS_libblktapctl = -L$(XEN_BLKTAP2)/control/.libs -lblktapctl
++SHLIB_libblktapctl  = -Wl,-rpath-link=$(XEN_BLKTAP2)/control/.libs
+ else
+ CFLAGS_libblktapctl =
+ LDLIBS_libblktapctl =
+diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
+index 0b780c0..90cfd0d 100644
+--- a/tools/libxl/Makefile
++++ b/tools/libxl/Makefile
+@@ -71,7 +71,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
+                       libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
+ LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
+-$(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl) -include $(XEN_ROOT)/tools/config.h
++$(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) -I$(XEN_ROOT)/tools/blktap2/include -include $(XEN_ROOT)/tools/config.h
+ AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h _libxl_list.h _paths.h \
+       _libxl_save_msgs_callout.h _libxl_save_msgs_helper.h
+diff --git a/tools/libxl/libxl_blktap2.c b/tools/libxl/libxl_blktap2.c
+index 2053403..c85b182 100644
+--- a/tools/libxl/libxl_blktap2.c
++++ b/tools/libxl/libxl_blktap2.c
+@@ -29,20 +29,15 @@ char *libxl__blktap_devpath(libxl__gc *gc,
+ {
+     const char *type;
+     char *params, *devname = NULL;
+-    tap_list_t tap;
+     int err;
+     type = libxl__device_disk_string_of_format(format);
+-    err = tap_ctl_find(type, disk, &tap);
+-    if (err == 0) {
+-        devname = libxl__sprintf(gc, "/dev/xen/blktap-2/tapdev%d", tap.minor);
+-        if (devname)
+-            return devname;
+-    }
+     params = libxl__sprintf(gc, "%s:%s", type, disk);
+-    err = tap_ctl_create(params, &devname);
++    fprintf(stderr, "DEBUG %s %d %s\n",__func__,__LINE__,params);
++    err = tap_ctl_create(params, &devname, 0, -1, 0);
+     if (!err) {
++        fprintf(stderr, "DEBUG %s %d %s\n",__func__,__LINE__,devname);
+         libxl__ptr_add(gc, devname);
+         return devname;
+     }
+@@ -55,7 +50,10 @@ int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *params)
+ {
+     char *type, *disk;
+     int err;
+-    tap_list_t tap;
++      struct list_head list = LIST_HEAD_INIT(list);
++      tap_list_t *entry;
++    int minor = -1;
++    pid_t pid = -1;
+     type = libxl__strdup(gc, params);
+@@ -65,19 +63,34 @@ int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *params)
+         return ERROR_INVAL;
+     }
++    fprintf(stderr, "DEBUG %s %d type=%s disk=%s\n",__func__,__LINE__,type,disk);
+     *disk++ = '\0';
+-    err = tap_ctl_find(type, disk, &tap);
+-    if (err < 0) {
+-        /* returns -errno */
++    err = tap_ctl_list(&list);
++    if (err)
++        return err;
++    tap_list_for_each_entry(entry, &list) {
++              if (type && (!entry->type || strcmp(entry->type, type)))
++                      continue;
++
++              if (disk && (!entry->path || strcmp(entry->path, disk)))
++                      continue;
++
++        minor = entry->minor;
++        pid = entry->pid;
++              break;
++      }
++      tap_ctl_list_free(&list);
++
++    if (minor < 0) {
+         LOGEV(ERROR, -err, "Unable to find type %s disk %s", type, disk);
+         return ERROR_FAIL;
+     }
+-    err = tap_ctl_destroy(tap.id, tap.minor);
++    err = tap_ctl_destroy(pid, minor, 1, NULL);
+     if (err < 0) {
+         LOGEV(ERROR, -err, "Failed to destroy tap device id %d minor %d",
+-              tap.id, tap.minor);
++              pid, minor);
+         return ERROR_FAIL;
+     }
diff --git a/SOURCES/xen-configure-xend.patch b/SOURCES/xen-configure-xend.patch
new file mode 100644 (file)
index 0000000..0bdc932
--- /dev/null
@@ -0,0 +1,37 @@
+diff -up xen-3.4.0/tools/examples/xend-config.sxp.config xen-3.4.0/tools/examples/xend-config.sxp
+--- xen-3.4.0/tools/examples/xend-config.sxp.config    2009-05-20 17:12:50.000000000 +0200
++++ xen-3.4.0/tools/examples/xend-config.sxp   2009-05-20 17:15:35.000000000 +0200
+@@ -58,11 +58,11 @@
+ #(xend-http-server no)
+-#(xend-unix-server no)
++(xend-unix-server yes)
+ #(xend-tcp-xmlrpc-server no)
+ #(xend-unix-xmlrpc-server yes)
+-#(xend-relocation-server no)
+-(xend-relocation-server yes)
++(xend-relocation-server no)
++#(xend-relocation-server yes)
+ #(xend-relocation-ssl-server no)
+ #(xend-udev-event-server no)
+@@ -154,7 +154,8 @@
+ # two fake interfaces per guest domain.  To do things like this, write
+ # yourself a wrapper script, and call network-bridge from it, as appropriate.
+ #
+-(network-script network-bridge)
++#(network-script network-bridge)
++(network-script /bin/true)
+ # The script used to control virtual interfaces.  This can be overridden on a
+ # per-vif basis when creating a domain or a configuring a new vif.  The
+@@ -186,7 +187,7 @@
+ # dom0-min-mem is the lowest permissible memory level (in MB) for dom0.
+ # This is a minimum both for auto-ballooning (as enabled by
+ # enable-dom0-ballooning below) and for xm mem-set when applied to dom0.
+-(dom0-min-mem 196)
++(dom0-min-mem 256)
+ # Whether to enable auto-ballooning of dom0 to allow domUs to be created.
+ # If enable-dom0-ballooning = no, dom0 will never balloon out.
diff --git a/SOURCES/xen-dumpdir.patch b/SOURCES/xen-dumpdir.patch
new file mode 100644 (file)
index 0000000..c0e7186
--- /dev/null
@@ -0,0 +1,32 @@
+diff -up xen-3.4.0/tools/Makefile.dump xen-3.4.0/tools/Makefile
+--- xen-3.4.0/tools/Makefile.dump      2009-05-18 13:05:38.000000000 +0200
++++ xen-3.4.0/tools/Makefile   2009-05-20 17:03:26.000000000 +0200
+@@ -46,7 +46,7 @@ all: subdirs-all
+ .PHONY: install
+ install: subdirs-install
+-      $(INSTALL_DIR) $(DESTDIR)/var/xen/dump
++      $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/dump
+       $(INSTALL_DIR) $(DESTDIR)/var/log/xen
+       $(INSTALL_DIR) $(DESTDIR)/var/lib/xen
+       $(INSTALL_DIR) $(DESTDIR)/var/lock/subsys
+--- xen-4.0.0/tools/python/xen/xend/XendDomainInfo.py.orig     2010-02-02 20:43:01.000000000 +0000
++++ xen-4.0.0/tools/python/xen/xend/XendDomainInfo.py  2010-02-02 21:36:57.000000000 +0000
+@@ -2287,7 +2287,7 @@
+             # To prohibit directory traversal
+             based_name = os.path.basename(self.info['name_label'])
+             
+-            coredir = "/var/xen/dump/%s" % (based_name)
++            coredir = "/var/lib/xen/dump/%s" % (based_name)
+             if not os.path.exists(coredir):
+                 try:
+                     mkdir.parents(coredir, stat.S_IRWXU)
+@@ -2296,7 +2296,7 @@
+             if not os.path.isdir(coredir):
+                 # Use former directory to dump core
+-                coredir = '/var/xen/dump'
++                coredir = '/var/lib/xen/dump'
+             this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
+             corefile = "%s/%s-%s.%s.core" % (coredir, this_time,
diff --git a/SOURCES/xen-initscript.patch b/SOURCES/xen-initscript.patch
new file mode 100644 (file)
index 0000000..b0112e5
--- /dev/null
@@ -0,0 +1,139 @@
+--- xen-4.2.1/tools/misc/xend.orig     2012-12-17 15:01:18.000000000 +0000
++++ xen-4.2.1/tools/misc/xend  2013-01-22 21:26:39.387953003 +0000
+@@ -8,103 +8,18 @@
+ """Xen management daemon.
+    Provides console server and HTTP management api.
+-   Run:
+-   xend start
+-
+-   Restart:
+-   xend restart
+-
+-   The daemon is stopped with:
+-   xend stop
+-
+    The daemon should reconnect to device control interfaces
+    and recover its state when restarted.
+-   On Solaris, the daemons are SMF managed, and you should not attempt
+-   to start xend by hand.
+ """
+-import fcntl
+-import glob
+-import os
+-import os.path
+ import sys
+-import socket
+-import signal
+-import time
+-import commands
+-
+ from xen.xend.server import SrvDaemon
+-class CheckError(ValueError):
+-    pass
+-
+-def hline():
+-    print >>sys.stderr, "*" * 70
+-
+-def msg(message):
+-    print >>sys.stderr, "*" * 3, message
+-
+-def check_logging():
+-    """Check python logging is installed and raise an error if not.
+-    Logging is standard from Python 2.3 on.
+-    """
+-    try:
+-        import logging
+-    except ImportError:
+-        hline()
+-        msg("Python logging is not installed.")
+-        msg("Use 'make install-logging' at the xen root to install.")
+-        msg("")
+-        msg("Alternatively download and install from")
+-        msg("http://www.red-dove.com/python_logging.html")
+-        hline()
+-        raise CheckError("logging is not installed")
+-
+-def check_user():
+-    """Check that the effective user id is 0 (root).
+-    """
+-    if os.geteuid() != 0:
+-        hline()
+-        msg("Xend must be run as root.")
+-        hline()
+-        raise CheckError("invalid user")
+-
+-def start_daemon(daemon, *args):
+-    if os.fork() == 0:
+-        os.execvp(daemon, (daemon,) + args)
+-
+-def start_blktapctrl():
+-    start_daemon("blktapctrl", "")
+-
+ def main():
+-    try:
+-        check_logging()
+-        check_user()
+-    except CheckError:
+-        sys.exit(1)
+-    
+     daemon = SrvDaemon.instance()
+-    if not sys.argv[1:]:
+-        print 'usage: %s {start|stop|reload|restart}' % sys.argv[0]
+-    elif sys.argv[1] == 'start':
+-        if os.uname()[0] != "SunOS":
+-            start_blktapctrl()
+-        return daemon.start()
+-    elif sys.argv[1] == 'trace_start':
+-        start_blktapctrl()
+-        return daemon.start(trace=1)
+-    elif sys.argv[1] == 'stop':
+-        return daemon.stop()
+-    elif sys.argv[1] == 'reload':
+-        return daemon.reloadConfig()
+-    elif sys.argv[1] == 'restart':
+-        start_blktapctrl()
+-        return daemon.stop() or daemon.start()
+-    elif sys.argv[1] == 'status':
++    if sys.argv[1:] and sys.argv[1] == 'status':
+         return daemon.status()
+-    else:
+-        print 'not an option:', sys.argv[1]
+-    return 1
++    return daemon.start()
+ if __name__ == '__main__':
+     sys.exit(main())
+diff -up xen-3.4.0/tools/python/xen/xend/osdep.py.fix xen-3.4.0/tools/python/xen/xend/osdep.py
+--- xen-3.4.0/tools/python/xen/xend/osdep.py.fix       2009-05-18 13:05:38.000000000 +0200
++++ xen-3.4.0/tools/python/xen/xend/osdep.py   2009-05-20 15:39:18.000000000 +0200
+@@ -27,7 +27,7 @@ _scripts_dir = {
+ _xend_autorestart = {
+     "NetBSD": True,
+-    "Linux": True,
++    "Linux": False,
+     "SunOS": False,
+ }
+diff -up xen-3.4.0/tools/python/xen/xend/server/SrvDaemon.py.fix xen-3.4.0/tools/python/xen/xend/server/SrvDaemon.py
+--- xen-3.4.0/tools/python/xen/xend/server/SrvDaemon.py.fix    2009-05-18 13:05:38.000000000 +0200
++++ xen-3.4.0/tools/python/xen/xend/server/SrvDaemon.py        2009-05-20 15:39:18.000000000 +0200
+@@ -110,7 +110,14 @@ class Daemon:
+         # Fork, this allows the group leader to exit,
+         # which means the child can never again regain control of the
+         # terminal
+-        if os.fork():
++        child = os.fork()
++        if child:
++            if not osdep.xend_autorestart:
++                pidfile = open(XEND_PID_FILE, 'w')
++                try:
++                    pidfile.write(str(child))
++                finally:
++                    pidfile.close()
+             os._exit(0)
+         # Detach from standard file descriptors, and redirect them to
diff --git a/SOURCES/xen-net-disable-iptables-on-bridge.patch b/SOURCES/xen-net-disable-iptables-on-bridge.patch
new file mode 100644 (file)
index 0000000..53383cf
--- /dev/null
@@ -0,0 +1,29 @@
+--- xen-4.1.0-orig/tools/hotplug/Linux/vif-bridge      2008-08-22 10:49:07.000000000 +0100
++++ xen-4.1.0-new/tools/hotplug/Linux/vif-bridge       2008-08-29 11:29:38.000000000 +0100
+@@ -96,10 +96,6 @@ case "$command" in
+         ;;
+ esac
+-if [ "$type_if" = vif ]; then
+-    handle_iptable
+-fi
+-
+ call_hooks vif post
+ log debug "Successful vif-bridge $command for $dev, bridge $bridge."
+--- xen-3.3.0-orig/tools/hotplug/Linux/xen-network-common.sh   2008-08-22 10:49:07.000000000 +0100
++++ xen-3.3.0-new/tools/hotplug/Linux/xen-network-common.sh    2008-08-29 11:29:38.000000000 +0100
+@@ -99,6 +99,13 @@ create_bridge () {
+       brctl addbr ${bridge}
+       brctl stp ${bridge} off
+       brctl setfd ${bridge} 0
++      # Setting these to zero stops guest<->LAN traffic
++      # traversing the bridge from hitting the *tables
++      # rulesets. guest<->host traffic still gets processed
++      # by the host's iptables rules so this isn't a hole
++      sysctl -q -w "net.bridge.bridge-nf-call-arptables=0"
++      sysctl -q -w "net.bridge.bridge-nf-call-ip6tables=0"
++      sysctl -q -w "net.bridge.bridge-nf-call-iptables=0"
+     fi
+ }
diff --git a/SOURCES/xen-watchdog.service b/SOURCES/xen-watchdog.service
new file mode 100644 (file)
index 0000000..8fd225a
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=Xen-watchdog - run xen watchdog daemon
+Requires=proc-xen.mount
+After=proc-xen.mount xend.service
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/xenwatchdogd 30 15
+KillSignal=USR1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/xen-xl-autoballon-with-auto-option.patch b/SOURCES/xen-xl-autoballon-with-auto-option.patch
new file mode 100644 (file)
index 0000000..c0f166b
--- /dev/null
@@ -0,0 +1,143 @@
+commit 48f4af18b3e1e36bf0eda793455ecaea9a316c65
+Author:     David Vrabel <[hidden email]>
+AuthorDate: Thu Apr 4 17:21:12 2013 +0000
+Commit:     Ian Jackson <[hidden email]>
+CommitDate: Mon Apr 8 17:04:52 2013 +0100
+
+    xl: extend autoballoon xl.conf option with an "auto" option
+   
+    autoballoon=1 is not recommened if dom0_mem was used to reduce the
+    amount of dom0 memory.  Instead of requiring users to change xl.conf
+    if they do this, extend the autoballoon option with a new choice:
+    "auto".
+   
+    With autoballoon="auto", autoballooning will be disabled if dom0_mem
+    was used on the Xen command line.
+   
+    For consistency, accept "on" and "off" as valid autoballoon options (1
+    and 0 are still accepted).
+   
+    The default remains "on" for now.
+   
+    Signed-off-by: David Vrabel <[hidden email]>
+    Acked-by: Ian Jackson <[hidden email]>
+---
+ docs/man/xl.conf.pod.5 |   21 ++++++++++++++-------
+ tools/examples/xl.conf |    7 ++++---
+ tools/libxl/xl.c       |   36 ++++++++++++++++++++++++++++++++++--
+ 3 files changed, 52 insertions(+), 12 deletions(-)
+
+diff --git a/docs/man/xl.conf.pod.5 b/docs/man/xl.conf.pod.5
+index 7b9fcac..a4ce3e5 100644
+--- a/docs/man/xl.conf.pod.5
++++ b/docs/man/xl.conf.pod.5
+@@ -45,15 +45,22 @@ The semantics of each C<KEY> defines which form of C<VALUE> is required.
+ =over 4
+-=item B<autoballoon=BOOLEAN>
++=item B<autoballoon="off"|"on"|"auto">
+-If disabled then C<xl> will not attempt to reduce the amount of memory
+-assigned to domain 0 in order to create free memory when starting a
+-new domain. You are strongly recommended to set this to C<0>
+-(C<False>) if you use the C<dom0_mem> hypervisor command line to
+-reduce the amount of memory given to domain 0 by default.
++If set to "on" then C<xl> will automatically reduce the amount of
++memory assigned to domain 0 in order to free memory for new domains.
+-Default: C<1>
++If set to "off" then C<xl> will not automatically reduce the amount of
++domain 0 memory.
++
++If set to "auto" then auto-ballooning will be disabled if the
++C<dom0_mem> option was provided on the Xen command line.
++
++You are strongly recommended to set this to C<"off"> (or C<"auto">) if
++you use the C<dom0_mem> hypervisor command line to reduce the amount
++of memory given to domain 0 by default.
++
++Default: C<"on">
+ =item B<run_hotplug_scripts=BOOLEAN>
+diff --git a/tools/examples/xl.conf b/tools/examples/xl.conf
+index b0caa32..50cba2b 100644
+--- a/tools/examples/xl.conf
++++ b/tools/examples/xl.conf
+@@ -1,8 +1,9 @@
+ ## Global XL config file ##
+-# automatically balloon down dom0 when xen doesn't have enough free
+-# memory to create a domain
+-#autoballoon=1
++# Control whether dom0 is ballooned down when xen doesn't have enough
++# free memory to create a domain.  "auto" means only balloon if dom0
++# starts with all the host's memory.
++#autoballoon="auto"
+ # full path of the lockfile used by xl during domain creation
+ #lockfile="/var/lock/xl"
+diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c
+index 4c598db..ac41fcd 100644
+--- a/tools/libxl/xl.c
++++ b/tools/libxl/xl.c
+@@ -26,6 +26,7 @@
+ #include <fcntl.h>
+ #include <ctype.h>
+ #include <inttypes.h>
++#include <regex.h>
+ #include "libxl.h"
+ #include "libxl_utils.h"
+@@ -48,6 +49,29 @@ enum output_format default_output_format = OUTPUT_FORMAT_JSON;
+ static xentoollog_level minmsglevel = XTL_PROGRESS;
++/* Get autoballoon option based on presence of dom0_mem Xen command
++   line option. */
++static int auto_autoballoon(void)
++{
++    const libxl_version_info *info;
++    regex_t regex;
++    int ret;
++
++    info = libxl_get_version_info(ctx);
++    if (!info)
++        return 1; /* default to on */
++
++    ret = regcomp(&regex,
++                  "(^| )dom0_mem=((|min:|max:)[0-9]+[bBkKmMgG]?,?)+($| )",
++                  REG_NOSUB | REG_EXTENDED);
++    if (ret)
++        return 1;
++
++    ret = regexec(&regex, info->commandline, 0, NULL, 0);
++    regfree(&regex);
++    return ret == REG_NOMATCH;
++}
++
+ static void parse_global_config(const char *configfile,
+                               const char *configfile_data,
+                               int configfile_len)
+@@ -69,8 +93,16 @@ static void parse_global_config(const char *configfile,
+         exit(1);
+     }
+-    if (!xlu_cfg_get_long (config, "autoballoon", &l, 0))
+-        autoballoon = l;
++    if (!xlu_cfg_get_string(config, "autoballoon", &buf, 0)) {
++        if (!strcmp(buf, "on") || !strcmp(buf, "1"))
++            autoballoon = 1;
++        else if (!strcmp(buf, "off") || !strcmp(buf, "0"))
++            autoballoon = 0;
++        else if (!strcmp(buf, "auto"))
++            autoballoon = auto_autoballoon();
++        else
++            fprintf(stderr, "invalid autoballoon option");
++    }
+     if (!xlu_cfg_get_long (config, "run_hotplug_scripts", &l, 0))
+         run_hotplug_scripts = l;
+--
+generated by git-patchbot for /home/xen/git/xen.git#master
diff --git a/SOURCES/xen-xl-set-autoballon-default-auto.patch b/SOURCES/xen-xl-set-autoballon-default-auto.patch
new file mode 100644 (file)
index 0000000..430899d
--- /dev/null
@@ -0,0 +1,60 @@
+commit 0e6086a7de36e539d54eb82e61cf94e7f5363c02
+Author:     David Vrabel <[hidden email]>
+AuthorDate: Thu Apr 4 17:21:12 2013 +0000
+Commit:     Ian Jackson <[hidden email]>
+CommitDate: Mon Apr 8 17:05:46 2013 +0100
+
+    xl: default autoballoon option to "auto"
+   
+    In xl.conf, autoballoon="auto" will do the right thing for most
+    people.  Make it the default (instead of "on").
+   
+    Signed-off-by: David Vrabel <[hidden email]>
+    Committed-by: Ian Jackson <[hidden email]>
+---
+ docs/man/xl.conf.pod.5 |    2 +-
+ tools/libxl/xl.c       |    6 ++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/docs/man/xl.conf.pod.5 b/docs/man/xl.conf.pod.5
+index a4ce3e5..aaf8da1 100644
+--- a/docs/man/xl.conf.pod.5
++++ b/docs/man/xl.conf.pod.5
+@@ -60,7 +60,7 @@ You are strongly recommended to set this to C<"off"> (or C<"auto">) if
+ you use the C<dom0_mem> hypervisor command line to reduce the amount
+ of memory given to domain 0 by default.
+-Default: C<"on">
++Default: C<"auto">
+ =item B<run_hotplug_scripts=BOOLEAN>
+diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c
+index ac41fcd..16cd3f3 100644
+--- a/tools/libxl/xl.c
++++ b/tools/libxl/xl.c
+@@ -38,7 +38,7 @@
+ xentoollog_logger_stdiostream *logger;
+ int dryrun_only;
+ int force_execution;
+-int autoballoon = 1;
++int autoballoon = -1;
+ char *blkdev_start;
+ int run_hotplug_scripts = 1;
+ char *lockfile;
+@@ -99,10 +99,12 @@ static void parse_global_config(const char *configfile,
+         else if (!strcmp(buf, "off") || !strcmp(buf, "0"))
+             autoballoon = 0;
+         else if (!strcmp(buf, "auto"))
+-            autoballoon = auto_autoballoon();
++            autoballoon = -1;
+         else
+             fprintf(stderr, "invalid autoballoon option");
+     }
++    if (autoballoon == -1)
++        autoballoon = auto_autoballoon();
+     if (!xlu_cfg_get_long (config, "run_hotplug_scripts", &l, 0))
+         run_hotplug_scripts = l;
+--
+generated by git-patchbot for /home/xen/git/xen.git#master
diff --git a/SOURCES/xen.fedora.efi.build.patch b/SOURCES/xen.fedora.efi.build.patch
new file mode 100644 (file)
index 0000000..1f5e402
--- /dev/null
@@ -0,0 +1,46 @@
+--- xen-4.2.0/xen/arch/x86/Makefile.orig       2012-05-12 16:40:48.000000000 +0100
++++ xen-4.2.0/xen/arch/x86/Makefile    2012-08-02 21:47:39.849910608 +0100
+@@ -126,18 +126,18 @@
+ $(TARGET).efi: guard = $(if $(shell echo efi/dis* | grep disabled),:)
+ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc
+       $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
+-                $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
++                $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
+                       $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).$(base).0 &&) :
+       $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S
+       $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).0 | $(guard) $(BASEDIR)/tools/symbols >$(@D)/.$(@F).0s.S
+       $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o
+       $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
+-                $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
++                $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
+                       $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o -o $(@D)/.$(@F).$(base).1 &&) :
+       $(guard) efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S
+       $(guard) $(NM) -n $(@D)/.$(@F).$(VIRT_BASE).1 | $(guard) $(BASEDIR)/tools/symbols >$(@D)/.$(@F).1s.S
+       $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o
+-      $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
++      $(guard) $(LD_EFI) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
+                       $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@
+       if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi
+       rm -f $(@D)/.$(@F).[0-9]*
+--- xen-4.2.0/xen/arch/x86/efi/Makefile.orig   2012-05-12 16:40:48.000000000 +0100
++++ xen-4.2.0/xen/arch/x86/efi/Makefile        2012-08-02 22:01:43.956357825 +0100
+@@ -6,7 +6,7 @@
+ efi := $(filter y,$(x86_64)$(shell rm -f disabled))
+ efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
+-efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
++efi := $(if $(efi),$(shell $(LD_EFI) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
+ efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
+ extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
+--- xen-4.2.0/xen/Makefile.orig        2012-07-30 19:21:20.000000000 +0100
++++ xen-4.2.0/xen/Makefile     2012-08-02 22:07:22.801121685 +0100
+@@ -13,6 +13,8 @@
+ export XEN_ROOT := $(BASEDIR)/..
+ EFI_MOUNTPOINT ?= /boot/efi
++EFI_VENDOR=fedora
++LD_EFI ?= $(LD)
+ .PHONY: default
+ default: build
diff --git a/SOURCES/xen.fedora19.buildfix.patch b/SOURCES/xen.fedora19.buildfix.patch
new file mode 100644 (file)
index 0000000..a02e45a
--- /dev/null
@@ -0,0 +1,20 @@
+--- xen-4.2.1/tools/debugger/gdbsx/xg/xg_main.c.orig   2012-11-15 20:08:11.000000000 +0000
++++ xen-4.2.1/tools/debugger/gdbsx/xg/xg_main.c        2012-11-16 23:08:08.716874198 +0000
+@@ -178,7 +178,7 @@
+     hypercall.op = __HYPERVISOR_domctl;
+     hypercall.arg[0] = (unsigned long)&domctl;
+-    rc = ioctl(_dom0_fd, IOCTL_PRIVCMD_HYPERCALL, (ulong)&hypercall);
++    rc = ioctl(_dom0_fd, IOCTL_PRIVCMD_HYPERCALL, (unsigned long)&hypercall);
+     if (domctlarg && sz)
+         munlock(domctlarg, sz);
+     return rc;
+@@ -218,7 +218,7 @@
+     hypercall.arg[0] = (unsigned long)XENVER_capabilities;
+     hypercall.arg[1] = (unsigned long)&xen_caps;
+-    rc = ioctl(_dom0_fd, IOCTL_PRIVCMD_HYPERCALL, (ulong)&hypercall);
++    rc = ioctl(_dom0_fd, IOCTL_PRIVCMD_HYPERCALL, (unsigned long)&hypercall);
+     munlock(&xen_caps, sizeof(xen_caps));
+     XGTRC("XENCAPS:%s\n", xen_caps);
diff --git a/SOURCES/xen.git-9c23a1d0eb7a6b5e3273d527cfd7960838fbfee6.patch b/SOURCES/xen.git-9c23a1d0eb7a6b5e3273d527cfd7960838fbfee6.patch
new file mode 100644 (file)
index 0000000..36d942a
--- /dev/null
@@ -0,0 +1,61 @@
+From 9c23a1d0eb7a6b5e3273d527cfd7960838fbfee6 Mon Sep 17 00:00:00 2001
+From: Bamvor Jian Zhang <bjzhang@suse.com>
+Date: Fri, 11 Jan 2013 12:22:28 +0000
+Subject: [PATCH 1/1] fix wrong path while calling pygrub and libxl-save-helper
+
+in current xen x86_64, the default libexec directory is /usr/lib/xen/bin,
+while the private binder is /usr/lib64/xen/bin. but some commands(pygrub,
+libxl-save-helper) located in private binder directory is called from
+libexec directory which lead to the following error:
+1, for pygrub bootloader:
+
+libxl: debug: libxl_bootloader.c:429:bootloader_disk_attached_cb: /usr/lib/xen/bin/pygrub doesn't exist, falling back to config path
+
+2, for libxl-save-helper:
+
+libxl: cannot execute /usr/lib/xen/bin/libxl-save-helper: No such file or directory
+libxl: error: libxl_utils.c:363:libxl_read_exactly: file/stream truncated reading ipc msg header from domain 3 save/restore helper stdout pipe
+libxl: error: libxl_exec.c:118:libxl_report_child_exitstatus: domain 3 save/restore helper [10222] exited with error status 255
+
+there are two ways to fix above error. the first one is make such command
+store in the /usr/lib/xen/bin and /usr/lib64/xen/bin(symbol link to
+previous), e.g. qemu-dm. The second way is using private binder dir
+instead of libexec dir. e.g. xenconsole.
+For these cases, the latter one is suitable.
+
+Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>
+Committed-by: Ian Campbell <ian.campbell@citrix.com>
+---
+ tools/libxl/libxl_bootloader.c   |    2 +-
+ tools/libxl/libxl_save_callout.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c
+index e103ee9..ed12b2c 100644
+--- a/tools/libxl/libxl_bootloader.c
++++ b/tools/libxl/libxl_bootloader.c
+@@ -419,7 +419,7 @@ static void bootloader_disk_attached_cb(libxl__egc *egc,
+         const char *bltmp;
+         struct stat st;
+-        bltmp = libxl__abs_path(gc, bootloader, libxl__libexec_path());
++        bltmp = libxl__abs_path(gc, bootloader, libxl__private_bindir_path());
+         /* Check to see if the file exists in this location; if not,
+          * fall back to checking the path */
+         LOG(DEBUG, "Checking for bootloader in libexec path: %s", bltmp);
+diff --git a/tools/libxl/libxl_save_callout.c b/tools/libxl/libxl_save_callout.c
+index 078b7ee..f164e98 100644
+--- a/tools/libxl/libxl_save_callout.c
++++ b/tools/libxl/libxl_save_callout.c
+@@ -172,7 +172,7 @@ static void run_helper(libxl__egc *egc, libxl__save_helper_state *shs,
+     shs->stdout_what = GCSPRINTF("domain %"PRIu32" save/restore helper"
+                                  " stdout pipe", domid);
+-    *arg++ = getenv("LIBXL_SAVE_HELPER") ?: LIBEXEC "/" "libxl-save-helper";
++    *arg++ = getenv("LIBXL_SAVE_HELPER") ?: PRIVATE_BINDIR "/" "libxl-save-helper";
+     *arg++ = mode_arg;
+     const char **stream_fd_arg = arg++;
+     for (i=0; i<num_argnums; i++)
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xen.logrotate b/SOURCES/xen.logrotate
new file mode 100644 (file)
index 0000000..f6c4203
--- /dev/null
@@ -0,0 +1,7 @@
+/var/log/xen/xend-debug.log /var/log/xen/xen-hotplug.log
+/var/log/xen/domain-builder-ng.log {
+    notifempty
+    missingok
+    copytruncate
+}
+
diff --git a/SOURCES/xen.modules b/SOURCES/xen.modules
new file mode 100644 (file)
index 0000000..1758380
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+test -d /proc/xen                              || exit 0
+test -f /proc/xen/capabilities                 || mount -t xenfs xen /proc/xen
+test -f /proc/xen/capabilities                 || exit 0
+grep -q "control_d" /proc/xen/capabilities     || exit 0
+
+for module in xen-evtchn evtchn xen-gntdev gntdev xen-blkback xen-netback blkbk netbk blktap xen-acpi-processor; do
+       modprobe ${module} >/dev/null 2>&1
+done
diff --git a/SOURCES/xen.use.fedora.ipxe.patch b/SOURCES/xen.use.fedora.ipxe.patch
new file mode 100644 (file)
index 0000000..4588474
--- /dev/null
@@ -0,0 +1,33 @@
+--- xen-4.2.0/tools/firmware/hvmloader/Makefile.orig   2012-05-27 21:57:04.481812859 +0100
++++ xen-4.2.0/tools/firmware/hvmloader/Makefile        2012-06-02 18:52:44.935034128 +0100
+@@ -48,7 +48,7 @@
+ else
+ CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.bin
+ endif
+-ETHERBOOT_ROMS := $(addprefix ../etherboot/ipxe/src/bin/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
++ETHERBOOT_ROMS := $(addprefix /usr/share/ipxe/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
+ endif
+ ROMS := 
+--- xen-4.2.0/Config.mk.orig   2012-05-27 21:57:04.479812884 +0100
++++ xen-4.2.0/Config.mk        2012-06-02 18:55:14.087169469 +0100
+@@ -206,7 +206,7 @@
+ # Sun Mar 11 09:27:07 2012 -0400
+ # Update version to 1.6.3.2
+-ETHERBOOT_NICS ?= rtl8139 8086100e
++ETHERBOOT_NICS ?= 10ec8139 8086100e
+ # Specify which qemu-dm to use. This may be `ioemu' to use the old
+ # Mercurial in-tree version, or a local directory, or a git URL.
+--- xen-4.2.0/tools/firmware/Makefile.orig     2012-05-27 21:57:04.480812871 +0100
++++ xen-4.2.0/tools/firmware/Makefile  2012-06-02 19:03:52.254691484 +0100
+@@ -10,7 +10,7 @@
+ #SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
+ SUBDIRS-$(CONFIG_ROMBIOS) += rombios
+ SUBDIRS-$(CONFIG_ROMBIOS) += vgabios
+-SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
++#SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
+ SUBDIRS-y += hvmloader
+ ovmf:
diff --git a/SOURCES/xen.use.fedora.seabios.patch b/SOURCES/xen.use.fedora.seabios.patch
new file mode 100644 (file)
index 0000000..86d46aa
--- /dev/null
@@ -0,0 +1,22 @@
+--- xen-4.2.0/tools/firmware/Makefile.orig     2012-05-12 16:40:47.000000000 +0100
++++ xen-4.2.0/tools/firmware/Makefile  2012-05-27 21:55:23.438076078 +0100
+@@ -7,7 +7,7 @@
+ SUBDIRS-y :=
+ SUBDIRS-$(CONFIG_OVMF) += ovmf
+-SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
++#SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir
+ SUBDIRS-$(CONFIG_ROMBIOS) += rombios
+ SUBDIRS-$(CONFIG_ROMBIOS) += vgabios
+ SUBDIRS-$(CONFIG_ROMBIOS) += etherboot
+--- xen-4.2.0/tools/firmware/hvmloader/Makefile.orig   2012-05-12 16:40:47.000000000 +0100
++++ xen-4.2.0/tools/firmware/hvmloader/Makefile        2012-05-27 21:53:45.625298906 +0100
+@@ -70,7 +70,7 @@
+ ifeq ($(CONFIG_SEABIOS),y)
+ OBJS += seabios.o
+ CFLAGS += -DENABLE_SEABIOS
+-SEABIOS_ROM := $(SEABIOS_DIR)/out/bios.bin
++SEABIOS_ROM := /usr/share/seabios/bios.bin
+ ROMS += $(SEABIOS_ROM)
+ endif
diff --git a/SOURCES/xenconsoled.service b/SOURCES/xenconsoled.service
new file mode 100644 (file)
index 0000000..4c5429f
--- /dev/null
@@ -0,0 +1,18 @@
+[Unit]
+Description=Xenconsoled - handles logging from guest consoles and hypervisor
+Requires=proc-xen.mount
+After=proc-xen.mount xenstored.service
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=simple
+Environment=XENCONSOLED_ARGS=
+Environment=XENCONSOLED_LOG=none
+Environment=XENCONSOLED_LOG_DIR=/var/log/xen/console
+EnvironmentFile=-/etc/sysconfig/xenconsoled
+PIDFile=/var/run/xenconsoled.pid
+ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
+ExecStart=/usr/sbin/xenconsoled --log=${XENCONSOLED_LOG} --log-dir=${XENCONSOLED_LOG_DIR} $XENCONSOLED_ARGS
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/xend-pci-loop.patch b/SOURCES/xend-pci-loop.patch
new file mode 100644 (file)
index 0000000..5c4118a
--- /dev/null
@@ -0,0 +1,19 @@
+# Don't crash due to weird PCI cards (Bug 767742)
+
+diff -r fb8dd4c67778 tools/python/xen/util/pci.py
+--- a/tools/python/xen/util/pci.py     Tue Dec 13 14:16:20 2011 -0500
++++ b/tools/python/xen/util/pci.py     Wed Dec 14 15:46:56 2011 -0500
+@@ -1268,7 +1268,12 @@ class PciDevice:
+             pass
+     def get_info_from_sysfs(self):
+-        self.find_capability(0x11)
++        try:
++            self.find_capability(0x11)
++        except PciDeviceParseError, err:
++            log.error("Caught '%s'" % err)
++            return False
++
+         sysfs_mnt = find_sysfs_mnt()
+         if sysfs_mnt == None:
+             return False
diff --git a/SOURCES/xend.catchbt.patch b/SOURCES/xend.catchbt.patch
new file mode 100644 (file)
index 0000000..95eac54
--- /dev/null
@@ -0,0 +1,30 @@
+--- xen-4.1.2/tools/python/xen/xend/image.py.orig      2011-10-20 18:05:44.000000000 +0100
++++ xen-4.1.2/tools/python/xen/xend/image.py   2011-11-20 20:41:10.730905790 +0000
+@@ -43,7 +43,11 @@
+ from xen.util import utils
+ from xen.xend import osdep
+-xc = xen.lowlevel.xc.xc()
++try:
++    xc = xen.lowlevel.xc.xc()
++except Exception:
++    print >>sys.stderr, ('xend/image.py: Error connecting to hypervisor')
++    os._exit(1)
+ MAX_GUEST_CMDLINE = 1024
+--- xen-4.1.2/tools/python/xen/xend/XendLogging.py.orig        2011-10-20 18:05:44.000000000 +0100
++++ xen-4.1.2/tools/python/xen/xend/XendLogging.py     2012-01-10 21:27:57.304916048 +0000
+@@ -132,7 +132,11 @@
+         fileHandler = openFileHandler(filename)
+         logfilename = filename
+     except IOError:
+-        logfilename = tempfile.mkstemp("-xend.log")[1]
++        try:
++            logfilename = tempfile.mkstemp("-xend.log")[1]
++        except IOError:
++            print >>sys.stderr, ('xend/XendLogging.py: Unable to open standard or temporary log file for xend')
++            os._exit(1)
+         fileHandler = openFileHandler(logfilename)
+     fileHandler.setFormatter(logging.Formatter(LOGFILE_FORMAT, DATE_FORMAT))
diff --git a/SOURCES/xend.selinux.fixes.patch b/SOURCES/xend.selinux.fixes.patch
new file mode 100644 (file)
index 0000000..61be90e
--- /dev/null
@@ -0,0 +1,20 @@
+--- xen-4.1.2/tools/python/xen/xend/server/SrvDaemon.py.orig   2012-04-15 17:17:50.167887550 +0100
++++ xen-4.1.2/tools/python/xen/xend/server/SrvDaemon.py        2012-04-15 17:31:13.648842655 +0100
+@@ -325,7 +325,8 @@
+     def set_user(self):
+         # Set the UID.
+         try:
+-            os.setuid(pwd.getpwnam(XEND_USER)[2])
++            if XEND_USER != "root":
++                os.setuid(pwd.getpwnam(XEND_USER)[2])
+             return 0
+         except KeyError:
+             print >>sys.stderr, "Error: no such user '%s'" % XEND_USER
+--- xen-4.1.2/tools/misc/xend.orig     2012-08-07 00:54:02.372867624 +0100
++++ xen-4.1.2/tools/misc/xend  2012-08-07 00:58:11.469753483 +0100
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/python -Es
+ #  -*- mode: python; -*-
+ #============================================================================
+ # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
diff --git a/SOURCES/xend.service b/SOURCES/xend.service
new file mode 100644 (file)
index 0000000..c9abb9f
--- /dev/null
@@ -0,0 +1,16 @@
+[Unit]
+Description=Xend - interface between hypervisor and some applications
+Requires=proc-xen.mount
+After=proc-xen.mount
+Before=libvirtd.service libvirt-guests.service
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=forking
+PIDFile=/var/run/xend.pid
+Environment=HOME=/root
+ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
+ExecStart=/usr/sbin/xend
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/xendomains.service b/SOURCES/xendomains.service
new file mode 100644 (file)
index 0000000..0bd72d7
--- /dev/null
@@ -0,0 +1,15 @@
+[Unit]
+Description=Xendomains - start and stop guests on boot and shutdown
+Requires=proc-xen.mount xenstored.service
+After=proc-xen.mount xenstored.service xenconsoled.service
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=oneshot
+RemainAfterExit=true
+ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
+ExecStart=-/usr/libexec/xendomains start
+ExecStop=/usr/libexec/xendomains stop
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/xenstored.service b/SOURCES/xenstored.service
new file mode 100644 (file)
index 0000000..59b640a
--- /dev/null
@@ -0,0 +1,18 @@
+[Unit]
+Description=Xenstored - daemon managing xenstore file system
+Requires=proc-xen.mount var-lib-xenstored.mount
+After=proc-xen.mount var-lib-xenstored.mount
+Before=libvirtd.service libvirt-guests.service
+RefuseManualStop=true
+ConditionPathExists=/proc/xen
+
+[Service]
+Type=forking
+Environment=XENSTORED_ARGS=
+EnvironmentFile=-/etc/sysconfig/xenstored
+PIDFile=/var/run/xenstored.pid
+ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
+ExecStart=/usr/sbin/xenstored --pid-file /var/run/xenstored.pid $XENSTORED_ARGS
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/xl.list.-l.format.patch b/SOURCES/xl.list.-l.format.patch
new file mode 100644 (file)
index 0000000..aa13218
--- /dev/null
@@ -0,0 +1,20 @@
+xl list -l should produce readable output when built with yajl2 so
+it is compatible with the xendomains script.
+
+Signed-off-by: Michael Young <m.a.young@durham.ac.uk>
+
+--- xen-4.2.2/tools/libxl/libxl_json.h.orig    2013-03-21 17:55:42.000000000 +0000
++++ xen-4.2.2/tools/libxl/libxl_json.h 2013-04-10 22:14:15.938459238 +0100
+@@ -54,7 +54,11 @@
+ static inline yajl_gen libxl_yajl_gen_alloc(const yajl_alloc_funcs *allocFuncs)
+ {
+-    return yajl_gen_alloc(allocFuncs);
++    yajl_gen g;
++    g = yajl_gen_alloc(allocFuncs);
++    if (g)
++        yajl_gen_config(g, yajl_gen_beautify, 1);
++    return g;
+ }
+ #else /* !HAVE_YAJL_V2 */
diff --git a/SOURCES/xsa45-4.2-01-vcpu-destroy-pagetables-preemptible.patch b/SOURCES/xsa45-4.2-01-vcpu-destroy-pagetables-preemptible.patch
new file mode 100644 (file)
index 0000000..f5ded0a
--- /dev/null
@@ -0,0 +1,252 @@
+x86: make vcpu_destroy_pagetables() preemptible
+
+... as it may take significant amounts of time.
+
+The function, being moved to mm.c as the better home for it anyway, and
+to avoid having to make a new helper function there non-static, is
+given a "preemptible" parameter temporarily (until, in a subsequent
+patch, its other caller is also being made capable of dealing with
+preemption).
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -73,8 +73,6 @@ void (*dead_idle) (void) __read_mostly =
+ static void paravirt_ctxt_switch_from(struct vcpu *v);
+ static void paravirt_ctxt_switch_to(struct vcpu *v);
+-static void vcpu_destroy_pagetables(struct vcpu *v);
+-
+ static void default_idle(void)
+ {
+     local_irq_disable();
+@@ -1058,7 +1056,7 @@ void arch_vcpu_reset(struct vcpu *v)
+     if ( !is_hvm_vcpu(v) )
+     {
+         destroy_gdt(v);
+-        vcpu_destroy_pagetables(v);
++        vcpu_destroy_pagetables(v, 0);
+     }
+     else
+     {
+@@ -2069,63 +2067,6 @@ static int relinquish_memory(
+     return ret;
+ }
+-static void vcpu_destroy_pagetables(struct vcpu *v)
+-{
+-    struct domain *d = v->domain;
+-    unsigned long pfn;
+-
+-#ifdef __x86_64__
+-    if ( is_pv_32on64_vcpu(v) )
+-    {
+-        pfn = l4e_get_pfn(*(l4_pgentry_t *)
+-                          __va(pagetable_get_paddr(v->arch.guest_table)));
+-
+-        if ( pfn != 0 )
+-        {
+-            if ( paging_mode_refcounts(d) )
+-                put_page(mfn_to_page(pfn));
+-            else
+-                put_page_and_type(mfn_to_page(pfn));
+-        }
+-
+-        l4e_write(
+-            (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
+-            l4e_empty());
+-
+-        v->arch.cr3 = 0;
+-        return;
+-    }
+-#endif
+-
+-    pfn = pagetable_get_pfn(v->arch.guest_table);
+-    if ( pfn != 0 )
+-    {
+-        if ( paging_mode_refcounts(d) )
+-            put_page(mfn_to_page(pfn));
+-        else
+-            put_page_and_type(mfn_to_page(pfn));
+-        v->arch.guest_table = pagetable_null();
+-    }
+-
+-#ifdef __x86_64__
+-    /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
+-    pfn = pagetable_get_pfn(v->arch.guest_table_user);
+-    if ( pfn != 0 )
+-    {
+-        if ( !is_pv_32bit_vcpu(v) )
+-        {
+-            if ( paging_mode_refcounts(d) )
+-                put_page(mfn_to_page(pfn));
+-            else
+-                put_page_and_type(mfn_to_page(pfn));
+-        }
+-        v->arch.guest_table_user = pagetable_null();
+-    }
+-#endif
+-
+-    v->arch.cr3 = 0;
+-}
+-
+ int domain_relinquish_resources(struct domain *d)
+ {
+     int ret;
+@@ -2143,7 +2084,11 @@ int domain_relinquish_resources(struct d
+         /* Drop the in-use references to page-table bases. */
+         for_each_vcpu ( d, v )
+-            vcpu_destroy_pagetables(v);
++        {
++            ret = vcpu_destroy_pagetables(v, 1);
++            if ( ret )
++                return ret;
++        }
+         if ( !is_hvm_domain(d) )
+         {
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -2808,6 +2808,82 @@ static void put_superpage(unsigned long 
+ #endif
++static int put_old_guest_table(struct vcpu *v)
++{
++    int rc;
++
++    if ( !v->arch.old_guest_table )
++        return 0;
++
++    switch ( rc = put_page_and_type_preemptible(v->arch.old_guest_table, 1) )
++    {
++    case -EINTR:
++    case -EAGAIN:
++        return -EAGAIN;
++    }
++
++    v->arch.old_guest_table = NULL;
++
++    return rc;
++}
++
++int vcpu_destroy_pagetables(struct vcpu *v, bool_t preemptible)
++{
++    unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
++    struct page_info *page;
++    int rc = put_old_guest_table(v);
++
++    if ( rc )
++        return rc;
++
++#ifdef __x86_64__
++    if ( is_pv_32on64_vcpu(v) )
++        mfn = l4e_get_pfn(*(l4_pgentry_t *)mfn_to_virt(mfn));
++#endif
++
++    if ( mfn )
++    {
++        page = mfn_to_page(mfn);
++        if ( paging_mode_refcounts(v->domain) )
++            put_page(page);
++        else
++            rc = put_page_and_type_preemptible(page, preemptible);
++    }
++
++#ifdef __x86_64__
++    if ( is_pv_32on64_vcpu(v) )
++    {
++        if ( !rc )
++            l4e_write(
++                (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
++                l4e_empty());
++    }
++    else
++#endif
++    if ( !rc )
++    {
++        v->arch.guest_table = pagetable_null();
++
++#ifdef __x86_64__
++        /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
++        mfn = pagetable_get_pfn(v->arch.guest_table_user);
++        if ( mfn )
++        {
++            page = mfn_to_page(mfn);
++            if ( paging_mode_refcounts(v->domain) )
++                put_page(page);
++            else
++                rc = put_page_and_type_preemptible(page, preemptible);
++        }
++        if ( !rc )
++            v->arch.guest_table_user = pagetable_null();
++#endif
++    }
++
++    v->arch.cr3 = 0;
++
++    return rc;
++}
+ int new_guest_cr3(unsigned long mfn)
+ {
+@@ -2994,12 +3070,21 @@ long do_mmuext_op(
+     unsigned int foreigndom)
+ {
+     struct mmuext_op op;
+-    int rc = 0, i = 0, okay;
+     unsigned long type;
+-    unsigned int done = 0;
++    unsigned int i = 0, done = 0;
+     struct vcpu *curr = current;
+     struct domain *d = curr->domain;
+     struct domain *pg_owner;
++    int okay, rc = put_old_guest_table(curr);
++
++    if ( unlikely(rc) )
++    {
++        if ( likely(rc == -EAGAIN) )
++            rc = hypercall_create_continuation(
++                     __HYPERVISOR_mmuext_op, "hihi", uops, count, pdone,
++                     foreigndom);
++        return rc;
++    }
+     if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
+     {
+--- a/xen/arch/x86/x86_64/compat/mm.c
++++ b/xen/arch/x86/x86_64/compat/mm.c
+@@ -365,7 +365,7 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
+                                     : mcs->call.args[1];
+                 unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
+-                BUG_ON(left == arg1);
++                BUG_ON(left == arg1 && left != i);
+                 BUG_ON(left > count);
+                 guest_handle_add_offset(nat_ops, i - left);
+                 guest_handle_subtract_offset(cmp_uops, left);
+--- a/xen/include/asm-x86/domain.h
++++ b/xen/include/asm-x86/domain.h
+@@ -464,6 +464,7 @@ struct arch_vcpu
+     pagetable_t guest_table_user;       /* (MFN) x86/64 user-space pagetable */
+ #endif
+     pagetable_t guest_table;            /* (MFN) guest notion of cr3 */
++    struct page_info *old_guest_table;  /* partially destructed pagetable */
+     /* guest_table holds a ref to the page, and also a type-count unless
+      * shadow refcounts are in use */
+     pagetable_t shadow_table[4];        /* (MFN) shadow(s) of guest */
+--- a/xen/include/asm-x86/mm.h
++++ b/xen/include/asm-x86/mm.h
+@@ -605,6 +605,7 @@ void audit_domains(void);
+ int new_guest_cr3(unsigned long pfn);
+ void make_cr3(struct vcpu *v, unsigned long mfn);
+ void update_cr3(struct vcpu *v);
++int vcpu_destroy_pagetables(struct vcpu *, bool_t preemptible);
+ void propagate_page_fault(unsigned long addr, u16 error_code);
+ void *do_page_walk(struct vcpu *v, unsigned long addr);
diff --git a/SOURCES/xsa45-4.2-02-new-guest-cr3-preemptible.patch b/SOURCES/xsa45-4.2-02-new-guest-cr3-preemptible.patch
new file mode 100644 (file)
index 0000000..f730b67
--- /dev/null
@@ -0,0 +1,169 @@
+x86: make new_guest_cr3() preemptible
+
+... as it may take significant amounts of time.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -2889,44 +2889,69 @@ int new_guest_cr3(unsigned long mfn)
+ {
+     struct vcpu *curr = current;
+     struct domain *d = curr->domain;
+-    int okay;
++    int rc;
+     unsigned long old_base_mfn;
+ #ifdef __x86_64__
+     if ( is_pv_32on64_domain(d) )
+     {
+-        okay = paging_mode_refcounts(d)
+-            ? 0 /* Old code was broken, but what should it be? */
+-            : mod_l4_entry(
++        rc = paging_mode_refcounts(d)
++             ? -EINVAL /* Old code was broken, but what should it be? */
++             : mod_l4_entry(
+                     __va(pagetable_get_paddr(curr->arch.guest_table)),
+                     l4e_from_pfn(
+                         mfn,
+                         (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)),
+-                    pagetable_get_pfn(curr->arch.guest_table), 0, 0, curr) == 0;
+-        if ( unlikely(!okay) )
++                    pagetable_get_pfn(curr->arch.guest_table), 0, 1, curr);
++        switch ( rc )
+         {
++        case 0:
++            break;
++        case -EINTR:
++        case -EAGAIN:
++            return -EAGAIN;
++        default:
+             MEM_LOG("Error while installing new compat baseptr %lx", mfn);
+-            return 0;
++            return rc;
+         }
+         invalidate_shadow_ldt(curr, 0);
+         write_ptbase(curr);
+-        return 1;
++        return 0;
+     }
+ #endif
+-    okay = paging_mode_refcounts(d)
+-        ? get_page_from_pagenr(mfn, d)
+-        : !get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 0);
+-    if ( unlikely(!okay) )
++    rc = put_old_guest_table(curr);
++    if ( unlikely(rc) )
++        return rc;
++
++    old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
++    /*
++     * This is particularly important when getting restarted after the
++     * previous attempt got preempted in the put-old-MFN phase.
++     */
++    if ( old_base_mfn == mfn )
+     {
+-        MEM_LOG("Error while installing new baseptr %lx", mfn);
++        write_ptbase(curr);
+         return 0;
+     }
+-    invalidate_shadow_ldt(curr, 0);
++    rc = paging_mode_refcounts(d)
++         ? (get_page_from_pagenr(mfn, d) ? 0 : -EINVAL)
++         : get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 1);
++    switch ( rc )
++    {
++    case 0:
++        break;
++    case -EINTR:
++    case -EAGAIN:
++        return -EAGAIN;
++    default:
++        MEM_LOG("Error while installing new baseptr %lx", mfn);
++        return rc;
++    }
+-    old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
++    invalidate_shadow_ldt(curr, 0);
+     curr->arch.guest_table = pagetable_from_pfn(mfn);
+     update_cr3(curr);
+@@ -2935,13 +2960,25 @@ int new_guest_cr3(unsigned long mfn)
+     if ( likely(old_base_mfn != 0) )
+     {
++        struct page_info *page = mfn_to_page(old_base_mfn);
++
+         if ( paging_mode_refcounts(d) )
+-            put_page(mfn_to_page(old_base_mfn));
++            put_page(page);
+         else
+-            put_page_and_type(mfn_to_page(old_base_mfn));
++            switch ( rc = put_page_and_type_preemptible(page, 1) )
++            {
++            case -EINTR:
++                rc = -EAGAIN;
++            case -EAGAIN:
++                curr->arch.old_guest_table = page;
++                break;
++            default:
++                BUG_ON(rc);
++                break;
++            }
+     }
+-    return 1;
++    return rc;
+ }
+ static struct domain *get_pg_owner(domid_t domid)
+@@ -3239,8 +3276,13 @@ long do_mmuext_op(
+         }
+         case MMUEXT_NEW_BASEPTR:
+-            okay = (!paging_mode_translate(d)
+-                    && new_guest_cr3(op.arg1.mfn));
++            if ( paging_mode_translate(d) )
++                okay = 0;
++            else
++            {
++                rc = new_guest_cr3(op.arg1.mfn);
++                okay = !rc;
++            }
+             break;
+         
+--- a/xen/arch/x86/traps.c
++++ b/xen/arch/x86/traps.c
+@@ -2407,12 +2407,23 @@ static int emulate_privileged_op(struct 
+ #endif
+             }
+             page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
+-            rc = page ? new_guest_cr3(page_to_mfn(page)) : 0;
+             if ( page )
++            {
++                rc = new_guest_cr3(page_to_mfn(page));
+                 put_page(page);
++            }
++            else
++                rc = -EINVAL;
+             domain_unlock(v->domain);
+-            if ( rc == 0 ) /* not okay */
++            switch ( rc )
++            {
++            case 0:
++                break;
++            case -EAGAIN: /* retry after preemption */
++                goto skip;
++            default:      /* not okay */
+                 goto fail;
++            }
+             break;
+         }
diff --git a/SOURCES/xsa45-4.2-03-new-user-base-preemptible.patch b/SOURCES/xsa45-4.2-03-new-user-base-preemptible.patch
new file mode 100644 (file)
index 0000000..9d5679e
--- /dev/null
@@ -0,0 +1,74 @@
+x86: make MMUEXT_NEW_USER_BASEPTR preemptible
+
+... as it may take significant amounts of time.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -3296,29 +3296,56 @@ long do_mmuext_op(
+                 break;
+             }
++            old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
++            /*
++             * This is particularly important when getting restarted after the
++             * previous attempt got preempted in the put-old-MFN phase.
++             */
++            if ( old_mfn == op.arg1.mfn )
++                break;
++
+             if ( op.arg1.mfn != 0 )
+             {
+                 if ( paging_mode_refcounts(d) )
+                     okay = get_page_from_pagenr(op.arg1.mfn, d);
+                 else
+-                    okay = !get_page_and_type_from_pagenr(
+-                        op.arg1.mfn, PGT_root_page_table, d, 0, 0);
++                {
++                    rc = get_page_and_type_from_pagenr(
++                        op.arg1.mfn, PGT_root_page_table, d, 0, 1);
++                    okay = !rc;
++                }
+                 if ( unlikely(!okay) )
+                 {
+-                    MEM_LOG("Error while installing new mfn %lx", op.arg1.mfn);
++                    if ( rc == -EINTR )
++                        rc = -EAGAIN;
++                    else if ( rc != -EAGAIN )
++                        MEM_LOG("Error while installing new mfn %lx",
++                                op.arg1.mfn);
+                     break;
+                 }
+             }
+-            old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
+             curr->arch.guest_table_user = pagetable_from_pfn(op.arg1.mfn);
+             if ( old_mfn != 0 )
+             {
++                struct page_info *page = mfn_to_page(old_mfn);
++
+                 if ( paging_mode_refcounts(d) )
+-                    put_page(mfn_to_page(old_mfn));
++                    put_page(page);
+                 else
+-                    put_page_and_type(mfn_to_page(old_mfn));
++                    switch ( rc = put_page_and_type_preemptible(page, 1) )
++                    {
++                    case -EINTR:
++                        rc = -EAGAIN;
++                    case -EAGAIN:
++                        curr->arch.old_guest_table = page;
++                        okay = 0;
++                        break;
++                    default:
++                        BUG_ON(rc);
++                        break;
++                    }
+             }
+             break;
diff --git a/SOURCES/xsa45-4.2-04-vcpu-reset-preemptible.patch b/SOURCES/xsa45-4.2-04-vcpu-reset-preemptible.patch
new file mode 100644 (file)
index 0000000..bbce567
--- /dev/null
@@ -0,0 +1,200 @@
+x86: make vcpu_reset() preemptible
+
+... as dropping the old page tables may take significant amounts of
+time.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -1051,17 +1051,16 @@ int arch_set_info_guest(
+ #undef c
+ }
+-void arch_vcpu_reset(struct vcpu *v)
++int arch_vcpu_reset(struct vcpu *v)
+ {
+     if ( !is_hvm_vcpu(v) )
+     {
+         destroy_gdt(v);
+-        vcpu_destroy_pagetables(v, 0);
+-    }
+-    else
+-    {
+-        vcpu_end_shutdown_deferral(v);
++        return vcpu_destroy_pagetables(v);
+     }
++
++    vcpu_end_shutdown_deferral(v);
++    return 0;
+ }
+ /* 
+@@ -2085,7 +2084,7 @@ int domain_relinquish_resources(struct d
+         /* Drop the in-use references to page-table bases. */
+         for_each_vcpu ( d, v )
+         {
+-            ret = vcpu_destroy_pagetables(v, 1);
++            ret = vcpu_destroy_pagetables(v);
+             if ( ret )
+                 return ret;
+         }
+--- a/xen/arch/x86/hvm/hvm.c
++++ b/xen/arch/x86/hvm/hvm.c
+@@ -3509,8 +3509,11 @@ static void hvm_s3_suspend(struct domain
+     for_each_vcpu ( d, v )
+     {
++        int rc;
++
+         vlapic_reset(vcpu_vlapic(v));
+-        vcpu_reset(v);
++        rc = vcpu_reset(v);
++        ASSERT(!rc);
+     }
+     vpic_reset(d);
+--- a/xen/arch/x86/hvm/vlapic.c
++++ b/xen/arch/x86/hvm/vlapic.c
+@@ -252,10 +252,13 @@ static void vlapic_init_sipi_action(unsi
+     {
+     case APIC_DM_INIT: {
+         bool_t fpu_initialised;
++        int rc;
++
+         domain_lock(target->domain);
+         /* Reset necessary VCPU state. This does not include FPU state. */
+         fpu_initialised = target->fpu_initialised;
+-        vcpu_reset(target);
++        rc = vcpu_reset(target);
++        ASSERT(!rc);
+         target->fpu_initialised = fpu_initialised;
+         vlapic_reset(vcpu_vlapic(target));
+         domain_unlock(target->domain);
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -2827,7 +2827,7 @@ static int put_old_guest_table(struct vc
+     return rc;
+ }
+-int vcpu_destroy_pagetables(struct vcpu *v, bool_t preemptible)
++int vcpu_destroy_pagetables(struct vcpu *v)
+ {
+     unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
+     struct page_info *page;
+@@ -2847,7 +2847,7 @@ int vcpu_destroy_pagetables(struct vcpu 
+         if ( paging_mode_refcounts(v->domain) )
+             put_page(page);
+         else
+-            rc = put_page_and_type_preemptible(page, preemptible);
++            rc = put_page_and_type_preemptible(page, 1);
+     }
+ #ifdef __x86_64__
+@@ -2873,7 +2873,7 @@ int vcpu_destroy_pagetables(struct vcpu 
+             if ( paging_mode_refcounts(v->domain) )
+                 put_page(page);
+             else
+-                rc = put_page_and_type_preemptible(page, preemptible);
++                rc = put_page_and_type_preemptible(page, 1);
+         }
+         if ( !rc )
+             v->arch.guest_table_user = pagetable_null();
+--- a/xen/common/domain.c
++++ b/xen/common/domain.c
+@@ -779,14 +779,18 @@ void domain_unpause_by_systemcontroller(
+         domain_unpause(d);
+ }
+-void vcpu_reset(struct vcpu *v)
++int vcpu_reset(struct vcpu *v)
+ {
+     struct domain *d = v->domain;
++    int rc;
+     vcpu_pause(v);
+     domain_lock(d);
+-    arch_vcpu_reset(v);
++    set_bit(_VPF_in_reset, &v->pause_flags);
++    rc = arch_vcpu_reset(v);
++    if ( rc )
++        goto out_unlock;
+     set_bit(_VPF_down, &v->pause_flags);
+@@ -802,9 +806,13 @@ void vcpu_reset(struct vcpu *v)
+ #endif
+     cpumask_clear(v->cpu_affinity_tmp);
+     clear_bit(_VPF_blocked, &v->pause_flags);
++    clear_bit(_VPF_in_reset, &v->pause_flags);
++ out_unlock:
+     domain_unlock(v->domain);
+     vcpu_unpause(v);
++
++    return rc;
+ }
+--- a/xen/common/domctl.c
++++ b/xen/common/domctl.c
+@@ -306,8 +306,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
+         if ( guest_handle_is_null(op->u.vcpucontext.ctxt) )
+         {
+-            vcpu_reset(v);
+-            ret = 0;
++            ret = vcpu_reset(v);
++            if ( ret == -EAGAIN )
++                ret = hypercall_create_continuation(
++                          __HYPERVISOR_domctl, "h", u_domctl);
+             goto svc_out;
+         }
+--- a/xen/include/asm-x86/mm.h
++++ b/xen/include/asm-x86/mm.h
+@@ -605,7 +605,7 @@ void audit_domains(void);
+ int new_guest_cr3(unsigned long pfn);
+ void make_cr3(struct vcpu *v, unsigned long mfn);
+ void update_cr3(struct vcpu *v);
+-int vcpu_destroy_pagetables(struct vcpu *, bool_t preemptible);
++int vcpu_destroy_pagetables(struct vcpu *);
+ void propagate_page_fault(unsigned long addr, u16 error_code);
+ void *do_page_walk(struct vcpu *v, unsigned long addr);
+--- a/xen/include/xen/domain.h
++++ b/xen/include/xen/domain.h
+@@ -13,7 +13,7 @@ typedef union {
+ struct vcpu *alloc_vcpu(
+     struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
+ struct vcpu *alloc_dom0_vcpu0(void);
+-void vcpu_reset(struct vcpu *v);
++int vcpu_reset(struct vcpu *);
+ struct xen_domctl_getdomaininfo;
+ void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info);
+@@ -67,7 +67,7 @@ void arch_dump_vcpu_info(struct vcpu *v)
+ void arch_dump_domain_info(struct domain *d);
+-void arch_vcpu_reset(struct vcpu *v);
++int arch_vcpu_reset(struct vcpu *);
+ extern spinlock_t vcpu_alloc_lock;
+ bool_t domctl_lock_acquire(void);
+--- a/xen/include/xen/sched.h
++++ b/xen/include/xen/sched.h
+@@ -644,6 +644,9 @@ static inline struct domain *next_domain
+  /* VCPU is blocked due to missing mem_sharing ring. */
+ #define _VPF_mem_sharing     6
+ #define VPF_mem_sharing      (1UL<<_VPF_mem_sharing)
++ /* VCPU is being reset. */
++#define _VPF_in_reset        7
++#define VPF_in_reset         (1UL<<_VPF_in_reset)
+ static inline int vcpu_runnable(struct vcpu *v)
+ {
diff --git a/SOURCES/xsa45-4.2-05-set-info-guest-preemptible.patch b/SOURCES/xsa45-4.2-05-set-info-guest-preemptible.patch
new file mode 100644 (file)
index 0000000..b584b38
--- /dev/null
@@ -0,0 +1,204 @@
+x86: make arch_set_info_guest() preemptible
+
+.. as the root page table validation (and the dropping of an eventual
+old one) can require meaningful amounts of time.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -858,6 +858,9 @@ int arch_set_info_guest(
+     if ( !v->is_initialised )
+     {
++        if ( !compat && !(flags & VGCF_in_kernel) && !c.nat->ctrlreg[1] )
++            return -EINVAL;
++
+         v->arch.pv_vcpu.ldt_base = c(ldt_base);
+         v->arch.pv_vcpu.ldt_ents = c(ldt_ents);
+     }
+@@ -955,24 +958,44 @@ int arch_set_info_guest(
+     if ( rc != 0 )
+         return rc;
++    set_bit(_VPF_in_reset, &v->pause_flags);
++
+     if ( !compat )
+-    {
+         cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]);
+-        cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
+-
+-        if ( !cr3_page )
+-        {
+-            destroy_gdt(v);
+-            return -EINVAL;
+-        }
+-        if ( !paging_mode_refcounts(d)
+-             && !get_page_type(cr3_page, PGT_base_page_table) )
+-        {
+-            put_page(cr3_page);
+-            destroy_gdt(v);
+-            return -EINVAL;
+-        }
++#ifdef CONFIG_COMPAT
++    else
++        cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
++#endif
++    cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
++    if ( !cr3_page )
++        rc = -EINVAL;
++    else if ( paging_mode_refcounts(d) )
++        /* nothing */;
++    else if ( cr3_page == v->arch.old_guest_table )
++    {
++        v->arch.old_guest_table = NULL;
++        put_page(cr3_page);
++    }
++    else
++    {
++        /*
++         * Since v->arch.guest_table{,_user} are both NULL, this effectively
++         * is just a call to put_old_guest_table().
++         */
++        if ( !compat )
++            rc = vcpu_destroy_pagetables(v);
++        if ( !rc )
++            rc = get_page_type_preemptible(cr3_page,
++                                           !compat ? PGT_root_page_table
++                                                   : PGT_l3_page_table);
++        if ( rc == -EINTR )
++            rc = -EAGAIN;
++    }
++    if ( rc )
++        /* handled below */;
++    else if ( !compat )
++    {
+         v->arch.guest_table = pagetable_from_page(cr3_page);
+ #ifdef __x86_64__
+         if ( c.nat->ctrlreg[1] )
+@@ -980,56 +1003,44 @@ int arch_set_info_guest(
+             cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[1]);
+             cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
+-            if ( !cr3_page ||
+-                 (!paging_mode_refcounts(d)
+-                  && !get_page_type(cr3_page, PGT_base_page_table)) )
++            if ( !cr3_page )
++                rc = -EINVAL;
++            else if ( !paging_mode_refcounts(d) )
+             {
+-                if (cr3_page)
+-                    put_page(cr3_page);
+-                cr3_page = pagetable_get_page(v->arch.guest_table);
+-                v->arch.guest_table = pagetable_null();
+-                if ( paging_mode_refcounts(d) )
+-                    put_page(cr3_page);
+-                else
+-                    put_page_and_type(cr3_page);
+-                destroy_gdt(v);
+-                return -EINVAL;
++                rc = get_page_type_preemptible(cr3_page, PGT_root_page_table);
++                switch ( rc )
++                {
++                case -EINTR:
++                    rc = -EAGAIN;
++                case -EAGAIN:
++                    v->arch.old_guest_table =
++                        pagetable_get_page(v->arch.guest_table);
++                    v->arch.guest_table = pagetable_null();
++                    break;
++                }
+             }
+-
+-            v->arch.guest_table_user = pagetable_from_page(cr3_page);
+-        }
+-        else if ( !(flags & VGCF_in_kernel) )
+-        {
+-            destroy_gdt(v);
+-            return -EINVAL;
++            if ( !rc )
++               v->arch.guest_table_user = pagetable_from_page(cr3_page);
+         }
+     }
+     else
+     {
+         l4_pgentry_t *l4tab;
+-        cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
+-        cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
+-
+-        if ( !cr3_page)
+-        {
+-            destroy_gdt(v);
+-            return -EINVAL;
+-        }
+-
+-        if (!paging_mode_refcounts(d)
+-            && !get_page_type(cr3_page, PGT_l3_page_table) )
+-        {
+-            put_page(cr3_page);
+-            destroy_gdt(v);
+-            return -EINVAL;
+-        }
+-
+         l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
+         *l4tab = l4e_from_pfn(page_to_mfn(cr3_page),
+             _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
+ #endif
+     }
++    if ( rc )
++    {
++        if ( cr3_page )
++            put_page(cr3_page);
++        destroy_gdt(v);
++        return rc;
++    }
++
++    clear_bit(_VPF_in_reset, &v->pause_flags);
+     if ( v->vcpu_id == 0 )
+         update_domain_wallclock_time(d);
+--- a/xen/common/compat/domain.c
++++ b/xen/common/compat/domain.c
+@@ -50,6 +50,10 @@ int compat_vcpu_op(int cmd, int vcpuid, 
+         rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt);
+         domain_unlock(d);
++        if ( rc == -EAGAIN )
++            rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
++                                               cmd, vcpuid, arg);
++
+         xfree(cmp_ctxt);
+         break;
+     }
+--- a/xen/common/domain.c
++++ b/xen/common/domain.c
+@@ -849,6 +849,11 @@ long do_vcpu_op(int cmd, int vcpuid, XEN
+         domain_unlock(d);
+         free_vcpu_guest_context(ctxt);
++
++        if ( rc == -EAGAIN )
++            rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
++                                               cmd, vcpuid, arg);
++
+         break;
+     case VCPUOP_up: {
+--- a/xen/common/domctl.c
++++ b/xen/common/domctl.c
+@@ -338,6 +338,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
+             domain_pause(d);
+             ret = arch_set_info_guest(v, c);
+             domain_unpause(d);
++
++            if ( ret == -EAGAIN )
++                ret = hypercall_create_continuation(
++                          __HYPERVISOR_domctl, "h", u_domctl);
+         }
+     svc_out:
diff --git a/SOURCES/xsa45-4.2-06-unpin-preemptible.patch b/SOURCES/xsa45-4.2-06-unpin-preemptible.patch
new file mode 100644 (file)
index 0000000..a18f3dd
--- /dev/null
@@ -0,0 +1,127 @@
+x86: make page table unpinning preemptible
+
+... as it may take significant amounts of time.
+
+Since we can't re-invoke the operation in a second attempt, the
+continuation logic must be slightly tweaked so that we make sure
+do_mmuext_op() gets run one more time even when the preempted unpin
+operation was the last one in a batch.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -3123,6 +3123,14 @@ long do_mmuext_op(
+         return rc;
+     }
++    if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
++         likely(guest_handle_is_null(uops)) )
++    {
++        /* See the curr->arch.old_guest_table related
++         * hypercall_create_continuation() below. */
++        return (int)foreigndom;
++    }
++
+     if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
+     {
+         count &= ~MMU_UPDATE_PREEMPTED;
+@@ -3146,7 +3154,7 @@ long do_mmuext_op(
+     for ( i = 0; i < count; i++ )
+     {
+-        if ( hypercall_preempt_check() )
++        if ( curr->arch.old_guest_table || hypercall_preempt_check() )
+         {
+             rc = -EAGAIN;
+             break;
+@@ -3266,7 +3274,17 @@ long do_mmuext_op(
+                 break;
+             }
+-            put_page_and_type(page);
++            switch ( rc = put_page_and_type_preemptible(page, 1) )
++            {
++            case -EINTR:
++            case -EAGAIN:
++                curr->arch.old_guest_table = page;
++                rc = 0;
++                break;
++            default:
++                BUG_ON(rc);
++                break;
++            }
+             put_page(page);
+             /* A page is dirtied when its pin status is cleared. */
+@@ -3587,9 +3605,27 @@ long do_mmuext_op(
+     }
+     if ( rc == -EAGAIN )
++    {
++        ASSERT(i < count);
+         rc = hypercall_create_continuation(
+             __HYPERVISOR_mmuext_op, "hihi",
+             uops, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
++    }
++    else if ( curr->arch.old_guest_table )
++    {
++        XEN_GUEST_HANDLE(void) null;
++
++        ASSERT(rc || i == count);
++        set_xen_guest_handle(null, NULL);
++        /*
++         * In order to have a way to communicate the final return value to
++         * our continuation, we pass this in place of "foreigndom", building
++         * on the fact that this argument isn't needed anymore.
++         */
++        rc = hypercall_create_continuation(
++                __HYPERVISOR_mmuext_op, "hihi", null,
++                MMU_UPDATE_PREEMPTED, null, rc);
++    }
+     put_pg_owner(pg_owner);
+--- a/xen/arch/x86/x86_64/compat/mm.c
++++ b/xen/arch/x86/x86_64/compat/mm.c
+@@ -268,6 +268,13 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
+     int rc = 0;
+     XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
++    if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
++         likely(guest_handle_is_null(cmp_uops)) )
++    {
++        set_xen_guest_handle(nat_ops, NULL);
++        return do_mmuext_op(nat_ops, count, pdone, foreigndom);
++    }
++
+     preempt_mask = count & MMU_UPDATE_PREEMPTED;
+     count ^= preempt_mask;
+@@ -370,12 +377,18 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
+                 guest_handle_add_offset(nat_ops, i - left);
+                 guest_handle_subtract_offset(cmp_uops, left);
+                 left = 1;
+-                BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
+-                BUG_ON(left != arg1);
+-                if (!test_bit(_MCSF_in_multicall, &mcs->flags))
+-                    regs->_ecx += count - i;
++                if ( arg1 != MMU_UPDATE_PREEMPTED )
++                {
++                    BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops,
++                                                        cmp_uops));
++                    if ( !test_bit(_MCSF_in_multicall, &mcs->flags) )
++                        regs->_ecx += count - i;
++                    else
++                        mcs->compat_call.args[1] += count - i;
++                }
+                 else
+-                    mcs->compat_call.args[1] += count - i;
++                    BUG_ON(hypercall_xlat_continuation(&left, 0));
++                BUG_ON(left != arg1);
+             }
+             else
+                 BUG_ON(err > 0);
diff --git a/SOURCES/xsa45-4.2-07-mm-error-paths-preemptible.patch b/SOURCES/xsa45-4.2-07-mm-error-paths-preemptible.patch
new file mode 100644 (file)
index 0000000..0b7ce18
--- /dev/null
@@ -0,0 +1,255 @@
+x86: make page table handling error paths preemptible
+
+... as they may take significant amounts of time.
+
+This requires cloning the tweaked continuation logic from
+do_mmuext_op() to do_mmu_update().
+
+Note that in mod_l[34]_entry() a negative "preemptible" value gets
+passed to put_page_from_l[34]e() now, telling the callee to store the
+respective page in current->arch.old_guest_table (for a hypercall
+continuation to pick up), rather than carrying out the put right away.
+This is going to be made a little more explicit by a subsequent cleanup
+patch.
+
+This is part of CVE-2013-1918 / XSA-45.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Tim Deegan <tim@xen.org>
+
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -1241,7 +1241,16 @@ static int put_page_from_l3e(l3_pgentry_
+ #endif
+     if ( unlikely(partial > 0) )
++    {
++        ASSERT(preemptible >= 0);
+         return __put_page_type(l3e_get_page(l3e), preemptible);
++    }
++
++    if ( preemptible < 0 )
++    {
++        current->arch.old_guest_table = l3e_get_page(l3e);
++        return 0;
++    }
+     return put_page_and_type_preemptible(l3e_get_page(l3e), preemptible);
+ }
+@@ -1254,7 +1263,17 @@ static int put_page_from_l4e(l4_pgentry_
+          (l4e_get_pfn(l4e) != pfn) )
+     {
+         if ( unlikely(partial > 0) )
++        {
++            ASSERT(preemptible >= 0);
+             return __put_page_type(l4e_get_page(l4e), preemptible);
++        }
++
++        if ( preemptible < 0 )
++        {
++            current->arch.old_guest_table = l4e_get_page(l4e);
++            return 0;
++        }
++
+         return put_page_and_type_preemptible(l4e_get_page(l4e), preemptible);
+     }
+     return 1;
+@@ -1549,12 +1568,17 @@ static int alloc_l3_table(struct page_in
+     if ( rc < 0 && rc != -EAGAIN && rc != -EINTR )
+     {
+         MEM_LOG("Failure in alloc_l3_table: entry %d", i);
++        if ( i )
++        {
++            page->nr_validated_ptes = i;
++            page->partial_pte = 0;
++            current->arch.old_guest_table = page;
++        }
+         while ( i-- > 0 )
+         {
+             if ( !is_guest_l3_slot(i) )
+                 continue;
+             unadjust_guest_l3e(pl3e[i], d);
+-            put_page_from_l3e(pl3e[i], pfn, 0, 0);
+         }
+     }
+@@ -1584,22 +1608,24 @@ static int alloc_l4_table(struct page_in
+             page->nr_validated_ptes = i;
+             page->partial_pte = partial ?: 1;
+         }
+-        else if ( rc == -EINTR )
++        else if ( rc < 0 )
+         {
++            if ( rc != -EINTR )
++                MEM_LOG("Failure in alloc_l4_table: entry %d", i);
+             if ( i )
+             {
+                 page->nr_validated_ptes = i;
+                 page->partial_pte = 0;
+-                rc = -EAGAIN;
++                if ( rc == -EINTR )
++                    rc = -EAGAIN;
++                else
++                {
++                    if ( current->arch.old_guest_table )
++                        page->nr_validated_ptes++;
++                    current->arch.old_guest_table = page;
++                }
+             }
+         }
+-        else if ( rc < 0 )
+-        {
+-            MEM_LOG("Failure in alloc_l4_table: entry %d", i);
+-            while ( i-- > 0 )
+-                if ( is_guest_l4_slot(d, i) )
+-                    put_page_from_l4e(pl4e[i], pfn, 0, 0);
+-        }
+         if ( rc < 0 )
+             return rc;
+@@ -2047,7 +2073,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
+         pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);
+     }
+-    put_page_from_l3e(ol3e, pfn, 0, 0);
++    put_page_from_l3e(ol3e, pfn, 0, -preemptible);
+     return rc;
+ }
+@@ -2110,7 +2136,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
+         return -EFAULT;
+     }
+-    put_page_from_l4e(ol4e, pfn, 0, 0);
++    put_page_from_l4e(ol4e, pfn, 0, -preemptible);
+     return rc;
+ }
+@@ -2268,7 +2294,15 @@ static int alloc_page_type(struct page_i
+                 PRtype_info ": caf=%08lx taf=%" PRtype_info,
+                 page_to_mfn(page), get_gpfn_from_mfn(page_to_mfn(page)),
+                 type, page->count_info, page->u.inuse.type_info);
+-        page->u.inuse.type_info = 0;
++        if ( page != current->arch.old_guest_table )
++            page->u.inuse.type_info = 0;
++        else
++        {
++            ASSERT((page->u.inuse.type_info &
++                    (PGT_count_mask | PGT_validated)) == 1);
++            get_page_light(page);
++            page->u.inuse.type_info |= PGT_partial;
++        }
+     }
+     else
+     {
+@@ -3218,21 +3252,17 @@ long do_mmuext_op(
+             }
+             if ( (rc = xsm_memory_pin_page(d, pg_owner, page)) != 0 )
+-            {
+-                put_page_and_type(page);
+                 okay = 0;
+-                break;
+-            }
+-
+-            if ( unlikely(test_and_set_bit(_PGT_pinned,
+-                                           &page->u.inuse.type_info)) )
++            else if ( unlikely(test_and_set_bit(_PGT_pinned,
++                                                &page->u.inuse.type_info)) )
+             {
+                 MEM_LOG("Mfn %lx already pinned", page_to_mfn(page));
+-                put_page_and_type(page);
+                 okay = 0;
+-                break;
+             }
++            if ( unlikely(!okay) )
++                goto pin_drop;
++
+             /* A page is dirtied when its pin status is set. */
+             paging_mark_dirty(pg_owner, page_to_mfn(page));
+@@ -3246,7 +3276,13 @@ long do_mmuext_op(
+                                                &page->u.inuse.type_info));
+                 spin_unlock(&pg_owner->page_alloc_lock);
+                 if ( drop_ref )
+-                    put_page_and_type(page);
++                {
++        pin_drop:
++                    if ( type == PGT_l1_page_table )
++                        put_page_and_type(page);
++                    else
++                        curr->arch.old_guest_table = page;
++                }
+             }
+             break;
+@@ -3652,11 +3688,28 @@ long do_mmu_update(
+     void *va;
+     unsigned long gpfn, gmfn, mfn;
+     struct page_info *page;
+-    int rc = 0, i = 0;
+-    unsigned int cmd, done = 0, pt_dom;
+-    struct vcpu *v = current;
++    unsigned int cmd, i = 0, done = 0, pt_dom;
++    struct vcpu *curr = current, *v = curr;
+     struct domain *d = v->domain, *pt_owner = d, *pg_owner;
+     struct domain_mmap_cache mapcache;
++    int rc = put_old_guest_table(curr);
++
++    if ( unlikely(rc) )
++    {
++        if ( likely(rc == -EAGAIN) )
++            rc = hypercall_create_continuation(
++                     __HYPERVISOR_mmu_update, "hihi", ureqs, count, pdone,
++                     foreigndom);
++        return rc;
++    }
++
++    if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
++         likely(guest_handle_is_null(ureqs)) )
++    {
++        /* See the curr->arch.old_guest_table related
++         * hypercall_create_continuation() below. */
++        return (int)foreigndom;
++    }
+     if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
+     {
+@@ -3705,7 +3758,7 @@ long do_mmu_update(
+     for ( i = 0; i < count; i++ )
+     {
+-        if ( hypercall_preempt_check() )
++        if ( curr->arch.old_guest_table || hypercall_preempt_check() )
+         {
+             rc = -EAGAIN;
+             break;
+@@ -3886,9 +3939,27 @@ long do_mmu_update(
+     }
+     if ( rc == -EAGAIN )
++    {
++        ASSERT(i < count);
+         rc = hypercall_create_continuation(
+             __HYPERVISOR_mmu_update, "hihi",
+             ureqs, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
++    }
++    else if ( curr->arch.old_guest_table )
++    {
++        XEN_GUEST_HANDLE(void) null;
++
++        ASSERT(rc || i == count);
++        set_xen_guest_handle(null, NULL);
++        /*
++         * In order to have a way to communicate the final return value to
++         * our continuation, we pass this in place of "foreigndom", building
++         * on the fact that this argument isn't needed anymore.
++         */
++        rc = hypercall_create_continuation(
++                __HYPERVISOR_mmu_update, "hihi", null,
++                MMU_UPDATE_PREEMPTED, null, rc);
++    }
+     put_pg_owner(pg_owner);
diff --git a/SOURCES/xsa46-regression-xend-xm.patch b/SOURCES/xsa46-regression-xend-xm.patch
new file mode 100644 (file)
index 0000000..a1c5642
--- /dev/null
@@ -0,0 +1,40 @@
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Tested-by: Andreas Falck <falck.andreas.lists@gmail.com> (on 4.1)
+Tested-by: Gordan Bobic <gordan@bobich.net> (on 4.2)
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+master commit: 934a5253d932b6f67fe40fc48975a2b0117e4cce
+master date: 2013-05-21 11:32:34 +0200
+---
+ tools/libxc/xc_physdev.c              |    2 +-
+ tools/python/xen/xend/server/pciif.py |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/libxc/xc_physdev.c b/tools/libxc/xc_physdev.c
+index bdbcba7..cf02d85 100644
+--- a/tools/libxc/xc_physdev.c
++++ b/tools/libxc/xc_physdev.c
+@@ -49,7 +49,7 @@ int xc_physdev_map_pirq(xc_interface *xch,
+     map.domid = domid;
+     map.type = MAP_PIRQ_TYPE_GSI;
+     map.index = index;
+-    map.pirq = *pirq;
++    map.pirq = *pirq < 0 ? index : *pirq;
+     rc = do_physdev_op(xch, PHYSDEVOP_map_pirq, &map, sizeof(map));
+diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py
+index 43d0c80..27c1b75 100644
+--- a/tools/python/xen/xend/server/pciif.py
++++ b/tools/python/xen/xend/server/pciif.py
+@@ -340,7 +340,7 @@ class PciController(DevController):
+                 raise VmError(('pci: failed to configure I/O memory on device '+
+                             '%s - errno=%d')%(dev.name,rc))
+-        if not self.vm.info.is_hvm() and dev.irq:
++        if dev.irq > 0:
+             rc = xc.physdev_map_pirq(domid = fe_domid,
+                                    index = dev.irq,
+                                    pirq  = dev.irq)
+-- 
+1.7.2.5
diff --git a/SOURCES/xsa48-4.2.patch b/SOURCES/xsa48-4.2.patch
new file mode 100644 (file)
index 0000000..c44806e
--- /dev/null
@@ -0,0 +1,114 @@
+Add -f FMT  / --format FMT arg to qemu-nbd
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Currently the qemu-nbd program will auto-detect the format of
+any disk it is given. This behaviour is known to be insecure.
+For example, if qemu-nbd initially exposes a 'raw' file to an
+unprivileged app, and that app runs
+
+   'qemu-img create -f qcow2 -o backing_file=/etc/shadow /dev/nbd0'
+
+then the next time the app is started, the qemu-nbd will now
+detect it as a 'qcow2' file and expose /etc/shadow to the
+unprivileged app.
+
+The only way to avoid this is to explicitly tell qemu-nbd what
+disk format to use on the command line, completely disabling
+auto-detection. This patch adds a '-f' / '--format' arg for
+this purpose, mirroring what is already available via qemu-img
+and qemu commands.
+
+  qemu-nbd --format raw -p 9000 evil.img
+
+will now always use raw, regardless of what format 'evil.img'
+looks like it contains
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+[Use errx, not err. - Paolo]
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+
+[ This is a security issue, CVE-2013-1922 / XSA-48. ]
+
+diff --git a/qemu-nbd.c b/qemu-nbd.c
+index 291cba2..8fbe2cf 100644
+--- a/qemu-nbd.c
++++ b/qemu-nbd.c
+@@ -247,6 +247,7 @@ out:
+ int main(int argc, char **argv)
+ {
+     BlockDriverState *bs;
++    BlockDriver *drv;
+     off_t dev_offset = 0;
+     off_t offset = 0;
+     uint32_t nbdflags = 0;
+@@ -256,7 +257,7 @@ int main(int argc, char **argv)
+     struct sockaddr_in addr;
+     socklen_t addr_len = sizeof(addr);
+     off_t fd_size;
+-    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
++    const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
+     struct option lopt[] = {
+         { "help", 0, NULL, 'h' },
+         { "version", 0, NULL, 'V' },
+@@ -271,6 +272,7 @@ int main(int argc, char **argv)
+         { "snapshot", 0, NULL, 's' },
+         { "nocache", 0, NULL, 'n' },
+         { "shared", 1, NULL, 'e' },
++        { "format", 1, NULL, 'f' },
+         { "persistent", 0, NULL, 't' },
+         { "verbose", 0, NULL, 'v' },
+         { NULL, 0, NULL, 0 }
+@@ -292,6 +294,7 @@ int main(int argc, char **argv)
+     int max_fd;
+     int persistent = 0;
+     pthread_t client_thread;
++    const char *fmt = NULL;
+     /* The client thread uses SIGTERM to interrupt the server.  A signal
+      * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
+@@ -368,6 +371,9 @@ int main(int argc, char **argv)
+                 errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
+             }
+             break;
++        case 'f':
++            fmt = optarg;
++            break;
+       case 't':
+           persistent = 1;
+           break;
+@@ -478,9 +484,19 @@ int main(int argc, char **argv)
+     bdrv_init();
+     atexit(bdrv_close_all);
++    if (fmt) {
++        drv = bdrv_find_format(fmt);
++        if (!drv) {
++            errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
++        }
++    } else {
++        drv = NULL;
++    }
++
+     bs = bdrv_new("hda");
+     srcpath = argv[optind];
+-    if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
++    ret = bdrv_open(bs, srcpath, flags, drv);
++    if (ret < 0) {
+         errno = -ret;
+         err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
+     }
+diff --git a/qemu-nbd.texi b/qemu-nbd.texi
+index 44996cc..f56c68e 100644
+--- a/qemu-nbd.texi
++++ b/qemu-nbd.texi
+@@ -36,6 +36,8 @@ Export Qemu disk image using NBD protocol.
+   disconnect the specified device
+ @item -e, --shared=@var{num}
+   device can be shared by @var{num} clients (default @samp{1})
++@item -f, --format=@var{fmt}
++  force block driver for format @var{fmt} instead of auto-detecting
+ @item -t, --persistent
+   don't exit on the last connection
+ @item -v, --verbose
diff --git a/SOURCES/xsa49-4.2.patch b/SOURCES/xsa49-4.2.patch
new file mode 100644 (file)
index 0000000..4b92c7f
--- /dev/null
@@ -0,0 +1,50 @@
+VT-d: don't permit SVT_NO_VERIFY entries for known device types
+
+Only in cases where we don't know what to do we should leave the IRTE
+blank (suppressing all validation), but we should always log a warning
+in those cases (as being insecure).
+
+This is CVE-2013-1952 / XSA-49.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: "Zhang, Xiantao" <xiantao.zhang@intel.com>
+
+--- a/xen/drivers/passthrough/vtd/intremap.c
++++ b/xen/drivers/passthrough/vtd/intremap.c
+@@ -440,16 +440,15 @@ static void set_msi_source_id(struct pci
+     type = pdev_type(seg, bus, devfn);
+     switch ( type )
+     {
++    case DEV_TYPE_PCIe_ENDPOINT:
+     case DEV_TYPE_PCIe_BRIDGE:
+     case DEV_TYPE_PCIe2PCI_BRIDGE:
+-    case DEV_TYPE_LEGACY_PCI_BRIDGE:
+-        break;
+-
+-    case DEV_TYPE_PCIe_ENDPOINT:
+         set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn));
+         break;
+     case DEV_TYPE_PCI:
++    case DEV_TYPE_LEGACY_PCI_BRIDGE:
++    /* case DEV_TYPE_PCI2PCIe_BRIDGE: */
+         ret = find_upstream_bridge(seg, &bus, &devfn, &secbus);
+         if ( ret == 0 ) /* integrated PCI device */
+         {
+@@ -461,10 +460,15 @@ static void set_msi_source_id(struct pci
+             if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
+                 set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
+                             (bus << 8) | pdev->bus);
+-            else if ( pdev_type(seg, bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE )
++            else
+                 set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
+                             PCI_BDF2(bus, devfn));
+         }
++        else
++            dprintk(XENLOG_WARNING VTDPREFIX,
++                    "d%d: no upstream bridge for %04x:%02x:%02x.%u\n",
++                    pdev->domain->domain_id,
++                    seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+         break;
+     default:
diff --git a/SOURCES/xsa52-4.2-unstable.patch b/SOURCES/xsa52-4.2-unstable.patch
new file mode 100644 (file)
index 0000000..14db8a8
--- /dev/null
@@ -0,0 +1,46 @@
+x86/xsave: fix information leak on AMD CPUs
+
+Just like for FXSAVE/FXRSTOR, XSAVE/XRSTOR also don't save/restore the
+last instruction and operand pointers as well as the last opcode if
+there's no pending unmasked exception (see CVE-2006-1056 and commit
+9747:4d667a139318).
+
+While the FXSR solution sits in the save path, I prefer to have this in
+the restore path because there the handling is simpler (namely in the
+context of the pending changes to properly save the selector values for
+32-bit guest code).
+
+Also this is using FFREE instead of EMMS, as it doesn't seem unlikely
+that in the future we may see CPUs with x87 and SSE/AVX but no MMX
+support. The goal here anyway is just to avoid an FPU stack overflow.
+I would have preferred to use FFREEP instead of FFREE (freeing two
+stack slots at once), but AMD doesn't document that instruction.
+
+This is CVE-2013-2076 / XSA-52.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+
+--- a/xen/arch/x86/xstate.c
++++ b/xen/arch/x86/xstate.c
+@@ -78,6 +78,21 @@ void xrstor(struct vcpu *v, uint64_t mas
+     struct xsave_struct *ptr = v->arch.xsave_area;
++    /*
++     * AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
++     * is pending. Clear the x87 state here by setting it to fixed
++     * values. The hypervisor data segment can be sometimes 0 and
++     * sometimes new user value. Both should be ok. Use the FPU saved
++     * data block as a safe address because it should be in L1.
++     */
++    if ( (mask & ptr->xsave_hdr.xstate_bv & XSTATE_FP) &&
++         !(ptr->fpu_sse.fsw & 0x0080) &&
++         boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
++        asm volatile ( "fnclex\n\t"        /* clear exceptions */
++                       "ffree %%st(7)\n\t" /* clear stack tag */
++                       "fildl %0"          /* load to clear state */
++                       : : "m" (ptr->fpu_sse) );
++
+     asm volatile (
+         ".byte " REX_PREFIX "0x0f,0xae,0x2f"
+         :
diff --git a/SOURCES/xsa53-4.2.patch b/SOURCES/xsa53-4.2.patch
new file mode 100644 (file)
index 0000000..eb8e79b
--- /dev/null
@@ -0,0 +1,57 @@
+x86/xsave: recover from faults on XRSTOR
+
+Just like FXRSTOR, XRSTOR can raise #GP if bad content is being passed
+to it in the memory block (i.e. aspects not under the control of the
+hypervisor, other than e.g. proper alignment of the block).
+
+Also correct the comment explaining why FXRSTOR needs exception
+recovery code to not wrongly state that this can only be a result of
+the control tools passing a bad image.
+
+This is CVE-2013-2077 / XSA-53.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+
+--- a/xen/arch/x86/i387.c
++++ b/xen/arch/x86/i387.c
+@@ -53,7 +53,7 @@ static inline void fpu_fxrstor(struct vc
+     /*
+      * FXRSTOR can fault if passed a corrupted data block. We handle this
+      * possibility, which may occur if the block was passed to us by control
+-     * tools, by silently clearing the block.
++     * tools or through VCPUOP_initialise, by silently clearing the block.
+      */
+     asm volatile (
+ #ifdef __i386__
+--- a/xen/arch/x86/xstate.c
++++ b/xen/arch/x86/xstate.c
+@@ -93,10 +93,25 @@ void xrstor(struct vcpu *v, uint64_t mas
+                        "fildl %0"          /* load to clear state */
+                        : : "m" (ptr->fpu_sse) );
+-    asm volatile (
+-        ".byte " REX_PREFIX "0x0f,0xae,0x2f"
+-        :
+-        : "m" (*ptr), "a" (lmask), "d" (hmask), "D"(ptr) );
++    /*
++     * XRSTOR can fault if passed a corrupted data block. We handle this
++     * possibility, which may occur if the block was passed to us by control
++     * tools or through VCPUOP_initialise, by silently clearing the block.
++     */
++    asm volatile ( "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
++                   ".section .fixup,\"ax\"\n"
++                   "2: mov %5,%%ecx       \n"
++                   "   xor %1,%1          \n"
++                   "   rep stosb          \n"
++                   "   lea %2,%0          \n"
++                   "   mov %3,%1          \n"
++                   "   jmp 1b             \n"
++                   ".previous             \n"
++                   _ASM_EXTABLE(1b, 2b)
++                   : "+&D" (ptr), "+&a" (lmask)
++                   : "m" (*ptr), "g" (lmask), "d" (hmask),
++                     "m" (xsave_cntxt_size)
++                   : "ecx" );
+ }
+ bool_t xsave_enabled(const struct vcpu *v)
diff --git a/SOURCES/xsa54.patch b/SOURCES/xsa54.patch
new file mode 100644 (file)
index 0000000..83c8993
--- /dev/null
@@ -0,0 +1,24 @@
+x86/xsave: properly check guest input to XSETBV
+
+Other than the HVM emulation path, the PV case so far failed to check
+that YMM state requires SSE state to be enabled, allowing for a #GP to
+occur upon passing the inputs to XSETBV inside the hypervisor.
+
+This is CVE-2013-2078 / XSA-54.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+
+--- a/xen/arch/x86/traps.c
++++ b/xen/arch/x86/traps.c
+@@ -2205,6 +2205,11 @@ static int emulate_privileged_op(struct 
+                     if ( !(new_xfeature & XSTATE_FP) || (new_xfeature & ~xfeature_mask) )
+                         goto fail;
++                    /* YMM state takes SSE state as prerequisite. */
++                    if ( (xfeature_mask & new_xfeature & XSTATE_YMM) &&
++                         !(new_xfeature & XSTATE_SSE) )
++                        goto fail;
++
+                     v->arch.xcr0 = new_xfeature;
+                     v->arch.xcr0_accum |= new_xfeature;
+                     set_xcr0(new_xfeature);
diff --git a/SOURCES/xsa55-4.2-0001-libelf-abolish-libelf-relocate.c.patch b/SOURCES/xsa55-4.2-0001-libelf-abolish-libelf-relocate.c.patch
new file mode 100644 (file)
index 0000000..315735d
--- /dev/null
@@ -0,0 +1,417 @@
+From 9737484becab4a25159f1e985700eaee89690d34 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:15 +0100
+Subject: [PATCH 01/23] libelf: abolish libelf-relocate.c
+
+This file is not actually used.  It's not built in Xen's instance of
+libelf; in libxc's it's built but nothing in it is called.  Do not
+compile it in libxc, and delete it.
+
+This reduces the amount of work we need to do in forthcoming patches
+to libelf (particularly since as libelf-relocate.c is not used it is
+probably full of bugs).
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+---
+ tools/libxc/Makefile                |    2 +-
+ xen/common/libelf/libelf-relocate.c |  372 -----------------------------------
+ 2 files changed, 1 insertions(+), 373 deletions(-)
+ delete mode 100644 xen/common/libelf/libelf-relocate.c
+
+diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
+index ca38cbd..d8c6a60 100644
+--- a/tools/libxc/Makefile
++++ b/tools/libxc/Makefile
+@@ -53,7 +53,7 @@ vpath %.c ../../xen/common/libelf
+ CFLAGS += -I../../xen/common/libelf
+ GUEST_SRCS-y += libelf-tools.c libelf-loader.c
+-GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
++GUEST_SRCS-y += libelf-dominfo.c
+ # new domain builder
+ GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
+diff --git a/xen/common/libelf/libelf-relocate.c b/xen/common/libelf/libelf-relocate.c
+deleted file mode 100644
+index 7ef4b01..0000000
+--- a/xen/common/libelf/libelf-relocate.c
++++ /dev/null
+@@ -1,372 +0,0 @@
+-/*
+- * ELF relocation code (not used by xen kernel right now).
+- *
+- * 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;
+- * version 2.1 of the License.
+- *
+- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+- */
+-
+-#include "libelf-private.h"
+-
+-/* ------------------------------------------------------------------------ */
+-
+-static const char *rel_names_i386[] = {
+-    "R_386_NONE",
+-    "R_386_32",
+-    "R_386_PC32",
+-    "R_386_GOT32",
+-    "R_386_PLT32",
+-    "R_386_COPY",
+-    "R_386_GLOB_DAT",
+-    "R_386_JMP_SLOT",
+-    "R_386_RELATIVE",
+-    "R_386_GOTOFF",
+-    "R_386_GOTPC",
+-    "R_386_32PLT",
+-    "R_386_TLS_TPOFF",
+-    "R_386_TLS_IE",
+-    "R_386_TLS_GOTIE",
+-    "R_386_TLS_LE",
+-    "R_386_TLS_GD",
+-    "R_386_TLS_LDM",
+-    "R_386_16",
+-    "R_386_PC16",
+-    "R_386_8",
+-    "R_386_PC8",
+-    "R_386_TLS_GD_32",
+-    "R_386_TLS_GD_PUSH",
+-    "R_386_TLS_GD_CALL",
+-    "R_386_TLS_GD_POP",
+-    "R_386_TLS_LDM_32",
+-    "R_386_TLS_LDM_PUSH",
+-    "R_386_TLS_LDM_CALL",
+-    "R_386_TLS_LDM_POP",
+-    "R_386_TLS_LDO_32",
+-    "R_386_TLS_IE_32",
+-    "R_386_TLS_LE_32",
+-    "R_386_TLS_DTPMOD32",
+-    "R_386_TLS_DTPOFF32",
+-    "R_386_TLS_TPOFF32",
+-};
+-
+-static int elf_reloc_i386(struct elf_binary *elf, int type,
+-                          uint64_t addr, uint64_t value)
+-{
+-    void *ptr = elf_get_ptr(elf, addr);
+-    uint32_t *u32;
+-
+-    switch ( type )
+-    {
+-    case 1 /* R_386_32 */ :
+-        u32 = ptr;
+-        *u32 += elf->reloc_offset;
+-        break;
+-    case 2 /* R_386_PC32 */ :
+-        /* nothing */
+-        break;
+-    default:
+-        return -1;
+-    }
+-    return 0;
+-}
+-
+-/* ------------------------------------------------------------------------ */
+-
+-static const char *rel_names_x86_64[] = {
+-    "R_X86_64_NONE",
+-    "R_X86_64_64",
+-    "R_X86_64_PC32",
+-    "R_X86_64_GOT32",
+-    "R_X86_64_PLT32",
+-    "R_X86_64_COPY",
+-    "R_X86_64_GLOB_DAT",
+-    "R_X86_64_JUMP_SLOT",
+-    "R_X86_64_RELATIVE",
+-    "R_X86_64_GOTPCREL",
+-    "R_X86_64_32",
+-    "R_X86_64_32S",
+-    "R_X86_64_16",
+-    "R_X86_64_PC16",
+-    "R_X86_64_8",
+-    "R_X86_64_PC8",
+-    "R_X86_64_DTPMOD64",
+-    "R_X86_64_DTPOFF64",
+-    "R_X86_64_TPOFF64",
+-    "R_X86_64_TLSGD",
+-    "R_X86_64_TLSLD",
+-    "R_X86_64_DTPOFF32",
+-    "R_X86_64_GOTTPOFF",
+-    "R_X86_64_TPOFF32",
+-};
+-
+-static int elf_reloc_x86_64(struct elf_binary *elf, int type,
+-                            uint64_t addr, uint64_t value)
+-{
+-    void *ptr = elf_get_ptr(elf, addr);
+-    uint64_t *u64;
+-    uint32_t *u32;
+-    int32_t *s32;
+-
+-    switch ( type )
+-    {
+-    case 1 /* R_X86_64_64 */ :
+-        u64 = ptr;
+-        value += elf->reloc_offset;
+-        *u64 = value;
+-        break;
+-    case 2 /* R_X86_64_PC32 */ :
+-        u32 = ptr;
+-        *u32 = value - addr;
+-        if ( *u32 != (uint32_t)(value - addr) )
+-        {
+-            elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32
+-                    " != 0x%" PRIx32 "\n",
+-                    *u32, (uint32_t) (value - addr));
+-            return -1;
+-        }
+-        break;
+-    case 10 /* R_X86_64_32 */ :
+-        u32 = ptr;
+-        value += elf->reloc_offset;
+-        *u32 = value;
+-        if ( *u32 != value )
+-        {
+-            elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32
+-                    " != 0x%" PRIx64 "\n",
+-                    *u32, value);
+-            return -1;
+-        }
+-        break;
+-    case 11 /* R_X86_64_32S */ :
+-        s32 = ptr;
+-        value += elf->reloc_offset;
+-        *s32 = value;
+-        if ( *s32 != (int64_t) value )
+-        {
+-            elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32
+-                    " != 0x%" PRIx64 "\n",
+-                    *s32, (int64_t) value);
+-            return -1;
+-        }
+-        break;
+-    default:
+-        return -1;
+-    }
+-    return 0;
+-}
+-
+-/* ------------------------------------------------------------------------ */
+-
+-static struct relocs {
+-    const char **names;
+-    int count;
+-    int (*func) (struct elf_binary * elf, int type, uint64_t addr,
+-                 uint64_t value);
+-} relocs[] =
+-/* *INDENT-OFF* */
+-{
+-    [EM_386] = {
+-        .names = rel_names_i386,
+-        .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]),
+-        .func = elf_reloc_i386,
+-    },
+-    [EM_X86_64] = {
+-        .names = rel_names_x86_64,
+-        .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]),
+-        .func = elf_reloc_x86_64,
+-    }
+-};
+-/* *INDENT-ON* */
+-
+-/* ------------------------------------------------------------------------ */
+-
+-static const char *rela_name(int machine, int type)
+-{
+-    if ( machine > sizeof(relocs) / sizeof(relocs[0]) )
+-        return "unknown mach";
+-    if ( !relocs[machine].names )
+-        return "unknown mach";
+-    if ( type > relocs[machine].count )
+-        return "unknown rela";
+-    return relocs[machine].names[type];
+-}
+-
+-static int elf_reloc_section(struct elf_binary *elf,
+-                             const elf_shdr * rels,
+-                             const elf_shdr * sect, const elf_shdr * syms)
+-{
+-    const void *ptr, *end;
+-    const elf_shdr *shdr;
+-    const elf_rela *rela;
+-    const elf_rel *rel;
+-    const elf_sym *sym;
+-    uint64_t s_type;
+-    uint64_t r_offset;
+-    uint64_t r_info;
+-    uint64_t r_addend;
+-    int r_type, r_sym;
+-    size_t rsize;
+-    uint64_t shndx, sbase, addr, value;
+-    const char *sname;
+-    int machine;
+-
+-    machine = elf_uval(elf, elf->ehdr, e_machine);
+-    if ( (machine >= (sizeof(relocs) / sizeof(relocs[0]))) ||
+-         (relocs[machine].func == NULL) )
+-    {
+-        elf_err(elf, "%s: can't handle machine %d\n",
+-                __FUNCTION__, machine);
+-        return -1;
+-    }
+-    if ( elf_swap(elf) )
+-    {
+-        elf_err(elf, "%s: non-native byte order, relocation not supported\n",
+-                __FUNCTION__);
+-        return -1;
+-    }
+-
+-    s_type = elf_uval(elf, rels, sh_type);
+-    rsize = (SHT_REL == s_type) ? elf_size(elf, rel) : elf_size(elf, rela);
+-    ptr = elf_section_start(elf, rels);
+-    end = elf_section_end(elf, rels);
+-
+-    for ( ; ptr < end; ptr += rsize )
+-    {
+-        switch ( s_type )
+-        {
+-        case SHT_REL:
+-            rel = ptr;
+-            r_offset = elf_uval(elf, rel, r_offset);
+-            r_info = elf_uval(elf, rel, r_info);
+-            r_addend = 0;
+-            break;
+-        case SHT_RELA:
+-            rela = ptr;
+-            r_offset = elf_uval(elf, rela, r_offset);
+-            r_info = elf_uval(elf, rela, r_info);
+-            r_addend = elf_uval(elf, rela, r_addend);
+-            break;
+-        default:
+-            /* can't happen */
+-            return -1;
+-        }
+-        if ( elf_64bit(elf) )
+-        {
+-            r_type = ELF64_R_TYPE(r_info);
+-            r_sym = ELF64_R_SYM(r_info);
+-        }
+-        else
+-        {
+-            r_type = ELF32_R_TYPE(r_info);
+-            r_sym = ELF32_R_SYM(r_info);
+-        }
+-
+-        sym = elf_sym_by_index(elf, r_sym);
+-        shndx = elf_uval(elf, sym, st_shndx);
+-        switch ( shndx )
+-        {
+-        case SHN_UNDEF:
+-            sname = "*UNDEF*";
+-            sbase = 0;
+-            break;
+-        case SHN_COMMON:
+-            elf_err(elf, "%s: invalid section: %" PRId64 "\n",
+-                    __FUNCTION__, shndx);
+-            return -1;
+-        case SHN_ABS:
+-            sname = "*ABS*";
+-            sbase = 0;
+-            break;
+-        default:
+-            shdr = elf_shdr_by_index(elf, shndx);
+-            if ( shdr == NULL )
+-            {
+-                elf_err(elf, "%s: invalid section: %" PRId64 "\n",
+-                        __FUNCTION__, shndx);
+-                return -1;
+-            }
+-            sname = elf_section_name(elf, shdr);
+-            sbase = elf_uval(elf, shdr, sh_addr);
+-        }
+-
+-        addr = r_offset;
+-        value = elf_uval(elf, sym, st_value);
+-        value += r_addend;
+-
+-        if ( elf->log_callback && (elf->verbose > 1) )
+-        {
+-            uint64_t st_name = elf_uval(elf, sym, st_name);
+-            const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
+-
+-            elf_msg(elf,
+-                    "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 ","
+-                    " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]"
+-                    "  ->  addr 0x%" PRIx64 " value 0x%" PRIx64 "\n",
+-                    __FUNCTION__, rela_name(machine, r_type), r_type, r_offset,
+-                    r_addend, name, elf_uval(elf, sym, st_value), sname, sbase,
+-                    addr, value);
+-        }
+-
+-        if ( relocs[machine].func(elf, r_type, addr, value) == -1 )
+-        {
+-            elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n",
+-                    __FUNCTION__, rela_name(machine, r_type), r_type);
+-            return -1;
+-        }
+-    }
+-    return 0;
+-}
+-
+-int elf_reloc(struct elf_binary *elf)
+-{
+-    const elf_shdr *rels, *sect, *syms;
+-    uint64_t i, count, type;
+-
+-    count = elf_shdr_count(elf);
+-    for ( i = 0; i < count; i++ )
+-    {
+-        rels = elf_shdr_by_index(elf, i);
+-        type = elf_uval(elf, rels, sh_type);
+-        if ( (type != SHT_REL) && (type != SHT_RELA) )
+-            continue;
+-
+-        sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info));
+-        syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link));
+-        if ( NULL == sect || NULL == syms )
+-            continue;
+-
+-        if ( !(elf_uval(elf, sect, sh_flags) & SHF_ALLOC) )
+-        {
+-            elf_msg(elf, "%s: relocations for %s, skipping\n",
+-                    __FUNCTION__, elf_section_name(elf, sect));
+-            continue;
+-        }
+-
+-        elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n",
+-                __FUNCTION__, elf_section_name(elf, sect),
+-                elf_uval(elf, sect, sh_addr));
+-        if ( elf_reloc_section(elf, rels, sect, syms) != 0 )
+-            return -1;
+-    }
+-    return 0;
+-}
+-
+-/*
+- * Local variables:
+- * mode: C
+- * c-set-style: "BSD"
+- * c-basic-offset: 4
+- * tab-width: 4
+- * indent-tabs-mode: nil
+- * End:
+- */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0002-libxc-introduce-xc_dom_seg_to_ptr_pages.patch b/SOURCES/xsa55-4.2-0002-libxc-introduce-xc_dom_seg_to_ptr_pages.patch
new file mode 100644 (file)
index 0000000..c26605f
--- /dev/null
@@ -0,0 +1,56 @@
+From a672da4b2d58ef12be9d7407160e9fb43cac75d9 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 02/23] libxc: introduce xc_dom_seg_to_ptr_pages
+
+Provide a version of xc_dom_seg_to_ptr which returns the number of
+guest pages it has actually mapped.  This is useful for callers who
+want to do range checking; we will use this later in this series.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+---
+ tools/libxc/xc_dom.h |   19 ++++++++++++++++---
+ 1 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
+index 6a72aa9..9af2195 100644
+--- a/tools/libxc/xc_dom.h
++++ b/tools/libxc/xc_dom.h
+@@ -278,14 +278,27 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first,
+ void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn);
+ void xc_dom_unmap_all(struct xc_dom_image *dom);
+-static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
+-                                      struct xc_dom_seg *seg)
++static inline void *xc_dom_seg_to_ptr_pages(struct xc_dom_image *dom,
++                                      struct xc_dom_seg *seg,
++                                      xen_pfn_t *pages_out)
+ {
+     xen_vaddr_t segsize = seg->vend - seg->vstart;
+     unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
+     xen_pfn_t pages = (segsize + page_size - 1) / page_size;
++    void *retval;
++
++    retval = xc_dom_pfn_to_ptr(dom, seg->pfn, pages);
++
++    *pages_out = retval ? pages : 0;
++    return retval;
++}
++
++static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
++                                      struct xc_dom_seg *seg)
++{
++    xen_pfn_t dummy;
+-    return xc_dom_pfn_to_ptr(dom, seg->pfn, pages);
++    return xc_dom_seg_to_ptr_pages(dom, seg, &dummy);
+ }
+ static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0003-libxc-Fix-range-checking-in-xc_dom_pfn_to_ptr-etc.patch b/SOURCES/xsa55-4.2-0003-libxc-Fix-range-checking-in-xc_dom_pfn_to_ptr-etc.patch
new file mode 100644 (file)
index 0000000..5930321
--- /dev/null
@@ -0,0 +1,156 @@
+From 8c738fa5c1f3cfcd935b6191b3526f7ac8b2a5bd Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 03/23] libxc: Fix range checking in xc_dom_pfn_to_ptr etc.
+
+* Ensure that xc_dom_pfn_to_ptr (when called with count==0) does not
+  return a previously-allocated block which is entirely before the
+  requested pfn (!)
+
+* Provide a version of xc_dom_pfn_to_ptr, xc_dom_pfn_to_ptr_retcount,
+  which provides the length of the mapped region via an out parameter.
+
+* Change xc_dom_vaddr_to_ptr to always provide the length of the
+  mapped region and change the call site in xc_dom_binloader.c to
+  check it.  The call site in xc_dom_load_elf_symtab will be corrected
+  in a forthcoming patch, and for now ignores the returned length.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_dom.h           |   16 +++++++++++++---
+ tools/libxc/xc_dom_binloader.c |   11 ++++++++++-
+ tools/libxc/xc_dom_core.c      |   13 +++++++++++++
+ tools/libxc/xc_dom_elfloader.c |    3 ++-
+ 4 files changed, 38 insertions(+), 5 deletions(-)
+
+diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
+index 9af2195..9f8037e 100644
+--- a/tools/libxc/xc_dom.h
++++ b/tools/libxc/xc_dom.h
+@@ -275,6 +275,8 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
+ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first,
+                         xen_pfn_t count);
++void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image *dom, xen_pfn_t first,
++                                 xen_pfn_t count, xen_pfn_t *count_out);
+ void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn);
+ void xc_dom_unmap_all(struct xc_dom_image *dom);
+@@ -302,13 +304,21 @@ static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
+ }
+ static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
+-                                        xen_vaddr_t vaddr)
++                                        xen_vaddr_t vaddr,
++                                        size_t *safe_region_out)
+ {
+     unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
+     xen_pfn_t page = (vaddr - dom->parms.virt_base) / page_size;
+     unsigned int offset = (vaddr - dom->parms.virt_base) % page_size;
+-    void *ptr = xc_dom_pfn_to_ptr(dom, page, 0);
+-    return (ptr ? (ptr + offset) : NULL);
++    xen_pfn_t safe_region_count;
++    void *ptr;
++
++    *safe_region_out = 0;
++    ptr = xc_dom_pfn_to_ptr_retcount(dom, page, 0, &safe_region_count);
++    if ( ptr == NULL )
++        return ptr;
++    *safe_region_out = (safe_region_count << XC_DOM_PAGE_SHIFT(dom)) - offset;
++    return ptr;
+ }
+ static inline int xc_dom_feature_translated(struct xc_dom_image *dom)
+diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
+index 769e97d..bde93f7 100644
+--- a/tools/libxc/xc_dom_binloader.c
++++ b/tools/libxc/xc_dom_binloader.c
+@@ -249,6 +249,7 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
+     char *image = dom->kernel_blob;
+     char *dest;
+     size_t image_size = dom->kernel_size;
++    size_t dest_size;
+     uint32_t start_addr;
+     uint32_t load_end_addr;
+     uint32_t bss_end_addr;
+@@ -272,7 +273,15 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
+     DOMPRINTF("  text_size: 0x%" PRIx32 "", text_size);
+     DOMPRINTF("  bss_size:  0x%" PRIx32 "", bss_size);
+-    dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
++    dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
++
++    if ( dest_size < text_size ||
++         dest_size - text_size < bss_size )
++    {
++        DOMPRINTF("%s: mapped region is too small for image", __FUNCTION__);
++        return -EINVAL;
++    }
++
+     memcpy(dest, image + skip, text_size);
+     memset(dest + text_size, 0, bss_size);
+diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
+index 2a01d7c..8913e41 100644
+--- a/tools/libxc/xc_dom_core.c
++++ b/tools/libxc/xc_dom_core.c
+@@ -351,10 +351,19 @@ int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size)
+ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
+                         xen_pfn_t count)
+ {
++    xen_pfn_t count_out_dummy;
++    return xc_dom_pfn_to_ptr_retcount(dom, pfn, count, &count_out_dummy);
++}
++
++void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image *dom, xen_pfn_t pfn,
++                                 xen_pfn_t count, xen_pfn_t *count_out)
++{
+     struct xc_dom_phys *phys;
+     unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
+     char *mode = "unset";
++    *count_out = 0;
++
+     if ( pfn > dom->total_pages ||    /* multiple checks to avoid overflows */
+          count > dom->total_pages ||
+          pfn > dom->total_pages - count )
+@@ -384,6 +393,7 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
+                           phys->count);
+                 return NULL;
+             }
++            *count_out = count;
+         }
+         else
+         {
+@@ -391,6 +401,9 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
+                just hand out a pointer to it */
+             if ( pfn < phys->first )
+                 continue;
++            if ( pfn >= phys->first + phys->count )
++                continue;
++            *count_out = phys->count - (pfn - phys->first);
+         }
+         return phys->ptr + ((pfn - phys->first) << page_shift);
+     }
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 2e69559..031b5b6 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -130,10 +130,11 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     if ( load )
+     {
++        size_t allow_size; /* will be used in a forthcoming XSA-55 patch */
+         if ( !dom->bsd_symtab_start )
+             return 0;
+         size = dom->kernel_seg.vend - dom->bsd_symtab_start;
+-        hdr  = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start);
++        hdr  = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
+         *(int *)hdr = size - sizeof(int);
+     }
+     else
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0004-libelf-add-struct-elf_binary-parameter-to-elf_load_i.patch b/SOURCES/xsa55-4.2-0004-libelf-add-struct-elf_binary-parameter-to-elf_load_i.patch
new file mode 100644 (file)
index 0000000..6eb2bac
--- /dev/null
@@ -0,0 +1,55 @@
+From 035634047d10c678cbb8801c4263747bdaf4e5b1 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 04/23] libelf: add `struct elf_binary*' parameter to elf_load_image
+
+The meat of this function is going to need a copy of the elf pointer,
+in forthcoming patches.
+
+No functional change in this patch.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+---
+ xen/common/libelf/libelf-loader.c |    8 +++++---
+ 1 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index ab58b8b..0559d88 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -108,7 +108,8 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+     elf->verbose = verbose;
+ }
+-static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz)
++static int elf_load_image(struct elf_binary *elf,
++                          void *dst, const void *src, uint64_t filesz, uint64_t memsz)
+ {
+     memcpy(dst, src, filesz);
+     memset(dst + filesz, 0, memsz - filesz);
+@@ -122,7 +123,8 @@ void elf_set_verbose(struct elf_binary *elf)
+     elf->verbose = 1;
+ }
+-static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz)
++static int elf_load_image(struct elf_binary *elf,
++                          void *dst, const void *src, uint64_t filesz, uint64_t memsz)
+ {
+     int rc;
+     if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
+@@ -279,7 +281,7 @@ int elf_load_binary(struct elf_binary *elf)
+         dest = elf_get_ptr(elf, paddr);
+         elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
+                 __func__, i, dest, dest + filesz);
+-        if ( elf_load_image(dest, elf->image + offset, filesz, memsz) != 0 )
++        if ( elf_load_image(elf, dest, elf->image + offset, filesz, memsz) != 0 )
+             return -1;
+     }
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0005-libelf-abolish-elf_sval-and-elf_access_signed.patch b/SOURCES/xsa55-4.2-0005-libelf-abolish-elf_sval-and-elf_access_signed.patch
new file mode 100644 (file)
index 0000000..3f315c6
--- /dev/null
@@ -0,0 +1,86 @@
+From 83ec905922b496e1a5756e3a88405eb6c2c6ba88 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 05/23] libelf: abolish elf_sval and elf_access_signed
+
+These are not used anywhere.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+---
+ xen/common/libelf/libelf-tools.c |   28 ----------------------------
+ xen/include/xen/libelf.h         |   11 -----------
+ 2 files changed, 0 insertions(+), 39 deletions(-)
+
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index cb97908..2f54142 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -48,34 +48,6 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
+     }
+ }
+-int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
+-                          uint64_t offset, size_t size)
+-{
+-    int need_swap = elf_swap(elf);
+-    const int8_t *s8;
+-    const int16_t *s16;
+-    const int32_t *s32;
+-    const int64_t *s64;
+-
+-    switch ( size )
+-    {
+-    case 1:
+-        s8 = ptr + offset;
+-        return *s8;
+-    case 2:
+-        s16 = ptr + offset;
+-        return need_swap ? bswap_16(*s16) : *s16;
+-    case 4:
+-        s32 = ptr + offset;
+-        return need_swap ? bswap_32(*s32) : *s32;
+-    case 8:
+-        s64 = ptr + offset;
+-        return need_swap ? bswap_64(*s64) : *s64;
+-    default:
+-        return 0;
+-    }
+-}
+-
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
+ {
+     int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index e8f6508..38e490c 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -136,23 +136,12 @@ struct elf_binary {
+                            offsetof(typeof(*(str)),e32.elem),           \
+                            sizeof((str)->e32.elem)))
+-#define elf_sval(elf, str, elem)                                        \
+-    ((ELFCLASS64 == (elf)->class)                                       \
+-     ? elf_access_signed((elf), (str),                                  \
+-                         offsetof(typeof(*(str)),e64.elem),             \
+-                         sizeof((str)->e64.elem))                       \
+-     : elf_access_signed((elf), (str),                                  \
+-                         offsetof(typeof(*(str)),e32.elem),             \
+-                         sizeof((str)->e32.elem)))
+-
+ #define elf_size(elf, str)                              \
+     ((ELFCLASS64 == (elf)->class)                       \
+      ? sizeof((str)->e64) : sizeof((str)->e32))
+ uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
+                              uint64_t offset, size_t size);
+-int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
+-                          uint64_t offset, size_t size);
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0006-libelf-move-include-of-asm-guest_access.h-to-top-of-.patch b/SOURCES/xsa55-4.2-0006-libelf-move-include-of-asm-guest_access.h-to-top-of-.patch
new file mode 100644 (file)
index 0000000..adbd32a
--- /dev/null
@@ -0,0 +1,50 @@
+From 682a04488e7b3bd6c3448ab60599566eb7c6177a Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 06/23] libelf: move include of <asm/guest_access.h> to top of file
+
+libelf-loader.c #includes <asm/guest_access.h>, when being compiled
+for Xen.  Currently it does this in the middle of the file.
+
+Move this #include to the top of the file, before libelf-private.h.
+This is necessary because in forthcoming patches we will introduce
+private #defines of memcpy etc. which would interfere with definitions
+in headers #included from guest_access.h.
+
+No semantic or functional change in this patch.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+---
+ xen/common/libelf/libelf-loader.c |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index 0559d88..ec0706b 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -16,6 +16,10 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+  */
++#ifdef __XEN__
++#include <asm/guest_access.h>
++#endif
++
+ #include "libelf-private.h"
+ /* ------------------------------------------------------------------------ */
+@@ -116,7 +120,6 @@ static int elf_load_image(struct elf_binary *elf,
+     return 0;
+ }
+ #else
+-#include <asm/guest_access.h>
+ void elf_set_verbose(struct elf_binary *elf)
+ {
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0007-libelf-xc_dom_load_elf_symtab-Do-not-use-syms-uninit.patch b/SOURCES/xsa55-4.2-0007-libelf-xc_dom_load_elf_symtab-Do-not-use-syms-uninit.patch
new file mode 100644 (file)
index 0000000..25425d0
--- /dev/null
@@ -0,0 +1,41 @@
+From de9089b449d2508b1ba05590905c7ebaee00c8c4 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:16 +0100
+Subject: [PATCH 07/23] libelf/xc_dom_load_elf_symtab: Do not use "syms" uninitialised
+
+xc_dom_load_elf_symtab (with load==0) calls elf_round_up, but it
+mistakenly used the uninitialised variable "syms" when calculating
+dom->bsd_symtab_start.  This should be a reference to "elf".
+
+This change might have the effect of rounding the value differently.
+Previously if the uninitialised value (a single byte on the stack) was
+ELFCLASS64 (ie, 2), the alignment would be to 8 bytes, otherwise to 4.
+
+However, the value is calculated from dom->kernel_seg.vend so this
+could only make a difference if that value wasn't already aligned to 8
+bytes.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+---
+ tools/libxc/xc_dom_elfloader.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 031b5b6..e82f6e9 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -144,7 +144,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         hdr = xc_dom_malloc(dom, size);
+         if ( hdr == NULL )
+             return 0;
+-        dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend);
++        dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
+     }
+     memcpy(hdr + sizeof(int),
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0008-libelf-introduce-macros-for-memory-access-and-pointe.patch b/SOURCES/xsa55-4.2-0008-libelf-introduce-macros-for-memory-access-and-pointe.patch
new file mode 100644 (file)
index 0000000..a9256b5
--- /dev/null
@@ -0,0 +1,1196 @@
+From 40020ab55a1e9a1674ddecdb70299fab4fe8579d Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 08/23] libelf: introduce macros for memory access and pointer handling
+
+We introduce a collection of macros which abstract away all the
+pointer arithmetic and dereferences used for accessing the input ELF
+and the output area(s).  We use the new macros everywhere.
+
+For now, these macros are semantically identical to the code they
+replace, so this patch has no functional change.
+
+elf_is_elfbinary is an exception: since it doesn't take an elf*, we
+need to handle it differently.  In a future patch we will change it to
+take, and check, a length parameter.  For now we just mark it with a
+fixme.
+
+That this patch has no functional change can be verified as follows:
+
+  0. Copy the scripts "comparison-generate" and "function-filter"
+     out of this commit message.
+  1. Check out the tree before this patch.
+  2. Run the script ../comparison-generate .... ../before
+  3. Check out the tree after this patch.
+  4. Run the script ../comparison-generate .... ../after
+  5. diff --exclude=\*.[soi] -ruN before/ after/ |less
+
+Expect these differences:
+  * stubdom/zlib-x86_64/ztest*.s2
+      The filename of this test file apparently contains the pid.
+  * xen/common/version.s2
+      The xen build timestamp appears in two diff hunks.
+
+Verification that this is all that's needed:
+  In a completely built xen.git,
+     find * -name .*.d -type f | xargs grep -l libelf\.h
+  Expect results in:
+     xen/arch/x86:            Checked above.
+     tools/libxc:             Checked above.
+     tools/xcutils/readnotes: Checked above.
+     tools/xenstore:          Checked above.
+     xen/common/libelf:
+       This is the build for the hypervisor; checked in B above.
+     stubdom:
+       We have one stubdom which reads ELFs using our libelf,
+       pvgrub, which is checked above.
+
+I have not done this verification for ARM.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+-8<- comparison-generate -8<-
+ #!/bin/bash
+ # usage:
+ #  cd xen.git
+ #  .../comparison-generate OUR-CONFIG BUILD-RUNE-PREFIX ../before|../after
+ # eg:
+ #  .../comparison-generate ~/work/.config 'schroot -pc64 --' ../before
+ set -ex
+
+ test $# = 3 || need-exactly-three-arguments
+
+ our_config=$1
+ build_rune_prefix=$2
+ result_dir=$3
+
+ git clean -x -d -f
+
+ cp "$our_config" .
+
+ cat <<END >>.config
+         debug_symbols=n
+         CFLAGS += -save-temps
+ END
+
+ perl -i~ -pe 's/ -g / -g0 / if m/^CFLAGS/' xen/Rules.mk
+
+ if [ -f ./configure ]; then
+         $build_rune_prefix ./configure
+ fi
+
+ $build_rune_prefix make -C xen
+ $build_rune_prefix make -C tools/include
+ $build_rune_prefix make -C stubdom grub
+ $build_rune_prefix make -C tools/libxc
+ $build_rune_prefix make -C tools/xenstore
+ $build_rune_prefix make -C tools/xcutils
+
+ rm -rf "$result_dir"
+ mkdir "$result_dir"
+
+ set +x
+ for f in `find xen tools stubdom -name \*.[soi]`; do
+         mkdir -p "$result_dir"/`dirname $f`
+         cp $f "$result_dir"/${f}
+         case $f in
+         *.s)
+                 ../function-filter <$f >"$result_dir"/${f}2
+                 ;;
+         esac
+ done
+
+ echo ok.
+-8<-
+
+-8<- function-filter -8<-
+ #!/usr/bin/perl -w
+ # function-filter
+ # script for massaging gcc-generated labels to be consistent
+ use strict;
+ our @lines;
+ my $sedderybody = "sub seddery () {\n";
+ while (<>) {
+     push @lines, $_;
+     if (m/^(__FUNCTION__|__func__)\.(\d+)\:/) {
+         $sedderybody .= "    s/\\b$1\\.$2\\b/__XSA55MANGLED__$1.$./g;\n";
+     }
+ }
+ $sedderybody .= "}\n1;\n";
+ eval $sedderybody or die $@;
+ foreach (@lines) {
+     seddery();
+     print or die $!;
+ }
+-8<-
+---
+ tools/libxc/xc_dom_elfloader.c     |   30 +++---
+ tools/libxc/xc_hvm_build_x86.c     |    2 +-
+ tools/xcutils/readnotes.c          |   26 +++---
+ xen/common/libelf/libelf-dominfo.c |   51 +++++-----
+ xen/common/libelf/libelf-loader.c  |   84 +++++++++--------
+ xen/common/libelf/libelf-tools.c   |   94 +++++++++---------
+ xen/include/xen/libelf.h           |  188 +++++++++++++++++++++++++++++++-----
+ 7 files changed, 312 insertions(+), 163 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index e82f6e9..cc0f206 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -115,9 +115,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+                                   struct elf_binary *elf, int load)
+ {
+     struct elf_binary syms;
+-    const elf_shdr *shdr, *shdr2;
++    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
+     xen_vaddr_t symtab, maxaddr;
+-    char *hdr;
++    ELF_PTRVAL_CHAR hdr;
+     size_t size;
+     int h, count, type, i, tables = 0;
+@@ -147,11 +147,11 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
+     }
+-    memcpy(hdr + sizeof(int),
+-           elf->image,
++    elf_memcpy_safe(elf, hdr + sizeof(int),
++           ELF_IMAGE_BASE(elf),
+            elf_size(elf, elf->ehdr));
+-    memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr),
+-           elf->image + elf_uval(elf, elf->ehdr, e_shoff),
++    elf_memcpy_safe(elf, hdr + sizeof(int) + elf_size(elf, elf->ehdr),
++           ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
+            elf_shdr_count(elf) * elf_size(elf, shdr));
+     if ( elf_64bit(elf) )
+     {
+@@ -189,7 +189,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     count = elf_shdr_count(&syms);
+     for ( h = 0; h < count; h++ )
+     {
+-        shdr = elf_shdr_by_index(&syms, h);
++        shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
+         type = elf_uval(&syms, shdr, sh_type);
+         if ( type == SHT_STRTAB )
+         {
+@@ -205,9 +205,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             if ( i == count )
+             {
+                 if ( elf_64bit(&syms) )
+-                    *(Elf64_Off*)(&shdr->e64.sh_offset) = 0;
++                    elf_store_field(elf, shdr, e64.sh_offset, 0);
+                 else
+-                    *(Elf32_Off*)(&shdr->e32.sh_offset) = 0;
++                    elf_store_field(elf, shdr, e32.sh_offset, 0);
+                 continue;
+             }
+         }
+@@ -216,9 +216,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         {
+             /* Mangled to be based on ELF header location. */
+             if ( elf_64bit(&syms) )
+-                *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab;
++                elf_store_field(elf, shdr, e64.sh_offset, maxaddr - symtab);
+             else
+-                *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab;
++                elf_store_field(elf, shdr, e32.sh_offset, maxaddr - symtab);
+             size = elf_uval(&syms, shdr, sh_size);
+             maxaddr = elf_round_up(&syms, maxaddr + size);
+             tables++;
+@@ -230,7 +230,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             if ( load )
+             {
+                 shdr2 = elf_shdr_by_index(elf, h);
+-                memcpy((void*)elf_section_start(&syms, shdr),
++                elf_memcpy_safe(elf, ELF_OBSOLETE_VOIDP_CAST elf_section_start(&syms, shdr),
+                        elf_section_start(elf, shdr2),
+                        size);
+             }
+@@ -238,9 +238,9 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         /* Name is NULL. */
+         if ( elf_64bit(&syms) )
+-            *(Elf64_Word*)(&shdr->e64.sh_name) = 0;
++            elf_store_field(elf, shdr, e64.sh_name, 0);
+         else
+-            *(Elf32_Word*)(&shdr->e32.sh_name) = 0;
++            elf_store_field(elf, shdr, e32.sh_name, 0);
+     }
+     if ( tables == 0 )
+@@ -275,7 +275,7 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
+     }
+     /* Find the section-header strings table. */
+-    if ( elf->sec_strtab == NULL )
++    if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
+     {
+         xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
+                      " has no shstrtab", __FUNCTION__);
+diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
+index cf5d7fb..15b603d 100644
+--- a/tools/libxc/xc_hvm_build_x86.c
++++ b/tools/libxc/xc_hvm_build_x86.c
+@@ -110,7 +110,7 @@ static int loadelfimage(
+     if ( elf->dest == NULL )
+         goto err;
+-    elf->dest += elf->pstart & (PAGE_SIZE - 1);
++    ELF_ADVANCE_DEST(elf, elf->pstart & (PAGE_SIZE - 1));
+     /* Load the initial elf image. */
+     rc = elf_load_binary(elf);
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index c926186..2af047d 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -61,13 +61,13 @@ struct setup_header {
+ } __attribute__((packed));
+ static void print_string_note(const char *prefix, struct elf_binary *elf,
+-                            const elf_note *note)
++                            ELF_HANDLE_DECL(elf_note) note)
+ {
+       printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
+ }
+ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
+-                             const elf_note *note)
++                             ELF_HANDLE_DECL(elf_note) note)
+ {
+       uint64_t value = elf_note_numeric(elf, note);
+       int descsz = elf_uval(elf, note, descsz);
+@@ -98,12 +98,12 @@ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
+ }
+-static int print_notes(struct elf_binary *elf, const elf_note *start, const elf_note *end)
++static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start, ELF_HANDLE_DECL(elf_note) end)
+ {
+-      const elf_note *note;
++      ELF_HANDLE_DECL(elf_note) note;
+       int notes_found = 0;
+-      for ( note = start; note < end; note = elf_note_next(elf, note) )
++      for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
+       {
+               if (0 != strcmp(elf_note_name(elf, note), "Xen"))
+                       continue;
+@@ -170,7 +170,7 @@ int main(int argc, char **argv)
+       void *image,*tmp;
+       struct stat st;
+       struct elf_binary elf;
+-      const elf_shdr *shdr;
++      ELF_HANDLE_DECL(elf_shdr) shdr;
+       int notes_found = 0;
+       struct setup_header *hdr;
+@@ -257,7 +257,7 @@ int main(int argc, char **argv)
+       count = elf_phdr_count(&elf);
+       for ( h=0; h < count; h++)
+       {
+-              const elf_phdr *phdr;
++              ELF_HANDLE_DECL(elf_phdr) phdr;
+               phdr = elf_phdr_by_index(&elf, h);
+               if (elf_uval(&elf, phdr, p_type) != PT_NOTE)
+                       continue;
+@@ -269,8 +269,8 @@ int main(int argc, char **argv)
+                       continue;
+               notes_found = print_notes(&elf,
+-                                        elf_segment_start(&elf, phdr),
+-                                        elf_segment_end(&elf, phdr));
++                                        ELF_MAKE_HANDLE(elf_note, elf_segment_start(&elf, phdr)),
++                                        ELF_MAKE_HANDLE(elf_note, elf_segment_end(&elf, phdr)));
+       }
+       if ( notes_found == 0 )
+@@ -278,13 +278,13 @@ int main(int argc, char **argv)
+               count = elf_shdr_count(&elf);
+               for ( h=0; h < count; h++)
+               {
+-                      const elf_shdr *shdr;
++                      ELF_HANDLE_DECL(elf_shdr) shdr;
+                       shdr = elf_shdr_by_index(&elf, h);
+                       if (elf_uval(&elf, shdr, sh_type) != SHT_NOTE)
+                               continue;
+                       notes_found = print_notes(&elf,
+-                                                elf_section_start(&elf, shdr),
+-                                                elf_section_end(&elf, shdr));
++                                                ELF_MAKE_HANDLE(elf_note, elf_section_start(&elf, shdr)),
++                                                ELF_MAKE_HANDLE(elf_note, elf_section_end(&elf, shdr)));
+                       if ( notes_found )
+                               fprintf(stderr, "using notes from SHT_NOTE section\n");
+@@ -292,7 +292,7 @@ int main(int argc, char **argv)
+       }
+       shdr = elf_shdr_by_name(&elf, "__xen_guest");
+-      if (shdr)
++      if (ELF_HANDLE_VALID(shdr))
+               printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));
+       return 0;
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index 523837f..7140d59 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -44,7 +44,7 @@ int elf_xen_parse_features(const char *features,
+     for ( pos = 0; features[pos] != '\0'; pos += len )
+     {
+-        memset(feature, 0, sizeof(feature));
++        elf_memset_unchecked(feature, 0, sizeof(feature));
+         for ( len = 0;; len++ )
+         {
+             if ( len >= sizeof(feature)-1 )
+@@ -96,7 +96,7 @@ int elf_xen_parse_features(const char *features,
+ int elf_xen_parse_note(struct elf_binary *elf,
+                        struct elf_dom_parms *parms,
+-                       const elf_note *note)
++                       ELF_HANDLE_DECL(elf_note) note)
+ {
+ /* *INDENT-OFF* */
+     static const struct {
+@@ -215,15 +215,16 @@ int elf_xen_parse_note(struct elf_binary *elf,
+ static int elf_xen_parse_notes(struct elf_binary *elf,
+                                struct elf_dom_parms *parms,
+-                               const void *start, const void *end)
++                               ELF_PTRVAL_CONST_VOID start,
++                               ELF_PTRVAL_CONST_VOID end)
+ {
+     int xen_elfnotes = 0;
+-    const elf_note *note;
++    ELF_HANDLE_DECL(elf_note) note;
+     parms->elf_note_start = start;
+     parms->elf_note_end   = end;
+-    for ( note = parms->elf_note_start;
+-          (void *)note < parms->elf_note_end;
++    for ( note = ELF_MAKE_HANDLE(elf_note, parms->elf_note_start);
++          ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
+           note = elf_note_next(elf, note) )
+     {
+         if ( strcmp(elf_note_name(elf, note), "Xen") )
+@@ -241,45 +242,46 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
+ int elf_xen_parse_guest_info(struct elf_binary *elf,
+                              struct elf_dom_parms *parms)
+ {
+-    const char *h;
++    ELF_PTRVAL_CONST_CHAR h;
+     char name[32], value[128];
+     int len;
+     h = parms->guest_info;
+-    while ( *h )
++#define STAR(h) (*(h))
++    while ( STAR(h) )
+     {
+-        memset(name, 0, sizeof(name));
+-        memset(value, 0, sizeof(value));
++        elf_memset_unchecked(name, 0, sizeof(name));
++        elf_memset_unchecked(value, 0, sizeof(value));
+         for ( len = 0;; len++, h++ )
+         {
+             if ( len >= sizeof(name)-1 )
+                 break;
+-            if ( *h == '\0' )
++            if ( STAR(h) == '\0' )
+                 break;
+-            if ( *h == ',' )
++            if ( STAR(h) == ',' )
+             {
+                 h++;
+                 break;
+             }
+-            if ( *h == '=' )
++            if ( STAR(h) == '=' )
+             {
+                 h++;
+                 for ( len = 0;; len++, h++ )
+                 {
+                     if ( len >= sizeof(value)-1 )
+                         break;
+-                    if ( *h == '\0' )
++                    if ( STAR(h) == '\0' )
+                         break;
+-                    if ( *h == ',' )
++                    if ( STAR(h) == ',' )
+                     {
+                         h++;
+                         break;
+                     }
+-                    value[len] = *h;
++                    value[len] = STAR(h);
+                 }
+                 break;
+             }
+-            name[len] = *h;
++            name[len] = STAR(h);
+         }
+         elf_msg(elf, "%s: %s=\"%s\"\n", __FUNCTION__, name, value);
+@@ -328,7 +330,8 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
+ static int elf_xen_note_check(struct elf_binary *elf,
+                               struct elf_dom_parms *parms)
+ {
+-    if ( (parms->elf_note_start == NULL) && (parms->guest_info == NULL) )
++    if ( (ELF_PTRVAL_INVALID(parms->elf_note_start)) &&
++         (ELF_PTRVAL_INVALID(parms->guest_info)) )
+     {
+         int machine = elf_uval(elf, elf->ehdr, e_machine);
+         if ( (machine == EM_386) || (machine == EM_X86_64) )
+@@ -457,12 +460,12 @@ static int elf_xen_addr_calc_check(struct elf_binary *elf,
+ int elf_xen_parse(struct elf_binary *elf,
+                   struct elf_dom_parms *parms)
+ {
+-    const elf_shdr *shdr;
+-    const elf_phdr *phdr;
++    ELF_HANDLE_DECL(elf_shdr) shdr;
++    ELF_HANDLE_DECL(elf_phdr) phdr;
+     int xen_elfnotes = 0;
+     int i, count, rc;
+-    memset(parms, 0, sizeof(*parms));
++    elf_memset_unchecked(parms, 0, sizeof(*parms));
+     parms->virt_base = UNSET_ADDR;
+     parms->virt_entry = UNSET_ADDR;
+     parms->virt_hypercall = UNSET_ADDR;
+@@ -532,11 +535,11 @@ int elf_xen_parse(struct elf_binary *elf,
+         for ( i = 0; i < count; i++ )
+         {
+             shdr = elf_shdr_by_name(elf, "__xen_guest");
+-            if ( shdr )
++            if ( ELF_HANDLE_VALID(shdr) )
+             {
+                 parms->guest_info = elf_section_start(elf, shdr);
+-                parms->elf_note_start = NULL;
+-                parms->elf_note_end   = NULL;
++                parms->elf_note_start = ELF_INVALID_PTRVAL;
++                parms->elf_note_end   = ELF_INVALID_PTRVAL;
+                 elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
+                         parms->guest_info);
+                 elf_xen_parse_guest_info(elf, parms);
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index ec0706b..0fef84c 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -26,7 +26,7 @@
+ int elf_init(struct elf_binary *elf, const char *image, size_t size)
+ {
+-    const elf_shdr *shdr;
++    ELF_HANDLE_DECL(elf_shdr) shdr;
+     uint64_t i, count, section, offset;
+     if ( !elf_is_elfbinary(image) )
+@@ -35,7 +35,7 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
+         return -1;
+     }
+-    memset(elf, 0, sizeof(*elf));
++    elf_memset_unchecked(elf, 0, sizeof(*elf));
+     elf->image = image;
+     elf->size = size;
+     elf->ehdr = (elf_ehdr *)image;
+@@ -65,7 +65,7 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
+     /* Find section string table. */
+     section = elf_uval(elf, elf->ehdr, e_shstrndx);
+     shdr = elf_shdr_by_index(elf, section);
+-    if ( shdr != NULL )
++    if ( ELF_HANDLE_VALID(shdr) )
+         elf->sec_strtab = elf_section_start(elf, shdr);
+     /* Find symbol table and symbol string table. */
+@@ -77,9 +77,9 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size)
+             continue;
+         elf->sym_tab = shdr;
+         shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
+-        if ( shdr == NULL )
++        if ( !ELF_HANDLE_VALID(shdr) )
+         {
+-            elf->sym_tab = NULL;
++            elf->sym_tab = ELF_INVALID_HANDLE(elf_shdr);
+             continue;
+         }
+         elf->sym_strtab = elf_section_start(elf, shdr);
+@@ -113,10 +113,11 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+ }
+ static int elf_load_image(struct elf_binary *elf,
+-                          void *dst, const void *src, uint64_t filesz, uint64_t memsz)
++                          ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src,
++                          uint64_t filesz, uint64_t memsz)
+ {
+-    memcpy(dst, src, filesz);
+-    memset(dst + filesz, 0, memsz - filesz);
++    elf_memcpy_safe(elf, dst, src, filesz);
++    elf_memset_safe(elf, dst + filesz, 0, memsz - filesz);
+     return 0;
+ }
+ #else
+@@ -126,16 +127,17 @@ void elf_set_verbose(struct elf_binary *elf)
+     elf->verbose = 1;
+ }
+-static int elf_load_image(struct elf_binary *elf,
+-                          void *dst, const void *src, uint64_t filesz, uint64_t memsz)
++static int elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
+ {
+     int rc;
+     if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
+         return -1;
+-    rc = raw_copy_to_guest(dst, src, filesz);
++    /* We trust the dom0 kernel image completely, so we don't care
++     * about overruns etc. here. */
++    rc = raw_copy_to_guest(ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), filesz);
+     if ( rc != 0 )
+         return -1;
+-    rc = raw_clear_guest(dst + filesz, memsz - filesz);
++    rc = raw_clear_guest(ELF_UNSAFE_PTR(dst + filesz), memsz - filesz);
+     if ( rc != 0 )
+         return -1;
+     return 0;
+@@ -146,10 +148,10 @@ static int elf_load_image(struct elf_binary *elf,
+ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+ {
+     uint64_t sz;
+-    const elf_shdr *shdr;
++    ELF_HANDLE_DECL(elf_shdr) shdr;
+     int i, type;
+-    if ( !elf->sym_tab )
++    if ( !ELF_HANDLE_VALID(elf->sym_tab) )
+         return;
+     pstart = elf_round_up(elf, pstart);
+@@ -166,7 +168,7 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
+         shdr = elf_shdr_by_index(elf, i);
+-        type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
++        type = elf_uval(elf, shdr, sh_type);
+         if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+             sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
+     }
+@@ -177,10 +179,12 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+ static void elf_load_bsdsyms(struct elf_binary *elf)
+ {
+-    elf_ehdr *sym_ehdr;
++    ELF_HANDLE_DECL_NONCONST(elf_ehdr) sym_ehdr;
+     unsigned long sz;
+-    char *maxva, *symbase, *symtab_addr;
+-    elf_shdr *shdr;
++    ELF_PTRVAL_VOID maxva;
++    ELF_PTRVAL_VOID symbase;
++    ELF_PTRVAL_VOID symtab_addr;
++    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
+     int i, type;
+     if ( !elf->bsd_symtab_pstart )
+@@ -189,18 +193,18 @@ static void elf_load_bsdsyms(struct elf_binary *elf)
+ #define elf_hdr_elm(_elf, _hdr, _elm, _val)     \
+ do {                                            \
+     if ( elf_64bit(_elf) )                      \
+-        (_hdr)->e64._elm = _val;                \
++        elf_store_field(_elf, _hdr, e64._elm, _val);  \
+     else                                        \
+-        (_hdr)->e32._elm = _val;                \
++        elf_store_field(_elf, _hdr, e32._elm, _val);  \
+ } while ( 0 )
+     symbase = elf_get_ptr(elf, elf->bsd_symtab_pstart);
+     symtab_addr = maxva = symbase + sizeof(uint32_t);
+     /* Set up Elf header. */
+-    sym_ehdr = (elf_ehdr *)symtab_addr;
++    sym_ehdr = ELF_MAKE_HANDLE(elf_ehdr, symtab_addr);
+     sz = elf_uval(elf, elf->ehdr, e_ehsize);
+-    memcpy(sym_ehdr, elf->ehdr, sz);
++    elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(sym_ehdr), ELF_HANDLE_PTRVAL(elf->ehdr), sz);
+     maxva += sz; /* no round up */
+     elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
+@@ -209,37 +213,39 @@ do {                                            \
+     elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
+     /* Copy Elf section headers. */
+-    shdr = (elf_shdr *)maxva;
++    shdr = ELF_MAKE_HANDLE(elf_shdr, maxva);
+     sz = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
+-    memcpy(shdr, elf->image + elf_uval(elf, elf->ehdr, e_shoff), sz);
+-    maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
++    elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
++                    ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
++                    sz);
++    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
+         type = elf_uval(elf, shdr, sh_type);
+         if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+         {
+-             elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
++             elf_msg(elf, "%s: shdr %i at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n", __func__, i,
+                      elf_section_start(elf, shdr), maxva);
+              sz = elf_uval(elf, shdr, sh_size);
+-             memcpy(maxva, elf_section_start(elf, shdr), sz);
++             elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
+              /* Mangled to be based on ELF header location. */
+              elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
+-             maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
++             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
+         }
+-        shdr = (elf_shdr *)((long)shdr +
++        shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
+                             (long)elf_uval(elf, elf->ehdr, e_shentsize));
+     }
+     /* Write down the actual sym size. */
+-    *(uint32_t *)symbase = maxva - symtab_addr;
++    elf_store_val(elf, uint32_t, symbase, maxva - symtab_addr);
+ #undef elf_ehdr_elm
+ }
+ void elf_parse_binary(struct elf_binary *elf)
+ {
+-    const elf_phdr *phdr;
++    ELF_HANDLE_DECL(elf_phdr) phdr;
+     uint64_t low = -1;
+     uint64_t high = 0;
+     uint64_t i, count, paddr, memsz;
+@@ -267,9 +273,9 @@ void elf_parse_binary(struct elf_binary *elf)
+ int elf_load_binary(struct elf_binary *elf)
+ {
+-    const elf_phdr *phdr;
++    ELF_HANDLE_DECL(elf_phdr) phdr;
+     uint64_t i, count, paddr, offset, filesz, memsz;
+-    char *dest;
++    ELF_PTRVAL_VOID dest;
+     count = elf_uval(elf, elf->ehdr, e_phnum);
+     for ( i = 0; i < count; i++ )
+@@ -282,9 +288,9 @@ int elf_load_binary(struct elf_binary *elf)
+         filesz = elf_uval(elf, phdr, p_filesz);
+         memsz = elf_uval(elf, phdr, p_memsz);
+         dest = elf_get_ptr(elf, paddr);
+-        elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
+-                __func__, i, dest, dest + filesz);
+-        if ( elf_load_image(elf, dest, elf->image + offset, filesz, memsz) != 0 )
++        elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n",
++                __func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
++        if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, memsz) != 0 )
+             return -1;
+     }
+@@ -292,18 +298,18 @@ int elf_load_binary(struct elf_binary *elf)
+     return 0;
+ }
+-void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
++ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr)
+ {
+     return elf->dest + addr - elf->pstart;
+ }
+ uint64_t elf_lookup_addr(struct elf_binary * elf, const char *symbol)
+ {
+-    const elf_sym *sym;
++    ELF_HANDLE_DECL(elf_sym) sym;
+     uint64_t value;
+     sym = elf_sym_by_name(elf, symbol);
+-    if ( sym == NULL )
++    if ( !ELF_HANDLE_VALID(sym) )
+     {
+         elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol);
+         return -1;
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 2f54142..f1fd886 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -67,10 +67,10 @@ int elf_phdr_count(struct elf_binary *elf)
+     return elf_uval(elf, elf->ehdr, e_phnum);
+ }
+-const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *name)
+ {
+     uint64_t count = elf_shdr_count(elf);
+-    const elf_shdr *shdr;
++    ELF_HANDLE_DECL(elf_shdr) shdr;
+     const char *sname;
+     int i;
+@@ -81,76 +81,80 @@ const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name)
+         if ( sname && !strcmp(sname, name) )
+             return shdr;
+     }
+-    return NULL;
++    return ELF_INVALID_HANDLE(elf_shdr);
+ }
+-const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index)
+ {
+     uint64_t count = elf_shdr_count(elf);
+-    const void *ptr;
++    ELF_PTRVAL_CONST_VOID ptr;
+     if ( index >= count )
+-        return NULL;
++        return ELF_INVALID_HANDLE(elf_shdr);
+-    ptr = (elf->image
++    ptr = (ELF_IMAGE_BASE(elf)
+            + elf_uval(elf, elf->ehdr, e_shoff)
+            + elf_uval(elf, elf->ehdr, e_shentsize) * index);
+-    return ptr;
++    return ELF_MAKE_HANDLE(elf_shdr, ptr);
+ }
+-const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index)
+ {
+     uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
+-    const void *ptr;
++    ELF_PTRVAL_CONST_VOID ptr;
+     if ( index >= count )
+-        return NULL;
++        return ELF_INVALID_HANDLE(elf_phdr);
+-    ptr = (elf->image
++    ptr = (ELF_IMAGE_BASE(elf)
+            + elf_uval(elf, elf->ehdr, e_phoff)
+            + elf_uval(elf, elf->ehdr, e_phentsize) * index);
+-    return ptr;
++    return ELF_MAKE_HANDLE(elf_phdr, ptr);
+ }
+-const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr)
++
++const char *elf_section_name(struct elf_binary *elf,
++                             ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+-    if ( elf->sec_strtab == NULL )
++    if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
+         return "unknown";
++
+     return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
+ }
+-const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr)
++ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+-    return elf->image + elf_uval(elf, shdr, sh_offset);
++    return ELF_IMAGE_BASE(elf) + elf_uval(elf, shdr, sh_offset);
+ }
+-const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr)
++ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+-    return elf->image
++    return ELF_IMAGE_BASE(elf)
+         + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
+ }
+-const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr)
++ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+-    return elf->image + elf_uval(elf, phdr, p_offset);
++    return ELF_IMAGE_BASE(elf)
++        + elf_uval(elf, phdr, p_offset);
+ }
+-const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr)
++ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+-    return elf->image
++    return ELF_IMAGE_BASE(elf)
+         + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
+ }
+-const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol)
+ {
+-    const void *ptr = elf_section_start(elf, elf->sym_tab);
+-    const void *end = elf_section_end(elf, elf->sym_tab);
+-    const elf_sym *sym;
++    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
++    ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
++    ELF_HANDLE_DECL(elf_sym) sym;
+     uint64_t info, name;
+     for ( ; ptr < end; ptr += elf_size(elf, sym) )
+     {
+-        sym = ptr;
++        sym = ELF_MAKE_HANDLE(elf_sym, ptr);
+         info = elf_uval(elf, sym, st_info);
+         name = elf_uval(elf, sym, st_name);
+         if ( ELF32_ST_BIND(info) != STB_GLOBAL )
+@@ -159,33 +163,33 @@ const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol)
+             continue;
+         return sym;
+     }
+-    return NULL;
++    return ELF_INVALID_HANDLE(elf_sym);
+ }
+-const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
+ {
+-    const void *ptr = elf_section_start(elf, elf->sym_tab);
+-    const elf_sym *sym;
++    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
++    ELF_HANDLE_DECL(elf_sym) sym;
+-    sym = ptr + index * elf_size(elf, sym);
++    sym = ELF_MAKE_HANDLE(elf_sym, ptr + index * elf_size(elf, sym));
+     return sym;
+ }
+-const char *elf_note_name(struct elf_binary *elf, const elf_note * note)
++const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    return (void *)note + elf_size(elf, note);
++    return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note);
+ }
+-const void *elf_note_desc(struct elf_binary *elf, const elf_note * note)
++ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+     int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+-    return (void *)note + elf_size(elf, note) + namesz;
++    return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz;
+ }
+-uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
++uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    const void *desc = elf_note_desc(elf, note);
++    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+     int descsz = elf_uval(elf, note, descsz);
+     switch (descsz)
+@@ -200,10 +204,10 @@ uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note)
+     }
+ }
+-uint64_t elf_note_numeric_array(struct elf_binary *elf, const elf_note *note,
++uint64_t elf_note_numeric_array(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note,
+                                 unsigned int unitsz, unsigned int idx)
+ {
+-    const void *desc = elf_note_desc(elf, note);
++    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+     int descsz = elf_uval(elf, note, descsz);
+     if ( descsz % unitsz || idx >= descsz / unitsz )
+@@ -220,12 +224,12 @@ uint64_t elf_note_numeric_array(struct elf_binary *elf, const elf_note *note,
+     }
+ }
+-const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note)
++ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+     int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+     int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
+-    return (void *)note + elf_size(elf, note) + namesz + descsz;
++    return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz + descsz);
+ }
+ /* ------------------------------------------------------------------------ */
+@@ -234,10 +238,10 @@ int elf_is_elfbinary(const void *image)
+ {
+     const Elf32_Ehdr *ehdr = image;
+-    return IS_ELF(*ehdr);
++    return IS_ELF(*ehdr); /* fixme unchecked */
+ }
+-int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr)
++int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+     uint64_t p_type = elf_uval(elf, phdr, p_type);
+     uint64_t p_flags = elf_uval(elf, phdr, p_flags);
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index 38e490c..cefd3d3 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -48,6 +48,97 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+ /* ------------------------------------------------------------------------ */
++/* Macros for accessing the input image and output area. */
++
++/*
++ * We abstract away the pointerness of these pointers, replacing
++ * various void*, char* and struct* with the following:
++ *   PTRVAL      A pointer to a byte; one can do pointer arithmetic
++ *               on this.
++ *               This replaces variables which were char*,void*
++ *               and their const versions, so we provide four
++ *               different declaration macros:
++ *                   ELF_PTRVAL_{,CONST}{VOID,CHAR}
++ *   HANDLE      A pointer to a struct.  There is one of these types
++ *               for each pointer type - that is, for each "structname".
++ *               In the arguments to the various HANDLE macros, structname
++ *               must be a single identifier which is a typedef.
++ *               It is not permitted to do arithmetic on these
++ *               pointers.  In the current code attempts to do so will
++ *               compile, but in the next patch this will become a
++ *               compile error.
++ *               We provide two declaration macros for const and
++ *               non-const pointers.
++ */
++
++#define ELF_REALPTR2PTRVAL(realpointer) (realpointer)
++  /* Converts an actual C pointer into a PTRVAL */
++
++#define ELF_HANDLE_DECL_NONCONST(structname)  structname *
++#define ELF_HANDLE_DECL(structname)           const structname *
++  /* Provides a type declaration for a HANDLE. */
++  /* May only be used to declare ONE variable at a time */
++
++#define ELF_PTRVAL_VOID         void *
++#define ELF_PTRVAL_CHAR         char *
++#define ELF_PTRVAL_CONST_VOID   const void *
++#define ELF_PTRVAL_CONST_CHAR   const char *
++  /* Provides a type declaration for a PTRVAL. */
++  /* May only be used to declare ONE variable at a time */
++
++#define ELF_DEFINE_HANDLE(structname) /* empty */
++  /*
++   * This must be invoked for each HANDLE type to define
++   * the actual C type used for that kind of HANDLE.
++   */
++
++#define ELF_PRPTRVAL "p"
++  /* printf format a la PRId... for a PTRVAL */
++
++#define ELF_MAKE_HANDLE(structname, ptrval) (ptrval)
++  /* Converts a PTRVAL to a HANDLE */
++
++#define ELF_IMAGE_BASE(elf) ((elf)->image)
++  /* Returns the base of the image as a PTRVAL. */
++
++#define ELF_HANDLE_PTRVAL(handleval) ((void*)(handleval))
++  /* Converts a HANDLE to a PTRVAL. */
++
++#define ELF_OBSOLETE_VOIDP_CAST (void*)(uintptr_t)
++  /*
++   * In some places the existing code needs to
++   *  - cast away const (the existing code uses const a fair
++   *    bit but actually sometimes wants to write to its input)
++   *    from a PTRVAL.
++   *  - convert an integer representing a pointer to a PTRVAL
++   * This macro provides a suitable cast.
++   */
++
++#define ELF_UNSAFE_PTR(ptrval) ((void*)(uintptr_t)(ptrval))
++  /*
++   * Turns a PTRVAL into an actual C pointer.  Before this is done
++   * the caller must have ensured that the PTRVAL does in fact point
++   * to a permissible location.
++   */
++
++/* PTRVALs can be INVALID (ie, NULL). */
++#define ELF_INVALID_PTRVAL            (NULL)        /* returns NULL PTRVAL */
++#define ELF_INVALID_HANDLE(structname)                    /* returns NULL handle */ \
++    ELF_MAKE_HANDLE(structname, ELF_INVALID_PTRVAL)
++#define ELF_PTRVAL_VALID(ptrval)      (ptrval)            /* }            */
++#define ELF_HANDLE_VALID(handleval)   (handleval)         /* } predicates */
++#define ELF_PTRVAL_INVALID(ptrval)    ((ptrval) == NULL)  /* }            */
++
++/* For internal use by other macros here */
++#define ELF__HANDLE_FIELD_TYPE(handleval, elm) \
++  typeof((handleval)->elm)
++#define ELF__HANDLE_FIELD_OFFSET(handleval, elm) \
++  offsetof(typeof(*(handleval)),elm)
++
++
++/* ------------------------------------------------------------------------ */
++
++
+ typedef union {
+     Elf32_Ehdr e32;
+     Elf64_Ehdr e64;
+@@ -83,6 +174,12 @@ typedef union {
+     Elf64_Note e64;
+ } elf_note;
++ELF_DEFINE_HANDLE(elf_ehdr)
++ELF_DEFINE_HANDLE(elf_shdr)
++ELF_DEFINE_HANDLE(elf_phdr)
++ELF_DEFINE_HANDLE(elf_sym)
++ELF_DEFINE_HANDLE(elf_note)
++
+ struct elf_binary {
+     /* elf binary */
+     const char *image;
+@@ -90,10 +187,10 @@ struct elf_binary {
+     char class;
+     char data;
+-    const elf_ehdr *ehdr;
+-    const char *sec_strtab;
+-    const elf_shdr *sym_tab;
+-    const char *sym_strtab;
++    ELF_HANDLE_DECL(elf_ehdr) ehdr;
++    ELF_PTRVAL_CONST_CHAR sec_strtab;
++    ELF_HANDLE_DECL(elf_shdr) sym_tab;
++    ELF_PTRVAL_CONST_CHAR sym_strtab;
+     /* loaded to */
+     char *dest;
+@@ -135,45 +232,72 @@ struct elf_binary {
+      : elf_access_unsigned((elf), (str),                                \
+                            offsetof(typeof(*(str)),e32.elem),           \
+                            sizeof((str)->e32.elem)))
++  /*
++   * Reads an unsigned field in a header structure in the ELF.
++   * str is a HANDLE, and elem is the field name in it.
++   */
+ #define elf_size(elf, str)                              \
+     ((ELFCLASS64 == (elf)->class)                       \
+      ? sizeof((str)->e64) : sizeof((str)->e32))
++  /*
++   * Returns the size of the substructure for the appropriate 32/64-bitness.
++   * str should be a HANDLE.
++   */
+-uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
++uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
+                              uint64_t offset, size_t size);
++  /* Reads a field at arbitrary offset and alignemnt */
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
++
++#define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
++#define elf_memset_safe(elf, dst, c, sz)   memset((dst),(c),(sz))
++  /*
++   * Versions of memcpy and memset which will (in the next patch)
++   * arrange never to write outside permitted areas.
++   */
++
++#define elf_store_val(elf, type, ptr, val)   (*(type*)(ptr) = (val))
++  /* Stores a value at a particular PTRVAL. */
++
++#define elf_store_field(elf, hdr, elm, val)                     \
++    (elf_store_val((elf), ELF__HANDLE_FIELD_TYPE(hdr, elm),     \
++                   &((hdr)->elm),                               \
++                   (val)))
++  /* Stores a 32/64-bit field.  hdr is a HANDLE and elm is the field name. */
++
++
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_tools.c                                                        */
+ int elf_shdr_count(struct elf_binary *elf);
+ int elf_phdr_count(struct elf_binary *elf);
+-const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name);
+-const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index);
+-const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index);
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *name);
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
++ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
+-const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr);
+-const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr);
+-const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr);
++const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
++ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
++ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+-const void *elf_segment_start(struct elf_binary *elf, const elf_phdr * phdr);
+-const void *elf_segment_end(struct elf_binary *elf, const elf_phdr * phdr);
++ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
++ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+-const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol);
+-const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index);
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
+-const char *elf_note_name(struct elf_binary *elf, const elf_note * note);
+-const void *elf_note_desc(struct elf_binary *elf, const elf_note * note);
+-uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note);
+-uint64_t elf_note_numeric_array(struct elf_binary *, const elf_note *,
++const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
++ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
++uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
++uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+                                 unsigned int unitsz, unsigned int idx);
+-const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note);
++ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ int elf_is_elfbinary(const void *image);
+-int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
++int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_loader.c                                                       */
+@@ -189,7 +313,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback*,
+ void elf_parse_binary(struct elf_binary *elf);
+ int elf_load_binary(struct elf_binary *elf);
+-void *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
++ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr);
+ uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
+ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
+@@ -221,9 +345,9 @@ struct xen_elfnote {
+ struct elf_dom_parms {
+     /* raw */
+-    const char *guest_info;
+-    const void *elf_note_start;
+-    const void *elf_note_end;
++    ELF_PTRVAL_CONST_CHAR guest_info;
++    ELF_PTRVAL_CONST_VOID elf_note_start;
++    ELF_PTRVAL_CONST_VOID elf_note_end;
+     struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
+     /* parsed */
+@@ -262,10 +386,22 @@ int elf_xen_parse_features(const char *features,
+                            uint32_t *required);
+ int elf_xen_parse_note(struct elf_binary *elf,
+                        struct elf_dom_parms *parms,
+-                       const elf_note *note);
++                       ELF_HANDLE_DECL(elf_note) note);
+ int elf_xen_parse_guest_info(struct elf_binary *elf,
+                              struct elf_dom_parms *parms);
+ int elf_xen_parse(struct elf_binary *elf,
+                   struct elf_dom_parms *parms);
++#define elf_memcpy_unchecked memcpy
++#define elf_memset_unchecked memset
++  /*
++   * Unsafe versions of memcpy and memset which take actual C
++   * pointers.  These are just like real memcpy and memset.
++   */
++
++
++#define ELF_ADVANCE_DEST(elf, amount)  elf->dest += (amount)
++  /* Advances past amount bytes of the current destination area. */
++
++
+ #endif /* __XEN_LIBELF_H__ */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0009-tools-xcutils-readnotes-adjust-print_l1_mfn_valid_no.patch b/SOURCES/xsa55-4.2-0009-tools-xcutils-readnotes-adjust-print_l1_mfn_valid_no.patch
new file mode 100644 (file)
index 0000000..707c570
--- /dev/null
@@ -0,0 +1,58 @@
+From 59f66d58180832af6b99a9e4489031b5c2f627ab Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 09/23] tools/xcutils/readnotes: adjust print_l1_mfn_valid_note
+
+Use the new PTRVAL macros and elf_access_unsigned in
+print_l1_mfn_valid_note.
+
+No functional change unless the input is wrong, or we are reading a
+file for a different endianness.
+
+Separated out from the previous patch because this change does produce
+a difference in the generated code.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+---
+ tools/xcutils/readnotes.c |   11 ++++++-----
+ 1 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index 2af047d..7ff2530 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -77,22 +77,23 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
+ }
+ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
+-                                  const elf_note *note)
++                                  ELF_HANDLE_DECL(elf_note) note)
+ {
+       int descsz = elf_uval(elf, note, descsz);
+-      const uint32_t *desc32 = elf_note_desc(elf, note);
+-      const uint64_t *desc64 = elf_note_desc(elf, note);
++      ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+       /* XXX should be able to cope with a list of values. */
+       switch ( descsz / 2 )
+       {
+       case 8:
+               printf("%s: mask=%#"PRIx64" value=%#"PRIx64"\n", prefix,
+-                     desc64[0], desc64[1]);
++                     elf_access_unsigned(elf, desc, 0, 8),
++                     elf_access_unsigned(elf, desc, 8, 8));
+               break;
+       case 4:
+               printf("%s: mask=%#"PRIx32" value=%#"PRIx32"\n", prefix,
+-                     desc32[0],desc32[1]);
++                     (uint32_t)elf_access_unsigned(elf, desc, 0, 4),
++                     (uint32_t)elf_access_unsigned(elf, desc, 4, 4));
+               break;
+       }
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0010-libelf-check-nul-terminated-strings-properly.patch b/SOURCES/xsa55-4.2-0010-libelf-check-nul-terminated-strings-properly.patch
new file mode 100644 (file)
index 0000000..b782936
--- /dev/null
@@ -0,0 +1,204 @@
+From db14d5bd9b6508adfcd2b910f454fae12fa4ba00 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 10/23] libelf: check nul-terminated strings properly
+
+It is not safe to simply take pointers into the ELF and use them as C
+pointers.  They might not be properly nul-terminated (and the pointers
+might be wild).
+
+So we are going to introduce a new function elf_strval for safely
+getting strings.  This will check that the addresses are in range and
+that there is a proper nul-terminated string.  Of course it might
+discover that there isn't.  In that case, it will be made to fail.
+This means that elf_note_name might fail, too.
+
+For the benefit of call sites which are just going to pass the value
+to a printf-like function, we provide elf_strfmt which returns
+"(invalid)" on failure rather than NULL.
+
+In this patch we introduce dummy definitions of these functions.  We
+introduce calls to elf_strval and elf_strfmt everywhere, and update
+all the call sites with appropriate error checking.
+
+There is not yet any semantic change, since before this patch all the
+places where we introduce elf_strval dereferenced the value anyway, so
+it mustn't have been NULL.
+
+In future patches, when elf_strval is made able return NULL, when it
+does so it will mark the elf "broken" so that an appropriate
+diagnostic can be printed.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+---
+ tools/xcutils/readnotes.c          |   11 ++++++++---
+ xen/common/libelf/libelf-dominfo.c |   13 ++++++++++---
+ xen/common/libelf/libelf-tools.c   |   10 +++++++---
+ xen/include/xen/libelf.h           |    7 +++++--
+ 4 files changed, 30 insertions(+), 11 deletions(-)
+
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index 7ff2530..cfae994 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -63,7 +63,7 @@ struct setup_header {
+ static void print_string_note(const char *prefix, struct elf_binary *elf,
+                             ELF_HANDLE_DECL(elf_note) note)
+ {
+-      printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
++      printf("%s: %s\n", prefix, elf_strfmt(elf, elf_note_desc(elf, note)));
+ }
+ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
+@@ -103,10 +103,14 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
+ {
+       ELF_HANDLE_DECL(elf_note) note;
+       int notes_found = 0;
++      const char *this_note_name;
+       for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
+       {
+-              if (0 != strcmp(elf_note_name(elf, note), "Xen"))
++              this_note_name = elf_note_name(elf, note);
++              if (NULL == this_note_name)
++                      continue;
++              if (0 != strcmp(this_note_name, "Xen"))
+                       continue;
+               notes_found++;
+@@ -294,7 +298,8 @@ int main(int argc, char **argv)
+       shdr = elf_shdr_by_name(&elf, "__xen_guest");
+       if (ELF_HANDLE_VALID(shdr))
+-              printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));
++              printf("__xen_guest: %s\n",
++                       elf_strfmt(&elf, elf_section_start(&elf, shdr)));
+       return 0;
+ }
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index 7140d59..b217f8f 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -137,7 +137,10 @@ int elf_xen_parse_note(struct elf_binary *elf,
+     if ( note_desc[type].str )
+     {
+-        str = elf_note_desc(elf, note);
++        str = elf_strval(elf, elf_note_desc(elf, note));
++        if (str == NULL)
++            /* elf_strval will mark elf broken if it fails so no need to log */
++            return 0;
+         elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
+                 note_desc[type].name, str);
+         parms->elf_notes[type].type = XEN_ENT_STR;
+@@ -220,6 +223,7 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
+ {
+     int xen_elfnotes = 0;
+     ELF_HANDLE_DECL(elf_note) note;
++    const char *note_name;
+     parms->elf_note_start = start;
+     parms->elf_note_end   = end;
+@@ -227,7 +231,10 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
+           ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
+           note = elf_note_next(elf, note) )
+     {
+-        if ( strcmp(elf_note_name(elf, note), "Xen") )
++        note_name = elf_note_name(elf, note);
++        if ( note_name == NULL )
++            continue;
++        if ( strcmp(note_name, "Xen") )
+             continue;
+         if ( elf_xen_parse_note(elf, parms, note) )
+             return -1;
+@@ -541,7 +548,7 @@ int elf_xen_parse(struct elf_binary *elf,
+                 parms->elf_note_start = ELF_INVALID_PTRVAL;
+                 parms->elf_note_end   = ELF_INVALID_PTRVAL;
+                 elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
+-                        parms->guest_info);
++                        elf_strfmt(elf, parms->guest_info));
+                 elf_xen_parse_guest_info(elf, parms);
+                 break;
+             }
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index f1fd886..3a0cde1 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -119,7 +119,7 @@ const char *elf_section_name(struct elf_binary *elf,
+     if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
+         return "unknown";
+-    return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
++    return elf_strval(elf, elf->sec_strtab + elf_uval(elf, shdr, sh_name));
+ }
+ ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+@@ -151,6 +151,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
+     ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
+     ELF_HANDLE_DECL(elf_sym) sym;
+     uint64_t info, name;
++    const char *sym_name;
+     for ( ; ptr < end; ptr += elf_size(elf, sym) )
+     {
+@@ -159,7 +160,10 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
+         name = elf_uval(elf, sym, st_name);
+         if ( ELF32_ST_BIND(info) != STB_GLOBAL )
+             continue;
+-        if ( strcmp(elf->sym_strtab + name, symbol) )
++        sym_name = elf_strval(elf, elf->sym_strtab + name);
++        if ( sym_name == NULL ) /* out of range, oops */
++            return ELF_INVALID_HANDLE(elf_sym);
++        if ( strcmp(sym_name, symbol) )
+             continue;
+         return sym;
+     }
+@@ -177,7 +181,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
+ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note);
++    return elf_strval(elf, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note));
+ }
+ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index cefd3d3..af5b5c5 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -252,6 +252,9 @@ uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
++#define elf_strval(elf,x) ((const char*)(x)) /* may return NULL in the future */
++#define elf_strfmt(elf,x) ((const char*)(x)) /* will return (invalid) instead */
++
+ #define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
+ #define elf_memset_safe(elf, dst, c, sz)   memset((dst),(c),(sz))
+   /*
+@@ -279,7 +282,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
+ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
+ ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
+-const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
++const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
+ ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+ ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+@@ -289,7 +292,7 @@ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(el
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
+-const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
++const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
+ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0011-libelf-check-all-pointer-accesses.patch b/SOURCES/xsa55-4.2-0011-libelf-check-all-pointer-accesses.patch
new file mode 100644 (file)
index 0000000..5ad7827
--- /dev/null
@@ -0,0 +1,788 @@
+From cc8761371aac432318530c2ddfe2c8234bc0621f Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 11/23] libelf: check all pointer accesses
+
+We change the ELF_PTRVAL and ELF_HANDLE types and associated macros:
+
+ * PTRVAL becomes a uintptr_t, for which we provide a typedef
+   elf_ptrval.  This means no arithmetic done on it can overflow so
+   the compiler cannot do any malicious invalid pointer arithmetic
+   "optimisations".  It also means that any places where we
+   dereference one of these pointers without using the appropriate
+   macros or functions become a compilation error.
+
+   So we can be sure that we won't miss any memory accesses.
+
+   All the PTRVAL variables were previously void* or char*, so
+   the actual address calculations are unchanged.
+
+ * ELF_HANDLE becomes a union, one half of which keeps the pointer
+   value and the other half of which is just there to record the
+   type.
+
+   The new type is not a pointer type so there can be no address
+   calculations on it whose meaning would change.  Every assignment or
+   access has to go through one of our macros.
+
+ * The distinction between const and non-const pointers and char*s
+   and void*s in libelf goes away.  This was not important (and
+   anyway libelf tended to cast away const in various places).
+
+ * The fields elf->image and elf->dest are renamed.  That proves
+   that we haven't missed any unchecked uses of these actual
+   pointer values.
+
+ * The caller may fill in elf->caller_xdest_base and _size to
+   specify another range of memory which is safe for libelf to
+   access, besides the input and output images.
+
+ * When accesses fail due to being out of range, we mark the elf
+   "broken".  This will be checked and used for diagnostics in
+   a following patch.
+
+   We do not check for write accesses to the input image.  This is
+   because libelf actually does this in a number of places.  So we
+   simply permit that.
+
+ * Each caller of libelf which used to set dest now sets
+   dest_base and dest_size.
+
+ * In xc_dom_load_elf_symtab we provide a new actual-pointer
+   value hdr_ptr which we get from mapping the guest's kernel
+   area and use (checking carefully) as the caller_xdest area.
+
+ * The STAR(h) macro in libelf-dominfo.c now uses elf_access_unsigned.
+
+ * elf-init uses the new elf_uval_3264 accessor to access the 32-bit
+   fields, rather than an unchecked field access (ie, unchecked
+   pointer access).
+
+ * elf_uval has been reworked to use elf_uval_3264.  Both of these
+   macros are essentially new in this patch (although they are derived
+   from the old elf_uval) and need careful review.
+
+ * ELF_ADVANCE_DEST is now safe in the sense that you can use it to
+   chop parts off the front of the dest area but if you chop more than
+   is available, the dest area is simply set to be empty, preventing
+   future accesses.
+
+ * We introduce some #defines for memcpy, memset, memmove and strcpy:
+    - We provide elf_memcpy_safe and elf_memset_safe which take
+      PTRVALs and do checking on the supplied pointers.
+    - Users inside libelf must all be changed to either
+      elf_mem*_unchecked (which are just like mem*), or
+      elf_mem*_safe (which take PTRVALs) and are checked.  Any
+      unchanged call sites become compilation errors.
+
+ * We do _not_ at this time fix elf_access_unsigned so that it doesn't
+   make unaligned accesses.  We hope that unaligned accesses are OK on
+   every supported architecture.  But it does check the supplied
+   pointer for validity.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_dom_elfloader.c     |   49 ++++++++--
+ tools/libxc/xc_hvm_build_x86.c     |   10 +-
+ xen/arch/x86/domain_build.c        |    3 +-
+ xen/common/libelf/libelf-dominfo.c |    2 +-
+ xen/common/libelf/libelf-loader.c  |   16 ++--
+ xen/common/libelf/libelf-private.h |   13 +++
+ xen/common/libelf/libelf-tools.c   |  106 ++++++++++++++++++-
+ xen/include/xen/libelf.h           |  198 +++++++++++++++++++++++++-----------
+ 8 files changed, 312 insertions(+), 85 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index cc0f206..b82a08c 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -130,20 +130,30 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     if ( load )
+     {
+-        size_t allow_size; /* will be used in a forthcoming XSA-55 patch */
++        char *hdr_ptr;
++        size_t allow_size;
++
+         if ( !dom->bsd_symtab_start )
+             return 0;
+         size = dom->kernel_seg.vend - dom->bsd_symtab_start;
+-        hdr  = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
+-        *(int *)hdr = size - sizeof(int);
++        hdr_ptr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
++        elf->caller_xdest_base = hdr_ptr;
++        elf->caller_xdest_size = allow_size;
++        hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
++        elf_store_val(elf, int, hdr, size - sizeof(int));
+     }
+     else
+     {
++        char *hdr_ptr;
++
+         size = sizeof(int) + elf_size(elf, elf->ehdr) +
+             elf_shdr_count(elf) * elf_size(elf, shdr);
+-        hdr = xc_dom_malloc(dom, size);
+-        if ( hdr == NULL )
++        hdr_ptr = xc_dom_malloc(dom, size);
++        if ( hdr_ptr == NULL )
+             return 0;
++        elf->caller_xdest_base = hdr_ptr;
++        elf->caller_xdest_size = size;
++        hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
+         dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
+     }
+@@ -171,9 +181,32 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         ehdr->e_shoff = elf_size(elf, elf->ehdr);
+         ehdr->e_shstrndx = SHN_UNDEF;
+     }
+-    if ( elf_init(&syms, hdr + sizeof(int), size - sizeof(int)) )
++    if ( elf->caller_xdest_size < sizeof(int) )
++    {
++        DOMPRINTF("%s/%s: header size %"PRIx64" too small",
++                  __FUNCTION__, load ? "load" : "parse",
++                  (uint64_t)elf->caller_xdest_size);
++        return -1;
++    }
++    if ( elf_init(&syms, elf->caller_xdest_base + sizeof(int),
++                  elf->caller_xdest_size - sizeof(int)) )
+         return -1;
++    /*
++     * The caller_xdest_{base,size} and dest_{base,size} need to
++     * remain valid so long as each struct elf_image does.  The
++     * principle we adopt is that these values are set when the
++     * memory is allocated or mapped, and cleared when (and if)
++     * they are unmapped.
++     *
++     * Mappings of the guest are normally undone by xc_dom_unmap_all
++     * (directly or via xc_dom_release).  We do not explicitly clear
++     * these because in fact that happens only at the end of
++     * xc_dom_boot_image, at which time all of these ELF loading
++     * functions have returned.  No relevant struct elf_binary*
++     * escapes this file.
++     */
++
+     xc_elf_set_logfile(dom->xch, &syms, 1);
+     symtab = dom->bsd_symtab_start + sizeof(int);
+@@ -312,8 +345,10 @@ static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
+ {
+     struct elf_binary *elf = dom->private_loader;
+     int rc;
++    xen_pfn_t pages;
+-    elf->dest = xc_dom_seg_to_ptr(dom, &dom->kernel_seg);
++    elf->dest_base = xc_dom_seg_to_ptr_pages(dom, &dom->kernel_seg, &pages);
++    elf->dest_size = pages * XC_DOM_PAGE_SIZE(dom);
+     rc = elf_load_binary(elf);
+     if ( rc < 0 )
+     {
+diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
+index 15b603d..ccfd8b5 100644
+--- a/tools/libxc/xc_hvm_build_x86.c
++++ b/tools/libxc/xc_hvm_build_x86.c
+@@ -104,11 +104,12 @@ static int loadelfimage(
+     for ( i = 0; i < pages; i++ )
+         entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
+-    elf->dest = xc_map_foreign_ranges(
++    elf->dest_base = xc_map_foreign_ranges(
+         xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
+         entries, pages);
+-    if ( elf->dest == NULL )
++    if ( elf->dest_base == NULL )
+         goto err;
++    elf->dest_size = pages * PAGE_SIZE;
+     ELF_ADVANCE_DEST(elf, elf->pstart & (PAGE_SIZE - 1));
+@@ -117,8 +118,9 @@ static int loadelfimage(
+     if ( rc < 0 )
+         PERROR("Failed to load elf binary\n");
+-    munmap(elf->dest, pages << PAGE_SHIFT);
+-    elf->dest = NULL;
++    munmap(elf->dest_base, pages << PAGE_SHIFT);
++    elf->dest_base = NULL;
++    elf->dest_size = 0;
+  err:
+     free(entries);
+diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
+index 469d363..a655b21 100644
+--- a/xen/arch/x86/domain_build.c
++++ b/xen/arch/x86/domain_build.c
+@@ -908,7 +908,8 @@ int __init construct_dom0(
+     write_ptbase(v);
+     /* Copy the OS image and free temporary buffer. */
+-    elf.dest = (void*)vkern_start;
++    elf.dest_base = (void*)vkern_start;
++    elf.dest_size = vkern_end - vkern_start;
+     rc = elf_load_binary(&elf);
+     if ( rc < 0 )
+     {
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index b217f8f..98c80dc 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -254,7 +254,7 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
+     int len;
+     h = parms->guest_info;
+-#define STAR(h) (*(h))
++#define STAR(h) (elf_access_unsigned(elf, (h), 0, 1))
+     while ( STAR(h) )
+     {
+         elf_memset_unchecked(name, 0, sizeof(name));
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index 0fef84c..a3310e7 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -24,23 +24,25 @@
+ /* ------------------------------------------------------------------------ */
+-int elf_init(struct elf_binary *elf, const char *image, size_t size)
++int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
+ {
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+     uint64_t i, count, section, offset;
+-    if ( !elf_is_elfbinary(image) )
++    if ( !elf_is_elfbinary(image_input) )
+     {
+         elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
+         return -1;
+     }
+     elf_memset_unchecked(elf, 0, sizeof(*elf));
+-    elf->image = image;
++    elf->image_base = image_input;
+     elf->size = size;
+-    elf->ehdr = (elf_ehdr *)image;
+-    elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
+-    elf->data = elf->ehdr->e32.e_ident[EI_DATA];
++    elf->ehdr = ELF_MAKE_HANDLE(elf_ehdr, (elf_ptrval)image_input);
++    elf->class = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_CLASS]);
++    elf->data = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_DATA]);
++    elf->caller_xdest_base = NULL;
++    elf->caller_xdest_size = 0;
+     /* Sanity check phdr. */
+     offset = elf_uval(elf, elf->ehdr, e_phoff) +
+@@ -300,7 +302,7 @@ int elf_load_binary(struct elf_binary *elf)
+ ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr)
+ {
+-    return elf->dest + addr - elf->pstart;
++    return ELF_REALPTR2PTRVAL(elf->dest_base) + addr - elf->pstart;
+ }
+ uint64_t elf_lookup_addr(struct elf_binary * elf, const char *symbol)
+diff --git a/xen/common/libelf/libelf-private.h b/xen/common/libelf/libelf-private.h
+index 3ef753c..280dfd1 100644
+--- a/xen/common/libelf/libelf-private.h
++++ b/xen/common/libelf/libelf-private.h
+@@ -86,6 +86,19 @@ do { strncpy((d),(s),sizeof((d))-1);            \
+ #endif
++#undef memcpy
++#undef memset
++#undef memmove
++#undef strcpy
++
++#define memcpy  MISTAKE_unspecified_memcpy
++#define memset  MISTAKE_unspecified_memset
++#define memmove MISTAKE_unspecified_memmove
++#define strcpy  MISTAKE_unspecified_strcpy
++  /* This prevents libelf from using these undecorated versions
++   * of memcpy, memset, memmove and strcpy.  Every call site
++   * must either use elf_mem*_unchecked, or elf_mem*_safe. */
++
+ #endif /* __LIBELF_PRIVATE_H_ */
+ /*
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 3a0cde1..46ca553 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -20,28 +20,100 @@
+ /* ------------------------------------------------------------------------ */
+-uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
+-                             uint64_t offset, size_t size)
++void elf_mark_broken(struct elf_binary *elf, const char *msg)
+ {
++    if ( elf->broken == NULL )
++        elf->broken = msg;
++}
++
++const char *elf_check_broken(const struct elf_binary *elf)
++{
++    return elf->broken;
++}
++
++static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
++                               const void *region, uint64_t regionsize)
++    /*
++     * Returns true if the putative memory area [ptrval,ptrval+size>
++     * is completely inside the region [region,region+regionsize>.
++     *
++     * ptrval and size are the untrusted inputs to be checked.
++     * region and regionsize are trusted and must be correct and valid,
++     * although it is OK for region to perhaps be maliciously NULL
++     * (but not some other malicious value).
++     */
++{
++    elf_ptrval regionp = (elf_ptrval)region;
++
++    if ( (region == NULL) ||
++         (ptrval < regionp) ||              /* start is before region */
++         (ptrval > regionp + regionsize) || /* start is after region */
++         (size > regionsize - (ptrval - regionp)) ) /* too big */
++        return 0;
++    return 1;
++}
++
++int elf_access_ok(struct elf_binary * elf,
++                  uint64_t ptrval, size_t size)
++{
++    if ( elf_ptrval_in_range(ptrval, size, elf->image_base, elf->size) )
++        return 1;
++    if ( elf_ptrval_in_range(ptrval, size, elf->dest_base, elf->dest_size) )
++        return 1;
++    if ( elf_ptrval_in_range(ptrval, size,
++                             elf->caller_xdest_base, elf->caller_xdest_size) )
++        return 1;
++    elf_mark_broken(elf, "out of range access");
++    return 0;
++}
++
++void elf_memcpy_safe(struct elf_binary *elf, elf_ptrval dst,
++                     elf_ptrval src, size_t size)
++{
++    if ( elf_access_ok(elf, dst, size) &&
++         elf_access_ok(elf, src, size) )
++    {
++        /* use memmove because these checks do not prove that the
++         * regions don't overlap and overlapping regions grant
++         * permission for compiler malice */
++        elf_memmove_unchecked(ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), size);
++    }
++}
++
++void elf_memset_safe(struct elf_binary *elf, elf_ptrval dst, int c, size_t size)
++{
++    if ( elf_access_ok(elf, dst, size) )
++    {
++        elf_memset_unchecked(ELF_UNSAFE_PTR(dst), c, size);
++    }
++}
++
++uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
++                             uint64_t moreoffset, size_t size)
++{
++    elf_ptrval ptrval = base + moreoffset;
+     int need_swap = elf_swap(elf);
+     const uint8_t *u8;
+     const uint16_t *u16;
+     const uint32_t *u32;
+     const uint64_t *u64;
++    if ( !elf_access_ok(elf, ptrval, size) )
++        return 0;
++
+     switch ( size )
+     {
+     case 1:
+-        u8 = ptr + offset;
++        u8 = (const void*)ptrval;
+         return *u8;
+     case 2:
+-        u16 = ptr + offset;
++        u16 = (const void*)ptrval;
+         return need_swap ? bswap_16(*u16) : *u16;
+     case 4:
+-        u32 = ptr + offset;
++        u32 = (const void*)ptrval;
+         return need_swap ? bswap_32(*u32) : *u32;
+     case 8:
+-        u64 = ptr + offset;
++        u64 = (const void*)ptrval;
+         return need_swap ? bswap_64(*u64) : *u64;
+     default:
+         return 0;
+@@ -122,6 +194,28 @@ const char *elf_section_name(struct elf_binary *elf,
+     return elf_strval(elf, elf->sec_strtab + elf_uval(elf, shdr, sh_name));
+ }
++const char *elf_strval(struct elf_binary *elf, elf_ptrval start)
++{
++    uint64_t length;
++
++    for ( length = 0; ; length++ ) {
++        if ( !elf_access_ok(elf, start + length, 1) )
++            return NULL;
++        if ( !elf_access_unsigned(elf, start, length, 1) )
++            /* ok */
++            return ELF_UNSAFE_PTR(start);
++    }
++}
++
++const char *elf_strfmt(struct elf_binary *elf, elf_ptrval start)
++{
++    const char *str = elf_strval(elf, start);
++
++    if ( str == NULL )
++        return "(invalid)";
++    return str;
++}
++
+ ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+     return ELF_IMAGE_BASE(elf) + elf_uval(elf, shdr, sh_offset);
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index af5b5c5..ddc3ed7 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -57,8 +57,9 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+  *               on this.
+  *               This replaces variables which were char*,void*
+  *               and their const versions, so we provide four
+- *               different declaration macros:
++ *               different obsolete declaration macros:
+  *                   ELF_PTRVAL_{,CONST}{VOID,CHAR}
++ *               New code can simply use the elf_ptrval typedef.
+  *   HANDLE      A pointer to a struct.  There is one of these types
+  *               for each pointer type - that is, for each "structname".
+  *               In the arguments to the various HANDLE macros, structname
+@@ -67,54 +68,66 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+  *               pointers.  In the current code attempts to do so will
+  *               compile, but in the next patch this will become a
+  *               compile error.
+- *               We provide two declaration macros for const and
+- *               non-const pointers.
++ *               We also provide a second declaration macro for
++ *               pointers which were to const; this is obsolete.
+  */
+-#define ELF_REALPTR2PTRVAL(realpointer) (realpointer)
++typedef uintptr_t elf_ptrval;
++
++#define ELF_REALPTR2PTRVAL(realpointer) ((elf_ptrval)(realpointer))
+   /* Converts an actual C pointer into a PTRVAL */
+-#define ELF_HANDLE_DECL_NONCONST(structname)  structname *
+-#define ELF_HANDLE_DECL(structname)           const structname *
++#define ELF_HANDLE_DECL_NONCONST(structname) structname##_handle /*obsolete*/
++#define ELF_HANDLE_DECL(structname)          structname##_handle
+   /* Provides a type declaration for a HANDLE. */
+-  /* May only be used to declare ONE variable at a time */
+-#define ELF_PTRVAL_VOID         void *
+-#define ELF_PTRVAL_CHAR         char *
+-#define ELF_PTRVAL_CONST_VOID   const void *
+-#define ELF_PTRVAL_CONST_CHAR   const char *
+-  /* Provides a type declaration for a PTRVAL. */
+-  /* May only be used to declare ONE variable at a time */
++#define ELF_PTRVAL_VOID              elf_ptrval /*obsolete*/
++#define ELF_PTRVAL_CHAR              elf_ptrval /*obsolete*/
++#define ELF_PTRVAL_CONST_VOID        elf_ptrval /*obsolete*/
++#define ELF_PTRVAL_CONST_CHAR        elf_ptrval /*obsolete*/
++
++#ifdef __XEN__
++# define ELF_PRPTRVAL "lu"
++  /*
++   * PRIuPTR is misdefined in xen/include/xen/inttypes.h, on 32-bit,
++   * to "u", when in fact uintptr_t is an unsigned long.
++   */
++#else
++# define ELF_PRPTRVAL PRIuPTR
++#endif
++  /* printf format a la PRId... for a PTRVAL */
+-#define ELF_DEFINE_HANDLE(structname) /* empty */
++#define ELF_DEFINE_HANDLE(structname)                                   \
++    typedef union {                                                     \
++        elf_ptrval ptrval;                                              \
++        const structname *typeonly; /* for sizeof, offsetof, &c only */ \
++    } structname##_handle;
+   /*
+    * This must be invoked for each HANDLE type to define
+    * the actual C type used for that kind of HANDLE.
+    */
+-#define ELF_PRPTRVAL "p"
+-  /* printf format a la PRId... for a PTRVAL */
+-
+-#define ELF_MAKE_HANDLE(structname, ptrval) (ptrval)
++#define ELF_MAKE_HANDLE(structname, ptrval)    ((structname##_handle){ ptrval })
+   /* Converts a PTRVAL to a HANDLE */
+-#define ELF_IMAGE_BASE(elf) ((elf)->image)
++#define ELF_IMAGE_BASE(elf)    ((elf_ptrval)(elf)->image_base)
+   /* Returns the base of the image as a PTRVAL. */
+-#define ELF_HANDLE_PTRVAL(handleval) ((void*)(handleval))
++#define ELF_HANDLE_PTRVAL(handleval)      ((handleval).ptrval)
+   /* Converts a HANDLE to a PTRVAL. */
+-#define ELF_OBSOLETE_VOIDP_CAST (void*)(uintptr_t)
++#define ELF_OBSOLETE_VOIDP_CAST /*empty*/
+   /*
+-   * In some places the existing code needs to
++   * In some places the old code used to need to
+    *  - cast away const (the existing code uses const a fair
+    *    bit but actually sometimes wants to write to its input)
+    *    from a PTRVAL.
+    *  - convert an integer representing a pointer to a PTRVAL
+-   * This macro provides a suitable cast.
++   * Nowadays all of these re uintptr_ts so there is no const problem
++   * and no need for any casting.
+    */
+-#define ELF_UNSAFE_PTR(ptrval) ((void*)(uintptr_t)(ptrval))
++#define ELF_UNSAFE_PTR(ptrval) ((void*)(elf_ptrval)(ptrval))
+   /*
+    * Turns a PTRVAL into an actual C pointer.  Before this is done
+    * the caller must have ensured that the PTRVAL does in fact point
+@@ -122,18 +135,21 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+    */
+ /* PTRVALs can be INVALID (ie, NULL). */
+-#define ELF_INVALID_PTRVAL            (NULL)        /* returns NULL PTRVAL */
++#define ELF_INVALID_PTRVAL    ((elf_ptrval)0)       /* returns NULL PTRVAL */
+ #define ELF_INVALID_HANDLE(structname)                    /* returns NULL handle */ \
+     ELF_MAKE_HANDLE(structname, ELF_INVALID_PTRVAL)
+-#define ELF_PTRVAL_VALID(ptrval)      (ptrval)            /* }            */
+-#define ELF_HANDLE_VALID(handleval)   (handleval)         /* } predicates */
+-#define ELF_PTRVAL_INVALID(ptrval)    ((ptrval) == NULL)  /* }            */
++#define ELF_PTRVAL_VALID(ptrval)    (!!(ptrval))            /* }            */
++#define ELF_HANDLE_VALID(handleval) (!!(handleval).ptrval)  /* } predicates */
++#define ELF_PTRVAL_INVALID(ptrval)  (!ELF_PTRVAL_VALID((ptrval))) /* }      */
++
++#define ELF_MAX_PTRVAL        (~(elf_ptrval)0)
++  /* PTRVAL value guaranteed to compare > to any valid PTRVAL */
+ /* For internal use by other macros here */
+ #define ELF__HANDLE_FIELD_TYPE(handleval, elm) \
+-  typeof((handleval)->elm)
++  typeof((handleval).typeonly->elm)
+ #define ELF__HANDLE_FIELD_OFFSET(handleval, elm) \
+-  offsetof(typeof(*(handleval)),elm)
++  offsetof(typeof(*(handleval).typeonly),elm)
+ /* ------------------------------------------------------------------------ */
+@@ -182,7 +198,7 @@ ELF_DEFINE_HANDLE(elf_note)
+ struct elf_binary {
+     /* elf binary */
+-    const char *image;
++    const void *image_base;
+     size_t size;
+     char class;
+     char data;
+@@ -190,10 +206,16 @@ struct elf_binary {
+     ELF_HANDLE_DECL(elf_ehdr) ehdr;
+     ELF_PTRVAL_CONST_CHAR sec_strtab;
+     ELF_HANDLE_DECL(elf_shdr) sym_tab;
+-    ELF_PTRVAL_CONST_CHAR sym_strtab;
++    uint64_t sym_strtab;
+     /* loaded to */
+-    char *dest;
++    /*
++     * dest_base and dest_size are trusted and must be correct;
++     * whenever dest_size is not 0, both of these must be valid
++     * so long as the struct elf_binary is in use.
++     */
++    char *dest_base;
++    size_t dest_size;
+     uint64_t pstart;
+     uint64_t pend;
+     uint64_t reloc_offset;
+@@ -201,12 +223,22 @@ struct elf_binary {
+     uint64_t bsd_symtab_pstart;
+     uint64_t bsd_symtab_pend;
++    /*
++     * caller's other acceptable destination
++     *
++     * Again, these are trusted and must be valid (or 0) so long
++     * as the struct elf_binary is in use.
++     */
++    void *caller_xdest_base;
++    uint64_t caller_xdest_size;
++
+ #ifndef __XEN__
+     /* misc */
+     elf_log_callback *log_callback;
+     void *log_caller_data;
+ #endif
+     int verbose;
++    const char *broken;
+ };
+ /* ------------------------------------------------------------------------ */
+@@ -224,22 +256,27 @@ struct elf_binary {
+ #define elf_lsb(elf)   (ELFDATA2LSB == (elf)->data)
+ #define elf_swap(elf)  (NATIVE_ELFDATA != (elf)->data)
+-#define elf_uval(elf, str, elem)                                        \
+-    ((ELFCLASS64 == (elf)->class)                                       \
+-     ? elf_access_unsigned((elf), (str),                                \
+-                           offsetof(typeof(*(str)),e64.elem),           \
+-                           sizeof((str)->e64.elem))                     \
+-     : elf_access_unsigned((elf), (str),                                \
+-                           offsetof(typeof(*(str)),e32.elem),           \
+-                           sizeof((str)->e32.elem)))
++#define elf_uval_3264(elf, handle, elem)                                \
++    elf_access_unsigned((elf), (handle).ptrval,                         \
++                           offsetof(typeof(*(handle).typeonly),elem),    \
++                           sizeof((handle).typeonly->elem))
++
++#define elf_uval(elf, handle, elem)             \
++    ((ELFCLASS64 == (elf)->class)               \
++     ? elf_uval_3264(elf, handle, e64.elem)     \
++     : elf_uval_3264(elf, handle, e32.elem))
+   /*
+    * Reads an unsigned field in a header structure in the ELF.
+    * str is a HANDLE, and elem is the field name in it.
+    */
+-#define elf_size(elf, str)                              \
++
++#define elf_size(elf, handle_or_handletype) ({          \
++    typeof(handle_or_handletype) elf_size__dummy;       \
+     ((ELFCLASS64 == (elf)->class)                       \
+-     ? sizeof((str)->e64) : sizeof((str)->e32))
++     ? sizeof(elf_size__dummy.typeonly->e64)             \
++     : sizeof(elf_size__dummy.typeonly->e32));           \
++})
+   /*
+    * Returns the size of the substructure for the appropriate 32/64-bitness.
+    * str should be a HANDLE.
+@@ -251,23 +288,37 @@ uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
++const char *elf_strval(struct elf_binary *elf, elf_ptrval start);
++  /* may return NULL if the string is out of range etc. */
+-#define elf_strval(elf,x) ((const char*)(x)) /* may return NULL in the future */
+-#define elf_strfmt(elf,x) ((const char*)(x)) /* will return (invalid) instead */
++const char *elf_strfmt(struct elf_binary *elf, elf_ptrval start);
++  /* like elf_strval but returns "(invalid)" instead of NULL */
+-#define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
+-#define elf_memset_safe(elf, dst, c, sz)   memset((dst),(c),(sz))
++void elf_memcpy_safe(struct elf_binary*, elf_ptrval dst, elf_ptrval src, size_t);
++void elf_memset_safe(struct elf_binary*, elf_ptrval dst, int c, size_t);
+   /*
+-   * Versions of memcpy and memset which will (in the next patch)
+-   * arrange never to write outside permitted areas.
++   * Versions of memcpy and memset which arrange never to write
++   * outside permitted areas.
+    */
+-#define elf_store_val(elf, type, ptr, val)   (*(type*)(ptr) = (val))
++int elf_access_ok(struct elf_binary * elf,
++                  uint64_t ptrval, size_t size);
++
++#define elf_store_val(elf, type, ptr, val)                              \
++    ({                                                                  \
++        typeof(type) elf_store__val = (val);                            \
++        elf_ptrval elf_store__targ = ptr;                               \
++        if (elf_access_ok((elf), elf_store__targ,                       \
++                          sizeof(elf_store__val))) {                  \
++            elf_memcpy_unchecked((void*)elf_store__targ, &elf_store__val, \
++                             sizeof(elf_store__val));                   \
++        }                                                               \
++    })                                                                        \
+   /* Stores a value at a particular PTRVAL. */
+-#define elf_store_field(elf, hdr, elm, val)                     \
+-    (elf_store_val((elf), ELF__HANDLE_FIELD_TYPE(hdr, elm),     \
+-                   &((hdr)->elm),                               \
++#define elf_store_field(elf, hdr, elm, val)                             \
++    (elf_store_val((elf), ELF__HANDLE_FIELD_TYPE(hdr, elm),                   \
++                   ELF_HANDLE_PTRVAL(hdr) + ELF__HANDLE_FIELD_OFFSET(hdr, elm), \
+                    (val)))
+   /* Stores a 32/64-bit field.  hdr is a HANDLE and elm is the field name. */
+@@ -306,6 +357,10 @@ int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ /* xc_libelf_loader.c                                                       */
+ int elf_init(struct elf_binary *elf, const char *image, size_t size);
++  /*
++   * image and size must be correct.  They will be recorded in
++   * *elf, and must remain valid while the elf is in use.
++   */
+ #ifdef __XEN__
+ void elf_set_verbose(struct elf_binary *elf);
+ #else
+@@ -321,6 +376,9 @@ uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
+ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
++void elf_mark_broken(struct elf_binary *elf, const char *msg);
++const char *elf_check_broken(const struct elf_binary *elf); /* NULL means OK */
++
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_relocate.c                                                     */
+@@ -395,16 +453,38 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
+ int elf_xen_parse(struct elf_binary *elf,
+                   struct elf_dom_parms *parms);
+-#define elf_memcpy_unchecked memcpy
+-#define elf_memset_unchecked memset
++static inline void *elf_memcpy_unchecked(void *dest, const void *src, size_t n)
++    { return memcpy(dest, src, n); }
++static inline void *elf_memmove_unchecked(void *dest, const void *src, size_t n)
++    { return memmove(dest, src, n); }
++static inline void *elf_memset_unchecked(void *s, int c, size_t n)
++    { return memset(s, c, n); }
+   /*
+-   * Unsafe versions of memcpy and memset which take actual C
+-   * pointers.  These are just like real memcpy and memset.
++   * Unsafe versions of memcpy, memmove memset which take actual C
++   * pointers.  These are just like the real functions.
++   * We provide these so that in libelf-private.h we can #define
++   * memcpy, memset and memmove to undefined MISTAKE things.
+    */
+-#define ELF_ADVANCE_DEST(elf, amount)  elf->dest += (amount)
+-  /* Advances past amount bytes of the current destination area. */
++/* Advances past amount bytes of the current destination area. */
++static inline void ELF_ADVANCE_DEST(struct elf_binary *elf, uint64_t amount)
++{
++    if ( elf->dest_base == NULL )
++    {
++        elf_mark_broken(elf, "advancing in null image");
++    }
++    else if ( elf->dest_size >= amount )
++    {
++        elf->dest_base += amount;
++        elf->dest_size -= amount;
++    }
++    else
++    {
++        elf->dest_size = 0;
++        elf_mark_broken(elf, "advancing past end (image very short?)");
++    }
++}
+ #endif /* __XEN_LIBELF_H__ */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0012-libelf-Check-pointer-references-in-elf_is_elfbinary.patch b/SOURCES/xsa55-4.2-0012-libelf-Check-pointer-references-in-elf_is_elfbinary.patch
new file mode 100644 (file)
index 0000000..cefb4cb
--- /dev/null
@@ -0,0 +1,114 @@
+From d0790bdad7496e720416b2d4a04563c4c27e7b95 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 12/23] libelf: Check pointer references in elf_is_elfbinary
+
+elf_is_elfbinary didn't take a length parameter and could potentially
+access out of range when provided with a very short image.
+
+We only need to check the size is enough for the actual dereference in
+elf_is_elfbinary; callers are just using it to check the magic number
+and do their own checks (usually via the new elf_ptrval system) before
+dereferencing other parts of the header.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+---
+ tools/libxc/xc_dom_elfloader.c    |    2 +-
+ xen/arch/x86/bzimage.c            |    4 ++--
+ xen/common/libelf/libelf-loader.c |    2 +-
+ xen/common/libelf/libelf-tools.c  |    9 ++++++---
+ xen/include/xen/libelf.h          |    4 +++-
+ 5 files changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index b82a08c..ea45886 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -95,7 +95,7 @@ static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
+         return -EINVAL;
+     }
+-    if ( !elf_is_elfbinary(dom->kernel_blob) )
++    if ( !elf_is_elfbinary(dom->kernel_blob, dom->kernel_size) )
+     {
+         if ( verbose )
+             xc_dom_panic(dom->xch,
+diff --git a/xen/arch/x86/bzimage.c b/xen/arch/x86/bzimage.c
+index 5adc223..3600dca 100644
+--- a/xen/arch/x86/bzimage.c
++++ b/xen/arch/x86/bzimage.c
+@@ -220,7 +220,7 @@ unsigned long __init bzimage_headroom(char *image_start,
+         image_length = hdr->payload_length;
+     }
+-    if ( elf_is_elfbinary(image_start) )
++    if ( elf_is_elfbinary(image_start, image_length) )
+         return 0;
+     orig_image_len = image_length;
+@@ -251,7 +251,7 @@ int __init bzimage_parse(char *image_base, char **image_start, unsigned long *im
+         *image_len = hdr->payload_length;
+     }
+-    if ( elf_is_elfbinary(*image_start) )
++    if ( elf_is_elfbinary(*image_start, *image_len) )
+         return 0;
+     BUG_ON(!(image_base < *image_start));
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index a3310e7..f8be635 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -29,7 +29,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+     uint64_t i, count, section, offset;
+-    if ( !elf_is_elfbinary(image_input) )
++    if ( !elf_is_elfbinary(image_input, size) )
+     {
+         elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
+         return -1;
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 46ca553..744027e 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -332,11 +332,14 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
+ /* ------------------------------------------------------------------------ */
+-int elf_is_elfbinary(const void *image)
++int elf_is_elfbinary(const void *image_start, size_t image_size)
+ {
+-    const Elf32_Ehdr *ehdr = image;
++    const Elf32_Ehdr *ehdr = image_start;
+-    return IS_ELF(*ehdr); /* fixme unchecked */
++    if ( image_size < sizeof(*ehdr) )
++        return 0;
++
++    return IS_ELF(*ehdr);
+ }
+ int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index ddc3ed7..ac93858 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -350,7 +350,9 @@ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+                                 unsigned int unitsz, unsigned int idx);
+ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+-int elf_is_elfbinary(const void *image);
++/* (Only) checks that the image has the right magic number. */
++int elf_is_elfbinary(const void *image_start, size_t image_size);
++
+ int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+ /* ------------------------------------------------------------------------ */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0013-libelf-Make-all-callers-call-elf_check_broken.patch b/SOURCES/xsa55-4.2-0013-libelf-Make-all-callers-call-elf_check_broken.patch
new file mode 100644 (file)
index 0000000..43fe7f0
--- /dev/null
@@ -0,0 +1,257 @@
+From a965b8f80388603d439ae2b8ee7b9b018a079f90 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:17 +0100
+Subject: [PATCH 13/23] libelf: Make all callers call elf_check_broken
+
+This arranges that if the new pointer reference error checking
+tripped, we actually get a message about it.  In this patch these
+messages do not change the actual return values from the various
+functions: so pointer reference errors do not prevent loading.  This
+is for fear that some existing kernels might cause the code to make
+these wild references, which would then break, which is not a good
+thing in a security patch.
+
+In xen/arch/x86/domain_build.c we have to introduce an "out" label and
+change all of the "return rc" beyond the relevant point into "goto
+out".
+
+Difference in the 4.2 series, compared to unstable:
+
+* tools/libxc/xc_hvm_build_x86.c:setup_guest and
+  xen/arch/arm/kernel.c:kernel_try_elf_prepare have different
+  error handling in 4.2 to unstable; patch adjusted accordingly.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+
+xen-unstable version Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
+---
+ tools/libxc/xc_dom_elfloader.c |   25 +++++++++++++++++++++----
+ tools/libxc/xc_hvm_build_x86.c |    5 +++++
+ tools/xcutils/readnotes.c      |    3 +++
+ xen/arch/arm/kernel.c          |   15 ++++++++++++++-
+ xen/arch/x86/domain_build.c    |   28 +++++++++++++++++++++-------
+ 5 files changed, 64 insertions(+), 12 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index ea45886..4fb4da2 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -276,6 +276,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             elf_store_field(elf, shdr, e32.sh_name, 0);
+     }
++    if ( elf_check_broken(&syms) )
++        DOMPRINTF("%s: symbols ELF broken: %s", __FUNCTION__,
++                  elf_check_broken(&syms));
++    if ( elf_check_broken(elf) )
++        DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
++                  elf_check_broken(elf));
++
+     if ( tables == 0 )
+     {
+         DOMPRINTF("%s: no symbol table present", __FUNCTION__);
+@@ -312,19 +319,23 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
+     {
+         xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
+                      " has no shstrtab", __FUNCTION__);
+-        return -EINVAL;
++        rc = -EINVAL;
++        goto out;
+     }
+     /* parse binary and get xen meta info */
+     elf_parse_binary(elf);
+     if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
+-        return rc;
++    {
++        goto out;
++    }
+     if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
+     {
+         xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
+                      " support unprivileged (DomU) operation", __FUNCTION__);
+-        return -EINVAL;
++        rc = -EINVAL;
++        goto out;
+     }
+     /* find kernel segment */
+@@ -338,7 +349,13 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
+     DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
+               __FUNCTION__, dom->guest_type,
+               dom->kernel_seg.vstart, dom->kernel_seg.vend);
+-    return 0;
++    rc = 0;
++out:
++    if ( elf_check_broken(elf) )
++        DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
++                  elf_check_broken(elf));
++
++    return rc;
+ }
+ static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
+diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
+index ccfd8b5..8165287 100644
+--- a/tools/libxc/xc_hvm_build_x86.c
++++ b/tools/libxc/xc_hvm_build_x86.c
+@@ -403,11 +403,16 @@ static int setup_guest(xc_interface *xch,
+         munmap(page0, PAGE_SIZE);
+     }
++    if ( elf_check_broken(&elf) )
++        ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
++
+     free(page_array);
+     return 0;
+  error_out:
+     free(page_array);
++    if ( elf_check_broken(&elf) )
++        ERROR("HVM ELF broken, failing: %s", elf_check_broken(&elf));
+     return -1;
+ }
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index cfae994..d1f7a30 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -301,6 +301,9 @@ int main(int argc, char **argv)
+               printf("__xen_guest: %s\n",
+                        elf_strfmt(&elf, elf_section_start(&elf, shdr)));
++      if (elf_check_broken(&elf))
++              printf("warning: broken ELF: %s\n", elf_check_broken(&elf));
++
+       return 0;
+ }
+diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
+index 2d56130..dec0519 100644
+--- a/xen/arch/arm/kernel.c
++++ b/xen/arch/arm/kernel.c
+@@ -146,6 +146,8 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
+ {
+     int rc;
++    memset(&info->elf.elf, 0, sizeof(info->elf.elf));
++
+     info->kernel_order = get_order_from_bytes(KERNEL_FLASH_SIZE);
+     info->kernel_img = alloc_xenheap_pages(info->kernel_order, 0);
+     if ( info->kernel_img == NULL )
+@@ -160,7 +162,7 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
+ #endif
+     elf_parse_binary(&info->elf.elf);
+     if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 )
+-        return rc;
++        goto err;
+     /*
+      * TODO: can the ELF header be used to find the physical address
+@@ -169,7 +171,18 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
+     info->entry = info->elf.parms.virt_entry;
+     info->load = kernel_elf_load;
++    if ( elf_check_broken(&info->elf.elf) )
++        printk("Xen: warning: ELF kernel broken: %s\n",
++               elf_check_broken(&info->elf.elf));
++
+     return 0;
++
++err:
++    if ( elf_check_broken(&info->elf.elf) )
++        printk("Xen: ELF kernel broken: %s\n",
++               elf_check_broken(&info->elf.elf));
++
++    return rc;
+ }
+ int kernel_prepare(struct kernel_info *info)
+diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
+index a655b21..0dbec96 100644
+--- a/xen/arch/x86/domain_build.c
++++ b/xen/arch/x86/domain_build.c
+@@ -374,7 +374,7 @@ int __init construct_dom0(
+ #endif
+     elf_parse_binary(&elf);
+     if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
+-        return rc;
++        goto out;
+     /* compatibility check */
+     compatible = 0;
+@@ -413,14 +413,16 @@ int __init construct_dom0(
+     if ( !compatible )
+     {
+         printk("Mismatch between Xen and DOM0 kernel\n");
+-        return -EINVAL;
++        rc = -EINVAL;
++        goto out;
+     }
+     if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
+          !test_bit(XENFEAT_dom0, parms.f_supported) )
+     {
+         printk("Kernel does not support Dom0 operation\n");
+-        return -EINVAL;
++        rc = -EINVAL;
++        goto out;
+     }
+ #if defined(__x86_64__)
+@@ -734,7 +736,8 @@ int __init construct_dom0(
+          (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
+     {
+         printk("DOM0 image overlaps with Xen private area.\n");
+-        return -EINVAL;
++        rc = -EINVAL;
++        goto out;
+     }
+     if ( is_pv_32on64_domain(d) )
+@@ -914,7 +917,7 @@ int __init construct_dom0(
+     if ( rc < 0 )
+     {
+         printk("Failed to load the kernel binary\n");
+-        return rc;
++        goto out;
+     }
+     bootstrap_map(NULL);
+@@ -925,7 +928,8 @@ int __init construct_dom0(
+         {
+             write_ptbase(current);
+             printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
+-            return -1;
++            rc = -1;
++            goto out;
+         }
+         hypercall_page_initialise(
+             d, (void *)(unsigned long)parms.virt_hypercall);
+@@ -1272,9 +1276,19 @@ int __init construct_dom0(
+     BUG_ON(rc != 0);
+-    iommu_dom0_init(dom0);
++    if ( elf_check_broken(&elf) )
++        printk(" Xen warning: dom0 kernel broken ELF: %s\n",
++               elf_check_broken(&elf));
++    iommu_dom0_init(dom0);
+     return 0;
++
++out:
++    if ( elf_check_broken(&elf) )
++        printk(" Xen dom0 kernel broken ELF: %s\n",
++               elf_check_broken(&elf));
++
++    return rc;
+ }
+ /*
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0014-libelf-use-C99-bool-for-booleans.patch b/SOURCES/xsa55-4.2-0014-libelf-use-C99-bool-for-booleans.patch
new file mode 100644 (file)
index 0000000..67990a2
--- /dev/null
@@ -0,0 +1,252 @@
+From 3fb6ccf2faccaf5e22e33a3155ccc72d732896d8 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:18 +0100
+Subject: [PATCH 14/23] libelf: use C99 bool for booleans
+
+We want to remove uses of "int" because signed integers have
+undesirable undefined behaviours on overflow.  Malicious compilers can
+turn apparently-correct code into code with security vulnerabilities
+etc.
+
+In this patch we change all the booleans in libelf to C99 bool,
+from <stdbool.h>.
+
+For the one visible libelf boolean in libxc's public interface we
+retain the use of int to avoid changing the ABI; libxc converts it to
+a bool for consumption by libelf.
+
+It is OK to change all values only ever used as booleans to _Bool
+(bool) because conversion from any scalar type to a _Bool works the
+same as the boolean test in if() or ?: and is always defined (C99
+6.3.1.2).  But we do need to check that all these variables really are
+only ever used that way.  (It is theoretically possible that the old
+code truncated some 64-bit values to 32-bit ints which might become
+zero depending on the value, which would mean a behavioural change in
+this patch, but it seems implausible that treating 0x????????00000000
+as false could have been intended.)
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
+---
+ tools/libxc/xc_dom_elfloader.c     |    8 ++++----
+ xen/common/libelf/libelf-dominfo.c |    2 +-
+ xen/common/libelf/libelf-loader.c  |    4 ++--
+ xen/common/libelf/libelf-private.h |    2 +-
+ xen/common/libelf/libelf-tools.c   |   10 +++++-----
+ xen/include/xen/libelf.h           |   18 ++++++++++--------
+ 6 files changed, 23 insertions(+), 21 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 4fb4da2..9ba64ae 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -34,7 +34,7 @@
+ /* ------------------------------------------------------------------------ */
+ static void log_callback(struct elf_binary *elf, void *caller_data,
+-                         int iserr, const char *fmt, va_list al) {
++                         bool iserr, const char *fmt, va_list al) {
+     xc_interface *xch = caller_data;
+     xc_reportv(xch,
+@@ -46,7 +46,7 @@ static void log_callback(struct elf_binary *elf, void *caller_data,
+ void xc_elf_set_logfile(xc_interface *xch, struct elf_binary *elf,
+                         int verbose) {
+-    elf_set_log(elf, log_callback, xch, verbose);
++    elf_set_log(elf, log_callback, xch, verbose /* convert to bool */);
+ }
+ /* ------------------------------------------------------------------------ */
+@@ -84,7 +84,7 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
+ /* ------------------------------------------------------------------------ */
+ /* parse elf binary                                                         */
+-static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
++static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
+ {
+     if ( dom->kernel_blob == NULL )
+     {
+@@ -112,7 +112,7 @@ static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
+ }
+ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+-                                  struct elf_binary *elf, int load)
++                                  struct elf_binary *elf, bool load)
+ {
+     struct elf_binary syms;
+     ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index 98c80dc..12b6c2a 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -101,7 +101,7 @@ int elf_xen_parse_note(struct elf_binary *elf,
+ /* *INDENT-OFF* */
+     static const struct {
+         char *name;
+-        int str;
++        bool str;
+     } note_desc[] = {
+         [XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
+         [XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index f8be635..0dccd4d 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -92,7 +92,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
+ }
+ #ifndef __XEN__
+-void elf_call_log_callback(struct elf_binary *elf, int iserr,
++void elf_call_log_callback(struct elf_binary *elf, bool iserr,
+                            const char *fmt,...) {
+     va_list al;
+@@ -107,7 +107,7 @@ void elf_call_log_callback(struct elf_binary *elf, int iserr,
+ }
+     
+ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+-                 void *log_caller_data, int verbose)
++                 void *log_caller_data, bool verbose)
+ {
+     elf->log_callback = log_callback;
+     elf->log_caller_data = log_caller_data;
+diff --git a/xen/common/libelf/libelf-private.h b/xen/common/libelf/libelf-private.h
+index 280dfd1..277be04 100644
+--- a/xen/common/libelf/libelf-private.h
++++ b/xen/common/libelf/libelf-private.h
+@@ -77,7 +77,7 @@
+ #define elf_err(elf, fmt, args ... )                    \
+     elf_call_log_callback(elf, 1, fmt , ## args );
+-void elf_call_log_callback(struct elf_binary*, int iserr, const char *fmt,...);
++void elf_call_log_callback(struct elf_binary*, bool iserr, const char *fmt,...);
+ #define safe_strcpy(d,s)                        \
+ do { strncpy((d),(s),sizeof((d))-1);            \
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 744027e..fa58f76 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -31,7 +31,7 @@ const char *elf_check_broken(const struct elf_binary *elf)
+     return elf->broken;
+ }
+-static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
++static bool elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
+                                const void *region, uint64_t regionsize)
+     /*
+      * Returns true if the putative memory area [ptrval,ptrval+size>
+@@ -53,7 +53,7 @@ static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
+     return 1;
+ }
+-int elf_access_ok(struct elf_binary * elf,
++bool elf_access_ok(struct elf_binary * elf,
+                   uint64_t ptrval, size_t size)
+ {
+     if ( elf_ptrval_in_range(ptrval, size, elf->image_base, elf->size) )
+@@ -92,7 +92,7 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
+                              uint64_t moreoffset, size_t size)
+ {
+     elf_ptrval ptrval = base + moreoffset;
+-    int need_swap = elf_swap(elf);
++    bool need_swap = elf_swap(elf);
+     const uint8_t *u8;
+     const uint16_t *u16;
+     const uint32_t *u32;
+@@ -332,7 +332,7 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
+ /* ------------------------------------------------------------------------ */
+-int elf_is_elfbinary(const void *image_start, size_t image_size)
++bool elf_is_elfbinary(const void *image_start, size_t image_size)
+ {
+     const Elf32_Ehdr *ehdr = image_start;
+@@ -342,7 +342,7 @@ int elf_is_elfbinary(const void *image_start, size_t image_size)
+     return IS_ELF(*ehdr);
+ }
+-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
++bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+     uint64_t p_type = elf_uval(elf, phdr, p_type);
+     uint64_t p_flags = elf_uval(elf, phdr, p_flags);
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index ac93858..951430f 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -29,6 +29,8 @@
+ #error define architectural endianness
+ #endif
++#include <stdbool.h>
++
+ #undef ELFSIZE
+ #include "elfstructs.h"
+ #ifdef __XEN__
+@@ -42,7 +44,7 @@
+ struct elf_binary;
+ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+-                              int iserr, const char *fmt, va_list al);
++                              bool iserr, const char *fmt, va_list al);
+ #endif
+@@ -237,7 +239,7 @@ struct elf_binary {
+     elf_log_callback *log_callback;
+     void *log_caller_data;
+ #endif
+-    int verbose;
++    bool verbose;
+     const char *broken;
+ };
+@@ -301,8 +303,8 @@ void elf_memset_safe(struct elf_binary*, elf_ptrval dst, int c, size_t);
+    * outside permitted areas.
+    */
+-int elf_access_ok(struct elf_binary * elf,
+-                  uint64_t ptrval, size_t size);
++bool elf_access_ok(struct elf_binary * elf,
++                   uint64_t ptrval, size_t size);
+ #define elf_store_val(elf, type, ptr, val)                              \
+     ({                                                                  \
+@@ -351,9 +353,9 @@ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ /* (Only) checks that the image has the right magic number. */
+-int elf_is_elfbinary(const void *image_start, size_t image_size);
++bool elf_is_elfbinary(const void *image_start, size_t image_size);
+-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
++bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_loader.c                                                       */
+@@ -367,7 +369,7 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size);
+ void elf_set_verbose(struct elf_binary *elf);
+ #else
+ void elf_set_log(struct elf_binary *elf, elf_log_callback*,
+-                 void *log_caller_pointer, int verbose);
++                 void *log_caller_pointer, bool verbose);
+ #endif
+ void elf_parse_binary(struct elf_binary *elf);
+@@ -419,7 +421,7 @@ struct elf_dom_parms {
+     char xen_ver[16];
+     char loader[16];
+     int pae;
+-    int bsd_symtab;
++    bool bsd_symtab;
+     uint64_t virt_base;
+     uint64_t virt_entry;
+     uint64_t virt_hypercall;
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0015-libelf-use-only-unsigned-integers.patch b/SOURCES/xsa55-4.2-0015-libelf-use-only-unsigned-integers.patch
new file mode 100644 (file)
index 0000000..f55701d
--- /dev/null
@@ -0,0 +1,759 @@
+From e673ca50127b6c1263727aa31de0b8bb966ca7a2 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:18 +0100
+Subject: [PATCH 15/23] libelf: use only unsigned integers
+
+Signed integers have undesirable undefined behaviours on overflow.
+Malicious compilers can turn apparently-correct code into code with
+security vulnerabilities etc.
+
+So use only unsigned integers.  Exceptions are booleans (which we have
+already changed) and error codes.
+
+We _do_ change all the chars which aren't fixed constants from our own
+text segment, but not the char*s.  This is because it is safe to
+access an arbitrary byte through a char*, but not necessarily safe to
+convert an arbitrary value to a char.
+
+As a consequence we need to compile libelf with -Wno-pointer-sign.
+
+It is OK to change all the signed integers to unsigned because all the
+inequalities in libelf are in contexts where we don't "expect"
+negative numbers.
+
+In libelf-dominfo.c:elf_xen_parse we rename a variable "rc" to
+"more_notes" as it actually contains a note count derived from the
+input image.  The "error" return value from elf_xen_parse_notes is
+changed from -1 to ~0U.
+
+grepping shows only one occurrence of "PRId" or "%d" or "%ld" in
+libelf and xc_dom_elfloader.c (a "%d" which becomes "%u").
+
+This is part of the fix to a security issue, XSA-55.
+
+For those concerned about unintentional functional changes, the
+following rune produces a version of the patch which is much smaller
+and eliminates only non-functional changes:
+
+ GIT_EXTERNAL_DIFF=.../unsigned-differ git-diff <before>..<after>
+
+where <before> and <after> are git refs for the code before and after
+this patch, and unsigned-differ is this shell script:
+
+    #!/bin/bash
+    set -e
+
+    seddery () {
+            perl -pe 's/\b(?:elf_errorstatus|elf_negerrnoval)\b/int/g'
+    }
+
+    path="$1"
+    in="$2"
+    out="$5"
+
+    set +e
+    diff -pu --label "$path~" <(seddery <"$in") --label "$path" <(seddery <"$out")
+    rc=$?
+    set -e
+    if [ $rc = 1 ]; then rc=0; fi
+    exit $rc
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/Makefile               |    9 +++++-
+ tools/libxc/xc_dom.h               |    7 +++--
+ tools/libxc/xc_dom_elfloader.c     |   42 ++++++++++++++++-------------
+ tools/xcutils/readnotes.c          |   15 +++++-----
+ xen/common/libelf/Makefile         |    2 +
+ xen/common/libelf/libelf-dominfo.c |   52 ++++++++++++++++++-----------------
+ xen/common/libelf/libelf-loader.c  |   20 +++++++-------
+ xen/common/libelf/libelf-tools.c   |   24 ++++++++--------
+ xen/include/xen/libelf.h           |   21 ++++++++------
+ 9 files changed, 105 insertions(+), 87 deletions(-)
+
+diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
+index d8c6a60..a3fd90c 100644
+--- a/tools/libxc/Makefile
++++ b/tools/libxc/Makefile
+@@ -52,8 +52,13 @@ endif
+ vpath %.c ../../xen/common/libelf
+ CFLAGS += -I../../xen/common/libelf
+-GUEST_SRCS-y += libelf-tools.c libelf-loader.c
+-GUEST_SRCS-y += libelf-dominfo.c
++ELF_SRCS-y += libelf-tools.c libelf-loader.c
++ELF_SRCS-y += libelf-dominfo.c
++
++GUEST_SRCS-y += $(ELF_SRCS-y)
++
++$(patsubst %.c,%.o,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
++$(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
+ # new domain builder
+ GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
+diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
+index 9f8037e..0161459 100644
+--- a/tools/libxc/xc_dom.h
++++ b/tools/libxc/xc_dom.h
+@@ -140,9 +140,10 @@ struct xc_dom_image {
+ struct xc_dom_loader {
+     char *name;
+-    int (*probe) (struct xc_dom_image * dom);
+-    int (*parser) (struct xc_dom_image * dom);
+-    int (*loader) (struct xc_dom_image * dom);
++    /* Sadly the error returns from these functions are not consistent: */
++    elf_negerrnoval (*probe) (struct xc_dom_image * dom);
++    elf_negerrnoval (*parser) (struct xc_dom_image * dom);
++    elf_errorstatus (*loader) (struct xc_dom_image * dom);
+     struct xc_dom_loader *next;
+ };
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 9ba64ae..62a0d3b 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -84,7 +84,7 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
+ /* ------------------------------------------------------------------------ */
+ /* parse elf binary                                                         */
+-static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
++static elf_negerrnoval check_elf_kernel(struct xc_dom_image *dom, bool verbose)
+ {
+     if ( dom->kernel_blob == NULL )
+     {
+@@ -106,12 +106,12 @@ static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
+     return 0;
+ }
+-static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
++static elf_negerrnoval xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
+ {
+     return check_elf_kernel(dom, 0);
+ }
+-static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
++static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+                                   struct elf_binary *elf, bool load)
+ {
+     struct elf_binary syms;
+@@ -119,7 +119,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     xen_vaddr_t symtab, maxaddr;
+     ELF_PTRVAL_CHAR hdr;
+     size_t size;
+-    int h, count, type, i, tables = 0;
++    unsigned h, count, type, i, tables = 0;
+     if ( elf_swap(elf) )
+     {
+@@ -140,13 +140,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         elf->caller_xdest_base = hdr_ptr;
+         elf->caller_xdest_size = allow_size;
+         hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
+-        elf_store_val(elf, int, hdr, size - sizeof(int));
++        elf_store_val(elf, unsigned, hdr, size - sizeof(unsigned));
+     }
+     else
+     {
+         char *hdr_ptr;
+-        size = sizeof(int) + elf_size(elf, elf->ehdr) +
++        size = sizeof(unsigned) + elf_size(elf, elf->ehdr) +
+             elf_shdr_count(elf) * elf_size(elf, shdr);
+         hdr_ptr = xc_dom_malloc(dom, size);
+         if ( hdr_ptr == NULL )
+@@ -157,15 +157,15 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+         dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
+     }
+-    elf_memcpy_safe(elf, hdr + sizeof(int),
++    elf_memcpy_safe(elf, hdr + sizeof(unsigned),
+            ELF_IMAGE_BASE(elf),
+            elf_size(elf, elf->ehdr));
+-    elf_memcpy_safe(elf, hdr + sizeof(int) + elf_size(elf, elf->ehdr),
++    elf_memcpy_safe(elf, hdr + sizeof(unsigned) + elf_size(elf, elf->ehdr),
+            ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
+            elf_shdr_count(elf) * elf_size(elf, shdr));
+     if ( elf_64bit(elf) )
+     {
+-        Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int));
++        Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(unsigned));
+         ehdr->e_phoff = 0;
+         ehdr->e_phentsize = 0;
+         ehdr->e_phnum = 0;
+@@ -174,22 +174,22 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     }
+     else
+     {
+-        Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int));
++        Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(unsigned));
+         ehdr->e_phoff = 0;
+         ehdr->e_phentsize = 0;
+         ehdr->e_phnum = 0;
+         ehdr->e_shoff = elf_size(elf, elf->ehdr);
+         ehdr->e_shstrndx = SHN_UNDEF;
+     }
+-    if ( elf->caller_xdest_size < sizeof(int) )
++    if ( elf->caller_xdest_size < sizeof(unsigned) )
+     {
+         DOMPRINTF("%s/%s: header size %"PRIx64" too small",
+                   __FUNCTION__, load ? "load" : "parse",
+                   (uint64_t)elf->caller_xdest_size);
+         return -1;
+     }
+-    if ( elf_init(&syms, elf->caller_xdest_base + sizeof(int),
+-                  elf->caller_xdest_size - sizeof(int)) )
++    if ( elf_init(&syms, elf->caller_xdest_base + sizeof(unsigned),
++                  elf->caller_xdest_size - sizeof(unsigned)) )
+         return -1;
+     /*
+@@ -209,7 +209,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     xc_elf_set_logfile(dom->xch, &syms, 1);
+-    symtab = dom->bsd_symtab_start + sizeof(int);
++    symtab = dom->bsd_symtab_start + sizeof(unsigned);
+     maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
+                            elf_shdr_count(&syms) * elf_size(&syms, shdr));
+@@ -255,7 +255,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             size = elf_uval(&syms, shdr, sh_size);
+             maxaddr = elf_round_up(&syms, maxaddr + size);
+             tables++;
+-            DOMPRINTF("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "",
++            DOMPRINTF("%s: h=%u %s, size=0x%zx, maxaddr=0x%" PRIx64 "",
+                       __FUNCTION__, h,
+                       type == SHT_SYMTAB ? "symtab" : "strtab",
+                       size, maxaddr);
+@@ -294,10 +294,14 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     return 0;
+ }
+-static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
++static elf_errorstatus xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
++    /*
++     * This function sometimes returns -1 for error and sometimes
++     * an errno value.  ?!?!
++     */
+ {
+     struct elf_binary *elf;
+-    int rc;
++    elf_errorstatus rc;
+     rc = check_elf_kernel(dom, 1);
+     if ( rc != 0 )
+@@ -358,10 +362,10 @@ out:
+     return rc;
+ }
+-static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
++static elf_errorstatus xc_dom_load_elf_kernel(struct xc_dom_image *dom)
+ {
+     struct elf_binary *elf = dom->private_loader;
+-    int rc;
++    elf_errorstatus rc;
+     xen_pfn_t pages;
+     elf->dest_base = xc_dom_seg_to_ptr_pages(dom, &dom->kernel_seg, &pages);
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index d1f7a30..2ca7732 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -70,7 +70,7 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
+                              ELF_HANDLE_DECL(elf_note) note)
+ {
+       uint64_t value = elf_note_numeric(elf, note);
+-      int descsz = elf_uval(elf, note, descsz);
++      unsigned descsz = elf_uval(elf, note, descsz);
+       printf("%s: %#*" PRIx64 " (%d bytes)\n",
+              prefix, 2+2*descsz, value, descsz);
+@@ -79,7 +79,7 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
+ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
+                                   ELF_HANDLE_DECL(elf_note) note)
+ {
+-      int descsz = elf_uval(elf, note, descsz);
++      unsigned descsz = elf_uval(elf, note, descsz);
+       ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+       /* XXX should be able to cope with a list of values. */
+@@ -99,10 +99,10 @@ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
+ }
+-static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start, ELF_HANDLE_DECL(elf_note) end)
++static unsigned print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start, ELF_HANDLE_DECL(elf_note) end)
+ {
+       ELF_HANDLE_DECL(elf_note) note;
+-      int notes_found = 0;
++      unsigned notes_found = 0;
+       const char *this_note_name;
+       for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
+@@ -161,7 +161,7 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
+                       break;
+               default:
+                       printf("unknown note type %#x\n",
+-                             (int)elf_uval(elf, note, type));
++                             (unsigned)elf_uval(elf, note, type));
+                       break;
+               }
+       }
+@@ -171,12 +171,13 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
+ int main(int argc, char **argv)
+ {
+       const char *f;
+-      int fd,h,size,usize,count;
++      int fd;
++      unsigned h,size,usize,count;
+       void *image,*tmp;
+       struct stat st;
+       struct elf_binary elf;
+       ELF_HANDLE_DECL(elf_shdr) shdr;
+-      int notes_found = 0;
++      unsigned notes_found = 0;
+       struct setup_header *hdr;
+       uint64_t payload_offset, payload_length;
+diff --git a/xen/common/libelf/Makefile b/xen/common/libelf/Makefile
+index 18dc8e2..5bf8f76 100644
+--- a/xen/common/libelf/Makefile
++++ b/xen/common/libelf/Makefile
+@@ -2,6 +2,8 @@ obj-bin-y := libelf.o
+ SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
++CFLAGS += -Wno-pointer-sign
++
+ libelf.o: libelf-temp.o Makefile
+       $(OBJCOPY) $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index 12b6c2a..cdd0d31 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -29,15 +29,15 @@ static const char *const elf_xen_feature_names[] = {
+     [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb",
+     [XENFEAT_dom0] = "dom0"
+ };
+-static const int elf_xen_features =
++static const unsigned elf_xen_features =
+ sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
+-int elf_xen_parse_features(const char *features,
++elf_errorstatus elf_xen_parse_features(const char *features,
+                            uint32_t *supported,
+                            uint32_t *required)
+ {
+-    char feature[64];
+-    int pos, len, i;
++    unsigned char feature[64];
++    unsigned pos, len, i;
+     if ( features == NULL )
+         return 0;
+@@ -94,7 +94,7 @@ int elf_xen_parse_features(const char *features,
+ /* ------------------------------------------------------------------------ */
+ /* xen elf notes                                                            */
+-int elf_xen_parse_note(struct elf_binary *elf,
++elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
+                        struct elf_dom_parms *parms,
+                        ELF_HANDLE_DECL(elf_note) note)
+ {
+@@ -125,7 +125,7 @@ int elf_xen_parse_note(struct elf_binary *elf,
+     const char *str = NULL;
+     uint64_t val = 0;
+     unsigned int i;
+-    int type = elf_uval(elf, note, type);
++    unsigned type = elf_uval(elf, note, type);
+     if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
+          (note_desc[type].name == NULL) )
+@@ -216,12 +216,14 @@ int elf_xen_parse_note(struct elf_binary *elf,
+     return 0;
+ }
+-static int elf_xen_parse_notes(struct elf_binary *elf,
++#define ELF_NOTE_INVALID (~0U)
++
++static unsigned elf_xen_parse_notes(struct elf_binary *elf,
+                                struct elf_dom_parms *parms,
+                                ELF_PTRVAL_CONST_VOID start,
+                                ELF_PTRVAL_CONST_VOID end)
+ {
+-    int xen_elfnotes = 0;
++    unsigned xen_elfnotes = 0;
+     ELF_HANDLE_DECL(elf_note) note;
+     const char *note_name;
+@@ -237,7 +239,7 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
+         if ( strcmp(note_name, "Xen") )
+             continue;
+         if ( elf_xen_parse_note(elf, parms, note) )
+-            return -1;
++            return ELF_NOTE_INVALID;
+         xen_elfnotes++;
+     }
+     return xen_elfnotes;
+@@ -246,12 +248,12 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
+ /* ------------------------------------------------------------------------ */
+ /* __xen_guest section                                                      */
+-int elf_xen_parse_guest_info(struct elf_binary *elf,
++elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf,
+                              struct elf_dom_parms *parms)
+ {
+     ELF_PTRVAL_CONST_CHAR h;
+-    char name[32], value[128];
+-    int len;
++    unsigned char name[32], value[128];
++    unsigned len;
+     h = parms->guest_info;
+ #define STAR(h) (elf_access_unsigned(elf, (h), 0, 1))
+@@ -334,13 +336,13 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
+ /* ------------------------------------------------------------------------ */
+ /* sanity checks                                                            */
+-static int elf_xen_note_check(struct elf_binary *elf,
++static elf_errorstatus elf_xen_note_check(struct elf_binary *elf,
+                               struct elf_dom_parms *parms)
+ {
+     if ( (ELF_PTRVAL_INVALID(parms->elf_note_start)) &&
+          (ELF_PTRVAL_INVALID(parms->guest_info)) )
+     {
+-        int machine = elf_uval(elf, elf->ehdr, e_machine);
++        unsigned machine = elf_uval(elf, elf->ehdr, e_machine);
+         if ( (machine == EM_386) || (machine == EM_X86_64) )
+         {
+             elf_err(elf, "%s: ERROR: Not a Xen-ELF image: "
+@@ -378,7 +380,7 @@ static int elf_xen_note_check(struct elf_binary *elf,
+     return 0;
+ }
+-static int elf_xen_addr_calc_check(struct elf_binary *elf,
++static elf_errorstatus elf_xen_addr_calc_check(struct elf_binary *elf,
+                                    struct elf_dom_parms *parms)
+ {
+     if ( (parms->elf_paddr_offset != UNSET_ADDR) &&
+@@ -464,13 +466,13 @@ static int elf_xen_addr_calc_check(struct elf_binary *elf,
+ /* ------------------------------------------------------------------------ */
+ /* glue it all together ...                                                 */
+-int elf_xen_parse(struct elf_binary *elf,
++elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+                   struct elf_dom_parms *parms)
+ {
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+     ELF_HANDLE_DECL(elf_phdr) phdr;
+-    int xen_elfnotes = 0;
+-    int i, count, rc;
++    unsigned xen_elfnotes = 0;
++    unsigned i, count, more_notes;
+     elf_memset_unchecked(parms, 0, sizeof(*parms));
+     parms->virt_base = UNSET_ADDR;
+@@ -495,13 +497,13 @@ int elf_xen_parse(struct elf_binary *elf,
+         if (elf_uval(elf, phdr, p_offset) == 0)
+              continue;
+-        rc = elf_xen_parse_notes(elf, parms,
++        more_notes = elf_xen_parse_notes(elf, parms,
+                                  elf_segment_start(elf, phdr),
+                                  elf_segment_end(elf, phdr));
+-        if ( rc == -1 )
++        if ( more_notes == ELF_NOTE_INVALID )
+             return -1;
+-        xen_elfnotes += rc;
++        xen_elfnotes += more_notes;
+     }
+     /*
+@@ -518,17 +520,17 @@ int elf_xen_parse(struct elf_binary *elf,
+             if ( elf_uval(elf, shdr, sh_type) != SHT_NOTE )
+                 continue;
+-            rc = elf_xen_parse_notes(elf, parms,
++            more_notes = elf_xen_parse_notes(elf, parms,
+                                      elf_section_start(elf, shdr),
+                                      elf_section_end(elf, shdr));
+-            if ( rc == -1 )
++            if ( more_notes == ELF_NOTE_INVALID )
+                 return -1;
+-            if ( xen_elfnotes == 0 && rc > 0 )
++            if ( xen_elfnotes == 0 && more_notes > 0 )
+                 elf_msg(elf, "%s: using notes from SHT_NOTE section\n", __FUNCTION__);
+-            xen_elfnotes += rc;
++            xen_elfnotes += more_notes;
+         }
+     }
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index 0dccd4d..c3a9e51 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -24,7 +24,7 @@
+ /* ------------------------------------------------------------------------ */
+-int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
++elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t size)
+ {
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+     uint64_t i, count, section, offset;
+@@ -114,7 +114,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+     elf->verbose = verbose;
+ }
+-static int elf_load_image(struct elf_binary *elf,
++static elf_errorstatus elf_load_image(struct elf_binary *elf,
+                           ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src,
+                           uint64_t filesz, uint64_t memsz)
+ {
+@@ -129,9 +129,9 @@ void elf_set_verbose(struct elf_binary *elf)
+     elf->verbose = 1;
+ }
+-static int elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
++static elf_errorstatus elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
+ {
+-    int rc;
++    elf_errorstatus rc;
+     if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
+         return -1;
+     /* We trust the dom0 kernel image completely, so we don't care
+@@ -151,7 +151,7 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+ {
+     uint64_t sz;
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+-    int i, type;
++    unsigned i, type;
+     if ( !ELF_HANDLE_VALID(elf->sym_tab) )
+         return;
+@@ -187,7 +187,7 @@ static void elf_load_bsdsyms(struct elf_binary *elf)
+     ELF_PTRVAL_VOID symbase;
+     ELF_PTRVAL_VOID symtab_addr;
+     ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
+-    int i, type;
++    unsigned i, type;
+     if ( !elf->bsd_symtab_pstart )
+         return;
+@@ -220,7 +220,7 @@ do {                                            \
+     elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
+                     ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
+                     sz);
+-    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
++    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
+@@ -233,10 +233,10 @@ do {                                            \
+              elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
+              /* Mangled to be based on ELF header location. */
+              elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
+-             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
++             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
+         }
+         shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
+-                            (long)elf_uval(elf, elf->ehdr, e_shentsize));
++                            (unsigned long)elf_uval(elf, elf->ehdr, e_shentsize));
+     }
+     /* Write down the actual sym size. */
+@@ -273,7 +273,7 @@ void elf_parse_binary(struct elf_binary *elf)
+             __FUNCTION__, elf->pstart, elf->pend);
+ }
+-int elf_load_binary(struct elf_binary *elf)
++elf_errorstatus elf_load_binary(struct elf_binary *elf)
+ {
+     ELF_HANDLE_DECL(elf_phdr) phdr;
+     uint64_t i, count, paddr, offset, filesz, memsz;
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index fa58f76..46d4ab1 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -122,19 +122,19 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
+ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
+ {
+-    int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
++    uint64_t elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
+     return (addr + elf_round) & ~elf_round;
+ }
+ /* ------------------------------------------------------------------------ */
+-int elf_shdr_count(struct elf_binary *elf)
++unsigned elf_shdr_count(struct elf_binary *elf)
+ {
+     return elf_uval(elf, elf->ehdr, e_shnum);
+ }
+-int elf_phdr_count(struct elf_binary *elf)
++unsigned elf_phdr_count(struct elf_binary *elf)
+ {
+     return elf_uval(elf, elf->ehdr, e_phnum);
+ }
+@@ -144,7 +144,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
+     uint64_t count = elf_shdr_count(elf);
+     ELF_HANDLE_DECL(elf_shdr) shdr;
+     const char *sname;
+-    int i;
++    unsigned i;
+     for ( i = 0; i < count; i++ )
+     {
+@@ -156,7 +156,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
+     return ELF_INVALID_HANDLE(elf_shdr);
+ }
+-ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index)
+ {
+     uint64_t count = elf_shdr_count(elf);
+     ELF_PTRVAL_CONST_VOID ptr;
+@@ -170,7 +170,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index)
+     return ELF_MAKE_HANDLE(elf_shdr, ptr);
+ }
+-ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index)
+ {
+     uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
+     ELF_PTRVAL_CONST_VOID ptr;
+@@ -264,7 +264,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
+     return ELF_INVALID_HANDLE(elf_sym);
+ }
+-ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index)
+ {
+     ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
+     ELF_HANDLE_DECL(elf_sym) sym;
+@@ -280,7 +280,7 @@ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
+ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
++    unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+     return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz;
+ }
+@@ -288,7 +288,7 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
+ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+     ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+-    int descsz = elf_uval(elf, note, descsz);
++    unsigned descsz = elf_uval(elf, note, descsz);
+     switch (descsz)
+     {
+@@ -306,7 +306,7 @@ uint64_t elf_note_numeric_array(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note
+                                 unsigned int unitsz, unsigned int idx)
+ {
+     ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
+-    int descsz = elf_uval(elf, note, descsz);
++    unsigned descsz = elf_uval(elf, note, descsz);
+     if ( descsz % unitsz || idx >= descsz / unitsz )
+         return 0;
+@@ -324,8 +324,8 @@ uint64_t elf_note_numeric_array(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note
+ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+-    int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
++    unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
++    unsigned descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
+     return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz + descsz);
+ }
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index 951430f..87e126a 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -31,6 +31,9 @@
+ #include <stdbool.h>
++typedef int elf_errorstatus; /* 0: ok; -ve (normally -1): error */
++typedef int elf_negerrnoval; /* 0: ok; -EFOO: error */
++
+ #undef ELFSIZE
+ #include "elfstructs.h"
+ #ifdef __XEN__
+@@ -328,12 +331,12 @@ bool elf_access_ok(struct elf_binary * elf,
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_tools.c                                                        */
+-int elf_shdr_count(struct elf_binary *elf);
+-int elf_phdr_count(struct elf_binary *elf);
++unsigned elf_shdr_count(struct elf_binary *elf);
++unsigned elf_phdr_count(struct elf_binary *elf);
+ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *name);
+-ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
+-ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
++ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index);
++ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index);
+ const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
+ ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+@@ -343,7 +346,7 @@ ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(
+ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
+-ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
++ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index);
+ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
+ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+@@ -360,7 +363,7 @@ bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_loader.c                                                       */
+-int elf_init(struct elf_binary *elf, const char *image, size_t size);
++elf_errorstatus elf_init(struct elf_binary *elf, const char *image, size_t size);
+   /*
+    * image and size must be correct.  They will be recorded in
+    * *elf, and must remain valid while the elf is in use.
+@@ -373,7 +376,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback*,
+ #endif
+ void elf_parse_binary(struct elf_binary *elf);
+-int elf_load_binary(struct elf_binary *elf);
++elf_errorstatus elf_load_binary(struct elf_binary *elf);
+ ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr);
+ uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
+@@ -386,7 +389,7 @@ const char *elf_check_broken(const struct elf_binary *elf); /* NULL means OK */
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_relocate.c                                                     */
+-int elf_reloc(struct elf_binary *elf);
++elf_errorstatus elf_reloc(struct elf_binary *elf);
+ /* ------------------------------------------------------------------------ */
+ /* xc_libelf_dominfo.c                                                      */
+@@ -420,7 +423,7 @@ struct elf_dom_parms {
+     char guest_ver[16];
+     char xen_ver[16];
+     char loader[16];
+-    int pae;
++    int pae; /* some kind of enum apparently */
+     bool bsd_symtab;
+     uint64_t virt_base;
+     uint64_t virt_entry;
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0016-libelf-check-loops-for-running-away.patch b/SOURCES/xsa55-4.2-0016-libelf-check-loops-for-running-away.patch
new file mode 100644 (file)
index 0000000..fe09e46
--- /dev/null
@@ -0,0 +1,409 @@
+From 52d8cc2dd3bb3e0f6d51e00280da934e8d91653a Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:18 +0100
+Subject: [PATCH 16/23] libelf: check loops for running away
+
+Ensure that libelf does not have any loops which can run away
+indefinitely even if the input is bogus.  (Grepped for \bfor, \bwhile
+and \bgoto in libelf and xc_dom_*loader*.c.)
+
+Changes needed:
+ * elf_note_next uses the note's unchecked alleged length, which might
+   wrap round.  If it does, return ELF_MAX_PTRVAL (0xfff..fff) instead,
+   which will be beyond the end of the section and so terminate the
+   caller's loop.  Also check that the returned psuedopointer is sane.
+ * In various loops over section and program headers, check that the
+   calculated header pointer is still within the image, and quit the
+   loop if it isn't.
+ * Some fixed limits to avoid potentially O(image_size^2) loops:
+    - maximum length of strings: 4K (longer ones ignored totally)
+    - maximum total number of ELF notes: 65536 (any more are ignored)
+ * Check that the total program contents (text, data) we copy or
+   initialise doesn't exceed twice the output image area size.
+ * Remove an entirely useless loop from elf_xen_parse (!)
+ * Replace a nested search loop in in xc_dom_load_elf_symtab in
+   xc_dom_elfloader.c by a precomputation of a bitmap of referenced
+   symtabs.
+
+We have not changed loops which might, in principle, iterate over the
+whole image - even if they might do so one byte at a time with a
+nontrivial access check function in the middle.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_dom_elfloader.c     |   33 ++++++++++++++++++-------
+ xen/common/libelf/libelf-dominfo.c |   43 ++++++++++++++++++++------------
+ xen/common/libelf/libelf-loader.c  |   47 ++++++++++++++++++++++++++++++++++-
+ xen/common/libelf/libelf-tools.c   |   28 ++++++++++++++++++++-
+ xen/include/xen/libelf.h           |   13 ++++++++++
+ 5 files changed, 135 insertions(+), 29 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 62a0d3b..c5014d2 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -28,6 +28,7 @@
+ #include "xg_private.h"
+ #include "xc_dom.h"
++#include "xc_bitops.h"
+ #define XEN_VER "xen-3.0"
+@@ -120,6 +121,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     ELF_PTRVAL_CHAR hdr;
+     size_t size;
+     unsigned h, count, type, i, tables = 0;
++    unsigned long *strtab_referenced = NULL;
+     if ( elf_swap(elf) )
+     {
+@@ -220,22 +222,35 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+               symtab, maxaddr);
+     count = elf_shdr_count(&syms);
++    /* elf_shdr_count guarantees that count is reasonable */
++
++    strtab_referenced = xc_dom_malloc(dom, bitmap_size(count));
++    if ( strtab_referenced == NULL )
++        return -1;
++    bitmap_clear(strtab_referenced, count);
++    /* Note the symtabs @h linked to by any strtab @i. */
++    for ( i = 0; i < count; i++ )
++    {
++        shdr2 = elf_shdr_by_index(&syms, i);
++        if ( elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB )
++        {
++            h = elf_uval(&syms, shdr2, sh_link);
++            if (h < count)
++                set_bit(h, strtab_referenced);
++        }
++    }
++
+     for ( h = 0; h < count; h++ )
+     {
+         shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
++            /* input has an insane section header count field */
++            break;
+         type = elf_uval(&syms, shdr, sh_type);
+         if ( type == SHT_STRTAB )
+         {
+-            /* Look for a strtab @i linked to symtab @h. */
+-            for ( i = 0; i < count; i++ )
+-            {
+-                shdr2 = elf_shdr_by_index(&syms, i);
+-                if ( (elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) &&
+-                     (elf_uval(&syms, shdr2, sh_link) == h) )
+-                    break;
+-            }
+             /* Skip symtab @h if we found no corresponding strtab @i. */
+-            if ( i == count )
++            if ( !test_bit(h, strtab_referenced) )
+             {
+                 if ( elf_64bit(&syms) )
+                     elf_store_field(elf, shdr, e64.sh_offset, 0);
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index cdd0d31..25a10d7 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -221,7 +221,8 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
+ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
+                                struct elf_dom_parms *parms,
+                                ELF_PTRVAL_CONST_VOID start,
+-                               ELF_PTRVAL_CONST_VOID end)
++                               ELF_PTRVAL_CONST_VOID end,
++                               unsigned *total_note_count)
+ {
+     unsigned xen_elfnotes = 0;
+     ELF_HANDLE_DECL(elf_note) note;
+@@ -233,6 +234,12 @@ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
+           ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
+           note = elf_note_next(elf, note) )
+     {
++        if ( *total_note_count >= ELF_MAX_TOTAL_NOTE_COUNT )
++        {
++            elf_mark_broken(elf, "too many ELF notes");
++            break;
++        }
++        (*total_note_count)++;
+         note_name = elf_note_name(elf, note);
+         if ( note_name == NULL )
+             continue;
+@@ -473,6 +480,7 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+     ELF_HANDLE_DECL(elf_phdr) phdr;
+     unsigned xen_elfnotes = 0;
+     unsigned i, count, more_notes;
++    unsigned total_note_count = 0;
+     elf_memset_unchecked(parms, 0, sizeof(*parms));
+     parms->virt_base = UNSET_ADDR;
+@@ -487,6 +495,9 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+     for ( i = 0; i < count; i++ )
+     {
+         phdr = elf_phdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
++            /* input has an insane program header count field */
++            break;
+         if ( elf_uval(elf, phdr, p_type) != PT_NOTE )
+             continue;
+@@ -499,7 +510,8 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+         more_notes = elf_xen_parse_notes(elf, parms,
+                                  elf_segment_start(elf, phdr),
+-                                 elf_segment_end(elf, phdr));
++                                 elf_segment_end(elf, phdr),
++                                 &total_note_count);
+         if ( more_notes == ELF_NOTE_INVALID )
+             return -1;
+@@ -516,13 +528,17 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+         for ( i = 0; i < count; i++ )
+         {
+             shdr = elf_shdr_by_index(elf, i);
++            if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
++                /* input has an insane section header count field */
++                break;
+             if ( elf_uval(elf, shdr, sh_type) != SHT_NOTE )
+                 continue;
+             more_notes = elf_xen_parse_notes(elf, parms,
+                                      elf_section_start(elf, shdr),
+-                                     elf_section_end(elf, shdr));
++                                     elf_section_end(elf, shdr),
++                                     &total_note_count);
+             if ( more_notes == ELF_NOTE_INVALID )
+                 return -1;
+@@ -540,20 +556,15 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
+      */
+     if ( xen_elfnotes == 0 )
+     {
+-        count = elf_shdr_count(elf);
+-        for ( i = 0; i < count; i++ )
++        shdr = elf_shdr_by_name(elf, "__xen_guest");
++        if ( ELF_HANDLE_VALID(shdr) )
+         {
+-            shdr = elf_shdr_by_name(elf, "__xen_guest");
+-            if ( ELF_HANDLE_VALID(shdr) )
+-            {
+-                parms->guest_info = elf_section_start(elf, shdr);
+-                parms->elf_note_start = ELF_INVALID_PTRVAL;
+-                parms->elf_note_end   = ELF_INVALID_PTRVAL;
+-                elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
+-                        elf_strfmt(elf, parms->guest_info));
+-                elf_xen_parse_guest_info(elf, parms);
+-                break;
+-            }
++            parms->guest_info = elf_section_start(elf, shdr);
++            parms->elf_note_start = ELF_INVALID_PTRVAL;
++            parms->elf_note_end   = ELF_INVALID_PTRVAL;
++            elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
++                    elf_strfmt(elf, parms->guest_info));
++            elf_xen_parse_guest_info(elf, parms);
+         }
+     }
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index c3a9e51..06799af 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -75,6 +75,9 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
+     for ( i = 0; i < count; i++ )
+     {
+         shdr = elf_shdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
++            /* input has an insane section header count field */
++            break;
+         if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
+             continue;
+         elf->sym_tab = shdr;
+@@ -170,6 +173,9 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
+         shdr = elf_shdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
++            /* input has an insane section header count field */
++            break;
+         type = elf_uval(elf, shdr, sh_type);
+         if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+             sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
+@@ -224,6 +230,9 @@ do {                                            \
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
++        elf_ptrval old_shdr_p;
++        elf_ptrval new_shdr_p;
++
+         type = elf_uval(elf, shdr, sh_type);
+         if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+         {
+@@ -235,8 +244,16 @@ do {                                            \
+              elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
+              maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
+         }
+-        shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
+-                            (unsigned long)elf_uval(elf, elf->ehdr, e_shentsize));
++        old_shdr_p = ELF_HANDLE_PTRVAL(shdr);
++        new_shdr_p = old_shdr_p + elf_uval(elf, elf->ehdr, e_shentsize);
++        if ( new_shdr_p <= old_shdr_p ) /* wrapped or stuck */
++        {
++            elf_mark_broken(elf, "bad section header length");
++            break;
++        }
++        if ( !elf_access_ok(elf, new_shdr_p, 1) ) /* outside image */
++            break;
++        shdr = ELF_MAKE_HANDLE(elf_shdr, new_shdr_p);
+     }
+     /* Write down the actual sym size. */
+@@ -256,6 +273,9 @@ void elf_parse_binary(struct elf_binary *elf)
+     for ( i = 0; i < count; i++ )
+     {
+         phdr = elf_phdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
++            /* input has an insane program header count field */
++            break;
+         if ( !elf_phdr_is_loadable(elf, phdr) )
+             continue;
+         paddr = elf_uval(elf, phdr, p_paddr);
+@@ -278,11 +298,20 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
+     ELF_HANDLE_DECL(elf_phdr) phdr;
+     uint64_t i, count, paddr, offset, filesz, memsz;
+     ELF_PTRVAL_VOID dest;
++    /*
++     * Let bizarre ELFs write the output image up to twice; this
++     * calculation is just to ensure our copying loop is no worse than
++     * O(domain_size).
++     */
++    uint64_t remain_allow_copy = (uint64_t)elf->dest_size * 2;
+     count = elf_uval(elf, elf->ehdr, e_phnum);
+     for ( i = 0; i < count; i++ )
+     {
+         phdr = elf_phdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
++            /* input has an insane program header count field */
++            break;
+         if ( !elf_phdr_is_loadable(elf, phdr) )
+             continue;
+         paddr = elf_uval(elf, phdr, p_paddr);
+@@ -290,6 +319,20 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
+         filesz = elf_uval(elf, phdr, p_filesz);
+         memsz = elf_uval(elf, phdr, p_memsz);
+         dest = elf_get_ptr(elf, paddr);
++
++        /*
++         * We need to check that the input image doesn't have us copy
++         * the whole image zillions of times, as that could lead to
++         * O(n^2) time behaviour and possible DoS by a malicous ELF.
++         */
++        if ( remain_allow_copy < memsz )
++        {
++            elf_mark_broken(elf, "program segments total to more"
++                            " than the input image size");
++            break;
++        }
++        remain_allow_copy -= memsz;
++
+         elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n",
+                 __func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
+         if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, memsz) != 0 )
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 46d4ab1..4a83133 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -131,7 +131,16 @@ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
+ unsigned elf_shdr_count(struct elf_binary *elf)
+ {
+-    return elf_uval(elf, elf->ehdr, e_shnum);
++    unsigned count = elf_uval(elf, elf->ehdr, e_shnum);
++    uint64_t max = elf->size / sizeof(Elf32_Shdr);
++    if (max > ~(unsigned)0)
++        max = ~(unsigned)0; /* Xen doesn't have limits.h :-/ */
++    if (count > max)
++    {
++        elf_mark_broken(elf, "far too many section headers");
++        count = max;
++    }
++    return count;
+ }
+ unsigned elf_phdr_count(struct elf_binary *elf)
+@@ -149,6 +158,9 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
+     for ( i = 0; i < count; i++ )
+     {
+         shdr = elf_shdr_by_index(elf, i);
++        if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
++            /* input has an insane section header count field */
++            break;
+         sname = elf_section_name(elf, shdr);
+         if ( sname && !strcmp(sname, name) )
+             return shdr;
+@@ -204,6 +216,11 @@ const char *elf_strval(struct elf_binary *elf, elf_ptrval start)
+         if ( !elf_access_unsigned(elf, start, length, 1) )
+             /* ok */
+             return ELF_UNSAFE_PTR(start);
++        if ( length >= ELF_MAX_STRING_LENGTH )
++        {
++            elf_mark_broken(elf, "excessively long string");
++            return NULL;
++        }
+     }
+ }
+@@ -327,7 +344,14 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
+     unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+     unsigned descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
+-    return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz + descsz);
++    elf_ptrval ptrval = ELF_HANDLE_PTRVAL(note)
++        + elf_size(elf, note) + namesz + descsz;
++
++    if ( ( ptrval <= ELF_HANDLE_PTRVAL(note) || /* wrapped or stuck */
++           !elf_access_ok(elf, ELF_HANDLE_PTRVAL(note), 1) ) )
++        ptrval = ELF_MAX_PTRVAL; /* terminate caller's loop */
++
++    return ELF_MAKE_HANDLE(elf_note, ptrval);
+ }
+ /* ------------------------------------------------------------------------ */
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index 87e126a..f95fe88 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -51,6 +51,9 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+ #endif
++#define ELF_MAX_STRING_LENGTH 4096
++#define ELF_MAX_TOTAL_NOTE_COUNT 65536
++
+ /* ------------------------------------------------------------------------ */
+ /* Macros for accessing the input image and output area. */
+@@ -353,6 +356,16 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
+ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+                                 unsigned int unitsz, unsigned int idx);
++
++/*
++ * If you use elf_note_next in a loop, you must put a nontrivial upper
++ * bound on the returned value as part of your loop condition.  In
++ * some cases elf_note_next will substitute ELF_PTRVAL_MAX as return
++ * value to indicate that the iteration isn't going well (for example,
++ * the putative "next" value would be earlier in memory).  In this
++ * case the caller's loop must terminate.  Checking against the
++ * end of the notes segment with a strict inequality is sufficient.
++ */
+ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ /* (Only) checks that the image has the right magic number. */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0017-libelf-abolish-obsolete-macros.patch b/SOURCES/xsa55-4.2-0017-libelf-abolish-obsolete-macros.patch
new file mode 100644 (file)
index 0000000..4369599
--- /dev/null
@@ -0,0 +1,406 @@
+From 3baaa4ffcd3e7dd6227f9bdf817f90e5b75aeda2 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 17/23] libelf: abolish obsolete macros
+
+Abolish ELF_PTRVAL_[CONST_]{CHAR,VOID}; change uses to elf_ptrval.
+Abolish ELF_HANDLE_DECL_NONCONST; change uses to ELF_HANDLE_DECL.
+Abolish ELF_OBSOLETE_VOIDP_CAST; simply remove all uses.
+
+No functional change.  (Verified by diffing assembler output.)
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+
+v2: New patch.
+---
+ tools/libxc/xc_dom_elfloader.c     |    8 +++---
+ tools/xcutils/readnotes.c          |    2 +-
+ xen/common/libelf/libelf-dominfo.c |    6 ++--
+ xen/common/libelf/libelf-loader.c  |   24 +++++++++---------
+ xen/common/libelf/libelf-tools.c   |   24 +++++++++---------
+ xen/include/xen/libelf.h           |   48 +++++++++---------------------------
+ 6 files changed, 44 insertions(+), 68 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index c5014d2..9fc4b94 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -116,9 +116,9 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+                                   struct elf_binary *elf, bool load)
+ {
+     struct elf_binary syms;
+-    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
++    ELF_HANDLE_DECL(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
+     xen_vaddr_t symtab, maxaddr;
+-    ELF_PTRVAL_CHAR hdr;
++    elf_ptrval hdr;
+     size_t size;
+     unsigned h, count, type, i, tables = 0;
+     unsigned long *strtab_referenced = NULL;
+@@ -242,7 +242,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+     for ( h = 0; h < count; h++ )
+     {
+-        shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
++        shdr = elf_shdr_by_index(&syms, h);
+         if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
+             /* input has an insane section header count field */
+             break;
+@@ -278,7 +278,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             if ( load )
+             {
+                 shdr2 = elf_shdr_by_index(elf, h);
+-                elf_memcpy_safe(elf, ELF_OBSOLETE_VOIDP_CAST elf_section_start(&syms, shdr),
++                elf_memcpy_safe(elf, elf_section_start(&syms, shdr),
+                        elf_section_start(elf, shdr2),
+                        size);
+             }
+diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
+index 2ca7732..5fa445e 100644
+--- a/tools/xcutils/readnotes.c
++++ b/tools/xcutils/readnotes.c
+@@ -80,7 +80,7 @@ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
+                                   ELF_HANDLE_DECL(elf_note) note)
+ {
+       unsigned descsz = elf_uval(elf, note, descsz);
+-      ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
++      elf_ptrval desc = elf_note_desc(elf, note);
+       /* XXX should be able to cope with a list of values. */
+       switch ( descsz / 2 )
+diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
+index 25a10d7..412ea70 100644
+--- a/xen/common/libelf/libelf-dominfo.c
++++ b/xen/common/libelf/libelf-dominfo.c
+@@ -220,8 +220,8 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
+ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
+                                struct elf_dom_parms *parms,
+-                               ELF_PTRVAL_CONST_VOID start,
+-                               ELF_PTRVAL_CONST_VOID end,
++                               elf_ptrval start,
++                               elf_ptrval end,
+                                unsigned *total_note_count)
+ {
+     unsigned xen_elfnotes = 0;
+@@ -258,7 +258,7 @@ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
+ elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf,
+                              struct elf_dom_parms *parms)
+ {
+-    ELF_PTRVAL_CONST_CHAR h;
++    elf_ptrval h;
+     unsigned char name[32], value[128];
+     unsigned len;
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index 06799af..e2e75af 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -118,7 +118,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
+ }
+ static elf_errorstatus elf_load_image(struct elf_binary *elf,
+-                          ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src,
++                          elf_ptrval dst, elf_ptrval src,
+                           uint64_t filesz, uint64_t memsz)
+ {
+     elf_memcpy_safe(elf, dst, src, filesz);
+@@ -132,7 +132,7 @@ void elf_set_verbose(struct elf_binary *elf)
+     elf->verbose = 1;
+ }
+-static elf_errorstatus elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
++static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, elf_ptrval src, uint64_t filesz, uint64_t memsz)
+ {
+     elf_errorstatus rc;
+     if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
+@@ -187,12 +187,12 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+ static void elf_load_bsdsyms(struct elf_binary *elf)
+ {
+-    ELF_HANDLE_DECL_NONCONST(elf_ehdr) sym_ehdr;
++    ELF_HANDLE_DECL(elf_ehdr) sym_ehdr;
+     unsigned long sz;
+-    ELF_PTRVAL_VOID maxva;
+-    ELF_PTRVAL_VOID symbase;
+-    ELF_PTRVAL_VOID symtab_addr;
+-    ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
++    elf_ptrval maxva;
++    elf_ptrval symbase;
++    elf_ptrval symtab_addr;
++    ELF_HANDLE_DECL(elf_shdr) shdr;
+     unsigned i, type;
+     if ( !elf->bsd_symtab_pstart )
+@@ -226,7 +226,7 @@ do {                                            \
+     elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
+                     ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
+                     sz);
+-    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
++    maxva = elf_round_up(elf, (unsigned long)maxva + sz);
+     for ( i = 0; i < elf_shdr_count(elf); i++ )
+     {
+@@ -242,7 +242,7 @@ do {                                            \
+              elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
+              /* Mangled to be based on ELF header location. */
+              elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
+-             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
++             maxva = elf_round_up(elf, (unsigned long)maxva + sz);
+         }
+         old_shdr_p = ELF_HANDLE_PTRVAL(shdr);
+         new_shdr_p = old_shdr_p + elf_uval(elf, elf->ehdr, e_shentsize);
+@@ -297,7 +297,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
+ {
+     ELF_HANDLE_DECL(elf_phdr) phdr;
+     uint64_t i, count, paddr, offset, filesz, memsz;
+-    ELF_PTRVAL_VOID dest;
++    elf_ptrval dest;
+     /*
+      * Let bizarre ELFs write the output image up to twice; this
+      * calculation is just to ensure our copying loop is no worse than
+@@ -334,7 +334,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
+         remain_allow_copy -= memsz;
+         elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n",
+-                __func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
++                __func__, i, dest, (elf_ptrval)(dest + filesz));
+         if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, memsz) != 0 )
+             return -1;
+     }
+@@ -343,7 +343,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
+     return 0;
+ }
+-ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr)
++elf_ptrval elf_get_ptr(struct elf_binary *elf, unsigned long addr)
+ {
+     return ELF_REALPTR2PTRVAL(elf->dest_base) + addr - elf->pstart;
+ }
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 4a83133..e202249 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -171,7 +171,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
+ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index)
+ {
+     uint64_t count = elf_shdr_count(elf);
+-    ELF_PTRVAL_CONST_VOID ptr;
++    elf_ptrval ptr;
+     if ( index >= count )
+         return ELF_INVALID_HANDLE(elf_shdr);
+@@ -185,7 +185,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned ind
+ ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index)
+ {
+     uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
+-    ELF_PTRVAL_CONST_VOID ptr;
++    elf_ptrval ptr;
+     if ( index >= count )
+         return ELF_INVALID_HANDLE(elf_phdr);
+@@ -233,24 +233,24 @@ const char *elf_strfmt(struct elf_binary *elf, elf_ptrval start)
+     return str;
+ }
+-ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
++elf_ptrval elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+     return ELF_IMAGE_BASE(elf) + elf_uval(elf, shdr, sh_offset);
+ }
+-ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
++elf_ptrval elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
+ {
+     return ELF_IMAGE_BASE(elf)
+         + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
+ }
+-ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
++elf_ptrval elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+     return ELF_IMAGE_BASE(elf)
+         + elf_uval(elf, phdr, p_offset);
+ }
+-ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
++elf_ptrval elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+ {
+     return ELF_IMAGE_BASE(elf)
+         + elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
+@@ -258,8 +258,8 @@ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(el
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol)
+ {
+-    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
+-    ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
++    elf_ptrval ptr = elf_section_start(elf, elf->sym_tab);
++    elf_ptrval end = elf_section_end(elf, elf->sym_tab);
+     ELF_HANDLE_DECL(elf_sym) sym;
+     uint64_t info, name;
+     const char *sym_name;
+@@ -283,7 +283,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index)
+ {
+-    ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
++    elf_ptrval ptr = elf_section_start(elf, elf->sym_tab);
+     ELF_HANDLE_DECL(elf_sym) sym;
+     sym = ELF_MAKE_HANDLE(elf_sym, ptr + index * elf_size(elf, sym));
+@@ -295,7 +295,7 @@ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
+     return elf_strval(elf, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note));
+ }
+-ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
++elf_ptrval elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+     unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
+@@ -304,7 +304,7 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
+ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
+ {
+-    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
++    elf_ptrval desc = elf_note_desc(elf, note);
+     unsigned descsz = elf_uval(elf, note, descsz);
+     switch (descsz)
+@@ -322,7 +322,7 @@ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
+ uint64_t elf_note_numeric_array(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note,
+                                 unsigned int unitsz, unsigned int idx)
+ {
+-    ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
++    elf_ptrval desc = elf_note_desc(elf, note);
+     unsigned descsz = elf_uval(elf, note, descsz);
+     if ( descsz % unitsz || idx >= descsz / unitsz )
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index f95fe88..174f8da 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -61,13 +61,8 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+ /*
+  * We abstract away the pointerness of these pointers, replacing
+  * various void*, char* and struct* with the following:
+- *   PTRVAL      A pointer to a byte; one can do pointer arithmetic
++ *   elf_ptrval  A pointer to a byte; one can do pointer arithmetic
+  *               on this.
+- *               This replaces variables which were char*,void*
+- *               and their const versions, so we provide four
+- *               different obsolete declaration macros:
+- *                   ELF_PTRVAL_{,CONST}{VOID,CHAR}
+- *               New code can simply use the elf_ptrval typedef.
+  *   HANDLE      A pointer to a struct.  There is one of these types
+  *               for each pointer type - that is, for each "structname".
+  *               In the arguments to the various HANDLE macros, structname
+@@ -76,8 +71,6 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
+  *               pointers.  In the current code attempts to do so will
+  *               compile, but in the next patch this will become a
+  *               compile error.
+- *               We also provide a second declaration macro for
+- *               pointers which were to const; this is obsolete.
+  */
+ typedef uintptr_t elf_ptrval;
+@@ -85,15 +78,9 @@ typedef uintptr_t elf_ptrval;
+ #define ELF_REALPTR2PTRVAL(realpointer) ((elf_ptrval)(realpointer))
+   /* Converts an actual C pointer into a PTRVAL */
+-#define ELF_HANDLE_DECL_NONCONST(structname) structname##_handle /*obsolete*/
+ #define ELF_HANDLE_DECL(structname)          structname##_handle
+   /* Provides a type declaration for a HANDLE. */
+-#define ELF_PTRVAL_VOID              elf_ptrval /*obsolete*/
+-#define ELF_PTRVAL_CHAR              elf_ptrval /*obsolete*/
+-#define ELF_PTRVAL_CONST_VOID        elf_ptrval /*obsolete*/
+-#define ELF_PTRVAL_CONST_CHAR        elf_ptrval /*obsolete*/
+-
+ #ifdef __XEN__
+ # define ELF_PRPTRVAL "lu"
+   /*
+@@ -124,17 +111,6 @@ typedef uintptr_t elf_ptrval;
+ #define ELF_HANDLE_PTRVAL(handleval)      ((handleval).ptrval)
+   /* Converts a HANDLE to a PTRVAL. */
+-#define ELF_OBSOLETE_VOIDP_CAST /*empty*/
+-  /*
+-   * In some places the old code used to need to
+-   *  - cast away const (the existing code uses const a fair
+-   *    bit but actually sometimes wants to write to its input)
+-   *    from a PTRVAL.
+-   *  - convert an integer representing a pointer to a PTRVAL
+-   * Nowadays all of these re uintptr_ts so there is no const problem
+-   * and no need for any casting.
+-   */
+-
+ #define ELF_UNSAFE_PTR(ptrval) ((void*)(elf_ptrval)(ptrval))
+   /*
+    * Turns a PTRVAL into an actual C pointer.  Before this is done
+@@ -212,7 +188,7 @@ struct elf_binary {
+     char data;
+     ELF_HANDLE_DECL(elf_ehdr) ehdr;
+-    ELF_PTRVAL_CONST_CHAR sec_strtab;
++    elf_ptrval sec_strtab;
+     ELF_HANDLE_DECL(elf_shdr) sym_tab;
+     uint64_t sym_strtab;
+@@ -290,7 +266,7 @@ struct elf_binary {
+    * str should be a HANDLE.
+    */
+-uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
++uint64_t elf_access_unsigned(struct elf_binary *elf, elf_ptrval ptr,
+                              uint64_t offset, size_t size);
+   /* Reads a field at arbitrary offset and alignemnt */
+@@ -342,17 +318,17 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned ind
+ ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index);
+ const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
+-ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+-ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
++elf_ptrval elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
++elf_ptrval elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
+-ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+-ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
++elf_ptrval elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
++elf_ptrval elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
+ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index);
+ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
+-ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
++elf_ptrval elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
+ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
+                                 unsigned int unitsz, unsigned int idx);
+@@ -391,7 +367,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback*,
+ void elf_parse_binary(struct elf_binary *elf);
+ elf_errorstatus elf_load_binary(struct elf_binary *elf);
+-ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr);
++elf_ptrval elf_get_ptr(struct elf_binary *elf, unsigned long addr);
+ uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
+ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
+@@ -426,9 +402,9 @@ struct xen_elfnote {
+ struct elf_dom_parms {
+     /* raw */
+-    ELF_PTRVAL_CONST_CHAR guest_info;
+-    ELF_PTRVAL_CONST_VOID elf_note_start;
+-    ELF_PTRVAL_CONST_VOID elf_note_end;
++    elf_ptrval guest_info;
++    elf_ptrval elf_note_start;
++    elf_ptrval elf_note_end;
+     struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
+     /* parsed */
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0018-libxc-Add-range-checking-to-xc_dom_binloader.patch b/SOURCES/xsa55-4.2-0018-libxc-Add-range-checking-to-xc_dom_binloader.patch
new file mode 100644 (file)
index 0000000..74774ec
--- /dev/null
@@ -0,0 +1,69 @@
+From b06e277b1fc08c7da3befeb3ac3950e1d941585d Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 18/23] libxc: Add range checking to xc_dom_binloader
+
+This is a simple binary image loader with its own metadata format.
+However, it is too careless with image-supplied values.
+
+Add the following checks:
+
+ * That the image is bigger than the metadata table; otherwise the
+   pointer arithmetic to calculate the metadata table location may
+   yield undefined and dangerous values.
+
+ * When clamping the end of the region to search, that we do not
+   calculate pointers beyond the end of the image.  The C
+   specification does not permit this and compilers are becoming ever
+   more determined to miscompile code when they can "prove" various
+   falsehoods based on assertions from the C spec.
+
+ * That the supplied image is big enough for the text we are allegedly
+   copying from it.  Otherwise we might have a read overrun and copy
+   the results (perhaps a lot of secret data) into the guest.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_dom_binloader.c |   15 +++++++++++++--
+ 1 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
+index bde93f7..8596a28 100644
+--- a/tools/libxc/xc_dom_binloader.c
++++ b/tools/libxc/xc_dom_binloader.c
+@@ -123,10 +123,13 @@ static struct xen_bin_image_table *find_table(struct xc_dom_image *dom)
+     uint32_t *probe_ptr;
+     uint32_t *probe_end;
++    if ( dom->kernel_size < sizeof(*table) )
++        return NULL;
+     probe_ptr = dom->kernel_blob;
+-    probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table);
+-    if ( (void*)probe_end > (dom->kernel_blob + 8192) )
++    if ( dom->kernel_size > (8192 + sizeof(*table)) )
+         probe_end = dom->kernel_blob + 8192;
++    else
++        probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table);
+     for ( table = NULL; probe_ptr < probe_end; probe_ptr++ )
+     {
+@@ -282,6 +285,14 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
+         return -EINVAL;
+     }
++    if ( image_size < skip ||
++         image_size - skip < text_size )
++    {
++        DOMPRINTF("%s: image is too small for declared text size",
++                  __FUNCTION__);
++        return -EINVAL;
++    }
++
+     memcpy(dest, image + skip, text_size);
+     memset(dest + text_size, 0, bss_size);
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0019-libxc-check-failure-of-xc_dom_-_to_ptr-xc_map_foreig.patch b/SOURCES/xsa55-4.2-0019-libxc-check-failure-of-xc_dom_-_to_ptr-xc_map_foreig.patch
new file mode 100644 (file)
index 0000000..6107620
--- /dev/null
@@ -0,0 +1,382 @@
+From 77c0829fa751f052f7b8ec08287aef6e7ba97bc5 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 19/23] libxc: check failure of xc_dom_*_to_ptr, xc_map_foreign_range
+
+The return values from xc_dom_*_to_ptr and xc_map_foreign_range are
+sometimes dereferenced, or subjected to pointer arithmetic, without
+checking whether the relevant function failed and returned NULL.
+
+Add an appropriate error check at every call site.
+
+Changes in the 4.2 backport of this series:
+* Fix tools/libxc/xc_dom_x86.c:setup_pgtables_x86_32.
+* Fix tools/libxc/xc_dom_ia64.c:start_info_ia64.
+* Fix tools/libxc/ia64/xc_ia64_dom_fwloader.c:xc_dom_load_fw_kernel.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/ia64/xc_ia64_dom_fwloader.c |    2 +
+ tools/libxc/xc_dom_binloader.c          |    6 +++
+ tools/libxc/xc_dom_core.c               |    6 +++
+ tools/libxc/xc_dom_elfloader.c          |   13 +++++++
+ tools/libxc/xc_dom_ia64.c               |    6 +++
+ tools/libxc/xc_dom_x86.c                |   55 +++++++++++++++++++++++++++++++
+ tools/libxc/xc_domain_restore.c         |   27 +++++++++++++++
+ tools/libxc/xc_offline_page.c           |    5 +++
+ 8 files changed, 120 insertions(+), 0 deletions(-)
+
+diff --git a/tools/libxc/ia64/xc_ia64_dom_fwloader.c b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
+index cdf3333..dbd3349 100644
+--- a/tools/libxc/ia64/xc_ia64_dom_fwloader.c
++++ b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
+@@ -60,6 +60,8 @@ static int xc_dom_load_fw_kernel(struct xc_dom_image *dom)
+     unsigned long i;
+     dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
++    if ( dest == NULL )
++        return -1;
+     memcpy(dest, dom->kernel_blob, FW_SIZE);
+     /* Synchronize cache.  */
+diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
+index 8596a28..553b366 100644
+--- a/tools/libxc/xc_dom_binloader.c
++++ b/tools/libxc/xc_dom_binloader.c
+@@ -277,6 +277,12 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
+     DOMPRINTF("  bss_size:  0x%" PRIx32 "", bss_size);
+     dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
++    if ( dest == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart)"
++                  " => NULL", __FUNCTION__);
++        return -EINVAL;
++    }
+     if ( dest_size < text_size ||
+          dest_size - text_size < bss_size )
+diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
+index 8913e41..a54ddae 100644
+--- a/tools/libxc/xc_dom_core.c
++++ b/tools/libxc/xc_dom_core.c
+@@ -868,6 +868,12 @@ int xc_dom_build_image(struct xc_dom_image *dom)
+                                   ramdisklen) != 0 )
+             goto err;
+         ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg);
++        if ( ramdiskmap == NULL )
++        {
++            DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg) => NULL",
++                      __FUNCTION__);
++            goto err;
++        }
+         if ( unziplen )
+         {
+             if ( xc_dom_do_gunzip(dom->xch,
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 9fc4b94..61b5798 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -139,6 +139,12 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
+             return 0;
+         size = dom->kernel_seg.vend - dom->bsd_symtab_start;
+         hdr_ptr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
++        if ( hdr_ptr == NULL )
++        {
++            DOMPRINTF("%s/load: xc_dom_vaddr_to_ptr(dom,dom->bsd_symtab_start"
++                      " => NULL", __FUNCTION__);
++            return -1;
++        }
+         elf->caller_xdest_base = hdr_ptr;
+         elf->caller_xdest_size = allow_size;
+         hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
+@@ -384,7 +390,14 @@ static elf_errorstatus xc_dom_load_elf_kernel(struct xc_dom_image *dom)
+     xen_pfn_t pages;
+     elf->dest_base = xc_dom_seg_to_ptr_pages(dom, &dom->kernel_seg, &pages);
++    if ( elf->dest_base == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom,dom->kernel_seg)"
++                  " => NULL", __FUNCTION__);
++        return -1;
++    }
+     elf->dest_size = pages * XC_DOM_PAGE_SIZE(dom);
++
+     rc = elf_load_binary(elf);
+     if ( rc < 0 )
+     {
+diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
+index dcd1523..7c0eff1 100644
+--- a/tools/libxc/xc_dom_ia64.c
++++ b/tools/libxc/xc_dom_ia64.c
+@@ -60,6 +60,12 @@ int start_info_ia64(struct xc_dom_image *dom)
+     DOMPRINTF_CALLED(dom->xch);
++    if ( start_info == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
++        return -1; /* our caller throws away our return value :-/ */
++    }
++
+     memset(start_info, 0, sizeof(*start_info));
+     sprintf(start_info->magic, dom->guest_type);
+     start_info->flags = dom->flags;
+diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
+index 0cf1687..75d6b83 100644
+--- a/tools/libxc/xc_dom_x86.c
++++ b/tools/libxc/xc_dom_x86.c
+@@ -144,6 +144,9 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
+     xen_vaddr_t addr;
+     xen_pfn_t pgpfn;
++    if ( l2tab == NULL )
++        goto pfn_error;
++
+     for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
+           addr += PAGE_SIZE_X86 )
+     {
+@@ -151,6 +154,8 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
+         {
+             /* get L1 tab, make L2 entry */
+             l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
++            if ( l1tab == NULL )
++                goto pfn_error;
+             l2off = l2_table_offset_i386(addr);
+             l2tab[l2off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
+@@ -169,6 +174,11 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
+             l1tab = NULL;
+     }
+     return 0;
++
++pfn_error:
++    xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
++                 "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
++    return -EINVAL;
+ }
+ /*
+@@ -219,6 +229,12 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
+         goto out;
+     l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
++    if ( l3tab == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_pfn_to_ptr(dom, l3pfn, 1) => NULL",
++                  __FUNCTION__);
++        return l3mfn; /* our one call site will call xc_dom_panic and fail */
++    }
+     memset(l3tab, 0, XC_DOM_PAGE_SIZE(dom));
+     DOMPRINTF("%s: successfully relocated L3 below 4G. "
+@@ -262,6 +278,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
+     }
+     l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
++    if ( l3tab == NULL )
++        goto pfn_error;
+     for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
+           addr += PAGE_SIZE_X86 )
+@@ -270,6 +288,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
+         {
+             /* get L2 tab, make L3 entry */
+             l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
++            if ( l2tab == NULL )
++                goto pfn_error;
+             l3off = l3_table_offset_pae(addr);
+             l3tab[l3off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+@@ -280,6 +300,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
+         {
+             /* get L1 tab, make L2 entry */
+             l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
++            if ( l1tab == NULL )
++                goto pfn_error;
+             l2off = l2_table_offset_pae(addr);
+             l2tab[l2off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
+@@ -306,6 +328,11 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
+         l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+     }
+     return 0;
++
++pfn_error:
++    xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
++                 "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
++    return -EINVAL;
+ }
+ #undef L1_PROT
+@@ -344,6 +371,9 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
+     uint64_t addr;
+     xen_pfn_t pgpfn;
++    if ( l4tab == NULL )
++        goto pfn_error;
++
+     for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
+           addr += PAGE_SIZE_X86 )
+     {
+@@ -351,6 +381,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
+         {
+             /* get L3 tab, make L4 entry */
+             l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
++            if ( l3tab == NULL )
++                goto pfn_error;
+             l4off = l4_table_offset_x86_64(addr);
+             l4tab[l4off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT;
+@@ -361,6 +393,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
+         {
+             /* get L2 tab, make L3 entry */
+             l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
++            if ( l2tab == NULL )
++                goto pfn_error;
+             l3off = l3_table_offset_x86_64(addr);
+             l3tab[l3off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
+@@ -373,6 +407,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
+         {
+             /* get L1 tab, make L2 entry */
+             l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
++            if ( l1tab == NULL )
++                goto pfn_error;
+             l2off = l2_table_offset_x86_64(addr);
+             l2tab[l2off] =
+                 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
+@@ -393,6 +429,11 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
+             l1tab = NULL;
+     }
+     return 0;
++
++pfn_error:
++    xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
++                 "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
++    return -EINVAL;
+ }
+ #undef L1_PROT
+@@ -410,6 +451,8 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
+     if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size) )
+         return -1;
+     dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
++    if ( dom->p2m_guest == NULL )
++        return -1;
+     /* allocate special pages */
+     dom->start_info_pfn = xc_dom_alloc_page(dom, "start info");
+@@ -434,6 +477,12 @@ static int start_info_x86_32(struct xc_dom_image *dom)
+     DOMPRINTF_CALLED(dom->xch);
++    if ( start_info == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
++        return -1; /* our caller throws away our return value :-/ */
++    }
++
+     memset(start_info, 0, sizeof(*start_info));
+     strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
+     start_info->magic[sizeof(start_info->magic) - 1] = '\0';
+@@ -474,6 +523,12 @@ static int start_info_x86_64(struct xc_dom_image *dom)
+     DOMPRINTF_CALLED(dom->xch);
++    if ( start_info == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
++        return -1; /* our caller throws away our return value :-/ */
++    }
++
+     memset(start_info, 0, sizeof(*start_info));
+     strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
+     start_info->magic[sizeof(start_info->magic) - 1] = '\0';
+diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
+index b4c0b10..3994f8f 100644
+--- a/tools/libxc/xc_domain_restore.c
++++ b/tools/libxc/xc_domain_restore.c
+@@ -1556,6 +1556,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
+                     mfn = ctx->p2m[pfn];
+                     buf = xc_map_foreign_range(xch, dom, PAGE_SIZE,
+                                                PROT_READ | PROT_WRITE, mfn);
++                    if ( buf == NULL )
++                    {
++                        ERROR("xc_map_foreign_range for generation id"
++                              " buffer failed");
++                        goto out;
++                    }
+                     generationid = *(unsigned long long *)(buf + offset);
+                     *(unsigned long long *)(buf + offset) = generationid + 1;
+@@ -1713,6 +1719,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
+                 l3tab = (uint64_t *)
+                     xc_map_foreign_range(xch, dom, PAGE_SIZE,
+                                          PROT_READ, ctx->p2m[i]);
++                if ( l3tab == NULL )
++                {
++                    PERROR("xc_map_foreign_range failed (for l3tab)");
++                    goto out;
++                }
+                 for ( j = 0; j < 4; j++ )
+                     l3ptes[j] = l3tab[j];
+@@ -1739,6 +1750,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
+                 l3tab = (uint64_t *)
+                     xc_map_foreign_range(xch, dom, PAGE_SIZE,
+                                          PROT_READ | PROT_WRITE, ctx->p2m[i]);
++                if ( l3tab == NULL )
++                {
++                    PERROR("xc_map_foreign_range failed (for l3tab, 2nd)");
++                    goto out;
++                }
+                 for ( j = 0; j < 4; j++ )
+                     l3tab[j] = l3ptes[j];
+@@ -1909,6 +1925,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
+             SET_FIELD(ctxt, user_regs.edx, mfn);
+             start_info = xc_map_foreign_range(
+                 xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
++            if ( start_info == NULL )
++            {
++                PERROR("xc_map_foreign_range failed (for start_info)");
++                goto out;
++            }
++
+             SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
+             SET_FIELD(start_info, shared_info, shared_info_frame<<PAGE_SHIFT);
+             SET_FIELD(start_info, flags, 0);
+@@ -2056,6 +2078,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
+     /* Restore contents of shared-info page. No checking needed. */
+     new_shared_info = xc_map_foreign_range(
+         xch, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
++    if ( new_shared_info == NULL )
++    {
++        PERROR("xc_map_foreign_range failed (for new_shared_info)");
++        goto out;
++    }
+     /* restore saved vcpu_info and arch specific info */
+     MEMCPY_FIELD(new_shared_info, old_shared_info, vcpu_info);
+diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
+index 089a361..36b9812 100644
+--- a/tools/libxc/xc_offline_page.c
++++ b/tools/libxc/xc_offline_page.c
+@@ -714,6 +714,11 @@ int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
+         new_p = xc_map_foreign_range(xch, domid, PAGE_SIZE,
+                                      PROT_READ|PROT_WRITE, new_mfn);
++        if ( new_p == NULL )
++        {
++            ERROR("failed to map new_p for copy, guest may be broken?");
++            goto failed;
++        }
+         memcpy(new_p, backup, PAGE_SIZE);
+         munmap(new_p, PAGE_SIZE);
+         mops.arg1.mfn = new_mfn;
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0020-libxc-check-return-values-from-malloc.patch b/SOURCES/xsa55-4.2-0020-libxc-check-return-values-from-malloc.patch
new file mode 100644 (file)
index 0000000..8060a39
--- /dev/null
@@ -0,0 +1,272 @@
+From 8dc90d163650ce8aa36ae0b46debab83cc61edb6 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 20/23] libxc: check return values from malloc
+
+A sufficiently malformed input to libxc (such as a malformed input ELF
+or other guest-controlled data) might cause one of libxc's malloc() to
+fail.  In this case we need to make sure we don't dereference or do
+pointer arithmetic on the result.
+
+Search for all occurrences of \b(m|c|re)alloc in libxc, and all
+functions which call them, and add appropriate error checking where
+missing.
+
+This includes the functions xc_dom_malloc*, which now print a message
+when they fail so that callers don't have to do so.
+
+The function xc_cpuid_to_str wasn't provided with a sane return value
+and has a pretty strange API, which now becomes a little stranger.
+There are no in-tree callers.
+
+Changes in the Xen 4.2 version of this series:
+* No need to fix code relating to ARM.
+* No need to fix code relating to superpage support.
+* Additionally fix `dom->p2m_host = xc_dom_malloc...' in xc_dom_ia64.c.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_cpuid_x86.c      |   20 ++++++++++++++++++--
+ tools/libxc/xc_dom_core.c       |   13 +++++++++++++
+ tools/libxc/xc_dom_elfloader.c  |    2 ++
+ tools/libxc/xc_dom_ia64.c       |    6 ++++++
+ tools/libxc/xc_dom_x86.c        |    3 +++
+ tools/libxc/xc_domain_restore.c |    5 +++++
+ tools/libxc/xc_linux_osdep.c    |    4 ++++
+ tools/libxc/xc_private.c        |    2 ++
+ tools/libxc/xenctrl.h           |    2 +-
+ 9 files changed, 54 insertions(+), 3 deletions(-)
+
+diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
+index 0882ce6..da435ce 100644
+--- a/tools/libxc/xc_cpuid_x86.c
++++ b/tools/libxc/xc_cpuid_x86.c
+@@ -589,6 +589,8 @@ static int xc_cpuid_do_domctl(
+ static char *alloc_str(void)
+ {
+     char *s = malloc(33);
++    if ( s == NULL )
++        return s;
+     memset(s, 0, 33);
+     return s;
+ }
+@@ -600,6 +602,8 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs)
+     for ( i = 0; i < 4; i++ )
+     {
+         strs[i] = alloc_str();
++        if ( strs[i] == NULL )
++            continue;
+         for ( j = 0; j < 32; j++ )
+             strs[i][j] = !!((regs[i] & (1U << (31 - j)))) ? '1' : '0';
+     }
+@@ -680,7 +684,7 @@ int xc_cpuid_check(
+     const char **config,
+     char **config_transformed)
+ {
+-    int i, j;
++    int i, j, rc;
+     unsigned int regs[4];
+     memset(config_transformed, 0, 4 * sizeof(*config_transformed));
+@@ -692,6 +696,11 @@ int xc_cpuid_check(
+         if ( config[i] == NULL )
+             continue;
+         config_transformed[i] = alloc_str();
++        if ( config_transformed[i] == NULL )
++        {
++            rc = -ENOMEM;
++            goto fail_rc;
++        }
+         for ( j = 0; j < 32; j++ )
+         {
+             unsigned char val = !!((regs[i] & (1U << (31 - j))));
+@@ -708,12 +717,14 @@ int xc_cpuid_check(
+     return 0;
+  fail:
++    rc = -EPERM;
++ fail_rc:
+     for ( i = 0; i < 4; i++ )
+     {
+         free(config_transformed[i]);
+         config_transformed[i] = NULL;
+     }
+-    return -EPERM;
++    return rc;
+ }
+ /*
+@@ -758,6 +769,11 @@ int xc_cpuid_set(
+         }
+         
+         config_transformed[i] = alloc_str();
++        if ( config_transformed[i] == NULL )
++        {
++            rc = -ENOMEM;
++            goto fail;
++        }
+         for ( j = 0; j < 32; j++ )
+         {
+diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
+index a54ddae..3cbf9f7 100644
+--- a/tools/libxc/xc_dom_core.c
++++ b/tools/libxc/xc_dom_core.c
+@@ -120,9 +120,17 @@ void *xc_dom_malloc(struct xc_dom_image *dom, size_t size)
+ {
+     struct xc_dom_mem *block;
++    if ( size > SIZE_MAX - sizeof(*block) )
++    {
++        DOMPRINTF("%s: unreasonable allocation size", __FUNCTION__);
++        return NULL;
++    }
+     block = malloc(sizeof(*block) + size);
+     if ( block == NULL )
++    {
++        DOMPRINTF("%s: allocation failed", __FUNCTION__);
+         return NULL;
++    }
+     memset(block, 0, sizeof(*block) + size);
+     block->next = dom->memblocks;
+     dom->memblocks = block;
+@@ -138,7 +146,10 @@ void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
+     block = malloc(sizeof(*block));
+     if ( block == NULL )
++    {
++        DOMPRINTF("%s: allocation failed", __FUNCTION__);
+         return NULL;
++    }
+     memset(block, 0, sizeof(*block));
+     block->mmap_len = size;
+     block->mmap_ptr = mmap(NULL, block->mmap_len,
+@@ -146,6 +157,7 @@ void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
+                            -1, 0);
+     if ( block->mmap_ptr == MAP_FAILED )
+     {
++        DOMPRINTF("%s: mmap failed", __FUNCTION__);
+         free(block);
+         return NULL;
+     }
+@@ -202,6 +214,7 @@ void *xc_dom_malloc_filemap(struct xc_dom_image *dom,
+         close(fd);
+     if ( block != NULL )
+         free(block);
++    DOMPRINTF("%s: failed (on file `%s')", __FUNCTION__, filename);
+     return NULL;
+ }
+diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
+index 61b5798..be58276 100644
+--- a/tools/libxc/xc_dom_elfloader.c
++++ b/tools/libxc/xc_dom_elfloader.c
+@@ -329,6 +329,8 @@ static elf_errorstatus xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
+         return rc;
+     elf = xc_dom_malloc(dom, sizeof(*elf));
++    if ( elf == NULL )
++        return -1;
+     dom->private_loader = elf;
+     rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
+     xc_elf_set_logfile(dom->xch, elf, 1);
+diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
+index 7c0eff1..076821c 100644
+--- a/tools/libxc/xc_dom_ia64.c
++++ b/tools/libxc/xc_dom_ia64.c
+@@ -188,6 +188,12 @@ int arch_setup_meminit(struct xc_dom_image *dom)
+     /* setup initial p2m */
+     dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr);
++    if ( dom->p2m_host == NULL )
++    {
++        DOMPRINTF("%s: xc_dom_malloc failed for p2m_host",
++                  __FUNCTION__);
++        return -1;
++    }
+     for ( pfn = 0; pfn < nbr; pfn++ )
+         dom->p2m_host[pfn] = start + pfn;
+diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
+index 75d6b83..448d9a1 100644
+--- a/tools/libxc/xc_dom_x86.c
++++ b/tools/libxc/xc_dom_x86.c
+@@ -780,6 +780,9 @@ int arch_setup_meminit(struct xc_dom_image *dom)
+     }
+     dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
++    if ( dom->p2m_host == NULL )
++        return -EINVAL;
++
+     if ( dom->superpages )
+     {
+         int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
+diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
+index 3994f8f..f9ed6b2 100644
+--- a/tools/libxc/xc_domain_restore.c
++++ b/tools/libxc/xc_domain_restore.c
+@@ -1180,6 +1180,11 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx,
+     /* Map relevant mfns */
+     pfn_err = calloc(j, sizeof(*pfn_err));
++    if ( pfn_err == NULL )
++    {
++        PERROR("allocation for pfn_err failed");
++        return -1;
++    }
+     region_base = xc_map_foreign_bulk(
+         xch, dom, PROT_WRITE, region_mfn, pfn_err, j);
+diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c
+index 787e742..98e041c 100644
+--- a/tools/libxc/xc_linux_osdep.c
++++ b/tools/libxc/xc_linux_osdep.c
+@@ -378,6 +378,8 @@ static void *linux_privcmd_map_foreign_range(xc_interface *xch, xc_osdep_handle
+     num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
+     arr = calloc(num, sizeof(xen_pfn_t));
++    if ( arr == NULL )
++        return NULL;
+     for ( i = 0; i < num; i++ )
+         arr[i] = mfn + i;
+@@ -402,6 +404,8 @@ static void *linux_privcmd_map_foreign_ranges(xc_interface *xch, xc_osdep_handle
+     num_per_entry = chunksize >> XC_PAGE_SHIFT;
+     num = num_per_entry * nentries;
+     arr = calloc(num, sizeof(xen_pfn_t));
++    if ( arr == NULL )
++        return NULL;
+     for ( i = 0; i < nentries; i++ )
+         for ( j = 0; j < num_per_entry; j++ )
+diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
+index 3e03a91..848ceed 100644
+--- a/tools/libxc/xc_private.c
++++ b/tools/libxc/xc_private.c
+@@ -771,6 +771,8 @@ const char *xc_strerror(xc_interface *xch, int errcode)
+         errbuf = pthread_getspecific(errbuf_pkey);
+         if (errbuf == NULL) {
+             errbuf = malloc(XS_BUFSIZE);
++            if ( errbuf == NULL )
++                return "(failed to allocate errbuf)";
+             pthread_setspecific(errbuf_pkey, errbuf);
+         }
+diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
+index b7741ca..8952048 100644
+--- a/tools/libxc/xenctrl.h
++++ b/tools/libxc/xenctrl.h
+@@ -1778,7 +1778,7 @@ int xc_cpuid_set(xc_interface *xch,
+ int xc_cpuid_apply_policy(xc_interface *xch,
+                           domid_t domid);
+ void xc_cpuid_to_str(const unsigned int *regs,
+-                     char **strs);
++                     char **strs); /* some strs[] may be NULL if ENOMEM */
+ int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
+ #endif
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0021-libxc-range-checks-in-xc_dom_p2m_host-and-_guest.patch b/SOURCES/xsa55-4.2-0021-libxc-range-checks-in-xc_dom_p2m_host-and-_guest.patch
new file mode 100644 (file)
index 0000000..0baf7f5
--- /dev/null
@@ -0,0 +1,47 @@
+From 052a689aa526ca51fd70528d4b0f83dfb2de99c1 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 21/23] libxc: range checks in xc_dom_p2m_host and _guest
+
+These functions take guest pfns and look them up in the p2m.  They did
+no range checking.
+
+However, some callers, notably xc_dom_boot.c:setup_hypercall_page want
+to pass untrusted guest-supplied value(s).  It is most convenient to
+detect this here and return INVALID_MFN.
+
+This is part of the fix to a security issue, XSA-55.
+
+Changes from Xen 4.2 version of this patch:
+* 4.2 lacks dom->rambase_pfn, so don't add/subtract/check it.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+---
+ tools/libxc/xc_dom.h |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
+index 0161459..d801f66 100644
+--- a/tools/libxc/xc_dom.h
++++ b/tools/libxc/xc_dom.h
+@@ -331,6 +331,8 @@ static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn)
+ {
+     if (dom->shadow_enabled)
+         return pfn;
++    if (pfn >= dom->total_pages)
++        return INVALID_MFN;
+     return dom->p2m_host[pfn];
+ }
+@@ -339,6 +341,8 @@ static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom,
+ {
+     if (xc_dom_feature_translated(dom))
+         return pfn;
++    if (pfn >= dom->total_pages)
++        return INVALID_MFN;
+     return dom->p2m_host[pfn];
+ }
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0022-libxc-check-blob-size-before-proceeding-in-xc_dom_ch.patch b/SOURCES/xsa55-4.2-0022-libxc-check-blob-size-before-proceeding-in-xc_dom_ch.patch
new file mode 100644 (file)
index 0000000..fba1f4d
--- /dev/null
@@ -0,0 +1,31 @@
+From 2a548e22915535ac13694eb38222903bca7245e3 Mon Sep 17 00:00:00 2001
+From: Matthew Daley <mattjd@gmail.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 22/23] libxc: check blob size before proceeding in xc_dom_check_gzip
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Matthew Daley <mattjd@gmail.com>
+---
+ tools/libxc/xc_dom_core.c |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
+index 3cbf9f7..f8d1b08 100644
+--- a/tools/libxc/xc_dom_core.c
++++ b/tools/libxc/xc_dom_core.c
+@@ -284,6 +284,11 @@ size_t xc_dom_check_gzip(xc_interface *xch, void *blob, size_t ziplen)
+     unsigned char *gzlen;
+     size_t unziplen;
++    if ( ziplen < 6 )
++        /* Too small.  We need (i.e. the subsequent code relies on)
++         * 2 bytes for the magic number plus 4 bytes length. */
++        return 0;
++
+     if ( strncmp(blob, "\037\213", 2) )
+         /* not gzipped */
+         return 0;
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa55-4.2-0023-libxc-Better-range-check-in-xc_dom_alloc_segment.patch b/SOURCES/xsa55-4.2-0023-libxc-Better-range-check-in-xc_dom_alloc_segment.patch
new file mode 100644 (file)
index 0000000..896e4f3
--- /dev/null
@@ -0,0 +1,33 @@
+From d21d36e84354c04638b60a739a5f7c3d9f8adaf8 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Fri, 14 Jun 2013 16:43:19 +0100
+Subject: [PATCH 23/23] libxc: Better range check in xc_dom_alloc_segment
+
+If seg->pfn is too large, the arithmetic in the range check might
+overflow, defeating the range check.
+
+This is part of the fix to a security issue, XSA-55.
+
+Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ tools/libxc/xc_dom_core.c |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
+index f8d1b08..e79e38d 100644
+--- a/tools/libxc/xc_dom_core.c
++++ b/tools/libxc/xc_dom_core.c
+@@ -509,7 +509,8 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
+     seg->vstart = start;
+     seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
+-    if ( pages > dom->total_pages || /* double test avoids overflow probs */
++    if ( pages > dom->total_pages || /* multiple test avoids overflow probs */
++         seg->pfn > dom->total_pages ||
+          pages > dom->total_pages - seg->pfn)
+     {
+         xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
+-- 
+1.7.2.5
+
diff --git a/SOURCES/xsa56.patch b/SOURCES/xsa56.patch
new file mode 100644 (file)
index 0000000..1368ac3
--- /dev/null
@@ -0,0 +1,50 @@
+libxc: limit cpu values when setting vcpu affinity
+
+When support for pinning more than 64 cpus was added, check for cpu
+out-of-range values was removed. This can lead to subsequent
+out-of-bounds cpumap array accesses in case the cpu number is higher
+than the actual count.
+
+This patch returns the check.
+
+This is CVE-2013-2072 / XSA-56
+
+Signed-off-by: Petr Matousek <pmatouse@redhat.com>
+
+diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
+index e220f68..e611b24 100644
+--- a/tools/python/xen/lowlevel/xc/xc.c
++++ b/tools/python/xen/lowlevel/xc/xc.c
+@@ -228,6 +228,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
+     int vcpu = 0, i;
+     xc_cpumap_t cpumap;
+     PyObject *cpulist = NULL;
++    int nr_cpus;
+     static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
+@@ -235,6 +236,10 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
+                                       &dom, &vcpu, &cpulist) )
+         return NULL;
++    nr_cpus = xc_get_max_cpus(self->xc_handle);
++    if ( nr_cpus == 0 )
++        return pyxc_error_to_exception(self->xc_handle);
++
+     cpumap = xc_cpumap_alloc(self->xc_handle);
+     if(cpumap == NULL)
+         return pyxc_error_to_exception(self->xc_handle);
+@@ -244,6 +249,13 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
+         for ( i = 0; i < PyList_Size(cpulist); i++ ) 
+         {
+             long cpu = PyInt_AsLong(PyList_GetItem(cpulist, i));
++            if ( cpu < 0 || cpu >= nr_cpus )
++            {
++                free(cpumap);
++                errno = EINVAL;
++                PyErr_SetFromErrno(xc_error_obj);
++                return NULL;
++            }
+             cpumap[cpu / 8] |= 1 << (cpu % 8);
+         }
+     }
diff --git a/SPECS/xen.spec b/SPECS/xen.spec
new file mode 100644 (file)
index 0000000..60cfd2b
--- /dev/null
@@ -0,0 +1,2007 @@
+%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
+# Build ocaml bits unless rpmbuild was run with --without ocaml 
+# or ocamlopt is missing (the xen makefile doesn't build ocaml bits if it isn't there)
+%define with_ocaml  1
+%define build_ocaml %(test -x %{_bindir}/ocamlopt && echo %{with_ocaml} || echo 0)
+# build an efi boot image (where supported) unless rpmbuild was run with
+# --without efi
+%define build_efi %{?_without_efi: 0} %{?!_without_efi: 1}
+# xen only supports efi boot images on x86_64
+
+#for el6
+%define build_efi 0
+%define with_sysv 1
+%define with_systemd 0
+
+# Hypervisor ABI
+%define hv_abi  4.2
+
+Summary: Xen is a virtual machine monitor
+Name:    xen
+Version: 4.2.2
+Release: 22%{?dist}
+Group:   Development/Libraries
+License: GPLv2+ and LGPLv2+ and BSD
+URL:     http://xen.org/
+Source0: http://bits.xensource.com/oss-xen/release/%{version}/xen-%{version}.tar.gz
+Source1: %{name}.modules
+Source2: %{name}.logrotate
+# used by stubdoms
+Source10: lwip-1.3.0.tar.gz
+Source11: newlib-1.16.0.tar.gz
+Source12: zlib-1.2.3.tar.gz
+Source13: pciutils-2.2.9.tar.bz2
+Source14: grub-0.97.tar.gz
+# init.d bits
+Source20: init.xenstored
+Source21: init.xenconsoled
+Source22: init.blktapctrl
+Source23: init.xend
+# sysconfig bits
+Source30: sysconfig.xenstored
+Source31: sysconfig.xenconsoled
+Source32: sysconfig.blktapctrl
+Source33: sysconfig.xend
+# systemd bits
+Source40: proc-xen.mount
+Source41: var-lib-xenstored.mount
+Source42: xenstored.service
+Source43: blktapctrl.service
+Source44: xend.service
+Source45: xenconsoled.service
+Source46: xen-watchdog.service
+Source47: xendomains.service
+Source48: libexec.xendomains
+Source49: tmpfiles.d.xen.conf
+
+Source100: qemu-xen-4.2.2.tar.gz
+Source101: blktap-9960138790b9d3610b12acd153bba20235efa4f5.tar.gz
+
+Patch1: xen-initscript.patch
+Patch4: xen-dumpdir.patch
+Patch5: xen-net-disable-iptables-on-bridge.patch
+
+Patch28: pygrubfix.patch
+Patch34: xend.catchbt.patch
+Patch35: xend-pci-loop.patch
+Patch39: xend.selinux.fixes.patch
+Patch46: xen.use.fedora.seabios.patch
+Patch47: xen.use.fedora.ipxe.patch
+
+Patch49: xen.fedora.efi.build.patch
+Patch55: qemu-xen.trad.buildfix.patch
+Patch56: xen.fedora19.buildfix.patch
+
+Patch64: xl.list.-l.format.patch
+Patch65: xen.git-9c23a1d0eb7a6b5e3273d527cfd7960838fbfee6.patch
+Patch66: xsa45-4.2-01-vcpu-destroy-pagetables-preemptible.patch
+Patch67: xsa45-4.2-02-new-guest-cr3-preemptible.patch
+Patch68: xsa45-4.2-03-new-user-base-preemptible.patch
+Patch69: xsa45-4.2-04-vcpu-reset-preemptible.patch
+Patch70: xsa45-4.2-05-set-info-guest-preemptible.patch
+Patch71: xsa45-4.2-06-unpin-preemptible.patch
+Patch72: xsa45-4.2-07-mm-error-paths-preemptible.patch
+Patch73: xsa49-4.2.patch
+Patch74: xsa56.patch
+Patch75: xsa46-regression-xend-xm.patch
+Patch92: xsa52-4.2-unstable.patch
+Patch93: xsa53-4.2.patch
+Patch94: xsa54.patch
+Patch100: xen-configure-xend.patch
+Patch105: xsa48-4.2.patch
+Patch106: xen-xl-autoballon-with-auto-option.patch
+Patch107: xen-xl-set-autoballon-default-auto.patch
+Patch108: xsa55-4.2-0001-libelf-abolish-libelf-relocate.c.patch
+Patch109: xsa55-4.2-0002-libxc-introduce-xc_dom_seg_to_ptr_pages.patch
+Patch110: xsa55-4.2-0003-libxc-Fix-range-checking-in-xc_dom_pfn_to_ptr-etc.patch
+Patch111: xsa55-4.2-0004-libelf-add-struct-elf_binary-parameter-to-elf_load_i.patch
+Patch112: xsa55-4.2-0005-libelf-abolish-elf_sval-and-elf_access_signed.patch
+Patch113: xsa55-4.2-0006-libelf-move-include-of-asm-guest_access.h-to-top-of-.patch
+Patch114: xsa55-4.2-0007-libelf-xc_dom_load_elf_symtab-Do-not-use-syms-uninit.patch
+Patch115: xsa55-4.2-0008-libelf-introduce-macros-for-memory-access-and-pointe.patch
+Patch116: xsa55-4.2-0009-tools-xcutils-readnotes-adjust-print_l1_mfn_valid_no.patch
+Patch117: xsa55-4.2-0010-libelf-check-nul-terminated-strings-properly.patch
+Patch118: xsa55-4.2-0011-libelf-check-all-pointer-accesses.patch
+Patch119: xsa55-4.2-0012-libelf-Check-pointer-references-in-elf_is_elfbinary.patch
+Patch120: xsa55-4.2-0013-libelf-Make-all-callers-call-elf_check_broken.patch
+Patch121: xsa55-4.2-0014-libelf-use-C99-bool-for-booleans.patch
+Patch122: xsa55-4.2-0015-libelf-use-only-unsigned-integers.patch
+Patch123: xsa55-4.2-0016-libelf-check-loops-for-running-away.patch
+Patch124: xsa55-4.2-0017-libelf-abolish-obsolete-macros.patch
+Patch125: xsa55-4.2-0018-libxc-Add-range-checking-to-xc_dom_binloader.patch
+Patch126: xsa55-4.2-0019-libxc-check-failure-of-xc_dom_-_to_ptr-xc_map_foreig.patch
+Patch127: xsa55-4.2-0020-libxc-check-return-values-from-malloc.patch
+Patch128: xsa55-4.2-0021-libxc-range-checks-in-xc_dom_p2m_host-and-_guest.patch
+Patch129: xsa55-4.2-0022-libxc-check-blob-size-before-proceeding-in-xc_dom_ch.patch
+Patch130: xsa55-4.2-0023-libxc-Better-range-check-in-xc_dom_alloc_segment.patch
+
+Patch1000: xen-centos-disable-CFLAGS-for-qemu.patch
+Patch1001: xen-centos-disableWerror-blktap25.patch
+Patch1003: xen-centos-libxl-with-blktap25.patch
+Patch1005: xen-centos-blktap25-ctl-ipc-restart.patch
+
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRequires: transfig libidn-devel zlib-devel texi2html SDL-devel curl-devel
+BuildRequires: libX11-devel python-devel ghostscript texlive-latex
+BuildRequires: ncurses-devel gtk2-devel libaio-devel libtool
+# for the docs
+BuildRequires: perl texinfo graphviz
+# so that the makefile knows to install udev rules
+BuildRequires: udev
+%ifnarch ia64
+# so that x86_64 builds pick up glibc32 correctly
+BuildRequires: /usr/include/gnu/stubs-32.h
+# for the VMX "bios"
+BuildRequires: dev86
+%endif
+BuildRequires: gettext
+BuildRequires: gnutls-devel
+BuildRequires: openssl-devel
+# For ioemu PCI passthrough
+BuildRequires: pciutils-devel
+# Several tools now use uuid
+BuildRequires: libuuid-devel
+# iasl needed to build hvmloader
+BuildRequires: iasl
+# build using Fedora seabios and ipxe packages for roms
+BuildRequires: seabios ipxe-roms-qemu
+# modern compressed kernels
+BuildRequires: bzip2-devel xz-devel
+# libfsimage
+BuildRequires: e2fsprogs-devel
+# tools now require yajl
+BuildRequires: yajl-devel
+Requires: bridge-utils
+Requires: python-lxml
+Requires: udev >= 059
+Requires: pciutils
+Requires: xen-runtime = %{version}-%{release}
+# Not strictly a dependency, but kpartx is by far the most useful tool right
+# now for accessing domU data from within a dom0 so bring it in when the user
+# installs xen.
+Requires: kpartx
+Requires: chkconfig
+Requires: module-init-tools
+Requires: gawk
+Requires: grep
+ExclusiveArch: %{ix86} x86_64 ia64
+#ExclusiveArch: %{ix86} x86_64 ia64 noarch
+%if %with_ocaml
+BuildRequires: ocaml, ocaml-findlib
+%endif
+# efi image needs an ld that has -mi386pep option
+%if %build_efi
+BuildRequires: mingw64-binutils
+%endif
+
+%description
+This package contains the XenD daemon and xm command line
+tools, needed to manage virtual machines running under the
+Xen hypervisor
+
+%package libs
+Summary: Libraries for Xen tools
+Group: Development/Libraries
+Requires(pre): /sbin/ldconfig
+Requires(post): /sbin/ldconfig
+Requires: xen-licenses
+
+%description libs
+This package contains the libraries needed to run applications
+which manage Xen virtual machines.
+
+
+%package runtime
+Summary: Core Xen runtime environment
+Group: Development/Libraries
+Requires: xen-libs = %{version}-%{release}
+Requires: /usr/bin/qemu-img
+# Ensure we at least have a suitable kernel installed, though we can't
+# force user to actually boot it.
+Requires: xen-hypervisor-abi = %{hv_abi}
+
+%description runtime
+This package contains the runtime programs and daemons which
+form the core Xen userspace environment.
+
+
+%package hypervisor
+Summary: Libraries for Xen tools
+Group: Development/Libraries
+Provides: xen-hypervisor-abi = %{hv_abi}
+Requires: xen-licenses
+Requires: kernel >= 3.4.26
+
+%description hypervisor
+This package contains the Xen hypervisor
+
+
+%package doc
+Summary: Xen documentation
+Group: Documentation
+#BuildArch: noarch
+Requires: xen-licenses
+
+%description doc
+This package contains the Xen documentation.
+
+
+%package devel
+Summary: Development libraries for Xen tools
+Group: Development/Libraries
+Requires: xen-libs = %{version}-%{release}
+
+%description devel
+This package contains what's needed to develop applications
+which manage Xen virtual machines.
+
+
+%package licenses
+Summary: License files from Xen source
+Group: Documentation
+
+%description licenses
+This package contains the license files from the source used
+to build the xen packages.
+
+
+%if %build_ocaml
+%package ocaml
+Summary: Ocaml libraries for Xen tools
+Group: Development/Libraries
+Requires: ocaml-runtime, xen-libs = %{version}-%{release}
+
+%description ocaml
+This package contains libraries for ocaml tools to manage Xen
+virtual machines.
+
+
+%package ocaml-devel
+Summary: Ocaml development libraries for Xen tools
+Group: Development/Libraries
+Requires: xen-ocaml = %{version}-%{release}
+
+%description ocaml-devel
+This package contains libraries for developing ocaml tools to
+manage Xen virtual machines.
+%endif
+
+
+%prep
+%setup -q
+%patch1 -p1
+%patch4 -p1
+%patch5 -p1
+
+%patch28 -p1
+%patch34 -p1
+%patch35 -p1
+%patch39 -p1
+%patch46 -p1
+%patch47 -p1
+%patch49 -p1
+%patch55 -p1
+%patch56 -p1
+
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
+%patch67 -p1
+%patch68 -p1
+%patch69 -p1
+%patch70 -p1
+%patch71 -p1
+%patch72 -p1
+%patch73 -p1
+%patch74 -p1
+%patch75 -p1
+%patch92 -p1
+%patch93 -p1
+%patch94 -p1
+%patch100 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+%patch118 -p1
+%patch119 -p1
+%patch120 -p1
+%patch121 -p1
+%patch122 -p1
+%patch123 -p1
+%patch124 -p1
+%patch125 -p1
+%patch126 -p1
+%patch127 -p1
+%patch128 -p1
+%patch129 -p1
+%patch130 -p1
+
+%patch1000 -p1
+
+pushd `pwd`
+rm -rf ${RPM_BUILD_DIR}/%{name}-%{version}/tools/qemu-xen
+%{__tar} -C ${RPM_BUILD_DIR}/%{name}-%{version}/tools/ -zxf %{SOURCE100} 
+rm -rf ${RPM_BUILD_DIR}/%{name}-%{version}/tools/blktap2
+%{__tar} -C ${RPM_BUILD_DIR}/%{name}-%{version}/tools/ -zxf %{SOURCE101} 
+cd ${RPM_BUILD_DIR}/%{name}-%{version}/tools/blktap2
+./autogen.sh
+XEN_VENDORVERSION="-%{release}" ./configure --libdir=%{_libdir} --prefix=/user --libexecdir=/usr/lib/xen/bin
+popd 
+%patch1001 -p1
+%patch1003 -p1
+%patch1005 -p1
+
+pushd `pwd`
+cd ${RPM_BUILD_DIR}/%{name}-%{version}/tools/qemu-xen
+%patch105 -p1
+popd
+
+# stubdom sources
+cp -v %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14} stubdom
+
+
+%build
+%if !%build_ocaml
+%define ocaml_flags OCAML_TOOLS=n
+%endif
+%if %build_efi
+%define efi_flags LD_EFI=/usr/x86_64-w64-mingw32/bin/ld
+mkdir -p dist/install/boot/efi/efi/fedora
+%endif
+export XEN_VENDORVERSION="-$(echo %{release} | sed 's/.centos.alt//g')"
+export XEN_DOMAIN="centos.org"
+export CFLAGS="$RPM_OPT_FLAGS"
+make %{?_smp_mflags} %{?efi_flags} prefix=/usr dist-xen
+./configure --libdir=%{_libdir}
+make %{?_smp_mflags} %{?ocaml_flags} prefix=/usr dist-tools
+make                 prefix=/usr dist-docs
+unset CFLAGS
+make %{?ocaml_flags} dist-stubdom
+
+
+%install
+rm -rf %{buildroot}
+%if %build_ocaml
+mkdir -p %{buildroot}%{_libdir}/ocaml/stublibs
+%endif
+%if %build_efi
+mkdir -p %{buildroot}/boot/efi/efi/fedora
+%endif
+export XEN_VENDORVERSION="-$(echo %{release} | sed 's/.centos.alt//g')"
+export XEN_DOMAIN="centos.org"
+make DESTDIR=%{buildroot} %{?efi_flags}  prefix=/usr install-xen
+make DESTDIR=%{buildroot} %{?ocaml_flags} prefix=/usr install-tools
+make DESTDIR=%{buildroot} prefix=/usr install-docs
+make DESTDIR=%{buildroot} %{?ocaml_flags} prefix=/usr install-stubdom
+%if %build_efi
+mv %{buildroot}/boot/efi/efi %{buildroot}/boot/efi/EFI
+%endif
+
+############ debug packaging: list files ############
+
+find %{buildroot} -print | xargs ls -ld | sed -e 's|.*%{buildroot}||' > f1.list
+
+############ kill unwanted stuff ############
+
+# stubdom: newlib
+rm -rf %{buildroot}/usr/*-xen-elf
+
+# hypervisor symlinks
+rm -rf %{buildroot}/boot/xen-4.0.gz
+rm -rf %{buildroot}/boot/xen-4.gz
+
+# silly doc dir fun
+rm -fr %{buildroot}%{_datadir}/doc/xen
+rm -rf %{buildroot}%{_datadir}/doc/qemu
+
+# Pointless helper
+rm -f %{buildroot}%{_sbindir}/xen-python-path
+
+# qemu stuff (unused or available from upstream)
+rm -rf %{buildroot}/usr/share/xen/man
+rm -rf %{buildroot}/usr/bin/qemu-*-xen
+ln -s qemu-img %{buildroot}/%{_bindir}/qemu-img-xen
+ln -s qemu-img %{buildroot}/%{_bindir}/qemu-nbd-xen
+for file in bios.bin openbios-sparc32 openbios-sparc64 ppc_rom.bin \
+         pxe-e1000.bin pxe-ne2k_pci.bin pxe-pcnet.bin pxe-rtl8139.bin \
+         vgabios.bin vgabios-cirrus.bin video.x openbios-ppc bamboo.dtb
+do
+       rm -f %{buildroot}/%{_datadir}/xen/qemu/$file
+done
+rm -f %{buildroot}/%{_mandir}/man1/qemu*
+rm -f %{buildroot}/%{_mandir}/man8/qemu*
+mkdir -p %{buildroot}/%{_sysconfdir}/qemu/
+mv %{buildroot}/%{_prefix}/%{_sysconfdir}/qemu/* %{buildroot}/%{_sysconfdir}/qemu/
+rm -rf %{buildroot}/%{_prefix}/%{_sysconfdir}
+
+# README's not intended for end users
+rm -f %{buildroot}/%{_sysconfdir}/xen/README*
+
+# standard gnu info files
+rm -rf %{buildroot}/usr/info
+
+# adhere to Static Library Packaging Guidelines
+rm -rf %{buildroot}/%{_libdir}/*.a
+
+%if %build_efi
+# clean up extra efi files
+rm -rf %{buildroot}/%{_libdir}/efi
+%endif
+
+
+############ fixup files in /etc ############
+
+# udev
+#rm -rf %{buildroot}/etc/udev/rules.d/xen*.rules
+#mv %{buildroot}/etc/udev/xen*.rules %{buildroot}/etc/udev/rules.d
+
+# modules
+mkdir -p %{buildroot}%{_sysconfdir}/sysconfig/modules
+install -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/sysconfig/modules/%{name}.modules
+
+# logrotate
+mkdir -p %{buildroot}%{_sysconfdir}/logrotate.d/
+install -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
+
+# init scripts
+#mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d
+#mv %{buildroot}%{_sysconfdir}/init.d/* %{buildroot}%{_sysconfdir}/rc.d/init.d
+#rmdir %{buildroot}%{_sysconfdir}/init.d
+%if %with_sysv
+install -m 755 %{SOURCE20} %{buildroot}%{_sysconfdir}/rc.d/init.d/xenstored
+install -m 755 %{SOURCE21} %{buildroot}%{_sysconfdir}/rc.d/init.d/xenconsoled
+install -m 755 %{SOURCE22} %{buildroot}%{_sysconfdir}/rc.d/init.d/blktapctrl
+install -m 755 %{SOURCE23} %{buildroot}%{_sysconfdir}/rc.d/init.d/xend
+%else
+rm %{buildroot}%{_sysconfdir}/rc.d/init.d/xen-watchdog
+rm %{buildroot}%{_sysconfdir}/rc.d/init.d/xencommons
+rm %{buildroot}%{_sysconfdir}/rc.d/init.d/xend
+rm %{buildroot}%{_sysconfdir}/rc.d/init.d/xendomains
+%endif
+
+# sysconfig
+mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
+install -m 644 %{SOURCE30} %{buildroot}%{_sysconfdir}/sysconfig/xenstored
+install -m 644 %{SOURCE31} %{buildroot}%{_sysconfdir}/sysconfig/xenconsoled
+install -m 644 %{SOURCE32} %{buildroot}%{_sysconfdir}/sysconfig/blktapctrl
+
+# systemd
+%if %with_systemd
+mkdir -p %{buildroot}%{_unitdir}
+install -m 644 %{SOURCE40} %{buildroot}%{_unitdir}/proc-xen.mount
+install -m 644 %{SOURCE41} %{buildroot}%{_unitdir}/var-lib-xenstored.mount
+install -m 644 %{SOURCE42} %{buildroot}%{_unitdir}/xenstored.service
+install -m 644 %{SOURCE43} %{buildroot}%{_unitdir}/blktapctrl.service
+install -m 644 %{SOURCE44} %{buildroot}%{_unitdir}/xend.service
+install -m 644 %{SOURCE45} %{buildroot}%{_unitdir}/xenconsoled.service
+install -m 644 %{SOURCE46} %{buildroot}%{_unitdir}/xen-watchdog.service
+install -m 644 %{SOURCE47} %{buildroot}%{_unitdir}/xendomains.service
+mkdir -p %{buildroot}%{_libexecdir}
+install -m 644 %{SOURCE48} %{buildroot}%{_libexecdir}/xendomains
+mkdir -p %{buildroot}/usr/lib/tmpfiles.d
+install -m 644 %{SOURCE49} %{buildroot}/usr/lib/tmpfiles.d/xen.conf
+%endif
+
+# config file only used for hotplug, Fedora uses udev instead
+rm -f %{buildroot}/%{_sysconfdir}/sysconfig/xend
+
+#add new sysconfig/xend
+install -m 644 %{SOURCE33} %{buildroot}%{_sysconfdir}/sysconfig/xend
+
+############ create dirs in /var ############
+
+mkdir -p %{buildroot}%{_localstatedir}/lib/xen/xend-db/domain
+mkdir -p %{buildroot}%{_localstatedir}/lib/xen/xend-db/vnet
+mkdir -p %{buildroot}%{_localstatedir}/lib/xen/xend-db/migrate
+mkdir -p %{buildroot}%{_localstatedir}/lib/xen/images
+mkdir -p %{buildroot}%{_localstatedir}/log/xen/console
+mkdir -p %{buildroot}%{_localstatedir}/run/xenstored
+
+############ create symlink for x86_64 for compatibility with 3.4 ############
+
+%if "%{_libdir}" != "/usr/lib"
+ln -s /usr/lib/%{name}/bin/qemu-dm %{buildroot}/%{_libdir}/%{name}/bin/qemu-dm
+%endif
+
+############ debug packaging: list files ############
+
+find %{buildroot} -print | xargs ls -ld | sed -e 's|.*%{buildroot}||' > f2.list
+diff -u f1.list f2.list || true
+
+############ assemble license files ############
+
+mkdir licensedir
+# avoid licensedir to avoid recursion, also stubdom/ioemu and dist
+# which are copies of files elsewhere
+find . -path licensedir -prune -o -path stubdom/ioemu -prune -o \
+  -path dist -prune -o -name COPYING -o -name LICENSE | while read file; do
+  mkdir -p licensedir/`dirname $file`
+  install -m 644 $file licensedir/$file
+done
+
+%ifarch x86_64
+pushd %{buildroot}/usr/lib/xen/bin/
+for f in libxl-save-helper xc_save xc_restore pygrub
+  do
+    ln -sf ../../../lib64/xen/bin/$f .
+  done
+popd
+%endif
+############ all done now ############
+
+%post
+%if %with_sysv
+/sbin/chkconfig --add xend
+/sbin/chkconfig --add xendomains
+%endif
+%if %with_systemd
+/bin/systemctl enable xendomains.service
+%endif
+
+%if %with_sysv
+if [ $1 != 0 ]; then
+  service xend condrestart
+fi
+%endif
+
+%preun
+if [ $1 = 0 ]; then
+%if %with_sysv
+  /sbin/chkconfig --del xend
+  /sbin/chkconfig --del xendomains
+%endif
+%if %with_systemd
+/bin/systemctl enable xendomains.service
+%endif
+fi
+
+%post runtime
+%if %with_sysv
+/sbin/chkconfig --add xenconsoled
+/sbin/chkconfig --add xenstored
+/sbin/chkconfig --add xencommons
+/sbin/chkconfig --add blktapctrl
+%endif
+%if %with_systemd
+/bin/systemctl enable xenstored.service
+/bin/systemctl enable xenconsoled.service
+/bin/systemctl enable xencommons.service
+%endif
+
+%if %with_sysv
+if [ $1 != 0 ]; then
+  service xenconsoled condrestart
+fi
+%endif
+
+%preun runtime
+if [ $1 = 0 ]; then
+%if %with_sysv
+  /sbin/chkconfig --del xenconsoled
+  /sbin/chkconfig --del xenstored
+  /sbin/chkconfig --del xencommons
+  /sbin/chkconfig --del blktapctrl
+%endif
+%if %with_systemd
+  /bin/systemctl disable xenstored.service
+  /bin/systemctl disable xenconsoled.service
+%endif
+fi
+
+%post libs -p /sbin/ldconfig
+%postun libs -p /sbin/ldconfig
+
+%post hypervisor
+if [ $1 = 1 -a -f /sbin/grub2-mkconfig -a -f /boot/grub2/grub.cfg ]; then
+  /sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
+fi
+
+%postun hypervisor
+if [ -f /sbin/grub2-mkconfig -a -f /boot/grub2/grub.cfg ]; then
+  /sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
+fi
+
+%clean
+rm -rf %{buildroot}
+
+# Base package only contains XenD/xm python stuff
+#files -f xen-xm.lang
+%files
+%defattr(-,root,root)
+%doc COPYING README
+%{_bindir}/xencons
+%{_sbindir}/xend
+%{_sbindir}/xm
+%{python_sitearch}/%{name}
+%{python_sitearch}/xen-*.egg-info
+%{_mandir}/man1/xm.1*
+%{_mandir}/man5/xend-config.sxp.5*
+%{_mandir}/man5/xmdomain.cfg.5*
+%{_datadir}/%{name}/create.dtd
+
+# Startup script
+%if %with_sysv
+%{_sysconfdir}/rc.d/init.d/xend
+%{_sysconfdir}/rc.d/init.d/xendomains
+%endif
+# Guest config files
+%config(noreplace) %{_sysconfdir}/%{name}/xmexample*
+# Daemon config
+%config(noreplace) %{_sysconfdir}/%{name}/xend-*
+# xm config
+%config(noreplace) %{_sysconfdir}/%{name}/xm-*
+# Guest autostart links
+%dir %attr(0700,root,root) %{_sysconfdir}/%{name}/auto
+# Autostart of guests
+%config(noreplace) %{_sysconfdir}/sysconfig/xendomains
+# xemd sysconfig file
+%config(noreplace) %{_sysconfdir}/sysconfig/xend
+
+%if %with_systemd
+%{_unitdir}/xend.service
+%{_unitdir}/xendomains.service
+%{_libexecdir}/xendomains
+%endif
+
+# Persistent state for XenD
+%dir %{_localstatedir}/lib/%{name}/xend-db/
+%dir %{_localstatedir}/lib/%{name}/xend-db/domain
+%dir %{_localstatedir}/lib/%{name}/xend-db/migrate
+%dir %{_localstatedir}/lib/%{name}/xend-db/vnet
+
+%files libs
+%defattr(-,root,root)
+%{_libdir}/*.so.*
+%{_libdir}/fs
+
+# All runtime stuff except for XenD/xm python stuff
+%files runtime
+%defattr(-,root,root)
+# Hotplug rules
+%config(noreplace) %{_sysconfdir}/udev/rules.d/*
+
+%dir %attr(0700,root,root) %{_sysconfdir}/%{name}
+%dir %attr(0700,root,root) %{_sysconfdir}/%{name}/scripts/
+%config %attr(0700,root,root) %{_sysconfdir}/%{name}/scripts/*
+
+%if %with_sysv
+%{_sysconfdir}/rc.d/init.d/blktapctrl
+%{_sysconfdir}/rc.d/init.d/xenstored
+%{_sysconfdir}/rc.d/init.d/xenconsoled
+%{_sysconfdir}/rc.d/init.d/xen-watchdog
+%{_sysconfdir}/rc.d/init.d/xencommons
+%endif
+%{_sysconfdir}/bash_completion.d/xl.sh
+
+%if %with_systemd
+%{_unitdir}/proc-xen.mount
+%{_unitdir}/var-lib-xenstored.mount
+%{_unitdir}/xenstored.service
+%{_unitdir}/blktapctrl.service
+%{_unitdir}/xenconsoled.service
+%{_unitdir}/xen-watchdog.service
+/usr/lib/tmpfiles.d/xen.conf
+%endif
+
+%config(noreplace) %{_sysconfdir}/sysconfig/xenstored
+%config(noreplace) %{_sysconfdir}/sysconfig/xenconsoled
+%config(noreplace) %{_sysconfdir}/sysconfig/blktapctrl
+%config(noreplace) %{_sysconfdir}/sysconfig/xencommons
+%config(noreplace) %{_sysconfdir}/xen/xl.conf
+%config(noreplace) %{_sysconfdir}/xen/cpupool
+%config(noreplace) %{_sysconfdir}/xen/xlexample*
+
+# Auto-load xen backend drivers
+%attr(0755,root,root) %{_sysconfdir}/sysconfig/modules/%{name}.modules
+
+# Rotate console log files
+%config(noreplace) %{_sysconfdir}/logrotate.d/xen
+
+# Programs run by other programs
+%dir %{_libdir}/%{name}
+%dir %{_libdir}/%{name}/bin
+%attr(0700,root,root) %{_libdir}/%{name}/bin/*
+# QEMU-xen runtime files
+%dir %{_datadir}/qemu-xen
+%{_datadir}/qemu-xen/*
+%dir %{_sysconfdir}/qemu/
+%{_sysconfdir}/qemu/target-%{_arch}.conf
+
+# QEMU runtime files
+%dir %{_datadir}/%{name}/qemu
+%dir %{_datadir}/%{name}/qemu/keymaps
+%{_datadir}/%{name}/qemu/keymaps/*
+
+# man pages
+%{_mandir}/man1/xentop.1*
+%{_mandir}/man1/xentrace_format.1*
+%{_mandir}/man8/xentrace.8*
+%{_mandir}/man1/xl.1*
+%{_mandir}/man5/xl.cfg.5*
+%{_mandir}/man5/xl.conf.5*
+%{_mandir}/man5/xlcpupool.cfg.5*
+
+%{python_sitearch}/fsimage.so
+%{python_sitearch}/grub
+%{python_sitearch}/pygrub-*.egg-info
+
+# The firmware
+%ifnarch ia64
+# Avoid owning /usr/lib twice on i386
+%if "%{_libdir}" != "/usr/lib"
+%dir /usr/lib/%{name}
+%dir /usr/lib/%{name}/bin
+/usr/lib/%{name}/bin/*
+%endif
+%dir /usr/lib/%{name}/boot
+# HVM loader is always in /usr/lib regardless of multilib
+/usr/lib/xen/boot/hvmloader
+/usr/lib/xen/boot/ioemu-stubdom.gz
+/usr/lib/xen/boot/xenstore-stubdom.gz
+/usr/lib/xen/boot/pv-grub*.gz
+%endif
+# General Xen state
+%dir %{_localstatedir}/lib/%{name}
+%dir %{_localstatedir}/lib/%{name}/dump
+%dir %{_localstatedir}/lib/%{name}/images
+# Xenstore persistent state
+%dir %{_localstatedir}/lib/xenstored
+# Xenstore runtime state
+%dir %attr(0700,root,root) %{_localstatedir}/run/xenstored
+# XenD runtime state
+%ghost %attr(0700,root,root) %{_localstatedir}/run/xend
+%ghost %attr(0700,root,root) %{_localstatedir}/run/xend/boot
+
+# All xenstore CLI tools
+%{_bindir}/qemu-*-xen
+%{_bindir}/xenstore
+%{_bindir}/xenstore-*
+%{_bindir}/pygrub
+%{_bindir}/xentrace*
+%{_bindir}/remus
+# blktap daemon
+%{_sbindir}/blktapctrl
+%{_sbindir}/tapdisk*
+# XSM
+%{_sbindir}/flask-*
+# Disk utils
+%{_sbindir}/qcow-create
+%{_sbindir}/qcow2raw
+%{_sbindir}/img2qcow
+# Misc stuff
+%{_bindir}/xen-detect
+%{_sbindir}/gdbsx
+%{_sbindir}/gtrace*
+%{_sbindir}/kdd
+%{_sbindir}/tap-ctl
+%{_sbindir}/td-util
+%{_sbindir}/xen-bugtool
+%{_sbindir}/xen-hptool
+%{_sbindir}/xen-hvmcrash
+%{_sbindir}/xen-hvmctx
+%{_sbindir}/xen-tmem-list-parse
+%{_sbindir}/xenconsoled
+%{_sbindir}/xenlockprof
+%{_sbindir}/xenmon.py*
+%{_sbindir}/xentop
+%{_sbindir}/xentrace_setmask
+%{_sbindir}/xenbaked
+%{_sbindir}/xenstored
+%{_sbindir}/xenpm
+%{_sbindir}/xenpmd
+%{_sbindir}/xenperf
+%{_sbindir}/xenwatchdogd
+%{_sbindir}/xl
+%{_sbindir}/xsview
+%{_sbindir}/xen-lowmemd
+%{_sbindir}/xen-ringwatch
+#blktap
+%{_bindir}/vhd-index
+%{_bindir}/vhd-update
+%{_bindir}/vhd-util
+%{_sbindir}/lvm-util
+%{_sbindir}/part-util
+%{_sbindir}/td-rated
+%{_sbindir}/vhdpartx
+
+# Xen logfiles
+%dir %attr(0700,root,root) %{_localstatedir}/log/xen
+# Guest/HV console logs
+%dir %attr(0700,root,root) %{_localstatedir}/log/xen/console
+
+%files hypervisor
+%defattr(-,root,root)
+/boot/xen-syms-*
+/boot/xen-*.gz
+/boot/xen.gz
+%if %build_efi
+/boot/efi/EFI/fedora/*.efi
+%endif
+
+%files doc
+%defattr(-,root,root)
+%doc docs/misc/
+%doc dist/install/usr/share/doc/xen/html
+%doc dist/install/usr/share/doc/xen/pdf/*.pdf
+
+%files devel
+%defattr(-,root,root)
+%{_includedir}/*.h
+%dir %{_includedir}/xen
+%{_includedir}/xen/*
+%dir %{_includedir}/xenstore-compat
+%{_includedir}/xenstore-compat/*
+%dir %{_includedir}/blktap
+%{_includedir}/blktap/*
+%dir %{_includedir}/vhd
+%{_includedir}/vhd/*
+
+%{_libdir}/*.so
+%{_libdir}/*.la
+
+
+%files licenses
+%defattr(-,root,root)
+%doc licensedir/*
+
+%if %build_ocaml
+%files ocaml
+%defattr(-,root,root)
+%{_libdir}/ocaml/xen*
+%exclude %{_libdir}/ocaml/xen*/*.a
+%exclude %{_libdir}/ocaml/xen*/*.cmxa
+%exclude %{_libdir}/ocaml/xen*/*.cmx
+%{_libdir}/ocaml/stublibs/*.so
+%{_libdir}/ocaml/stublibs/*.so.owner
+%{_sbindir}/oxenstored
+%config(noreplace) %{_sysconfdir}/xen/oxenstored.conf
+
+%files ocaml-devel
+%defattr(-,root,root)
+%{_libdir}/ocaml/xen*/*.a
+%{_libdir}/ocaml/xen*/*.cmxa
+%{_libdir}/ocaml/xen*/*.cmx
+%endif
+
+%changelog
+* Fri Jun 14 2013 Johnny Hughes <johnny@cetnos.org> - 4.2.2-22.el6.centos
+- rolled in patches 108 through 130 for XSA-55
+
+* Tue Jun  5 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-21.el6.centos
+- remarked out XSA-55 patches while they are being better tested upstream 
+- cleaned up XEN_VENDORVERSION to remove .centos.alt
+
+* Tue Jun  5 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-20.el6.centos
+- added XEN_VENDORVERSION to the make install section of the spec
+- added XEN_DOMAIN=centos.org make and make install sections of the spec
+
+* Tue Jun  4 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-19.el6.centos
+- tried to work around an empty XEN_VENDORVERSION in the spec file
+
+* Mon Jun  3 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-18.el6.centos
+- added patches 76 to 91 for XSA-55 (No CVE Assigned)
+- added patch 92 for XSA-52 (CVE-2013-2076)
+- added patch 93 for XSA-53 (CVE-2013-2077)
+- added patch 94 for XSA-54 (CVE-2013-2078)
+  
+* Mon May 27 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-16.el6.centos
+- add patch 75 to fix xsa46 regression
+
+* Tue May 21 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-15.el6.centos
+- ln sf some files from lib64/xen/bin to lib/xen/bin
+
+* Mon May 20 2013 Johnny Hughes <johnny@centos.org> - 4.2.2-14.el6.centos
+- Rolled in patch 74 for XSA-56 (CVE-2013-2072)
+
+* Thu May  2 2013 Johnny Hughes <johnny@centos.org> 4.2.2-12.el6.centos
+- Rolled in patches 66 through 73 for XSA-45 (CVE-2013-1918) and XSA-49 (CVE-2013-1952)
+
+* Tue Apr 30 2013 Johnny Hughes <johnny@centos.org> 4.2.2-11.el6.centos
+- upgraded to upstream version 4.2.2 for xen
+- removed patches 48,57,58,59,61,63,101,102,103,104,108,1002,1004 as
+  they are already part of xen-4.2.2
+- added patches 64 and 65
+- upgraded Source100 to upstream qemu-xen-4.2.2 
+
+* Tue Apr 23 2013 Johnny Hughes <johnny@centos.org> 4.2.1-10.1.el6.centos.9
+- Roll in security fix for XSA-48,CVE-2013-1922 (Patch105)
+- Roll in patch to add auto option for autoballon(Patch106) and 
+  set the autoballon option to auto (Patch107)
+- Roll in security fix for XSA-44,CVE-2013-1917 (Patch108) 
+
+* Thu Apr  5 2013 Johnny Hughes <johnny@centos.org> 4.2.1-10.1.el6.centos.8
+- added patches 103 and 104.  Patch104 is Security fix for XSA-47,CVE-2013-1920  
+
+* Wed Mar 27 2013 Johnny Hughes <johnny@centos.org> 4.2.1-6.1.el6.centos.8
+- build with_ocaml
+- roll in xen-centos-blktap25-ctl-ipc-restart.patch 
+
+* Tue Mar 12 2013 Johnny Hughes <johnny@centos.org> 4.2.1-6.1.el6.centos.7
+- updated patches for XSA-36 (CVE-2013-0153, Patch101) and XSA-38 (CVE-2013-0215, Patch102).
+- rolled in Patch1004 in an effort to fix xl.tapdisk orphaning 
+
+* Tue Feb  5 2013 Johnny Hughes <johnny@centos.org> 4.2.1-6.1.el6.centos.6
+- Rolled in patch 101 and 102 to fix CVEs 2013-0153, 2013-0215
+
+* Fri Jan 25 2013 Johnny Hughes <johnny@centos.org> 4.2.1-5.1.el6.centos.6
+- added a create for /var/run/xenstored 
+
+* Thu Jan 24 2013 Johnny Hughes <johnny@centos.org> 4.2.1-5.1.el6.centos.5
+- Rolled in patches 57, 58, 59, 61, and 62 to incorporate XSA-33, XSA-34, XSA-35, XSA-37, and XSA-41
+  to fix CVE's 2012-5634, 2012-6075, 2013-0151, 2013-0152, CVE-2013-0154
+- restore status option to xend which is used by libvirt 
+* Wed Jan 23 2013 Karanbir Singh <kbsingh@centos.org
+- Pull in libxl patch to work with blktap25 (from Stefano )
+- move blktap25 code into tools/blktap and turn off -Werror (from Stefano )
+- Make kernel 3.4.26+ a hard Requires for the xen-hypervisor
+
+* Tue Jan 22 2013 Karanbir Singh <kbsingh@centos.org> - 4.2.1-1.1.el6.centos.4
+- add xencommons to chkconfig and set it to start 
+- xend needs pciutils 
+- import blktap2.5
+
+* Thu Jan 17 2013 Karanbir Singh <kbsingh@centos.org> - 4.2.1-1.1.el6.centos.3
+- build with seabious and gpxe
+- gpxe does not work, fall back to ipxe
+- build with included qemu-xen
+- drop in upstream qemu-xen-4.2.1
+- upgrade to qemu-upstream-4.2.1
+
+* Fri Jan  4 2013 Johnny Hughes <johnny@centos.org> - 4.2.1-1.1
+- set build_efi 0, with_sysv 1,  with_systemd 0  
+- remove the BuildRequires that are specific to .f18 dist
+
+* Tue Dec 18 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.1-1
+- update to xen-4.2.1
+- remove patches that are included in 4.2.1
+- rebase xen.fedora.efi.build.patch
+
+* Thu Dec 13 2012 Richard W.M. Jones <rjones@redhat.com> - 4.2.0-7
+- Rebuild for OCaml fix (RHBZ#877128).
+
+* Mon Dec 03 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-6
+- 6 security fixes
+  A guest can cause xen to crash [XSA-26, CVE-2012-5510] (#883082)
+  An HVM guest can cause xen to run slowly or crash [XSA-27, CVE-2012-5511]
+    (#883084)
+  A PV guest can cause xen to crash and might be able escalate privileges
+    [XSA-29, CVE-2012-5513] (#883088)
+  An HVM guest can cause xen to hang [XSA-30, CVE-2012-5514] (#883091)
+  A guest can cause xen to hang [XSA-31, CVE-2012-5515] (#883092)
+  A PV guest can cause xen to crash and might be able escalate privileges
+    [XSA-32, CVE-2012-5525] (#883094)
+
+* Sat Nov 17 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-5
+- two build fixes for Fedora 19
+- add texlive-ntgclass package to fix build
+
+* Tue Nov 13 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-4
+- 4 security fixes
+  A guest can block a cpu by setting a bad VCPU deadline [XSA 20,
+    CVE-2012-4535] (#876198)
+  HVM guest can exhaust p2m table crashing xen [XSA 22, CVE-2012-4537] (#876203)
+  PAE HVM guest can crash hypervisor [XSA-23, CVE-2012-4538] (#876205)
+  32-bit PV guest on 64-bit hypervisor can cause an hypervisor infinite
+    loop [XSA-24, CVE-2012-4539] (#876207)
+- texlive-2012 is now in Fedora 18
+
+* Sun Oct 28 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-3
+- texlive-2012 isn't in Fedora 18 yet
+
+* Fri Oct 26 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-2
+- limit the size of guest kernels and ramdisks to avoid running out
+  of memeory on dom0 during guest boot [XSA-25, CVE-2012-4544] (#870414)
+
+* Thu Oct 25 2012 Michael Young <m.a.young@durham.ac.uk> - 4.2.0-1
+- update to xen-4.2.0
+- rebase xen-net-disable-iptables-on-bridge.patch pygrubfix.patch
+- remove patches that are now upstream or with alternatives upstream
+- use ipxe and seabios from seabios-bin and ipxe-roms-qemu packages
+- xen tools now need ./configure to be run (x86_64 needs libdir set)
+- don't build upstream qemu version
+- amend list of files in package - relocate xenpaging
+  add /etc/xen/xlexample* oxenstored.conf /usr/include/xenstore-compat/*
+      xenstore-stubdom.gz xen-lowmemd xen-ringwatch xl.1.gz xl.cfg.5.gz
+      xl.conf.5.gz xlcpupool.cfg.5.gz
+- use a tmpfiles.d file to create /run/xen on boot
+- add BuildRequires for yajl-devel and graphviz
+- build an efi boot image where it is supported
+- adjust texlive changes so spec file still works on Fedora 17
+
+* Thu Oct 18 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.3-6
+- add font packages to build requires due to 2012 version of texlive in F19
+- use build requires of texlive-latex instead of tetex-latex which it
+  obsoletes
+
+* Wed Oct 17 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.3-5
+- rebuild for ocaml update
+
+* Thu Sep 06 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.3-4
+- disable qemu monitor by default [XSA-19, CVE-2012-4411] (#855141)
+
+* Wed Sep 05 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.3-3
+- 5 security fixes
+  a malicious 64-bit PV guest can crash the dom0 [XSA-12, CVE-2012-3494]
+    (#854585)
+  a malicious crash might be able to crash the dom0 or escalate privileges
+    [XSA-13, CVE-2012-3495] (#854589)
+  a malicious PV guest can crash the dom0 [XSA-14, CVE-2012-3496] (#854590)
+  a malicious HVM guest can crash the dom0 and might be able to read
+    hypervisor or guest memory [XSA-16, CVE-2012-3498] (#854593)
+  an HVM guest could use VT100 escape sequences to escalate privileges to
+    that of the qemu process [XSA-17, CVE-2012-3515] (#854599)
+
+* Fri Aug 10 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.3-1 4.1.3-2
+- update to 4.1.3
+  includes fix for untrusted HVM guest can cause the dom0 to hang or
+    crash [XSA-11, CVE-2012-3433] (#843582)
+- remove patches that are now upstream
+- remove some unnecessary compile fixes
+- adjust upstream-23936:cdb34816a40a-rework for backported fix for
+    upstream-23940:187d59e32a58
+- replace pygrub.size.limits.patch with upstreamed version
+- fix for (#845444) broke xend under systemd
+
+* Tue Aug 07 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-25
+- remove some unnecessary cache flushing that slow things down
+- change python options on xend to reduce selinux problems (#845444)
+
+* Thu Jul 26 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-24
+- in rare circumstances an unprivileged user can crash an HVM guest
+  [XSA-10,CVE-2012-3432] (#843766)
+
+* Tue Jul 24 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-23
+- add a patch to remove a dependency on PyXML and Require python-lxml
+  instead of PyXML (#842843)
+
+* Sun Jul 22 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-22
+- adjust systemd service files not to report failures when running without
+  a hypervisor or when xendomains.service doesn't find anything to start
+
+* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.1.2-21
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jun 12 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-20
+- Apply three security patches
+  64-bit PV guest privilege escalation vulnerability [CVE-2012-0217]
+  guest denial of service on syscall/sysenter exception generation
+    [CVE-2012-0218]
+  PV guest host Denial of Service [CVE-2012-2934]
+
+* Sat Jun 09 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-19
+- adjust xend.service systemd file to avoid selinux problems
+
+* Fri Jun 08 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-18
+- Enable xenconsoled by default under systemd (#829732)
+
+* Thu May 17 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-16 4.1.2-17
+- make pygrub cope better with big files from guest (#818412 CVE-2012-2625)
+- add patch from 4.1.3-rc2-pre to build on F17/8
+
+* Sun Apr 15 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-15
+- Make the udev tap rule more specific as it breaks openvpn (#812421)
+- don't try setuid in xend if we don't need to so selinux is happier
+
+* Sat Mar 31 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-14
+- /var/lib/xenstored mount has wrong selinux permissions in latest Fedora
+- load xen-acpi-processor module (kernel 3.4 onwards) if present
+
+* Thu Mar 08 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-13
+- fix a packaging error
+
+* Thu Mar 08 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-12
+- fix an error in an rpm script from the sysv configuration removal
+- migrate xendomains script to systemd
+
+* Wed Feb 29 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-11
+- put the systemd files back in the right place
+
+* Wed Feb 29 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-10
+- clean up systemd and sysv configuration including removal of migrated
+  sysv files for fc17+
+
+* Sat Feb 18 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-9
+- move xen-watchdog to systemd
+
+* Wed Feb 08 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-8
+- relocate systemd files for fc17+
+
+* Tue Feb 07 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-7
+- move xend and xenconsoled to systemd
+
+* Thu Feb 02 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-6
+- Fix buffer overflow in e1000 emulation for HVM guests [CVE-2012-0029]
+
+* Sat Jan 28 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-5
+- Start building xen's ocaml libraries if appropriate unless --without ocaml
+  was specified
+- add some backported patches from xen unstable (via Debian) for some
+  ocaml tidying and fixes
+
+* Sun Jan 15 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-4
+- actually apply the xend-pci-loop.patch
+- compile fixes for gcc-4.7
+
+* Wed Jan 11 2012 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-3
+- Add xend-pci-loop.patch to stop xend crashing with weird PCI cards (#767742)
+- avoid a backtrace if xend can't log to the standard file or a 
+  temporary directory (part of #741042)
+
+* Mon Nov 21 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-2
+- Fix lost interrupts on emulated devices
+- stop xend crashing if its state files are empty at start up
+- avoid a python backtrace if xend is run on bare metal
+- update grub2 configuration after the old hypervisor has gone
+- move blktapctrl to systemd
+- Drop obsolete dom0-kernel.repo file
+
+* Fri Oct 21 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.2-1
+- update to 4.1.2
+  remove upstream patches xen-4.1-testing.23104 and xen-4.1-testing.23112
+
+* Fri Oct 14 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-8
+- more pygrub improvements for grub2 on guest
+
+* Thu Oct 13 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-7
+- make pygrub work better with GPT partitions and grub2 on guest
+
+* Thu Sep 29 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-5 4.1.1-6
+- improve systemd functionality
+
+* Wed Sep 28 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-4
+- lsb header fixes - xenconsoled shutdown needs xenstored to be running
+- partial migration to systemd to fix shutdown delays
+- update grub2 configuration after hypervisor updates
+
+* Sun Aug 14 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-3
+- untrusted guest controlling PCI[E] device can lock up host CPU [CVE-2011-3131]
+
+* Wed Jul 20 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-2
+- clean up patch to solve a problem with hvmloader compiled with gcc 4.6
+
+* Wed Jun 15 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.1-1
+- update to 4.1.1
+  includes various bugfixes and fix for [CVE-2011-1898] guest with pci
+  passthrough can gain privileged access to base domain
+- remove upstream cve-2011-1583-4.1.patch 
+
+* Mon May 09 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.0-2
+- Overflows in kernel decompression can allow root on xen PV guest to gain
+  privileged access to base domain, or access to xen configuration info.
+  Lack of error checking could allow DoS attack from guest [CVE-2011-1583]
+- Don't require /usr/bin/qemu-nbd as it isn't used at present.
+
+* Fri Mar 25 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.0-1
+- update to 4.1.0 final
+
+* Tue Mar 22 2011 Michael Young <m.a.young@durham.ac.uk> - 4.1.0-0.1.rc8
+- update to 4.1.0-rc8 release candidate
+- create xen-4.1.0-rc8.tar.xz file from git/hg repositories
+- rebase xen-initscript.patch xen-dumpdir.patch
+  xen-net-disable-iptables-on-bridge.patch localgcc45fix.patch
+  sysconfig.xenstored init.xenstored
+- remove unnecessary or conflicting xen-xenstore-cli.patch localpy27fixes.patch
+  xen.irq.fixes.patch xen.xsave.disable.patch xen.8259afix.patch
+  localcleanups.patch libpermfixes.patch
+- add patch to allow pygrub to work with single partitions with boot sectors
+- create ipxe-git-v1.0.0.tar.gz from http://git.ipxe.org/ipxe.git
+  to avoid downloading at build time
+- no need to move udev rules or init scripts as now created in the right place
+- amend list of files shipped - remove fs-backend
+  add init.d scripts xen-watchdog xencommons
+  add config files xencommons xl.conf cpupool
+  add programs kdd tap-ctl xen-hptool xen-hvmcrash xenwatchdogd
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0.1-10
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Jan 31 2011 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-9
+- Make libraries executable so that rpm gets dependencies right
+
+* Sat Jan 29 2011 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-8
+- Temporarily turn off some compile options so it will build on rawhide
+
+* Fri Jan 28 2011 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-7
+- ghost directories in /var/run (#656724)
+- minor fixes to /usr/share/doc/xen-doc-4.?.?/misc/network_setup.txt (#653159)
+  /etc/xen/scripts/network-route, /etc/xen/scripts/vif-common.sh (#669747)
+  and /etc/sysconfig/modules/xen.modules (#656536)
+
+* Tue Oct 12 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-6
+- add upstream xen patch xen.8259afix.patch to fix boot panic
+  "IO-APIC + timer doesn't work!" (#642108)
+
+* Thu Oct 07 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-5
+- add ext4 support for pvgrub (grub-ext4-support.patch from grub-0.97-66.fc14)
+
+* Wed Sep 29 2010 jkeating - 4.0.1-4
+- Rebuilt for gcc bug 634757
+
+* Fri Sep 24 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-3
+- create symlink for qemu-dm on x86_64 for compatibility with 3.4
+- apply some patches destined for 4.0.2
+    add some irq fixes
+    disable xsave which causes problems for HVM
+
+* Sun Aug 29 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-2
+- fix compile problems on Fedora 15, I suspect due to gcc 4.5.1
+
+* Wed Aug 25 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.1-1
+- update to 4.0.1 release - many bug fixes
+- xen-dev-create-cleanup.patch no longer needed
+- remove part of localgcc45fix.patch no longer needed
+- package new files /etc/bash_completion.d/xl.sh
+  and /usr/sbin/gdbsx
+- add patch to get xm and xend working with python 2.7
+
+* Mon Aug 2 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.0-5
+- add newer module names and xen-gntdev to xen.modules
+- Update dom0-kernel.repo file to use repos.fedorapeople.org location
+
+* Mon Jul 26 2010 Michael Young <m.a.young@durham.ac.uk>
+- create a xen-licenses package to satisfy revised the Fedora
+  Licensing Guidelines
+
+* Sun Jul 25 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.0-4
+- fix gcc 4.5 compile problems
+
+* Thu Jul 22 2010 David Malcolm <dmalcolm@redhat.com> - 4.0.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild
+
+* Sun Jun 20 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.0-2
+- add patch to remove some old device creation code that doesn't
+  work with the latest pvops kernels
+
+* Mon Jun 7 2010 Michael Young <m.a.young@durham.ac.uk> - 4.0.0-1
+- update to 4.0.0 release
+- rebase xen-initscript.patch and xen-dumpdir.patch patches
+- adjust spec file for files added to or removed from the packages
+- add new build dependencies libuuid-devel and iasl
+
+* Tue Jun 1 2010 Michael Young <m.a.young@durham.ac.uk> - 3.4.3-1
+- update to 3.4.3 release including
+    support for latest pv_ops kernels (possibly incomplete)
+    should fix build problems (#565063) and crashes (#545307)
+- replace Prereq: with Requires: in spec file
+- drop static libraries (#556101)
+
+* Thu Dec 10 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.2-2
+- adapt module load script to evtchn.ko -> xen-evtchn.ko rename.
+
+* Thu Dec 10 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.2-1
+- update to 3.4.2 release.
+- drop backport patches.
+
+* Thu Oct 8 2009 Justin M. Forbes <jforbes@redhat.com> - 3.4.1-5
+- add PyXML to dependencies. (#496135)
+- Take ownership of {_libdir}/fs (#521806)
+
+* Mon Sep 14 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.1-4
+- add e2fsprogs-devel to build dependencies.
+
+* Wed Sep 2 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.1-3
+- swap bzip2+xz linux kernel compression support patches.
+- backport one more bugfix (videoram option).
+
+* Tue Sep 1 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.1-2
+- backport bzip2+xz linux kernel compression support.
+- backport a few bugfixes.
+
+* Fri Aug 7 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.1-1
+- update to 3.4.1 release.
+
+* Wed Aug 5 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.0-4
+- Kill info files.  No xen docs, just standard gnu stuff.
+- kill -Werror in tools/libxc to fix build.
+
+* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.4.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Thu May 28 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.0-2
+- rename info files to fix conflict with binutils.
+- add install-info calls for the doc subpackage.
+- un-parallelize doc build.
+
+* Wed May 27 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.4.0-1
+- update to version 3.4.0.
+- cleanup specfile, add doc subpackage.
+
+* Tue Mar 10 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-11
+- fix python 2.6 warnings.
+
+* Fri Mar 6 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-9
+- fix xen.modules init script for pv_ops kernel.
+- stick rpm release tag into XEN_VENDORVERSION.
+- use %{ix86} macro in ExclusiveArch.
+- keep blktapctrl turned off by default.
+
+* Mon Mar 2 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-7
+- fix xenstored init script for pv_ops kernel.
+
+* Fri Feb 27 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-6
+- fix xenstored crash.
+- backport qemu-unplug patch.
+
+* Tue Feb 24 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-5
+- fix gcc44 build (broken constrain in inline asm).
+- fix ExclusiveArch
+
+* Tue Feb 3 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-3
+- backport bzImage support for dom0 builder.
+
+* Sun Jan 18 2009 Tomas Mraz <tmraz@redhat.com> - 3.3.1-2
+- rebuild with new openssl
+
+* Thu Jan 8 2009 Gerd Hoffmann <kraxel@redhat.com> - 3.3.1-1
+- update to xen 3.3.1 release.
+
+* Wed Dec 17 2008 Gerd Hoffmann <kraxel@redhat.com> - 3.3.0-2
+- build and package stub domains (pvgrub, ioemu).
+- backport unstable fixes for pv_ops dom0.
+
+* Sat Nov 29 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm@gmail.com> - 3.3.0-1.1
+- Rebuild for Python 2.6
+
+* Fri Aug 29 2008 Daniel P. Berrange <berrange@redhat.com> - 3.3.0-1.fc10
+- Update to xen 3.3.0 release
+
+* Wed Jul 23 2008 Mark McLoughlin <markmc@redhat.com> - 3.2.0-17.fc10
+- Enable xen-hypervisor build
+- Backport support for booting DomU from bzImage
+- Re-diff all patches for zero fuzz
+
+* Wed Jul  9 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-16.fc10
+- Remove bogus ia64 hypercall arg (rhbz #433921)
+
+* Fri Jun 27 2008 Markus Armbruster <armbru@redhat.com> - 3.2.0-15.fc10
+- Re-enable QEMU image format auto-detection, without the security
+  loopholes
+
+* Wed Jun 25 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-14.fc10
+- Rebuild for GNU TLS ABI change
+
+* Fri Jun 13 2008 Markus Armbruster <armbru@redhat.com> - 3.2.0-13.fc10
+- Correctly limit PVFB size (CVE-2008-1952)
+
+* Tue Jun  3 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-12.fc10
+- Move /var/run/xend into xen-runtime for pygrub (rhbz #442052)
+
+* Wed May 14 2008 Markus Armbruster <armbru@redhat.com> - 3.2.0-11.fc10
+- Disable QEMU image format auto-detection (CVE-2008-2004)
+- Fix PVFB to validate frame buffer description (CVE-2008-1943)
+
+* Wed Feb 27 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-10.fc9
+- Fix block device checks for extendable disk formats
+
+* Wed Feb 27 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-9.fc9
+- Let XenD setup QEMU logfile (rhbz #435164)
+- Fix PVFB use of event channel filehandle
+
+* Sat Feb 23 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-8.fc9
+- Fix block device extents check (rhbz #433560)
+
+* Mon Feb 18 2008 Mark McLoughlin <markmc@redhat.com> - 3.2.0-7.fc9
+- Restore some network-bridge patches lost during 3.2.0 rebase
+
+* Wed Feb  6 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-6.fc9
+- Fixed xenstore-ls to automatically use xenstored socket as needed
+
+* Sun Feb  3 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-5.fc9
+- Fix timer mode parameter handling for HVM
+- Temporarily disable all Latex docs due to texlive problems (rhbz #431327)
+
+* Fri Feb  1 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-4.fc9
+- Add a xen-runtime subpackage to allow use of Xen without XenD
+- Split init script out to one script per daemon
+- Remove unused / broken / obsolete tools
+
+* Mon Jan 21 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-3.fc9
+- Remove legacy dependancy on python-virtinst
+
+* Mon Jan 21 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-2.fc9
+- Added XSM header files to -devel RPM
+
+* Fri Jan 18 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-1.fc9
+- Updated to 3.2.0 final release
+
+* Thu Jan 10 2008 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-0.fc9.rc5.dev16701.1
+- Rebase to Xen 3.2 rc5 changeset 16701
+
+* Thu Dec 13 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.2-3.fc9
+- Re-factor to make it easier to test dev trees in RPMs
+- Include hypervisor build if doing a dev RPM
+
+* Fri Dec 07 2007 Release Engineering <rel-eng@fedoraproject.org> - 3.1.2-2.fc9
+- Rebuild for deps
+
+* Sat Dec  1 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.2-1.fc9
+- Upgrade to 3.1.2 bugfix release
+
+* Sat Nov  3 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-14.fc9
+- Disable network-bridge script since it conflicts with NetworkManager
+  which is now on by default
+
+* Fri Oct 26 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-13.fc9
+- Fixed xenbaked tmpfile flaw (CVE-2007-3919)
+
+* Wed Oct 10 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-12.fc8
+- Pull in QEMU BIOS boot menu patch from KVM package
+- Fix QEMU patch for locating x509 certificates based on command line args
+- Add XenD config options for TLS x509 certificate setup
+
+* Wed Sep 26 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-11.fc8
+- Fixed rtl8139 checksum calculation for Vista (rhbz #308201)
+
+* Wed Sep 26 2007 Chris Lalancette <clalance@redhat.com> - 3.1.0-10.fc8
+- QEmu NE2000 overflow check - CVE-2007-1321
+- Pygrub guest escape - CVE-2007-4993
+
+* Mon Sep 24 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-9.fc8
+- Fix generation of manual pages (rhbz #250791)
+- Really fix FC-6 32-on-64 guests
+
+* Mon Sep 24 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-8.fc8
+- Make 32-bit FC-6 guest PVFB work on x86_64 host
+
+* Mon Sep 24 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-7.fc8
+- Re-add support for back-compat FC6 PVFB support
+- Fix handling of explicit port numbers (rhbz #279581)
+
+* Wed Sep 19 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-6.fc8
+- Don't clobber the VIF type attribute in FV guests (rhbz #296061)
+
+* Tue Aug 28 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-5.fc8
+- Added dep on openssl for blktap-qcow
+
+* Tue Aug 28 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-4.fc8
+- Switch PVFB over to use QEMU
+- Backport QEMU VNC security patches for TLS/x509
+
+* Wed Aug  1 2007 Markus Armbruster <armbru@redhat.com> - 3.1.0-3.fc8
+- Put guest's native protocol ABI into xenstore, to provide for older
+  kernels running 32-on-64.
+- VNC keymap fixes
+- Fix race conditions in LibVNCServer on client disconnect
+
+* Tue Jun 12 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-2.fc8
+- Remove patch which kills VNC monitor
+- Fix HVM save/restore file path to be /var/lib/xen instead of /tmp
+- Don't spawn a bogus xen-vncfb daemon for HVM guests
+- Add persistent logging of hypervisor & guest consoles
+- Add /etc/sysconfig/xen to allow admin choice of logging options
+- Re-write Xen startup to use standard init script functions
+- Add logrotate configuration for all xen related logs
+
+* Fri May 25 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-1.fc8
+- Updated to official 3.1.0 tar.gz
+- Fixed data corruption from VNC client disconnect (bz 241303)
+
+* Thu May 17 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-0.rc7.2.fc7
+- Ensure xen-vncfb processes are cleanedup if guest quits (bz 240406)
+- Tear down guest if device hotplug fails
+
+* Thu May  3 2007 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-0.rc7.1.fc7
+- Updated to 3.1.0 rc7, changeset  15021 (upstream renumbered from 3.0.5)
+
+* Tue May  1 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc4.4.fc7
+- Fix op_save RPC API
+
+* Mon Apr 30 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc4.3.fc7
+- Added BR on gettext
+
+* Mon Apr 30 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc4.2.fc7
+- Redo failed build.
+
+* Mon Apr 30 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc4.1.fc7
+- Updated to 3.0.5 rc4, changeset 14993
+- Reduce number of xenstore transactions used for listing domains
+- Hack to pre-balloon 2 MB for PV guests as well as HVM
+
+* Thu Apr 26 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc3.14934.2.fc7
+- Fixed display of bootloader menu with xm create -c
+- Added modprobe for both xenblktap & blktap to deal with rename issues
+- Hack to pre-balloon 10 MB for HVM guests
+
+* Thu Apr 26 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc3.14934.1.fc7
+- Updated to 3.0.5 rc3, changeset 14934
+- Fixed networking for service xend restart & minor IPv6 tweak
+
+* Tue Apr 24 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc2.14889.2.fc7
+- Fixed vfb/vkbd device startup race
+
+* Tue Apr 24 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.5-0.rc2.14889.1.fc7
+- Updated to xen 3.0.5 rc2, changeset 14889
+- Remove use of netloop from network-bridge script
+- Add backcompat support to vif-bridge script to translate xenbrN to ethN
+
+* Wed Mar 14 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-9.fc7
+- Disable access to QEMU monitor over VNC (CVE-2007-0998, bz 230295)
+
+* Tue Mar  6 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-8.fc7
+- Close QEMU file handles when running network script
+
+* Fri Mar  2 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-7.fc7
+- Fix interaction of bootloader with blktap (bz 230702)
+- Ensure PVFB daemon terminates if domain doesn't startup (bz 230634)
+
+* Thu Feb  8 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-6.fc7
+- Setup readonly loop devices for readonly disks
+- Extended error reporting for hotplug scripts
+- Pass all 8 mouse buttons from VNC through to kernel
+
+* Tue Jan 30 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-5.fc7
+- Don't run the pvfb daemons for HVM guests (bz 225413)
+- Fix handling of vnclisten parameter for HVM guests
+
+* Tue Jan 30 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-4.fc7
+- Fix pygrub memory corruption
+
+* Tue Jan 23 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-3.fc7
+- Added PVFB back compat for FC5/6 guests
+
+* Mon Jan 22 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-2.fc7
+- Ensure the arch-x86 header files are included in xen-devel package
+- Bring back patch to move /var/xen/dump to /var/lib/xen/dump
+- Make /var/log/xen mode 0700
+
+* Thu Jan 11 2007 Daniel P. Berrange <berrange@redhat.com> - 3.0.4-1
+- Upgrade to official xen-3.0.4_1 release tarball
+
+* Thu Dec 14 2006 Jeremy Katz <katzj@redhat.com> - 3.0.3-3
+- fix the build
+
+* Thu Dec  7 2006 Jeremy Katz <katzj@redhat.com> - 3.0.3-2
+- rebuild for python 2.5
+
+* Tue Oct 24 2006 Daniel P. Berrange <berrange@redhat.com> - 3.0.3-1
+- Pull in the official 3.0.3 tarball of xen (changeset 11774).
+- Add patches for VNC password authentication (bz 203196)
+- Switch /etc/xen directory to be mode 0700 because the config files
+  can contain plain text passwords (bz 203196)
+- Change the package dependency to python-virtinst to reflect the
+  package name change.
+- Fix str-2-int cast of VNC port for paravirt framebuffer (bz 211193)
+
+* Wed Oct  4 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-44
+- fix having "many" kernels in pygrub
+
+* Wed Oct  4 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-43
+- Fix SMBIOS tables for SVM guests [danpb] (bug 207501)
+
+* Fri Sep 29 2006 Daniel P. Berrange <berrange@redhat.com> - 3.0.2-42
+- Added vnclisten patches to make VNC only listen on localhost
+  out of the box, configurable by 'vnclisten' parameter (bz 203196)
+
+* Thu Sep 28 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-41
+- Update to xen-3.0.3-testing changeset 11633
+
+* Thu Sep 28 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-40
+- Workaround blktap/xenstore startup race
+- Add udev rules for xen blktap devices (srostedt)
+- Add support for dynamic blktap device nodes (srostedt)
+- Fixes for infinite dom0 cpu usage with blktap
+- Fix xm not to die on malformed "tap:" blkif config string
+- Enable blktap on kernels without epoll-for-aio support.
+- Load the blktap module automatically at startup
+- Reenable blktapctrl
+
+* Wed Sep 27 2006 Daniel Berrange <berrange@redhat.com> - 3.0.2-39
+- Disable paravirt framebuffer server side rendered cursor (bz 206313)
+- Ignore SIGPIPE in paravirt framebuffer daemon to avoid terminating
+  on client disconnects while writing data (bz 208025)
+
+* Wed Sep 27 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-38
+- Fix cursor in pygrub (#208041)
+
+* Tue Sep 26 2006 Daniel P. Berrange <berrange@redhat.com> - 3.0.2-37
+- Removed obsolete scary warnings in package description
+
+* Thu Sep 21 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-36
+- Add Requires: kpartx for dom0 access to domU data
+
+* Wed Sep 20 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-35
+- Don't strip qemu-dm early, so that we get proper debuginfo (danpb)
+- Fix compile problem with latest glibc
+
+* Wed Sep 20 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-34
+- Update to xen-unstable changeset 11539
+- Threading fixes for libVNCserver (danpb)
+
+* Tue Sep  5 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-33
+- update pvfb patch based on upstream feedback
+
+* Tue Sep  5 2006 Juan Quintela <quintela@redhat.com> - 3.0.2-31
+- re-enable ia64.
+
+* Thu Aug 31 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-31
+- update to changeset 11405
+
+* Thu Aug 31 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-30
+- fix pvfb for x86_64
+
+* Wed Aug 30 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-29
+- update libvncserver to hopefully fix problems with vnc clients disconnecting
+
+* Tue Aug 29 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-28
+- fix a typo
+
+* Mon Aug 28 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-27
+- add support for paravirt framebuffer
+
+* Mon Aug 28 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-26
+- update to xen-unstable cs 11251
+- clean up patches some
+- disable ia64 as it doesn't currently build 
+
+* Tue Aug 22 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-25
+- make initscript not spew on non-xen kernels (#202945)
+
+* Mon Aug 21 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-24
+- remove copy of xenguest-install from this package, require 
+  python-xeninst (the new home of xenguest-install)
+
+* Wed Aug  2 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-23
+- add patch to fix rtl8139 in FV, switch it back to the default nic
+- add necessary ia64 patches (#201040)
+- build on ia64
+
+* Fri Jul 28 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-22
+- add patch to fix net devices for HVM guests 
+
+* Fri Jul 28 2006 Rik van Riel <riel@redhat.com> - 3.0.2-21
+- make sure disk IO from HVM guests actually hits disk (#198851)
+
+* Fri Jul 28 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-20
+- don't start blktapctrl for now
+- fix HVM guest creation in xenguest-install
+- make sure log files have the right SELinux label
+
+* Tue Jul 25 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-19
+- fix libblktap symlinks (#199820)
+- make libxenstore executable (#197316)
+- version libxenstore (markmc) 
+
+* Fri Jul 21 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-18
+- include /var/xen/dump in file list
+- load blkbk, netbk and netloop when xend starts
+- update to cs 10712
+- avoid file conflicts with qemu (#199759)
+
+* Wed Jul 19 2006 Mark McLoughlin <markmc@redhat.com> - 3.0.2-17
+- libxenstore is unversioned, so make xen-libs own it rather
+  than xen-devel
+
+* Wed Jul 19 2006 Mark McLoughlin <markmc@redhat.com> 3.0.2-16
+- Fix network-bridge error (#199414)
+
+* Mon Jul 17 2006 Daniel Veillard <veillard@redhat.com> - 3.0.2-15
+- desactivating the relocation server in xend conf by default and
+  add a warning text about it.
+
+* Thu Jul 13 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-14
+- Compile fix: don't #include <linux/compiler.h>
+
+* Thu Jul 13 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-13
+- Update to xen-unstable cset 10675
+- Remove internal libvncserver build, new qemu device model has its own one
+  now.
+- Change default FV NIC model from rtl8139 to ne2k_pci until the former works
+  better
+
+* Tue Jul 11 2006 Daniel Veillard <veillard@redhat.com> - 3.0.2-12
+- bump libvirt requires to 0.1.2
+- drop xend httpd localhost server and use the unix socket instead
+
+* Mon Jul 10 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-11
+- split into main packages + -libs and -devel subpackages for #198260
+- add patch from jfautley to allow specifying other bridge for 
+  xenguest-install (#198097)
+
+* Mon Jul  3 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-10
+- make xenguest-install work with relative paths to disk 
+  images (markmc, #197518)
+
+* Fri Jun 23 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-9
+- own /var/run/xend for selinux (#196456, #195952)
+
+* Tue Jun 13 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-8
+- fix syntax error in xenguest-install
+
+* Mon Jun 12 2006 Daniel Veillard <veillard@redhat.com> - 3.0.2-7
+- more initscript patch to report status #184452
+
+* Wed Jun  7 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-6
+- Add BuildRequires: for gnu/stubs-32.h so that x86_64 builds pick up
+  glibc32 correctly
+
+* Wed Jun  7 2006 Stephen C. Tweedie <sct@redhat.com> - 3.0.2-5
+- Rebase to xen-unstable cset 10278
+
+* Fri May  5 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-4
+- update to new snapshot (changeset 9925)
+
+* Thu Apr 27 2006 Daniel Veillard <veillard@redhat.com> - 3.0.2-3
+- xen.h now requires xen-compat.h, install it too
+
+* Wed Apr 26 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-2
+- -m64 patch isn't needed anymore either
+
+* Tue Apr 25 2006 Jeremy Katz <katzj@redhat.com> - 3.0.2-1
+- update to post 3.0.2 snapshot (changeset:   9744:1ad06bd6832d)
+- stop applying patches that are upstreamed
+- add patches for bootloader to run on all domain creations
+- make xenguest-install create a persistent uuid
+- use libvirt for domain creation in xenguest-install, slightly improve 
+  error handling
+
+* Tue Apr 18 2006 Daniel Veillard <veillard@redhat.com> - 3.0.1-5
+- augment the close on exec patch with the fix for #188361
+
+* Thu Mar  9 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-4
+- add udev rule so that /dev/xen/evtchn gets created properly
+- make pygrub not use /tmp for SELinux
+- make xenguest-install actually unmount its nfs share.  also, don't use /tmp
+
+* Tue Mar  7 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-3
+- set /proc/xen/privcmd and /var/log/xend-debug.log as close on exec to avoid
+  SELinux problems
+- give better feedback on invalid urls (#184176)
+
+* Mon Mar  6 2006 Stephen Tweedie <sct@redhat.com> - 3.0.1-2
+- Use kva mmap to find the xenstore page (upstream xen-unstable cset 9130)
+
+* Mon Mar  6 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-1
+- fix xenguest-install so that it uses phy: for block devices instead of 
+  forcing them over loopback.  
+- change package versioning to be a little more accurate
+
+* Thu Mar  2 2006 Stephen Tweedie <sct@redhat.com> - 3.0.1-0.20060301.fc5.3
+- Remove unneeded CFLAGS spec file hack
+
+* Thu Mar  2 2006 Rik van Riel <riel@redhat.com> - 3.0.1-0.20060301.fc5.2
+- fix 64 bit CFLAGS issue with vmxloader and hvmloader
+
+* Wed Mar  1 2006 Stephen Tweedie <sct@redhat.com> - 3.0.1-0.20060301.fc5.1
+- Update to xen-unstable cset 9022
+
+* Tue Feb 28 2006 Stephen Tweedie <sct@redhat.com> - 3.0.1-0.20060228.fc5.1
+- Update to xen-unstable cset 9015
+
+* Thu Feb 23 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-0.20060208.fc5.3
+- add patch to ensure we get a unique fifo for boot loader (#182328)
+- don't try to read the whole disk if we can't find a partition table 
+  with pygrub 
+- fix restarting of domains (#179677)
+
+* Thu Feb  9 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-0.20060208.fc5.2
+- fix -h conflict for xenguest-isntall
+
+* Wed Feb  8 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-0.20060208.fc5.1
+- turn on http listener so you can do things with libvir as a user
+
+* Wed Feb  8 2006 Jeremy Katz <katzj@redhat.com> - 3.0.1-0.20060208.fc5
+- update to current hg snapshot for HVM support
+- update xenguest-install for hvm changes.  allow hvm on svm hardware
+- fix a few little xenguest-install bugs
+
+* Tue Feb  7 2006 Jeremy Katz <katzj@redhat.com> - 3.0-0.20060130.fc5.6
+- add a hack to fix VMX guests with video to balloon enough (#180375)
+
+* Tue Feb  7 2006 Jeremy Katz <katzj@redhat.com> - 3.0-0.20060130.fc5.5
+- fix build for new udev
+
+* Tue Feb  7 2006 Jeremy Katz <katzj@redhat.com> - 3.0-0.20060130.fc5.4
+- patch from David Lutterkort to pass macaddr (-m) to xenguest-install
+- rework xenguest-install a bit so that it can be used for creating 
+  fully-virtualized guests as well as paravirt.  Run with --help for 
+  more details (or follow the prompts)
+- add more docs (noticed by Andrew Puch)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 3.0-0.20060130.fc5.3.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Thu Feb  2 2006 Bill Nottingham <notting@redhat.com> 3.0-0.20060130.fc5.3
+- disable iptables/ip6tables/arptables on bridging when bringing up a
+  Xen bridge. If complicated filtering is needed that uses this, custom
+  firewalls will be needed. (#177794)
+
+* Tue Jan 31 2006 Bill Nottingham <notting@redhat.com> 3.0-0.20060130.fc5.2
+- use the default network device, don't hardcode eth0
+
+* Tue Jan 31 2006  <sct@redhat.com> - 3.0-0.20060130.fc5.1
+- Add xenguest-install.py in /usr/sbin
+
+* Mon Jan 30 2006  <sct@redhat.com> - 3.0-0.20060130.fc5
+- Update to xen-unstable from 20060130 (cset 8705)
+
+* Wed Jan 25 2006 Jeremy Katz <katzj@redhat.com> - 3.0-0.20060110.fc5.5
+- buildrequire dev86 so that vmx firmware gets built
+- include a copy of libvncserver and build vmx device models against it 
+
+* Tue Jan 24 2006 Bill Nottingham <notting@redhat.com> - 3.0-0.20060110.fc5.4
+- only put the udev rules in one place
+
+* Fri Jan 20 2006 Jeremy Katz <katzj@redhat.com> - 3.0-0.20060110.fc5.3
+- move xsls to xenstore-ls to not conflict (#171863)
+
+* Tue Jan 10 2006  <sct@redhat.com> - 3.0-0.20060110.fc5.1
+- Update to xen-unstable from 20060110 (cset 8526)
+
+* Thu Dec 22 2005 Jesse Keating <jkeating@redhat.com> - 3.0-0.20051206.fc5.2
+- rebuilt
+
+* Tue Dec  6 2005 Juan Quintela <quintela@trasno.org> - 3.0-0.20051206.fc5.1
+- 20051206 version (should be 3.0.0).
+- Remove xen-bootloader fixes (integrated upstream).
+
+* Wed Nov 30 2005 Daniel Veillard <veillard@redhat.com> - 3.0-0.20051109.fc5.4
+- adding missing headers for libxenctrl and libxenstore
+- use libX11-devel build require instead of xorg-x11-devel
+
+* Mon Nov 14 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051109.fc5.3
+- change default dom0 min-mem to 256M so that dom0 will try to balloon down
+
+* Sat Nov 12 2005 Jeremy Katz <katzj@redhat.com>
+- buildrequire ncurses-devel (reported by Justin Dearing)
+
+* Thu Nov 10 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051109.fc5.2
+- actually enable the initscripts
+
+* Wed Nov  9 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051109.fc5.1
+- udev rules moved
+
+* Wed Nov  9 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051109.fc5
+- update to current -unstable
+- add patches to fix pygrub 
+
+* Wed Nov  9 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051108.fc5
+- update to current -unstable
+
+* Fri Oct 21 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20051021.fc5
+- update to current -unstable
+
+* Thu Sep 15 2005 Jeremy Katz <katzj@redhat.com> - 3.0-0.20050912.fc5.1
+- doesn't require twisted anymore
+
+* Mon Sep 12 2005 Rik van Riel <riel@redhat.com> 3.0-0.20050912.fc5
+- add /var/{lib,run}/xenstored to the %files section (#167496, #167121)
+- upgrade to today's Xen snapshot
+- some small build fixes for x86_64
+- enable x86_64 builds
+
+* Thu Sep  8 2005 Rik van Riel <riel@redhat.com> 3.0-0.20050908
+- explicitly call /usr/sbin/xend from initscript (#167407)
+- add xenstored directories to spec file (#167496, #167121)
+- misc gcc4 fixes 
+- spec file cleanups (#161191)
+- upgrade to today's Xen snapshot
+- change the version to 3.0-0.<date> (real 3.0 release will be 3.0-1)
+
+* Tue Aug 23 2005 Rik van Riel <riel@redhat.com> 2-20050823
+- upgrade to today's Xen snapshot
+
+* Mon Aug 15 2005 Rik van Riel <riel@redhat.com> 2-20050726
+- upgrade to a known-working newer Xen, now that execshield works again
+
+* Mon May 30 2005 Rik van Riel <riel@redhat.com> 2-20050530
+- create /var/lib/xen/xen-db/migrate directory so "xm save" works (#158895)
+
+* Mon May 23 2005 Rik van Riel <riel@redhat.com> 2-20050522
+- change default display method for VMX domains to SDL
+
+* Fri May 20 2005 Rik van Riel <riel@redhat.com> 2-20050520
+- qemu device model for VMX
+
+* Thu May 19 2005 Rik van Riel <riel@redhat.com> 2-20050519
+- apply some VMX related bugfixes
+
+* Mon Apr 25 2005 Rik van Riel <riel@redhat.com> 2-20050424
+- upgrade to last night's snapshot
+
+* Fri Apr 15 2005 Jeremy Katz <katzj@redhat.com>
+- patch manpath instead of moving in specfile.  patch sent upstream
+- install to native python path instead of /usr/lib/python
+- other misc specfile duplication cleanup
+
+* Sun Apr  3 2005 Rik van Riel <riel@redhat.com> 2-20050403
+- fix context switch between vcpus in same domain, vcpus > cpus works again
+
+* Sat Apr  2 2005 Rik van Riel <riel@redhat.com> 2-20050402
+- move initscripts to /etc/rc.d/init.d (Florian La Roche) (#153188)
+- ship only PDF documentation, not the PS or tex duplicates
+
+* Thu Mar 31 2005 Rik van Riel <riel@redhat.com> 2-20050331
+- upgrade to new xen hypervisor
+- minor gcc4 compile fix
+
+* Mon Mar 28 2005 Rik van Riel <riel@redhat.com> 2-20050328
+- do not yet upgrade to new hypervisor ;)
+- add barrier to fix SMP boot bug
+- add tags target
+- add zlib-devel build requires (#150952)
+
+* Wed Mar  9 2005 Rik van Riel <riel@redhat.com> 2-20050308
+- upgrade to last night's snapshot
+- new compile fix patch
+
+* Sun Mar  6 2005 Rik van Riel <riel@redhat.com> 2-20050305
+- the gcc4 compile patches are now upstream
+- upgrade to last night's snapshot, drop patches locally
+
+* Fri Mar  4 2005 Rik van Riel <riel@redhat.com> 2-20050303
+- finally got everything to compile with gcc4 -Wall -Werror
+
+* Thu Mar  3 2005 Rik van Riel <riel@redhat.com> 2-20050303
+- upgrade to last night's Xen-unstable snapshot
+- drop printf warnings patch, which is upstream now
+
+* Wed Feb 23 2005 Rik van Riel <riel@redhat.com> 2-20050222
+- upgraded to last night's Xen snapshot
+- compile warning fixes are now upstream, drop patch
+
+* Sat Feb 19 2005 Rik van Riel <riel@redhat.com> 2-20050219
+- fix more compile warnings
+- fix the fwrite return check
+
+* Fri Feb 18 2005 Rik van Riel <riel@redhat.com> 2-20050218
+- upgrade to last night's Xen snapshot
+- a kernel upgrade is needed to run this Xen, the hypervisor
+  interface changed slightly
+- comment out unused debugging function in plan9 domain builder
+  that was giving compile errors with -Werror
+
+* Tue Feb  8 2005 Rik van Riel <riel@redhat.com> 2-20050207
+- upgrade to last night's Xen snapshot
+
+* Tue Feb  1 2005 Rik van Riel <riel@redhat.com> 2-20050201.1
+- move everything to /var/lib/xen
+
+* Tue Feb  1 2005 Rik van Riel <riel@redhat.com> 2-20050201
+- upgrade to new upstream Xen snapshot
+
+* Tue Jan 25 2005 Jeremy Katz <katzj@redhat.com>
+- add buildreqs on python-devel and xorg-x11-devel (strange AT nsk.no-ip.org)
+
+* Mon Jan 24 2005 Rik van Riel <riel@redhat.com> - 2-20050124
+- fix /etc/xen/scripts/network to not break with ipv6 (also sent upstream)
+
+* Fri Jan 14 2005 Jeremy Katz <katzj@redhat.com> - 2-20050114
+- update to new snap
+- python-twisted is its own package now
+- files are in /usr/lib/python now as well, ugh.
+
+* Tue Jan 11 2005 Rik van Riel <riel@redhat.com>
+- add segment fixup patch from xen tree
+- fix %files list for python-twisted
+
+* Mon Jan 10 2005 Rik van Riel <riel@redhat.com>
+- grab newer snapshot, that does start up
+- add /var/xen/xend-db/{domain,vnet} to %files section
+
+* Thu Jan  6 2005 Rik van Riel <riel@redhat.com>
+- upgrade to new snapshot of xen-unstable
+
+* Mon Dec 13 2004 Rik van Riel <riel@redhat.com>
+- build python-twisted as a subpackage
+- update to latest upstream Xen snapshot
+
+* Sun Dec  5 2004 Rik van Riel <riel@redhat.com>
+- grab new Xen tarball (with wednesday's patch already included)
+- transfig is a buildrequire, add it to the spec file
+
+* Wed Dec  1 2004 Rik van Riel <riel@redhat.com>
+- fix up Che's spec file a little bit
+- create patch to build just Xen, not the kernels
+
+* Wed Dec 01 2004 Che
+- initial rpm release