debian/0000775000000000000000000000000013167432446007202 5ustar debian/xen-utils-4.4.lintian-overrides0000664000000000000000000000007012314615614015003 0ustar statically-linked-binary usr/lib/xen-4.4/boot/hvmloader debian/xen-utils-common.dirs0000664000000000000000000000001412316260750013266 0ustar var/lib/xen debian/control0000664000000000000000000001427012321772310010575 0ustar Source: xen Section: kernel Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Debian Xen Team Uploaders: Guido Trotter , Bastian Blank Standards-Version: 3.9.4 Build-Depends: debhelper (>> 7), dpkg-dev (>= 1.16.0~), lsb-release, python-dev, bcc, gcc-multilib [!arm64], e2fslibs-dev, iasl, ipxe-qemu, seabios, libaio-dev, libglib2.0-dev, libgnutls-dev, liblzma-dev, libncurses5-dev, libpci-dev, libyajl-dev, libssl-dev, pkg-config, uuid-dev, zlib1g-dev, ocaml-nox, dh-ocaml, ocaml-findlib, libfdt-dev [armhf arm64] XS-Python-Version: current Package: libxen-4.4 Architecture: amd64 i386 armhf arm64 Section: libs Depends: ${shlibs:Depends}, ${misc:Depends} Description: Public libs for Xen This package contains the shared libraries for Xen. Package: libxenstore3.0 Architecture: amd64 i386 armhf arm64 Section: libs Depends: ${shlibs:Depends}, ${misc:Depends} Description: Xenstore communications library for Xen This package contains the public libxenstore. Package: libxen-dev Architecture: amd64 i386 armhf arm64 Section: libdevel Depends: libxen-4.4 (= ${binary:Version}), libxenstore3.0 (= ${binary:Version}), ${misc:Depends} Description: Public headers and libs for Xen This package contains the public headers and static libraries for Xen. Package: xenstore-utils Architecture: amd64 i386 armhf arm64 Section: admin Depends: ${shlibs:Depends}, ${misc:Depends} Replaces: xen-utils-common (<= 3.1.0-1) Conflicts: xen-utils-common (<= 3.1.0-1) Description: Xenstore utilities for Xen This package contains the Xenstore utilities. Package: libxen-ocaml Architecture: amd64 i386 Section: ocaml Provides: ${ocaml:Provides} Depends: ${shlibs:Depends}, ${misc:Depends}, ${ocaml:Depends} Description: OCaml libraries for controlling Xen This package contains the runtime libraries required for the ocaml bindings to the Xen control libraries. Package: libxen-ocaml-dev Architecture: amd64 i386 Section: ocaml Provides: ${ocaml:Provides} Depends: libxen-ocaml (= ${binary:Version}), libxen-dev (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, ${ocaml:Depends} Description: OCaml libraries for controlling Xen (devel package) This package contains the ocaml findlib packages for compiling applications that are designed to control the Xen hypervisor. Package: xen-utils-common Architecture: all Depends: gawk, lsb-base, python, udev, xenstore-utils, ${misc:Depends} Description: Xen administrative tools - common files The userspace tools to manage a system virtualized through the Xen virtual machine monitor. Package: xen-utils-4.4 Architecture: amd64 i386 armhf arm64 Provides: xen-utils Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, xen-utils-common (>= ${source:Version}) Recommends: bridge-utils, libc6-xen [i386], xen-hypervisor-4.4, qemu-system-x86 [i386 amd64] Description: XEN administrative tools The userspace tools to manage a system virtualized through the XEN virtual machine monitor. Built-Using: ${misc:Built-Using} Package: xen-hypervisor-4.4-amd64 Architecture: amd64 i386 Provides: xen-hypervisor, xen-hypervisor-4.4, xen-hypervisor-amd64 Depends: ${misc:Depends} Recommends: xen-utils-4.4 Description: Xen Hypervisor on AMD64 The hypervisor is the "core" for XEN itself. It gets booted by the boot loader and controls cpu and memory, sharing them between your administrative domain (Domain 0) and the virtual guest systems. . In order to boot a XEN system along with this package you also need a kernel specifically crafted to work as the Domain 0, mediating hardware access for XEN itself. Package: xen-system-amd64 Architecture: amd64 i386 Provides: xen-system Depends: xen-hypervisor-4.4-amd64, xen-utils-4.4, ${misc:Depends} Description: Xen System on AMD64 (meta-package) This package depends on the latest Xen hypervisor for use on AMD64 and the Xen utils. Package: xen-hypervisor-4.4-armhf Architecture: armhf Provides: xen-hypervisor, xen-hypervisor-4.4, xen-hypervisor-armhf Depends: ${misc:Depends} Recommends: xen-utils-4.4 Description: Xen Hypervisor on Arm v7/v8 The hypervisor is the "core" for XEN itself. It gets booted by the boot loader and controls cpu and memory, sharing them between your administrative domain (Domain 0) and the virtual guest systems. . In order to boot a XEN system along with this package you also need a kernel specifically crafted to work as the Domain 0, mediating hardware access for XEN itself. Package: xen-system-armhf Architecture: armhf Provides: xen-system Depends: xen-hypervisor-4.4-armhf, xen-utils-4.4, ${misc:Depends} Description: Xen System on Arm v7/v8 (meta-package) This package depends on the latest Xen hypervisor for use on armhf and the Xen utils. Package: xen-hypervisor-4.4-arm64 Architecture: arm64 Provides: xen-hypervisor, xen-hypervisor-4.4, xen-hypervisor-arm64 Depends: ${misc:Depends} Recommends: xen-utils-4.4 Description: Xen Hypervisor on Arm64 The hypervisor is the "core" for XEN itself. It gets booted by the boot loader and controls cpu and memory, sharing them between your administrative domain (Domain 0) and the virtual guest systems. . In order to boot a XEN system along with this package you also need a kernel specifically crafted to work as the Domain 0, mediating hardware access for XEN itself. Package: xen-system-arm64 Architecture: arm64 Provides: xen-system Depends: xen-hypervisor-4.4-arm64, xen-utils-4.4, ${misc:Depends} Description: Xen System on Arm64 (meta-package) This package depends on the latest Xen hypervisor for use on armhf and the Xen utils. # # Transitional packages for upgrading # Package: xen-hypervisor-4.1-amd64 Architecture: amd64 i386 Depends: xen-system-amd64 Section: oldlibs Description: Transitional package for upgrade Package: xen-hypervisor-4.1-i386 Architecture: i386 Depends: xen-system-amd64 Section: oldlibs Description: Transitional package for upgrade Package: xen-hypervisor-4.3-amd64 Architecture: amd64 i386 Depends: xen-system-amd64 Section: oldlibs Description: Transitional package for upgrade Package: xen-hypervisor-4.3-armhf Architecture: armhf Depends: xen-system-armhf Section: oldlibs Description: Transitional package for upgrade debian/xen-utils-common.xendomains.init0000664000000000000000000001125512222512661015442 0ustar #!/bin/bash ### BEGIN INIT INFO # Provides: xendomains # Required-Start: $syslog $remote_fs xen # Required-Stop: $syslog $remote_fs xen # Should-Start: drbd iscsi openvswitch-switch # Should-Stop: drbd iscsi openvswitch-switch # X-Start-Before: corosync heartbeat # X-Stop-After: corosync heartbeat # 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 . /lib/init/vars.sh . /lib/lsb/init-functions TOOLSTACK=$(/usr/lib/xen-common/bin/xen-toolstack 2>/dev/null) if [ $? -ne 0 ]; then log_warning_msg "No usable Xen toolstack selected" exit 0 fi if [ "$(basename "$TOOLSTACK")" != xm ] && [ "$(basename "$TOOLSTACK")" != xl ]; then exit 0 fi xen list &> /dev/null if test $? -ne 0 then exit 0; fi if ! [ -e /proc/xen/privcmd ]; then exit 0 fi [ -r /etc/default/xendomains ] && . /etc/default/xendomains shopt -s nullglob check_config_name() { xen create --quiet --dryrun --defconfig "$1" | sed -n 's/^.*(name \(.*\))$/\1/p' } check_running() { xen domid "$1" > /dev/null 2>&1 return $? } timeout_coproc() { local TIMEOUT=$1 shift coproc "$@" 2>&1 1>/dev/null local COPROC_OUT exec {COPROC_OUT}<&"${COPROC[0]}" local PID="$COPROC_PID" for no in $(seq 0 $TIMEOUT); do if [ -z "$COPROC_PID" ]; then break; fi sleep 1 log_action_cont_msg done kill -INT "$COPROC_PID" >/dev/null 2>&1 wait $PID local rc=$? log_action_end_msg $rc [ $rc -gt 0 ] && cat <&$COPROC_OUT exec <&$COPROC_OUT- } timeout_domain() { name="$1" TIMEOUT="$2" for no in $(seq 0 $TIMEOUT); do if ! check_running "$name"; then return 0; fi sleep 1 log_action_cont_msg done return 1 } do_start_restore() { [ -n "$XENDOMAINS_SAVE" ] || return [ -d "$XENDOMAINS_SAVE" ] || return [ -n "$XENDOMAINS_RESTORE" ] || return for file in $XENDOMAINS_SAVE/*; do if [ -f $file ] ; then name="${file##*/}" log_action_begin_msg "Restoring Xen domain $name (from $file)" out=$(xen restore "$file" 2>&1 1>/dev/null) case "$?" in 0) rm "$file" domains[$name]='started' log_action_end_msg 0 ;; *) domains[$name]='failed' log_action_end_msg 1 echo "$out" ;; esac fi done } do_start_auto() { [ -n "$XENDOMAINS_AUTO" ] || return [ -d "$XENDOMAINS_AUTO" ] || return for file in $XENDOMAINS_AUTO/*; do name="$(check_config_name $file)" if [ "${domains[$name]}" = started ]; then : elif check_running "$name"; then log_action_msg "Xen domain $name already running" else log_action_begin_msg "Starting Xen domain $name (from $file)" if [ "${domains[$name]}" = failed ]; then log_action_end_msg 1 "restore failed" else out=$(xen create --quiet --defconfig "$file" 2>&1 1>/dev/null) case "$?" in 0) log_action_end_msg 0 ;; *) log_action_end_msg 1 echo "$out" ;; esac fi fi done } do_start() { declare -A domains do_start_restore do_start_auto } do_stop_migrate() { [ -n "$XENDOMAINS_MIGRATE" ] || return while read id name rest; do log_action_begin_msg "Migrating Xen domain $name ($id)" (timeout_coproc "$XENDOMAINS_STOP_MAXWAIT" xen migrate $id $XENDOMAINS_MIGRATE) done < <(/usr/lib/xen-common/bin/xen-init-list) } do_stop_save() { [ -n "$XENDOMAINS_SAVE" ] || return [ -d "$XENDOMAINS_SAVE" ] || mkdir -m 0700 -p "$XENDOMAINS_SAVE" while read id name rest; do log_action_begin_msg "Saving Xen domain $name ($id)" (timeout_coproc "$XENDOMAINS_STOP_MAXWAIT" xen save $id $XENDOMAINS_SAVE/$name) done < <(/usr/lib/xen-common/bin/xen-init-list) } do_stop_shutdown() { while read id name rest; do log_action_begin_msg "Shutting down Xen domain $name ($id)" xen shutdown $id 2>&1 1>/dev/null log_action_end_msg $? done < <(/usr/lib/xen-common/bin/xen-init-list) while read id name rest; do log_action_begin_msg "Waiting for Xen domain $name ($id) to shut down" timeout_domain "$name" "$XENDOMAINS_STOP_MAXWAIT" log_action_end_msg $? done < <(/usr/lib/xen-common/bin/xen-init-list) } do_stop() { do_stop_migrate do_stop_save do_stop_shutdown } case "$1" in start) do_start ;; stop) do_stop ;; restart) do_stop do_start ;; reload|force-reload) do_stop do_start ;; *) echo "Usage: $0 {start|stop|restart|reload|force-reload}" exit 3 ;; esac exit 0 debian/scripts/0000775000000000000000000000000012317541164010663 5ustar debian/scripts/Makefile0000664000000000000000000000267012221315760012323 0ustar ETC_SCRIPTS = \ qemu-ifup GLOBAL_SCRIPTS = \ xen GLOBAL_TOOLSTACK_LINKS = \ xl \ xm GLOBAL_TOOLSTACK_WRAPPER = xen-toolstack-wrapper GLOBAL_UTILS_LINKS = \ cpuperf-perfcntr \ cpuperf-xen \ xenperf \ xenpm \ xentop \ xentrace \ xentrace_format \ xentrace_setmask \ xentrace_setsize GLOBAL_UTILS_WRAPPER = xen-utils-wrapper PRIVATE_SCRIPTS = \ xen-dir \ xen-init-list \ xen-toolstack \ xen-version \ xend-domain-config-path-strip \ $(GLOBAL_TOOLSTACK_WRAPPER) \ $(GLOBAL_UTILS_WRAPPER) ETC_SCRIPTS_DIR = /etc/xen/scripts GLOBAL_SCRIPTS_DIR = /usr/sbin PRIVATE_SCRIPTS_DIR = /usr/lib/xen-common/bin install: install -d $(DESTDIR)$(ETC_SCRIPTS_DIR) install $(ETC_SCRIPTS) $(DESTDIR)$(ETC_SCRIPTS_DIR) install -d $(DESTDIR)$(GLOBAL_SCRIPTS_DIR) install $(GLOBAL_SCRIPTS) $(DESTDIR)$(GLOBAL_SCRIPTS_DIR) @for i in $(GLOBAL_TOOLSTACK_LINKS); do \ echo ln -s $(PRIVATE_SCRIPTS_DIR)/$(GLOBAL_TOOLSTACK_WRAPPER) $(DESTDIR)$(GLOBAL_SCRIPTS_DIR)/$$i; \ ln -s $(PRIVATE_SCRIPTS_DIR)/$(GLOBAL_TOOLSTACK_WRAPPER) $(DESTDIR)$(GLOBAL_SCRIPTS_DIR)/$$i || exit 1; \ done @for i in $(GLOBAL_UTILS_LINKS); do \ echo ln -s $(PRIVATE_SCRIPTS_DIR)/$(GLOBAL_UTILS_WRAPPER) $(DESTDIR)$(GLOBAL_SCRIPTS_DIR)/$$i; \ ln -s $(PRIVATE_SCRIPTS_DIR)/$(GLOBAL_UTILS_WRAPPER) $(DESTDIR)$(GLOBAL_SCRIPTS_DIR)/$$i || exit 1; \ done install -d $(DESTDIR)$(PRIVATE_SCRIPTS_DIR) install $(PRIVATE_SCRIPTS) $(DESTDIR)$(PRIVATE_SCRIPTS_DIR) debian/scripts/xen-toolstack-wrapper0000775000000000000000000000047211652111637015064 0ustar #!/bin/sh -e COMMAND="$(basename $0)" TOOLSTACK=$(. /usr/lib/xen-common/bin/xen-toolstack); RET=$?; [ $RET -eq 0 ] || exit $RET if [ "$(basename "$TOOLSTACK")" != "$COMMAND" ]; then echo "ERROR: A different toolstack ($(basename "$TOOLSTACK")) have been selected!" >&2 exit 1 fi exec "$TOOLSTACK" "$@" debian/scripts/qemu-ifup0000664000000000000000000000054412000050346012503 0ustar #!/bin/sh echo -c 'config qemu network with xen bridge for ' echo $* # Initialise a dummy MAC address. We choose the numerically # largest non-broadcast address to prevent the address getting # stolen by an Ethernet bridge for STP purposes. # (FE:FF:FF:FF:FF:FF) ip link set $1 address fe:ff:ff:ff:ff:ff || true ifconfig $1 0.0.0.0 up brctl addif $2 $1 debian/scripts/xen-toolstack0000775000000000000000000000163111766352234013412 0ustar #!/bin/sh -e configfile=/etc/default/xen dir=$(. /usr/lib/xen-common/bin/xen-dir); ret=$?; [ $ret -eq 0 ] || exit $ret check() { local PATH if [ "$1" = xm ] || [ "$1" = xl ]; then PATH="$dir/bin" else PATH="$dir/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" fi command -v "$1" || : } if [ -e $configfile ]; then . $configfile || true fi if [ "$TOOLSTACK" ]; then cmd=$(check "$TOOLSTACK") if [ "$cmd" ]; then echo "$cmd" else echo "WARING: Can't find toolstack $TOOLSTACK, fallback to default!" >&2 TOOLSTACK= fi fi if [ -z "$TOOLSTACK" ]; then cmd_xm=$(check xm) cmd_xl=$(check xl) if [ "$cmd_xm" ]; then echo "$cmd_xm" elif [ "$cmd_xl" ]; then echo "$cmd_xl" else echo "ERROR: Toolstack not specifed and nothing detected, bailing out!" >&2 exit 127 fi fi debian/scripts/xen0000775000000000000000000000023111652107645011402 0ustar #!/bin/sh -e COMMAND="$(basename $0)" TOOLSTACK=$(. /usr/lib/xen-common/bin/xen-toolstack); RET=$?; [ $RET -eq 0 ] || exit $RET exec "$TOOLSTACK" "$@" debian/scripts/xen-version0000775000000000000000000000076211777774310013105 0ustar #!/bin/sh -e error() { echo "ERROR: " "$@" >&2 exit 1 } if [ -e "/sys/hypervisor/type" ]; then type="$(cat /sys/hypervisor/type)" if [ "$type" = xen ]; then DIR=/sys/hypervisor/version VERSION="$(cat $DIR/major).$(cat $DIR/minor)" elif [ -z "$type" ]; then error "Can't read hypervisor type from sysfs!" else error "Hypervisor is not xen but '$type'!" fi else error "Can't find hypervisor information in sysfs!" fi echo "$VERSION" debian/scripts/xen-dir0000775000000000000000000000042111767450762012167 0ustar #!/bin/sh -e VERSION=$(. /usr/lib/xen-common/bin/xen-version); RET=$?; [ $RET -eq 0 ] || exit $RET if [ -d "/usr/lib/xen-$VERSION" ]; then echo "/usr/lib/xen-$VERSION" else echo "ERROR: Can't find version $VERSION of xen utils, bailing out!" >&2 exit 127 fi debian/scripts/xen-init-list0000775000000000000000000000376012026064172013317 0ustar #!/usr/bin/python from __future__ import print_function import json import re import sys import subprocess class SXPParser(object): tokenizer_rules = r""" (?P \( ) | (?P \) ) | (?P \s+ ) | [^()^\s]+ """ tokenizer_re = re.compile(tokenizer_rules, re.X) def __init__(self): self.stack = [] self.data = [] def __call__(self, input): for match in self.tokenizer_re.finditer(input): if match.group('open'): self.stack.append([]) elif match.group('close'): top = self.stack.pop() if self.stack: self.stack[-1].append(top) else: self.data.append(top) elif match.group('whitespace'): pass else: if self.stack: self.stack[-1].append(match.group()) return self.data class Data(object): def __call__(self, out): for domid, info in sorted(self.data.iteritems(), reverse=True): print(str(domid), *info) class DataJSON(Data): def __init__(self, p): s = json.loads(p) self.data = d = {} for i in s: domid = i['domid'] name = i['config']['c_info']['name'] d[domid] = (name, ) class DataSXP(Data): def __init__(self, p): s = SXPParser()(p) self.data = d = {} for i in s: if i and i[0] == 'domain': try: data = dict(j for j in i if len(j) == 2) domid = int(data['domid']) name = data['name'] if domid == 0: continue d[domid] = (name, ) except (KeyError, ValueError) as e: pass if __name__ == '__main__': p = subprocess.check_output(('xen', 'list', '-l')) if p[0] == '(': d = DataSXP(p) else: d = DataJSON(p) d(sys.stdout) debian/scripts/xen-utils-wrapper0000775000000000000000000000015511652104434014214 0ustar #!/bin/sh -e COMMAND="$(basename $0)" DIR=$(/usr/lib/xen-common/bin/xen-dir) exec "$DIR/bin/$COMMAND" "$@" debian/scripts/xend-domain-config-path-strip0000775000000000000000000000110412221316003016326 0ustar #!/bin/sh -e CONFDIR=/var/lib/xend/domains if [ $(id -u) -ne 0 ]; then echo "Must be called as root" >&2 exit 1 fi for CFG in $(find $CONFDIR -type f); do awk ' /\(loader/ && /\/usr\/lib\/xen-/{ sub(/\/usr\/lib\/xen-.*\/boot\//, "") print next } /\(device_model/ && /\/usr\/lib\/xen-/{ sub(/\/usr\/lib\/xen-.*\/bin\//, "") print next } { print } ' $CFG >/tmp/xend-domain.$$ if ! diff -q $CFG /tmp/xend-domain.$$ >/dev/null; then echo "Updating $(basename $(dirname $CFG))" cat /tmp/xend-domain.$$ >$CFG fi rm /tmp/xend-domain.$$ done debian/libxenstore3.0.install0000664000000000000000000000003110746736114013342 0ustar usr/lib/libxenstore.so.* debian/pycompat0000664000000000000000000000000210470376574010754 0ustar 2 debian/control.md5sum0000664000000000000000000000176712221321221012003 0ustar ac0eaaff8a41be34286540b920471a29 debian/changelog c379f09bde66561f34d361dd9f89e345 debian/bin/gencontrol.py a4fad0ec66d977759a362165bf8aa31d debian/templates/control.hypervisor.in e9166b8a1e6e9ac9e2fba6050a59fbdb debian/templates/control.main.in d9d85cc5f2ddd8c23cc860bb4b1b3fe5 debian/templates/control.source.in fe9f3e8a9c9b716f7b4c5b7d7aec3128 debian/templates/control.system.latest.in 7f13b99c446eb6cf64d21a2de26b9460 debian/templates/control.utils.in a15fa64ce6deead28d33c1581b14dba7 debian/templates/xen-hypervisor.postinst.in 22492e0565a4754b5e008ca7cac871da debian/templates/xen-hypervisor.postrm.in dcabf82578122540e0534f72750698d5 debian/templates/xen-utils.lintian-overrides.in 03f63e67cf2d915bfbb535f8c9d9e2e4 debian/templates/xen-utils.postinst.in b6acd21c3924e6ec6f9c547afbbc7d9e debian/templates/xen-utils.prerm.in 2f0cc6973a228e4002e5b89f756e3d58 debian/arch/defines 7eec83f6c765a660ebaeb80dc4b433ad debian/arch/amd64/defines ea4d950fe2490d8a019d069852c8ffd3 debian/arch/i386/defines debian/xen-utils-common.xen.init0000664000000000000000000001440212442353041014063 0ustar #!/bin/sh ### BEGIN INIT INFO # Provides: xen xend # Required-Start: $syslog $remote_fs # Required-Stop: $syslog $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Xen daemons # Description: Xen daemons ### END INIT INFO . /lib/init/vars.sh . /lib/lsb/init-functions # Default variables XENSTORED_DIR="/var/run/xenstored" [ -r /etc/default/xen ] && . /etc/default/xen [ -r /etc/default/xend ] && . /etc/default/xend PATH=/sbin:/bin:/usr/sbin:/usr/bin DESC="Xen daemons" ROOT=$(/usr/lib/xen-common/bin/xen-dir 2>/dev/null) if [ $? -ne 0 ]; then log_warning_msg "Not running within Xen or no compatible utils" exit 0 fi TOOLSTACK=$(/usr/lib/xen-common/bin/xen-toolstack 2>/dev/null) if [ $? -ne 0 ]; then log_warning_msg "No usable Xen toolstack selected" exit 0 fi [ -e "$ROOT"/bin/xend ] && XEND="$ROOT"/bin/xend XENCONSOLED="$ROOT"/bin/xenconsoled XENCONSOLED_PIDFILE="/var/run/xenconsoled.pid" XENSTORED="$ROOT"/bin/xenstored XENSTORED_PIDFILE="/var/run/xenstore.pid" QEMU=/usr/bin/qemu-system-i386 QEMU_PIDFILE="/var/run/qemu-dom0.pid" QEMU_ARGS="-xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv -daemonize -monitor /dev/null -serial /dev/null -parallel /dev/null" modules_setup() { modprobe xenfs 2>/dev/null modprobe xen-evtchn 2>/dev/null modprobe xen-gntdev 2>/dev/null } xenfs_setup() { [ -e "/proc/xen/capabilities" ] && return 0 log_progress_msg "xenfs" [ -d "/proc/xen" ] || return 1 mount -t xenfs xenfs /proc/xen || return 1 return 0 } capability_check() { [ -e "/proc/xen/capabilities" ] || return 1 grep -q "control_d" /proc/xen/capabilities || return 1 return 0 } env_setup() { [ -d /run/xen ] && return 0 mkdir -m 700 /run/xen } xend_start() { if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then return 0 fi log_progress_msg "xend" xend_start_real return $? } xend_stop() { if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then return 0 fi log_progress_msg "xend" xend_stop_real return $? } xend_restart() { if [ -z "$XEND" ] || [ "$(basename "$TOOLSTACK")" != xm ]; then return 0 fi log_progress_msg "xend" xend_stop_real case "$?" in 0|1) xend_start_real case "$?" in 0) ;; *) return 2 ;; esac ;; *) return 2 ;; esac return 0 } xend_start_real() { $XEND status && return 1 $XEND start || return 2 i=0 while [ $i -lt 10 ]; do $XEND status && return 0 || true i=$(($i + 1)) sleep 1 done return 2 } xend_stop_real() { log_progress_msg "xend" $XEND status || return 0 $XEND stop || return 1 } xenconsoled_start() { log_progress_msg "xenconsoled" xenconsoled_start_real return $? } xenconsoled_stop() { log_progress_msg "xenconsoled" xenconsoled_stop_real return $? } xenconsoled_restart() { log_progress_msg "xenconsoled" xenconsoled_stop_real case "$?" in 0|1) xenconsoled_start_real case "$?" in 0) ;; *) return 2 ;; esac ;; *) return 2 ;; esac return 0 } xenconsoled_start_real() { start-stop-daemon --start --quiet --pidfile "$XENCONSOLED_PIDFILE" --exec "$XENCONSOLED" --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile "$XENCONSOLED_PIDFILE" --exec "$XENCONSOLED" -- \ $XENCONSOLED_ARGS --pid-file="$XENCONSOLED_PIDFILE" \ || return 2 } xenconsoled_stop_real() { start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$XENCONSOLED_PIDFILE" --name xenconsoled RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$XENCONSOLED" [ "$?" = 2 ] && return 2 rm -f $XENCONSOLED_PIDFILE return "$RETVAL" } qemu_start() { [ -x $QEMU ] || return 0 log_progress_msg "qemu" qemu_start_real return $? } qemu_stop() { [ -x $QEMU ] || return 0 log_progress_msg "qemu" qemu_stop_real return $? } qemu_restart() { [ -x $QEMU ] || return 0 log_progress_msg "qemu" qemu_stop_real case "$?" in 0|1) qemu_start_real case "$?" in 0) ;; *) return 2 ;; esac ;; *) return 2 ;; esac return 0 } qemu_start_real() { start-stop-daemon --start --quiet --pidfile "$QEMU_PIDFILE" --exec "$QEMU" --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile "$QEMU_PIDFILE" --exec "$QEMU" -- \ $QEMU_ARGS -pidfile "$QEMU_PIDFILE" \ || return 2 } qemu_stop_real() { start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$QEMU_PIDFILE" --exec "$QEMU" RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$QEMU" [ "$?" = 2 ] && return 2 rm -f $QEMU_PIDFILE return "$RETVAL" } xenstored_start() { log_progress_msg "xenstored" start-stop-daemon --start --quiet --pidfile "$XENSTORED_PIDFILE" --exec "$XENSTORED" --test > /dev/null \ || return 1 [ -d "$XENSTORED_DIR" ] || mkdir -p "$XENSTORED_DIR" export XENSTORED_ROOTDIR="$XENSTORED_DIR" start-stop-daemon --start --quiet --pidfile "$XENSTORED_PIDFILE" --exec "$XENSTORED" -- \ $XENSTORED_ARGS --pid-file="$XENSTORED_PIDFILE" \ || return 2 xenstore-write "/local/domain/0/name" "Domain-0" xenstore-write "/local/domain/0/domid" "0" } case "$1" in start) log_daemon_msg "Starting $DESC" modules_setup xenfs_setup case "$?" in 0) ;; *) log_end_msg 1; exit ;; esac capability_check case "$?" in 0) ;; *) log_end_msg 255; exit ;; esac env_setup xenstored_start case "$?" in 0|1) ;; *) log_end_msg 1; exit ;; esac xenconsoled_start case "$?" in 0|1) ;; *) log_end_msg 1; exit ;; esac xend_start case "$?" in 0|1) ;; *) log_end_msg 1; exit ;; esac qemu_start case "$?" in 0|1) ;; *) log_end_msg 1; exit ;; esac log_end_msg 0 ;; stop) capability_check case "$?" in 0) ;; *) exit ;; esac log_daemon_msg "Stopping $DESC" ret=0 qemu_stop case "$?" in 0|1) ;; *) ret=1 ;; esac xend_stop case "$?" in 0|1) ;; *) ret=1 ;; esac xenconsoled_stop case "$?" in 0|1) ;; *) ret=1 ;; esac log_end_msg $ret ;; restart|force-reload) capability_check case "$?" in 0) ;; *) exit ;; esac log_daemon_msg "Restarting $DESC" ret=0 qemu_restart case "$?" in 0|1) ;; *) ret=1 ;; esac xend_restart case "$?" in 0|1) ;; *) ret=1 ;; esac xenconsoled_restart case "$?" in 0|1) ;; *) ret=1 ;; esac log_end_msg $ret ;; *) echo "Usage: $0 {start|stop|restart|force-reload}" >&2 exit 3 ;; esac exit 0 debian/xen-utils-common.install0000664000000000000000000000017711742263066014012 0ustar etc/xen/scripts etc/xen/xl* etc/xen/xend* lib/udev/rules.d/*.rules usr/lib/xen-common usr/sbin ../../tree/xen-utils-common/* / debian/xen-utils-common.examples0000664000000000000000000000006311711764012014145 0ustar debian/tmp/etc/xen/cpupool* debian/tmp/etc/xen/xm* debian/libxenstore3.0.symbols0000664000000000000000000000243411767702363013400 0ustar libxenstore.so.3.0 libxenstore3.0 #MINVER# expanding_buffer_ensure@Base 3.2.0 sanitise_value@Base 3.2.0 unsanitise_value@Base 3.2.0 xprintf@Base 3.2.0 xs_check_watch@Base 4.2~ xs_close@Base 4.1.0~rc6 xs_count_strings@Base 3.2.0 xs_daemon_close@Base 3.2.0 xs_daemon_destroy_postfork@Base 4.0.1~rc4 xs_daemon_open@Base 3.2.0 xs_daemon_open_readonly@Base 3.2.0 xs_daemon_rootdir@Base 3.2.0 xs_daemon_rundir@Base 3.2.0 xs_daemon_socket@Base 3.2.0 xs_daemon_socket_ro@Base 3.2.0 xs_daemon_tdb@Base 3.2.0 xs_debug_command@Base 3.2.0 xs_directory@Base 3.2.0 xs_domain_dev@Base 3.2.0 xs_domain_open@Base 3.2.0 xs_fileno@Base 3.2.0 xs_get_domain_path@Base 3.2.0 xs_get_permissions@Base 3.2.0 xs_introduce_domain@Base 3.2.0 xs_is_domain_introduced@Base 3.2.0 xs_mkdir@Base 3.2.0 xs_open@Base 4.1.0~rc6 xs_path_is_subpath@Base 4.2~ xs_perm_to_string@Base 3.2.0 xs_read@Base 3.2.0 xs_read_watch@Base 3.2.0 xs_release_domain@Base 3.2.0 xs_restrict@Base 4.1.0~rc6 xs_resume_domain@Base 3.2.0 xs_rm@Base 3.2.0 xs_set_permissions@Base 3.2.0 xs_set_target@Base 3.4.0 xs_strings_to_perms@Base 3.2.0 xs_suspend_evtchn_port@Base 3.4.0 xs_transaction_end@Base 3.2.0 xs_transaction_start@Base 3.2.0 xs_unwatch@Base 3.2.0 xs_watch@Base 3.2.0 xs_write@Base 3.2.0 xs_write_all@Base 3.2.0 debian/xen-hypervisor-4.4-amd64.postrm0000664000000000000000000000055312212071167014656 0ustar #!/bin/bash set -e case "$1" in remove) if command -v update-grub > /dev/null && [ -d /boot/grub ]; then update-grub || : fi ;; purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/xen-utils-common.postinst0000664000000000000000000000102412221316141014201 0ustar #!/bin/sh set -e case "$1" in configure) install -d -m 2750 -g adm /var/log/xen ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac dpkg-maintscript-helper mv_conffile /etc/init.d/xend /etc/init.d/xen 4.1.2-4~ -- "$@" # Somehow the private lib path which is versioned ends up in the xend # domain configs. But the tools will automatically prefix the current # tools path. /usr/lib/xen-common/bin/xend-domain-config-path-strip #DEBHELPER# exit 0 debian/changelog0000664000000000000000000026401213167432446011061 0ustar xen (4.4.2-0ubuntu0.14.04.14) trusty-security; urgency=medium * Applying Xen Security Advisories: - CVE-2017-14316 / XSA-231 - xen/mm: make sure node is less than MAX_NUMNODES - CVE-2017-14317 / XSA-233 - tools/xenstore: dont unlink connection object twice - CVE-2017-14319 / XSA-234 - gnttab: also validate PTE permissions upon destroy/replace - XSA-235 - arm/mm: release grant lock on xenmem_add_to_physmap_one() error paths - XSA-237 - x86: don't allow MSI pIRQ mapping on unowned device - x86: enforce proper privilege when (un)mapping pIRQ-s - x86/MSI: disallow redundant enabling - x86/MSI: fix error handling - x86/IRQ: conditionally preserve irq <-> pirq mapping on map error paths - x86/FLASK: fix unmap-domain-IRQ XSM hook - XSA-239 - x86/HVM: prefill partially used variable on emulation paths - XSA-240 - x86: limit linear page table use to a single level - x86/mm: Disable PV linear pagetables by default - XSA-241 - x86: don't store possibly stale TLB flush time stamp - XSA-242 - x86: don't allow page_unlock() to drop the last type reference - XSA-243 - x86: Disable the use of auto-translated PV guestsx86: Disable the use of auto-translated PV guests - x86/shadow: Don't create self-linear shadow mappings for 4-level translated guests - XSA-244 - x86/cpu: Fix IST handling during PCPU bringup -- Stefan Bader Wed, 11 Oct 2017 16:26:04 +0200 xen (4.4.2-0ubuntu0.14.04.13) trusty-security; urgency=medium * Applying Xen Security Advisories: - XSA-226 / CVE-2017-12135 - gnttab: don't use possibly unbounded tail calls - gnttab: fix transitive grant handling - XSA-227 / CVE-2017-12137 - x86/grant: Disallow misaligned PTEs - XSA-230 / CVE-2017-12855 - gnttab: correct pin status fixup for copy -- Stefan Bader Tue, 22 Aug 2017 16:26:53 +0200 xen (4.4.2-0ubuntu0.14.04.12) trusty-security; urgency=low * Applying Xen Security Advisories: - XSA-217 - x86/mm: disallow page stealing from HVM domains - XSA-218 - IOMMU: handle IOMMU mapping and unmapping failures - gnttab: fix unmap pin accounting race - gnttab: Avoid potential double-put of maptrack entry - gnttab: correct maptrack table accesses - XSA-219 - 86/shadow: Hold references for the duration of emulated writes - XSA-221 - evtchn: avoid NULL derefs - XSA-222 - xen/memory: Fix return value handing of guest_remove_page() - guest_physmap_remove_page() needs its return value checked - XSA-224 - gnttab: Fix handling of dev_bus_addr during unmap - gnttab: never create host mapping unless asked to - gnttab: correct logic to get page references during map requests - gnttab: __gnttab_unmap_common_complete() is all-or-nothing -- Stefan Bader Tue, 04 Jul 2017 12:20:19 +0200 xen (4.4.2-0ubuntu0.14.04.11) trusty-security; urgency=low * Applying Xen Security Advisories: - XSA-206 * xenstored: apply a write transaction rate limit * xenstored: Log when the write transaction rate limit bites * oxenstored: exempt dom0 from domU node quotas * oxenstored: perform a 3-way merge of the quota after a transaction * oxenstored: catch the error when a connection is already deleted * oxenstored: use hash table to store socket connections * oxenstored: enable domain connection indexing based on eventchn port * oxenstored: only process domain connections that notify us by events * oxenstored: add a safe net mechanism for existing ill-behaved clients * oxenstored: refactor putting response on wire * oxenstored: remove some unused parameters * oxenstored: refactor request processing * oxenstored: keep track of each transaction's operations * oxenstored: move functions that process simple operations * oxenstored: replay transaction upon conflict * oxenstored: log request and response during transaction replay * oxenstored: allow compilation prior to OCaml 3.12.0 * oxenstored: comments explaining some variables * oxenstored: handling of domain conflict-credit * oxenstored: ignore domains with no conflict-credit * oxenstored: add transaction info relevant to history-tracking * oxenstored: support commit history tracking * oxenstored: only record operations with side-effects in history * oxenstored: discard old commit-history on txn end * oxenstored: track commit history * oxenstored: blame the connection that caused a transaction conflict * oxenstored: allow self-conflicts * oxenstored: do not commit read-only transactions * oxenstored: don't wake to issue no conflict-credit * oxenstored transaction conflicts: improve logging * oxenstored: trim history in the frequent_ops function - XSA-207 * IOMMU: always call teardown callback - CVE-2017-2615 / XSA-208 * CVE-2014-8106: cirrus: fix blit region check * cirrus: fix oob access issue (CVE-2017-2615) - CVE-2017-2620 / XSA-209 * cirrus: add blit_is_unsafe call to cirrus_bitblt_cputovideo - CVE-2016-9603 / XSA-211 * cirrus/vnc: zap drop bitblit support from console code. - CVE-2017-7228 / XSA-212 * memory: properly check guest memory ranges in XENMEM_exchange handling - XSA-213 * multicall: deal with early exit conditions - XSA-214 * x86: discard type information when stealing pages - XSA-215 * x86: correct create_bounce_frame -- Stefan Bader Tue, 09 May 2017 10:13:50 +0200 xen (4.4.2-0ubuntu0.14.04.10) trusty; urgency=medium * Backport upstream change to fix TSC_ADJUST MSR handling in HVM guests running on Intel based hosts (LP: #1671760) -- Stefan Bader Tue, 14 Mar 2017 11:17:48 +0100 xen (4.4.2-0ubuntu0.14.04.9) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2016-9386 / XSA-191 * x86/hvm: Fix the handling of non-present segments - CVE-2016-9382 / XSA-192 * x86/HVM: don't load LDTR with VM86 mode attrs during task switch - CVE-2016-9385 / XSA-193 * x86/PV: writes of %fs and %gs base MSRs require canonical addresses - CVE-2016-9383 / XSA-195 * x86emul: fix huge bit offset handling - CVE-2016-9381 / XSA-197 * xen: fix ioreq handling - CVE-2016-9379, CVE-2016-9380 / XSA-198 * pygrub: Properly quote results, when returning them to the caller - CVE-2016-9637 / XSA-199 * qemu: ioport_read, ioport_write: be defensive about 32-bit addresses - CVE-2016-9932 / XSA-200 * x86emul: CMPXCHG8B ignores operand size prefix - CVE-2016-9815, CVE-2016-9816, CVE-2016-9817, CVE-2016-9818 / XSA.201 * arm64: handle guest-generated EL1 asynchronous abort * arm64: handle async aborts delivered while at EL2 * arm: crash the guest when it traps on external abort * arm32: handle async aborts delivered while at HYP - CVE-2016-10024 / XSA-202 * x86: force EFLAGS.IF on when exiting to PV guests - CVE-2016-10013 / XSA-204 * x86/emul: Correct the handling of eflags with SYSCALL -- Stefan Bader Tue, 10 Jan 2017 16:47:39 +0100 xen (4.4.2-0ubuntu0.14.04.7) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2016-6258 / XSA-182 * x86/pv: Remove unsafe bits from the mod_l?_entry() fastpath - CVE-2016-5403 / XSA-184 * virtio: error out if guest exceeds virtqueue size - CVE-2016-7092 / XSA-185 * x86/32on64: don't allow recursive page tables from L3 - CVE-2016-7094 / XSA-187 * x86/shadow: Avoid overflowing sh_ctxt->seg_reg[] * x86/segment: Bounds check accesses to emulation ctxt->seg_reg[] - CVE-2016-7154 / XSA-188 * evtchn-fifo: prevent use after free - CVE-2016-7777 / XSA-190 * x86emul: honor guest CR0.TS and CR0.EM -- Stefan Bader Thu, 06 Oct 2016 15:56:51 +0200 xen (4.4.2-0ubuntu0.14.04.6) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2016-3158, CVE-2016-3159 / XSA-172 * x86: fix information leak on AMD CPUs - CVE-2016-3960 / XSA-173 * x86: limit GFNs to 32 bits for shadowed superpages. - CVE-2016-4962 / XSA-175 * libxl: Record backend/frontend paths in /libxl/$DOMID * libxl: Provide libxl__backendpath_parse_domid * libxl: Do not trust frontend in libxl__devices_destroy * libxl: Do not trust frontend in libxl__device_nextid * libxl: Do not trust frontend for disk eject event * libxl: Do not trust frontend for disk in getinfo * libxl: Do not trust frontend for vtpm list * libxl: Do not trust frontend for vtpm in getinfo * libxl: Do not trust frontend for nic in libxl_devid_to_device_nic * libxl: Do not trust frontend for nic in getinfo * libxl: Cleanup: Have libxl__alloc_vdev use /libxl * libxl: Document ~/serial/ correctly - CVE-2016-4480 / XSA-176 * x86/mm: fully honor PS bits in guest page table walks - CVE-2016-4963 / XSA-178 * libxl: Do not trust backend for vtpm in getinfo (except uuid) * libxl: Do not trust backend for vtpm in getinfo (uuid) * libxl: cdrom eject and insert: write to /libxl * libxl: Do not trust backend for disk eject vdev * libxl: Do not trust backend for disk; fix driver domain disks list * libxl: Do not trust backend for disk in getinfo * libxl: Do not trust backend for cdrom insert * libxl: Rename libxl__device_{nic,channel}_from_xs_be to _from_xenstore * libxl: Rename READ_BACKEND to READ_LIBXLDEV * libxl: Have READ_LIBXLDEV use libxl_path rather than be_path * libxl: Do not trust backend in nic getinfo * libxl: Do not trust backend for nic in devid_to_device * libxl: Do not trust backend for nic in list * libxl: Cleanup: use libxl__backendpath_parse_domid in libxl__device_disk_from_xs_be * libxl: Fix NULL pointer due to XSA-178 fix wrong XS nodename - CVE-2016-3710 / XSA-179 (qemu traditional) * vga: fix banked access bounds checking * vga: add vbe_enabled() helper * vga: factor out vga register setup * vga: update vga register setup on vbe changes * vga: make sure vga register setup for vbe stays intact - CVE-2014-3672 / XSA-180 (qemu traditional) * main loop: Big hammer to fix logfile disk DoS in Xen setups - CVE-2016-5242 / XSA-181 * xen/arm: Don't free p2m->first_level in p2m_teardown() before it has been allocated -- Stefan Bader Mon, 06 Jun 2016 14:17:35 +0200 xen (4.4.2-0ubuntu0.14.04.5) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2016-2270 / XSA-154 * x86: enforce consistent cachability of MMIO mappings - CVE-2016-1570 / XSA-167 * x86/mm: PV superpage handling lacks sanity checks - CVE-2016-1571 / XSA-168 * x86/VMX: prevent INVVPID failure due to non-canonical guest address - CVE-2015-8615 / XSA-169 * x86: make debug output consistent in hvm_set_callback_via - CVE-2016-2271 / XSA-170 * x86/VMX: sanitize rIP before re-entering guest -- Stefan Bader Tue, 23 Feb 2016 22:16:17 +0100 xen (4.4.2-0ubuntu0.14.04.4) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2015-8550 / XSA-155 * blkif: Avoid double access to src->nr_segments * xenfb: avoid reading twice the same fields from the shared page * xen: Add RING_COPY_REQUEST() * blktap2: Use RING_COPY_REQUEST * libvchan: Read prod/cons only once. - CVE-2015-8338 / XSA-158 * memory: split and tighten maximum order permitted in memops - CVE-2015-8339, CVE-2015-8340 / XSA-159 * memory: fix XENMEM_exchange error handling - CVE-2015-8341 / XSA-160 * libxl: Fix bootloader-related virtual memory leak on pv build failure - CVE-2015-7504 / XSA-162 * net: pcnet: add check to validate receive data size - CVE-2015-8554 / XSA-164 * MSI-X: avoid array overrun upon MSI-X table writes - CVE-2015-8555 / XSA-165 * x86: don't leak ST(n)/XMMn values to domains first using them - CVE-2015-???? / XSA-166 * x86/HVM: avoid reading ioreq state more than once -- Stefan Bader Wed, 16 Dec 2015 18:26:30 +0100 xen (4.4.2-0ubuntu0.14.04.3) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2015-7311 / XSA-142 * libxl: handle read-only drives with qemu-xen - CVE-2015-7812 / XSA-145 * xen/arm: Support hypercall_create_continuation for multicall - CVE-2015-7813 / XSA-146 * xen: arm: rate-limit logging from unimplemented PHYSDEVOP and HVMOP. - CVE-2015-7814 / XSA-147 * xen: arm: handle races between relinquish_memory and free_domheap_pages - CVE-2015-7835 / XSA-148 * x86: guard against undue super page PTE creation - CVE-2015-7969 / XSA-149 * xen: free domain's vcpu array - CVE-2015-7970 / XSA-150 * x86/PoD: Eager sweep for zeroed pages - CVE-2015-7969 / XSA-151 * xenoprof: free domain's vcpu array - CVE-2015-7971 / XSA-152 * x86: rate-limit logging in do_xen{oprof,pmu}_op() - CVE-2015-7972 / XSA-153 * libxl: adjust PoD target by memory fudge, too - CVE-2015-5307 / XSA-156 * x86/HVM: always intercept #AC and #DB -- Stefan Bader Tue, 03 Nov 2015 15:18:39 -0600 xen (4.4.2-0ubuntu0.14.04.2) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2015-4103 / XSA-128 * properly gate host writes of modified PCI CFG contents - CVE-2015-4104 / XSA-129 * xen: don't allow guest to control MSI mask register - CVE-2015-4105 / XSA-130 * xen/MSI-X: disable logging by default - CVE-2015-4106 / XSA-131 * xen/MSI: don't open-code pass-through of enable bit modifications * xen/pt: consolidate PM capability emu_mask * xen/pt: correctly handle PM status bit * xen/pt: split out calculation of throughable mask in PCI config space handling * xen/pt: mark all PCIe capability bits read-only * xen/pt: mark reserved bits in PCI config space fields * xen/pt: add a few PCI config space field descriptions * xen/pt: unknown PCI config space fields should be read-only - CVE-2015-4163 / XSA-134 * gnttab: add missing version check to GNTTABOP_swap_grant_ref handling - CVE-2015-3209 / XSA-135 * pcnet: fix Negative array index read * pcnet: force the buffer access to be in bounds during tx - CVE-2015-4164 / XSA-136 * x86/traps: loop in the correct direction in compat_iret() - CVE-2015-3259 / XSA-137 * xl: Sane handling of extra config file arguments - CVE-2015-5154 / XSA-138 * ide: Check array bounds before writing to io_buffer * ide: Clear DRQ after handling all expected accesses - CVE-2015-5165 / XSA-140 * rtl8139: avoid nested ifs in IP header parsing * rtl8139: drop tautologous if (ip) {...} statement * rtl8139: skip offload on short Ethernet/IP header * rtl8139: check IP Header Length field * rtl8139: check IP Total Length field * rtl8139: skip offload on short TCP header * rtl8139: check TCP Data Offset field - CVE-2015-6654 / XSA-141 * xen/arm: mm: Do not dump the p2m when mapping a foreign gfn -- Stefan Bader Mon, 31 Aug 2015 11:11:36 +0200 xen (4.4.2-0ubuntu0.14.04.1) trusty; urgency=low * Updating to lastest upstream stable release 4.4.2 (LP: #1476666) - Replacing the following security changes by upstream versions: * CVE-2014-5146, CVE-2014-5149 / XSA-97, CVE-2014-3969, CVE-2015-2290 / XSA-98 (additional fix), CVE-2014-7154 / XSA-104, CVE-2014-7155 / XSA-105, CVE-2014-7156 / XSA-106, CVE-2014-6268 / XSA-107, CVE-2014-7188 / XSA-108, CVE-2014-8594 / XSA-109, CVE-2014-8595 / XSA-110, CVE-2014-8866 / XSA-111, CVE-2014-8867 / XSA-112, CVE-2014-9030 / XSA-113, CVE-2014-9065, CVE-2014-9066 / XSA-114, CVE-2015-0361 / XSA-116, CVE-2015-1563 / XSA-118, CVE-2015-2152 / XSA-119, CVE-2015-2044 / XSA-121, CVE-2015-2045 / XSA-122, CVE-2015-2151 / XSA-123 * Refreshed d/p/version.patch to fix some fuzz when applying. No functional change. -- Stefan Bader Mon, 20 Jul 2015 11:34:38 +0200 xen (4.4.1-0ubuntu0.14.04.6) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2015-3340 / XSA-132 * domctl/sysctl: don't leak hypervisor stack to toolstacks - CVE-2015-3456 / XSA-133 * qemut: fdc: force the fifo access to be in bounds of the allocated buffer -- Stefan Bader Wed, 13 May 2015 16:38:10 +0200 xen (4.4.1-0ubuntu0.14.04.5) trusty-security; urgency=low * Applying Xen Security Advisories: * CVE-2014-5146 / XSA-97 (HAP, reworked) - x86/paging: make log-dirty operations preemptible * CVE-2015-2752 / XSA-125 - Limit XEN_DOMCTL_memory_mapping hypercall to only process up to 64 GFNs (or less) * CVE-2015-2756 / XSA-126 (qemu-dm) - xen: limit guest control of PCI command register * CVE-2015-2751 / XSA-127 - domctl: don't allow a toolstack domain to call domain_pause() on itself -- Stefan Bader Tue, 07 Apr 2015 11:42:08 +0200 xen (4.4.1-0ubuntu0.14.04.4) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2014-9065, CVE-2014-9066 / XSA-114 * switch to write-biased r/w locks - CVE-2015-0361 / XSA-116 * x86/HVM: prevent use-after-free when destroying a domain - CVE-2015-1563 / XSA-118 * xen/arm: vgic: message in the emulation code should be rate-limited - CVE-2015-2152 / XSA-119 * tools: libxl: Explicitly disable graphics backends on qemu cmdline - CVE-2015-2044 / XSA-121 * x86/HVM: return all ones on wrong-sized reads of system device I/O ports - CVE-2015-2045 / XSA-122 * pre-fill structures for certain HYPERVISOR_xen_version sub-ops - CVE-2015-2151 / XSA-123 * x86emul: fully ignore segment override for register-only operations -- Stefan Bader Wed, 04 Mar 2015 12:14:36 +0100 xen (4.4.1-0ubuntu0.14.04.3) trusty; urgency=low * d/xen-utils-common.xen.init: Update script to start a QEMU process for dom0. (LP: #1396068) -- Stefan Bader Thu, 11 Dec 2014 18:36:54 +0100 xen (4.4.1-0ubuntu0.14.04.2) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2013-3495 / XSA-59 * VT-d: suppress UR signaling for further desktop chipsets - CVE-2014-8594 / XSA-109 * x86: don't allow page table updates on non-PV page tables in do_mmu_update() - CVE-2014-8595 / XSA-110 * x86emul: enforce privilege level restrictions when loading CS - CVE-2014-8866 / XSA-111 * x86: limit checks in hypercall_xlat_continuation() to actual arguments - CVE-2014-8867 / XSA-112 * x86/HVM: confine internally handled MMIO to solitary regions - CVE-2014-9030 / XSA-113 * x86/mm: fix a reference counting error in MMU_MACHPHYS_UPDATE -- Stefan Bader Fri, 21 Nov 2014 13:49:20 +0100 xen (4.4.1-0ubuntu0.14.04.1) trusty; urgency=low * Updating to lastest upstream stable release 4.4.1 (LP: #1390352) - Replacing the following security changes by upstream versions: * CVE-2013-3495 / XSA-59 (additional work-around), CVE-2014-2599 / XSA-89, CVE-2014-3125 / XSA-91, CVE-2014-3124 / XSA-92, CVE-2014-2915 / XSA-93, CVE-2014-2986 / XSA-94, CVE-2014-3714,CVE-2014-3715,CVE-2014-3716,CVE-2014-3717 / XSA-95, CVE-2014-3967,CVE-2014-3968 / XSA-96, CVE-2014-3969 / XSA-98, CVE-2014-4021 / XSA-100, CVE-2014-4022 / XSA-101, CVE-2014-5147 / XSA-102, CVE-2014-5148 / XSA-103 - Dropped patches: * upstream-25290:7a6dcecb1781-rework (stale) * tools-flask-prefix.diff (stale) * ubuntu-tools-hotplug-disable-xend-socket.patch (stale, duplicate) - Refreshed patches: * d/p/debian/patches/ubuntu-arm64-enablement.patch Configure part fixed in Xen code. Duplicate defines for arm64 seem to be avoided by later libc, so need to keep that worked-around in Xen. -- Stefan Bader Mon, 10 Nov 2014 11:34:26 +0100 xen (4.4.0-0ubuntu5.2) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2014-5147 / XSA-102 * xen: arm: handle AArch32 userspace when dumping 64-bit guest state. * xen: arm: Correctly handle exception injection from userspace on 64-bit. * xen: arm: Handle traps from 32-bit userspace on 64-bit kernel as undef - CVE-2014-5148 / XSA-103 * xen: arm: Correctly handle do_sysreg exception injection from 64-bit userspace - CVE-2014-7154 / XSA-104 * x86/shadow: fix race condition sampling the dirty vram state - CVE-2014-7155 / XSA-105 * x86/emulate: check cpl for all privileged instructions - CVE-2014-7156 / XSA-106 * x86emul: only emulate software interrupt injection for real mode - CVE-2014-6268 / XSA-107 * evtchn: check control block exists when using FIFO-based events - CVE-2014-7188 / XSA-108 * x86/HVM: properly bound x2APIC MSR range -- Stefan Bader Fri, 26 Sep 2014 12:12:16 +0200 xen (4.4.0-0ubuntu5.1) trusty-security; urgency=low * Applying Xen Security Advisories: - CVE-2014-2599 / XSA-89 * x86: enforce preemption in HVM_set_mem_access / p2m_set_mem_access() - CVE-2014-3125 / XSA-91 * xen/arm: Correctly save/restore CNTKCTL_EL1 - CVE-2014-3124 / XSA-92 * x86/HVM: restrict HVMOP_set_mem_type - CVE-2014-2915 / XSA-93 * xen/arm: Inject an undefined instruction when the coproc/sysreg is not handled * xen/arm: Don't let the guest access the coprocessors registers * xen/arm: Upgrade DCISW into DCCISW * xen/arm: Trap cache and TCM lockdown registers * xen/arm: Don't expose implementation defined registers (Cp15 c15) to the guest * xen/arm: Don't let guess access to Debug and Performance Monitor registers - CVE-2014-2986 / XSA-94 * xen/arm: vgic: Check rank in GICD_ICFGR* emulation before locking - CVE-2014-3714, CVE-2014-3715, CVE-2014-3716, CVE-2014-3717 / XSA-95 * tools: arm: remove code to check for a DTB appended to the kernel - CVE-2014-3967,CVE-2014-3968 / XSA-96 * x86/HVM: eliminate vulnerabilities from hvm_inject_msi() - CVE-2014-3969 / XSA-98 * xen: arm: check permissions when copying to/from guest virtual addresses * xen: arm: ensure we hold a reference to guest pages while we copy to/from them - CVE-2014-4021 / XSA-100 * AMD IOMMU: don't free page table prematurely * page-alloc: scrub pages used by hypervisor upon freeing - CVE-2014-4022 / XSA-101 * xen: arm: initialise the grant_table_gpfn array on allocation -- Stefan Bader Mon, 23 Jun 2014 16:06:27 +0200 xen (4.4.0-0ubuntu5) trusty; urgency=low * Minimal changes to make arm64 build. It produces packages, whatever can be done with those is somebody elses problem. -- Stefan Bader Fri, 11 Apr 2014 15:12:47 +0200 xen (4.4.0-0ubuntu4) trusty; urgency=low * Fix up some more stale 4.3 references in xen-utils-4.4 debian packaging files. * Remove update-alternatives for postinst and prerm of xen-utils- as there is no xen-default anymore. * debian/rules.real: Add etc/default/grub.d and install xen.cfg into it. This adds a place to set Xen grub arguments and makes booting into Xen the default (with a warning message on running update-grub). * debian/rules.real, debian/xen-utils-$(VERSION).postinst, xen-sxp2xm, and xen-migrate-xend-managed-domains: Add migration scripts to the xen-utils-$(VERSION) package (LP: #1303886). * Add transitional packages for migrating xen-hypervisor-4.1-(i386|amd64) and xen-hypervisor-4.3-amd64 to add the xen-system-amd64 meta-package which is the preferred/recommeded way of installing Xen now. -- Stefan Bader Wed, 26 Mar 2014 19:25:53 +0100 xen (4.4.0-0ubuntu3) trusty; urgency=low * Fixing up changelog history and preparing for FFE (LP: #1290743). -- Stefan Bader Thu, 20 Mar 2014 12:53:21 +0100 xen (4.4.0-0ubuntu2) trusty; urgency=low * debian/patches/tools-ocaml-disable-test.patch: This disables the ocaml test build for now until linking issues are resolved. * debian/xen-utils-common.xen.init: Write domid for dom0 into xenstore (now required). -- Stefan Bader Tue, 11 Mar 2014 14:26:58 +0100 xen (4.4.0-0ubuntu1) trusty; urgency=low * New upstream release (Xen.4.4) * Refreshed patches: - debian/patches/tools-libxc-abiname.diff - debian/patches/tools-libxl-abiname.diff - debian/patches/tools-libxl-prefix.diff * debian/rules.real: Force xend to be built. * debian/rules.real: For utils_ installation move binaries from usr/sbin/ to usr/lib/xen-/bin. Several that used to go into the private bin directory moved to the public sbin directory. Not ideal but quicker to do without side-effects. * debian/rules.real: Hypervisor has no .gz type on armhf. * debian/control, debian/rules.gen: Manually update version from 4.3 to 4.4. * debian/control: Add build dependency for libfdt-dev on armhf. * debian/control: Only depend on qemu-system-x86 for i386 and amd64 builds. * debian/*: Also rename several versioned packaging files. * debian/tree/xen-utils-common/usr/share/xen-utils-common/default.xen: Add comment about toolstack names and make xl the default. -- Stefan Bader Tue, 11 Mar 2014 09:54:35 +0100 xen (4.3.0-1ubuntu5) trusty; urgency=low * Applying Xen Security Advisories: - CVE-2014-1642 / XSA-83 * x86/irq: avoid use-after-free on error path in pirq_guest_bind() - CVE-2014-1891 / XSA-84 * flask: fix reading strings from guest memory - CVE-2014-1895 / XSA-85 * xsm/flask: correct off-by-one in flask_security_avc_cachestats cpu id check - CVE-2014-1896 / XSA-86 * libvchan: Fix handling of invalid ring buffer indices - CVE-2014-1666 / XSA-87 * x86: PHYSDEVOP_{prepare,release}_msix are privileged - CVE-2014-1950 / XSA-88 * libxc: Fix out-of-memory error handling in xc_cpupool_getinfo() -- Stefan Bader Mon, 17 Feb 2014 13:54:15 +0100 xen (4.3.0-1ubuntu4) trusty; urgency=medium * Rebuild for ocaml-4.01. -- Matthias Klose Mon, 23 Dec 2013 16:18:35 +0000 xen (4.3.0-1ubuntu3) trusty; urgency=low * Applying Xen Security Advisories: - CVE-2013-4553 / XSA-74 * Lock order reversal between page_alloc_lock and mm_rwlock - CVE-2013-4551 / XSA-75 * Host crash due to guest VMX instruction execution - CVE-2013-4554 / XSA-76 * Hypercalls exposed to privilege rings 1 and 2 of HVM guests - CVE-????-???? / XSA-77 * Disaggregated domain management security status - CVE-2013-6375 / XSA-78 * Insufficient TLB flushing in VT-d (iommu) code - CVE-2013-6400 / XSA-80 * IOMMU TLB flushing may be inadvertently suppressed - CVE-2013-6885 / XSA-82 * Guest triggerable AMD CPU erratum may cause host hang -- Stefan Bader Fri, 06 Dec 2013 17:51:24 +0100 xen (4.3.0-1ubuntu2) trusty; urgency=low * Applying Xen Security Advisories: - CVE-2013-1442 / XSA-62 * Information leak on AVX and/or LWP capable CPUs - CVE-2013-4355 / XSA-63 * Information leaks through I/O instruction emulation - CVE-2013-4356 / XSA-64 * Memory accessible by 64-bit PV guests under live migration - CVE-2013-4361 / XSA-66 Information leak through fbld instruction emulation - CVE-2013-4368 / XSA-67 * Information leak through outs instruction emulation - CVE-2013-4369 / XSA-68 * possible null dereference when parsing vif ratelimiting info - CVE-2013-4370 / XSA-69 * misplaced free in ocaml xc_vcpu_getaffinity stub - CVE-2013-4371 / XSA-70 * use-after-free in libxl_list_cpupool under memory pressure - CVE-2013-4416 / XSA-72 * ocaml xenstored mishandles oversized message replies - CVE-2013-4494 / XSA-73 * Lock order reversal between page allocation and grant table locks -- Stefan Bader Tue, 05 Nov 2013 16:16:05 +0100 xen (4.3.0-1ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: - Add armhf to packages (except ocaml related) and create hypervisor and system-meta package. Modify build environment to produce Arm packages. * debian/control * debian/rules.gen * debian/rules.real * debian/patches/ubuntu-tools-armhf-without-ocaml.patch Ocaml source fail to build on Arm. - Re-introduce xen-hypervisor-amd64 for i386 builds. Otherwise i386 would be rendered uninstallable. * debian/arch/i386/defines * debian/control - Keep qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: * debian/patches/qemu-prefix.diff Modify LDFLAGS to point to lib dir for qemu-dm. * debian/patches/qemu-disable-blktap.diff Blktap never went upstream. * debian/patches/ubuntu-qemu-disable-qemu-upstream.diff We want to use the binary from qemu-system-x86. * debian/patches/ubuntu-qemu-upstream-location.patch Modify tools to look for qemu-system-i386 in public path. - Fixup hvmloader build to find the correct PXE boot roms. * ubuntu-tools-firmware-etherboot-kvm-ipxe.diff - Add packaging dependency on libxenstore to libxen (otherwise libtool fails to find references for libxenlight). * debian/rules.real - Add migration helper that removes private paths from xend domain configs. * debian/scripts/Makefile * debian/scripts/xend-domain-config-path-strip * debian/xen-utils-common.postinst - Fix for using ulong instead of unsigned long in gdbsx. * debian/patches/toolchain.diff * First test for suitable toolstack in xendomains before using the list command as that causes the xapi daemon to hang. - debian/xen-utils-common.xendomains.init -- Stefan Bader Fri, 27 Sep 2013 15:12:17 +0200 xen (4.3.0-1) unstable; urgency=low * New upstream release. - Fix HVM PCI passthrough. (closes: #706543) * Call configure with proper arguments. * Remove now empty xen-docs package. * Disable external code retrieval. * Drop all i386 hypervisor packages. * Drop complete blktap support. * Create /run/xen. * Make xen-utils recommend qemu-system-x86. (closes: #688311) - This version comes with audio support. (closes: #635166) * Make libxenlight and libxlutil public. (closes: #644390) - Set versioned ABI name. - Install headers. - Move libs into normal library path. * Use build flags in the tools build. - Fix fallout from harderning flags. * Update Standards-Version to 3.9.4. No changes. -- Bastian Blank Thu, 05 Sep 2013 13:54:03 +0200 xen (4.3.0-0ubuntu4) saucy; urgency=low * Re-introduce xen-hypervisor-amd64 for i386 builds. Otherwise i386 would be rendered uninstallable. -- Stefan Bader Thu, 19 Sep 2013 15:28:06 -0500 xen (4.3.0-0ubuntu3) saucy; urgency=low * Avoid building libxenlight with blktap support (at least for now). - ubuntu-tools-force-build-without-blktap2.patch - debian/rules.real: Do not install libblktapctl - debian/libxen-dev.install: Do not package libblktapctl -- Stefan Bader Thu, 15 Aug 2013 10:07:46 +0200 xen (4.3.0-0ubuntu2) saucy; urgency=low * debian/rules.real: Avoid ocaml install and trying to strip hvmload which does not exist on Arm. * debian/rules.gen: Remove i386 related rules for arch-flavour which would try to build the hypervisor (not supported anymore). * debian/rules.gen: Add rules for armhf builds. * debian/control: Add armhf to packages (except ocaml related) and create hypervisor and system-meta package. -- Stefan Bader Sat, 03 Aug 2013 10:23:42 +0100 xen (4.3.0-0ubuntu1) saucy; urgency=low * debian/rules.real: Drop installing pdf for docs. Upstream dropped the xen-abi documentation. * debian/rules.real: Add --prefix=/usr to configure calls. (Default prefix is now /usr/local) * debian/rules -> debian/rules.real: Move modification of LDFLAGS as the latter does the compile and since 4.2.2 includes default.mk which would set the values back (either to the gcc version or to nothing). * debian/rules.real: Hack around checks for wget which the Debian build does not allow to use. * debian/control: Drop i386 versions of xen-hypervisor and xen-system. Upstream dropped i386 support for those. * debian/control: Add recommends for qemu-system-x86 to xen-utils-4.3. Utils (xl stack) will use the generic qemu-system-i386 when being told to use qemu-xen and qemu-dm for qemu-xen-traditional. * xen-utils-common.xen.init: Create /var/run/xen if not present on startup (this directory is used by libxl for qmp sockets). * Add support to allow libvirt to build the libxl driver: - tools/libxl: Create versioned variants of libxenlight.so and libblktapctl.so - debian/rules.real: Add packaging dependency on libxenstore to libxen (otherwise libtool fails to find references). - debian/libxen-dev.install: Package headers and library files of libxenlight. * Carried over from previous versions: - Keep qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: - qemu-prefix (modify LDFLAGS to point to lib dir for qemu-dm) - qemu-disable-blktap (this is not present in upstream) - ubuntu-qemu-disable-qemu-upstream (breaks build and also should be provided by qemu/kvm package) -- Stefan Bader Tue, 25 Jun 2013 16:39:42 +0200 xen (4.2.2-1ubuntu1) saucy; urgency=low * Merge with Debian unstable. Dropping the following patches in favour of Debian ones: - xsa52-4.2-unstable.patch - xsa53-4.2.patch - xsa54.patch - xsa56.patch * Remaining changes: - Use dpkg-buildflags and strip the gcc prefix for getting LDFLAGS. This will again use the Ubuntu specific LDFLAGS (using some hardening options). Older releases would always pass those options in the environment but that changed. - Ressurrect qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: - qemu-prefix (modify LDFLAGS to point to lib dir for qemu-dm) - qemu-disable-blktap (this is not present in upstream) - ubuntu-qemu-disable-qemu-upstream (breaks build and also should be provided by qemu/kvm package) * Remaining additional patches: - qemu-fix-librt-test.patch Fix build regression caused by glibc not requiring to link against librt for the clock_gettime function. Patch picked from xen-devel mailing list. - tools-gdbsx-fix-build-failure-with-glibc-2.17.patch Add direct include to sys/types.h for xg_main.c which likely was indirectly done before. Needed to get ulong type definition. - tools-ocaml-fix-build: refresh and reenable (and fix the description of) this patch. Without it the ocam native libraries (*.cmxa) build in /build local paths rather than appropriatly versioned library references. - APIC Register Virtualization (backported from Xen 4.3) - 0001-xen-enable-APIC-Register-Virtualization.patch - 0002-xen-enable-Virtual-interrupt-delivery.patch - 0003-xen-add-virtual-x2apic-support-for-apicv.patch - TSC Adjust Support (backported from Xen 4.3) - 0004-x86-Implement-TSC-adjust-feature-for-HVM-guest.patch - 0005-x86-Save-restore-TSC-adjust-during-HVM-guest-migrati.patch - 0006-x86-Expose-TSC-adjust-to-HVM-guest.patch - Fix FTBS on i386 - 0007-x86-Fix-i386-virtual-apic.patch - silence-gcc-warnings.patch: Silence gcc warnings. -- Stefan Bader Wed, 17 Jul 2013 09:41:37 +0200 xen (4.2.2-1) unstable; urgency=low * New upstream release. - Fix build with gcc 4.8. (closes: #712376) * Build-depend on libssl-dev. (closes: #712366) * Enable hardening as much as possible. * Re-enable ocaml build fixes. (closes: #695176) * Check for out-of-bound values in CPU affinity setup. CVE-2013-2072 * Fix information leak on AMD CPUs. CVE-2013-2076 * Recover from faults on XRSTOR. CVE-2013-2077 * Properly check guest input to XSETBV. CVE-2013-2078 -- Bastian Blank Thu, 11 Jul 2013 00:28:24 +0200 xen (4.2.1-2ubuntu2) saucy; urgency=low * Applying Xen Security Advisories: - CVE-2013-2194, CVE-2013-2195, CVE-2013-2196 / XSA55 * libelf: abolish libelf-relocate.c * libxc: introduce xc_dom_seg_to_ptr_pages * libxc: Fix range checking in xc_dom_pfn_to_ptr etc. * libelf: add `struct elf_binary*' parameter to elf_load_image * libelf: abolish elf_sval and elf_access_signed * libelf: move include of to top of file * libelf/xc_dom_load_elf_symtab: Do not use "syms" uninitialised * libelf: introduce macros for memory access and pointer handling * tools/xcutils/readnotes: adjust print_l1_mfn_valid_note * libelf: check nul-terminated strings properly * libelf: check all pointer accesses * libelf: Check pointer references in elf_is_elfbinary * libelf: Make all callers call elf_check_broken * libelf: use C99 bool for booleans * libelf: use only unsigned integers * libelf: check loops for running away * libelf: abolish obsolete macros * libxc: Add range checking to xc_dom_binloader * libxc: check failure of xc_dom_*_to_ptr, xc_map_foreign_range * libxc: check return values from malloc * libxc: range checks in xc_dom_p2m_host and _guest * libxc: check blob size before proceeding in xc_dom_check_gzip * libxc: Better range check in xc_dom_alloc_segment - CVE-XXXX-XXXX / XSA57 * libxl: Restrict permissions on PV console device xenstore nodes -- Stefan Bader Fri, 21 Jun 2013 14:23:14 +0200 xen (4.2.1-2ubuntu1) saucy; urgency=low * Merge with Debian unstable. Dropping the following patches in favour of Debian ones: - xsa33-4.2-unstable.patch - xsa36-4.2.patch - xsa44-4.2.patch - xsa45-4.2-01-vcpu-destroy-pagetables-preemptible.patch - xsa45-4.2-02-new-guest-cr3-preemptible.patch - xsa45-4.2-03-new-user-base-preemptible.patch - xsa45-4.2-04-vcpu-reset-preemptible.patch - xsa45-4.2-05-set-info-guest-preemptible.patch - xsa45-4.2-06-unpin-preemptible.patch - xsa45-4.2-07-mm-error-paths-preemptible.patch - xsa46-4.2.patch - xsa47-4.2-unstable.patch - xsa49-4.2.patch * Remaining changes: - debian/control: Depend on libssl-dev - Use dpkg-buildflags and strip the gcc prefix for getting LDFLAGS. This will again use the Ubuntu specific LDFLAGS (using some hardening options). Older releases would always pass those options in the environment but that changed. - Ressurrect qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: - qemu-prefix (modify LDFLAGS to point to lib dir for qemu-dm) - qemu-disable-blktap (this is not present in upstream) - ubuntu-qemu-disable-qemu-upstream (breaks build and also should be provided by qemu/kvm package) * Remaining additional patches: - qemu-cve-2012-6075-1.patch / qemu-cve-2012-6075-2.patch - xsa34-4.2.patch - xsa35-4.2-with-xsa34.patch - xsa38.patch - xsa52-4.2-unstable.patch - xsa53-4.2.patch - xsa54.patch - xsa56.patch - qemu-fix-librt-test.patch Fix build regression caused by glibc not requiring to link against librt for the clock_gettime function. Patch picked from xen-devel mailing list. - tools-gdbsx-fix-build-failure-with-glibc-2.17.patch Add direct include to sys/types.h for xg_main.c which likely was indirectly done before. Needed to get ulong type definition. - tools-ocaml-fix-build: refresh and reenable (and fix the description of) this patch. Without it the ocam native libraries (*.cmxa) build in /build local paths rather than appropriatly versioned library references. - APIC Register Virtualization (backported from Xen 4.3) - 0001-xen-enable-APIC-Register-Virtualization.patch - 0002-xen-enable-Virtual-interrupt-delivery.patch - 0003-xen-add-virtual-x2apic-support-for-apicv.patch - TSC Adjust Support (backported from Xen 4.3) - 0004-x86-Implement-TSC-adjust-feature-for-HVM-guest.patch - 0005-x86-Save-restore-TSC-adjust-during-HVM-guest-migrati.patch - 0006-x86-Expose-TSC-adjust-to-HVM-guest.patch - Fix FTBS on i386 - 0007-x86-Fix-i386-virtual-apic.patch - Fix HVM regression when host supports SMEP - 0008-vmx-Simplify-cr0-update-handling-by-deferring-cr4-ch.patch - 0009-VMX-disable-SMEP-feature-when-guest-is-in-non-paging.patch - 0010-VMX-Always-disable-SMEP-when-guest-is-in-non-paging-.patch - silence-gcc-warnings.patch: Silence gcc warnings. - gcc48-ftbfs.patch - gcc48-ftbfs-2.patch -- Stefan Bader Fri, 14 Jun 2013 10:01:32 +0200 xen (4.2.1-2) unstable; urgency=low * Actually upload to unstable. -- Bastian Blank Sun, 12 May 2013 00:20:58 +0200 xen (4.2.1-1) experimental; urgency=low * New upstream release. * Enable usage of seabios. * Fix some toolchain issues. -- Bastian Blank Sat, 11 May 2013 23:55:46 +0200 xen (4.2.1-0ubuntu4) saucy; urgency=low [ Stefan Bader ] * Applying Xen Security Advisories: - CVE-2013-1918 / XSA-45 * x86: make vcpu_destroy_pagetables() preemptible * x86: make new_guest_cr3() preemptible * x86: make MMUEXT_NEW_USER_BASEPTR preemptible * x86: make vcpu_reset() preemptible * x86: make arch_set_info_guest() preemptible * x86: make page table unpinning preemptible * x86: make page table handling error paths preemptible - CVE-2013-1952 / XSA-49 * VT-d: don't permit SVT_NO_VERIFY entries for known device types - CVE-2013-2076 / XSA-52 * x86/xsave: fix information leak on AMD CPUs - CVE-2013-2077 / XSA-53 * x86/xsave: recover from faults on XRSTOR - CVE-2013-2078 / XSA-54 * x86/xsave: properly check guest input to XSETBV - CVE-2013-2072 / XSA-56 * libxc: limit cpu values when setting vcpu affinity [ Marc Deslauriers ] * debian/patches/gcc48-ftbfs.patch: Add -Wno-unused-local-typedefs to CFLAGS. * debian/patches/gcc48-ftbfs-2.patch: fix memset(&p,0,sizeof(p)) idiom in several places. -- Marc Deslauriers Mon, 10 Jun 2013 15:03:13 -0400 xen (4.2.1-0ubuntu3.1) raring-security; urgency=low * Applying Xen Security Advisories: - CVE-2013-1917 / XSA-44 x86: clear EFLAGS.NT in SYSENTER entry path - CVE-2013-1919 / XSA-46 x86: fix various issues with handling guest IRQs - CVE-2013-1920 / XSA-47 defer event channel bucket pointer store until after XSM checks -- Stefan Bader Wed, 10 Apr 2013 14:21:15 +0200 xen (4.2.1-0ubuntu3) raring; urgency=low * Fix FTBS on i386 - 0007-x86-Fix-i386-virtual-apic.patch * Fix HVM VCPUs getting stuck on boot when host supports SMEP (LP: #1157757) - 0008-vmx-Simplify-cr0-update-handling-by-deferring-cr4-ch.patch - 0009-VMX-disable-SMEP-feature-when-guest-is-in-non-paging.patch - 0010-VMX-Always-disable-SMEP-when-guest-is-in-non-paging-.patch -- Stefan Bader Fri, 05 Apr 2013 16:39:45 +0200 xen (4.2.1-0ubuntu2) raring; urgency=low * Backporting support for Intel APIC virtualization (LP: #1160373) - 0001-xen-enable-APIC-Register-Virtualization.patch - 0002-xen-enable-Virtual-interrupt-delivery.patch - 0003-xen-add-virtual-x2apic-support-for-apicv.patch * Backporting support for Intel TSC adjust (LP: #1160378) - 0004-x86-Implement-TSC-adjust-feature-for-HVM-guest.patch - 0005-x86-Save-restore-TSC-adjust-during-HVM-guest-migrati.patch - 0006-x86-Expose-TSC-adjust-to-HVM-guest.patch -- Stefan Bader Tue, 26 Mar 2013 09:41:25 +0100 xen (4.2.1-0ubuntu1) raring; urgency=low * New upstream stable release. Remaining changes: - Fix to qemu for CVE-2012-6075 - Patches for XSA33-36 and 38 - qemu-fix-librt-test.patch Fix build regression caused by glibc not requiring to link against librt for the clock_gettime function. Patch picked from xen-devel mailing list. - tools-gdbsx-fix-build-failure-with-glibc-2.17.patch Add direct include to sys/types.h for xg_main.c which likely was indirectly done before. Needed to get ulong type definition. - tools-ocaml-fix-build: refresh and reenable (and fix the description of) this patch. Without it the ocam native libraries (*.cmxa) build in /build local paths rather than appropriatly versioned library references. - Use dpkg-buildflags and strip the gcc prefix for getting LDFLAGS. This will again use the Ubuntu specific LDFLAGS (using some hardening options). Older releases would always pass those options in the environment but that changed. - Ressurrect qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: - qemu-prefix (modify LDFLAGS to point to lib dir for qemu-dm) - qemu-disable-blktap (this is not present in upstream) - ubuntu-qemu-disable-qemu-upstream (breaks build and also should be provided by qemu/kvm package) - Build depend on kvm-ipxe (instead of ipxe) as it is smaller and fix up hvmloader build. kvm-ipxe contains a subset of the rom files from which the Xen build only uses two to be embedded in the hvmloader. - debian/patches/silence-gcc-warnings.patch: Silence gcc warnings. -- Stefan Bader Fri, 08 Mar 2013 10:34:54 +0100 xen (4.2.0-2) experimental; urgency=low * Support JSON output in domain init script helper. -- Bastian Blank Mon, 01 Oct 2012 15:11:30 +0200 xen (4.2.0-1ubuntu6) raring; urgency=low * Applying Xen Security Advisory: - VT-d: fix interrupt remapping source validation for devices behind legacy bridges CVE-2012-5634 / XSA-33 - x86_32: don't allow use of nested HVM CVE-2013-0151 / XSA-34 - xen: Do not allow guests to enable nested HVM on themselves CVE-2013-0152 / XSA-35 - ACPI: acpi_table_parse() should return handler's error code CVE-2013-0153 / XSA-36 - oxenstored incorrect handling of certain Xenbus ring states CVE-2013-0215 / XSA-38 * Applying qemu security fixes: - e1000: Discard packets that are too long if !SBP and !LPE CVE-2012-6075 / XSA-41 - Discard packets longer than 16384 when !SBP to match the hardware behavior. CVE-2012-6075 / XSA-41 * qemu-fix-librt-test.patch Fix build regression caused by glibc not requiring to link against librt for the clock_gettime function. Patch picked from xen-devel mailing list. * tools-gdbsx-fix-build-failure-with-glibc-2.17.patch Add direct include to sys/types.h for xg_main.c which likely was indirectly done before. Needed to get ulong type definition. -- Stefan Bader Tue, 29 Jan 2013 15:48:47 +0100 xen (4.2.0-1ubuntu5) raring; urgency=low * Add libssl-dev to Build-Depends. -- Chris J Arges Tue, 15 Jan 2013 11:13:48 -0600 xen (4.2.0-1ubuntu4) raring; urgency=low * Applying Xen Security fixes (LP: #1086875) - gnttab: fix releasing of memory upon switches between versions CVE-2012-5510 - hvm: Limit the size of large HVM op batches CVE-2012-5511 - xen: add missing guest address range checks to XENMEM_exchange handlers CVE-2012-5513 - xen: fix error handling of guest_physmap_mark_populate_on_demand() CVE-2012-5514 - memop: limit guest specified extent order CVE-2012-5515 - x86: get_page_from_gfn() must return NULL for invalid GFNs CVE-2012-5525 -- Stefan Bader Wed, 05 Dec 2012 18:13:25 +0100 xen (4.2.0-1ubuntu3) raring; urgency=low * tools-ocaml-fix-build: refresh and reenable (and fix the description of) this patch. Without it the ocam native libraries (*.cmxa) build in /build local paths rather than appropriatly versioned library references. -- Andy Whitcroft Thu, 29 Nov 2012 21:49:00 +0000 xen (4.2.0-1ubuntu2) raring; urgency=low * Drop replaces and conflicts for xen3 packages (they are no longer in the upgrade path) from debian/control: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3 - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-3.3 * Use dpkg-buildflags and strip the gcc prefix for getting LDFLAGS. This will again use the Ubuntu specific LDFLAGS (using some hardening options). Older releases would always pass those options in the environment but that changed. * Ressurrect qemu-dm for now (upstream qemu would not support migration, yet). Forward-port some patches from the old Debian package which still included qemu-dm: - qemu-prefix (modify LDFLAGS to point to lib dir for qemu-dm) - qemu-disable-blktap (this is not present in upstream) - ubuntu-qemu-disable-qemu-upstream (breaks build and also should be provided by qemu/kvm package) * Build depend on kvm-ipxe (instead of ipxe) as it is smaller and fix up hvmloader build. kvm-ipxe contains a subset of the rom files from which the Xen build only uses two to be embedded in the hvmloader. * XSA-20: Prevent overflow in calculations, leading to DoS vulnerability - CVE-2012-4535 * XSA-22: Prevent incorrect updates of m2p mappings - CVE-2012-4537 * XSA-23: check toplevel pagetables are present before unhooking them - CVE-2012-4538 * XSA-24: Prevent infinite loop in compat code - CVE-2012-4539 * XSA-25: limit maximum size of kernel/ramdisk - CVE-2012-4544 -- Stefan Bader Tue, 13 Nov 2012 09:03:58 +0100 xen (4.2.0-1ubuntu1) raring; urgency=low * Merge from Debian Experimental, Remaining changes: - debian/control: - Build depends on ipxe-qemu. - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3 - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. - Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. - disable debian/patches/config-etherboot.diff. - debian/patches/silence-gcc-warnings.patch: Silence gcc warnings. -- Chuck Short Thu, 08 Nov 2012 12:14:30 -0600 xen (4.2.0-1) experimental; urgency=low * New upstream release. -- Bastian Blank Tue, 18 Sep 2012 13:54:30 +0200 xen (4.2.0~rc3-1) experimental; urgency=low * New upstream snapshot. -- Bastian Blank Fri, 07 Sep 2012 20:28:46 +0200 xen (4.2.0~rc2-1) experimental; urgency=low * New upstream snapshot. * Build-depend against libglib2.0-dev and libyajl-dev. * Disable seabios build for now. * Remove support for Lenny and earlier. * Support build-arch and build-indep make targets. -- Bastian Blank Sun, 13 May 2012 12:21:10 +0000 xen (4.1.4-4) unstable; urgency=high * Make several long runing operations preemptible. CVE-2013-1918 * Fix source validation for VT-d interrupt remapping. CVE-2013-1952 -- Bastian Blank Thu, 02 May 2013 14:30:29 +0200 xen (4.1.4-3) unstable; urgency=high * Fix return from SYSENTER. CVE-2013-1917 * Fix various problems with guest interrupt handling. CVE-2013-1919 * Only save pointer after access checks. CVE-2013-1920 * Fix domain locking for transitive grants. CVE-2013-1964 -- Bastian Blank Fri, 19 Apr 2013 13:01:57 +0200 xen (4.1.4-2) unstable; urgency=low * Use pre-device interrupt remapping mode per default. Fix removing old remappings. CVE-2013-0153 -- Bastian Blank Wed, 06 Feb 2013 13:04:52 +0100 xen (4.1.4-1) unstable; urgency=low * New upstream release. - Disable process-context identifier support in newer CPUs for all domains. - Add workarounds for AMD errata. - Don't allow any non-canonical addresses. - Use Multiboot memory map if BIOS emulation does not provide one. - Fix several problems in tmem. CVE-2012-3497 - Fix error handling in domain creation. - Adjust locking and interrupt handling during S3 resume. - Tighten more resource and memory range checks. - Reset performance counters. (closes: #698651) - Remove special-case for first IO-APIC. - Fix MSI handling for HVM domains. (closes: #695123) - Revert cache value of disks in HVM domains. -- Bastian Blank Thu, 31 Jan 2013 15:44:50 +0100 xen (4.1.3-8) unstable; urgency=high * Fix error in VT-d interrupt remapping source validation. CVE-2012-5634 * Fix buffer overflow in qemu e1000 emulation. CVE-2012-6075 * Update patch, mention second CVE. CVE-2012-5511, CVE-2012-6333 -- Bastian Blank Sat, 19 Jan 2013 13:55:07 +0100 xen (4.1.3-7) unstable; urgency=low * Fix clock jump due to incorrect annotated inline assembler. (closes: #599161) * Add support for XZ compressed Linux kernels to hypervisor and userspace based loaders, it is needed for any Linux kernels newer then Wheezy. (closes: #695056) -- Bastian Blank Tue, 11 Dec 2012 18:54:59 +0100 xen (4.1.3-6) unstable; urgency=high * Fix error handling in physical to machine memory mapping. CVE-2012-5514 -- Bastian Blank Tue, 04 Dec 2012 10:51:43 +0100 xen (4.1.3-5) unstable; urgency=high * Fix state corruption due to incomplete grant table switch. CVE-2012-5510 * Check range of arguments to several HVM operations. CVE-2012-5511, CVE-2012-6333 * Check array index before using it in HVM memory operation. CVE-2012-5512 * Check memory range in memory exchange operation. CVE-2012-5513 * Don't allow too large memory size and avoid busy looping. CVE-2012-5515 -- Bastian Blank Mon, 03 Dec 2012 19:37:38 +0100 xen (4.1.3-4) unstable; urgency=high * Use linux 3.2.0-4 stuff. * Fix overflow in timer calculations. CVE-2012-4535 * Check value of physical interrupts parameter before using it. CVE-2012-4536 * Error out on incorrect memory mapping updates. CVE-2012-4537 * Check if toplevel page tables are present. CVE-2012-4538 * Fix infinite loop in compatibility code. CVE-2012-4539 * Limit maximum kernel and ramdisk size. CVE-2012-2625, CVE-2012-4544 -- Bastian Blank Tue, 20 Nov 2012 15:51:01 +0100 xen (4.1.3-3ubuntu1) quantal; urgency=low * Merge from Debian unstable. Remaining changes: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. - Change depend back to ipxe as we do not have ipxe-qemu. - etherboot: Change the config back to include the 8086100e.rom - Dropped: - Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. Right now there seem to be no LDFLAGS passed. * Backported AMD specific improvements from upstream Xen (LP: #1009098): - svm: Do not intercept RDTSC(P) when TSC scaling is supported by hardware - x86: Use deep C states for off-lined CPUs - x86/AMD: Add support for AMD's OSVW feature in guests. - hvm: vpmu: Enable HVM VPMU for AMD Family 12h and 14h processors -- Stefan Bader Thu, 27 Sep 2012 21:27:44 +0200 xen (4.1.3-3) unstable; urgency=low * Xen domain init script: - Make sure Open vSwitch is started before any domain. - Properly handle and show output of failed migration and save. - Ask all domains to shut down before checking them. -- Bastian Blank Tue, 18 Sep 2012 13:26:32 +0200 xen (4.1.3-2) unstable; urgency=medium * Don't allow writing reserved bits in debug register. CVE-2012-3494 * Fix error handling in interrupt assignment. CVE-2012-3495 * Don't trigger bug messages on invalid flags. CVE-2012-3496 * Check array bounds in interrupt assignment. CVE-2012-3498 * Properly check bounds while setting the cursor in qemu. CVE-2012-3515 * Disable monitor in qemu by default. CVE-2012-4411 -- Bastian Blank Fri, 07 Sep 2012 19:41:46 +0200 xen (4.1.3-1) unstable; urgency=medium * New upstream release: (closes: #683286) - Don't leave the x86 emulation in a bad state. (closes: #683279) CVE-2012-3432 - Only check for shared pages while any exist on teardown. CVE-2012-3433 - Fix error handling for unexpected conditions. - Update CPUID masking to latest Intel spec. - Allow large ACPI ids. - Fix IOMMU support for PCI-to-PCIe bridges. - Disallow access to some sensitive IO-ports. - Fix wrong address in IOTLB. - Fix deadlock on CPUs without working cpufreq driver. - Use uncached disk access in qemu. - Fix buffer size on emulated e1000 device in qemu. * Fixup broken and remove applied patches. -- Bastian Blank Fri, 17 Aug 2012 11:25:02 +0200 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-5) unstable; urgency=low [ Ian Campbell ] * Set tap device MAC addresses to fe:ff:ff:ff:ff:ff (Closes: #671018) * Only run xendomains initscript if toolstack is xl or xm (Closes: #680528) [ Bastian Blank ] * Actually build-depend on new enough version of dpkg-dev. * Add xen-sytem-* meta-packages. We are finally in a position to do automatic upgrades and this package is missing. (closes: #681376) -- Bastian Blank Sat, 28 Jul 2012 10:23:26 +0200 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-4ubuntu1) quantal; urgency=low [ Ubuntu Merge-o-Matic ] * Merge from Debian unstable. Remaining changes: - Thanks to Stefan Bader. - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. - Change depend back to ipxe as we do not have ipxe-qemu. - etherboot: Change the config back to include the 8086100e.rom - Dropped: - Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. Right now there seem to be no LDFLAGS passed. -- Chuck Short Tue, 03 Jul 2012 08:43:03 -0400 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-4) unstable; urgency=low * Add Build-Using info to xen-utils package. * Fix build-arch target. -- Bastian Blank Sun, 01 Jul 2012 19:52:30 +0200 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-3) unstable; urgency=low * Remove /usr/lib/xen-default. It breaks systems if xenstored is not compatible. * Fix init script usage. * Fix udev rules for emulated network devices: - Force names of emulated network devices to a predictable name. -- Bastian Blank Sun, 01 Jul 2012 16:59:04 +0200 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-2) unstable; urgency=low * Fix pointer missmatch in interrupt functions. Fixes build on i386. -- Bastian Blank Fri, 15 Jun 2012 18:00:51 +0200 xen (4.1.3~rc1+hg-20120614.a9c0a89c08f2-1) unstable; urgency=low * New upstream snapshot. - Fix privilege escalation and syscall/sysenter DoS while using non-canonical addresses by untrusted PV guests. (closes: #677221) CVE-2012-0217 CVE-2012-0218 - Disable Xen on CPUs affected by AMD Erratum #121. PV guests can cause a DoS of the host. CVE-2012-2934 * Don't fail if standard toolstacks are not available. (closes: #677244) -- Bastian Blank Thu, 14 Jun 2012 17:06:25 +0200 xen (4.1.2-7) unstable; urgency=low * Really use ucf. * Update init script dependencies: - Start $syslog before xen. - Start drbd and iscsi before xendomains. (closes: #626356) - Start corosync and heartbeat after xendomains. * Remove /var/log/xen on purge. (closes: #656216) -- Bastian Blank Tue, 22 May 2012 10:44:41 +0200 xen (4.1.2-6) unstable; urgency=low * Fix generation of architectures for hypervisor packages. * Remove information about loop devices, it is incorrect. (closes: #503044) * Update xendomains init script: - Create directory for domain images only root readable. (closes: #596048) - Add missing sanity checks for variables. (closes: #671750) - Remove not longer supported config options. - Don't fail if no config is available. - Remove extra output if domain was restored. -- Bastian Blank Sun, 06 May 2012 20:07:41 +0200 xen (4.1.2-5) unstable; urgency=low * Actually force init script rename. (closes: #669341) * Fix long output from xl. * Move complete init script setup. * Rewrite xendomains init script: - Use LSB output functions. - Make output more clear. - Use xen toolstack wrapper. - Use a python script to properly read domain details. * Set name for Domain-0. -- Bastian Blank Mon, 23 Apr 2012 11:56:45 +0200 xen (4.1.2-4) unstable; urgency=low [ Bastian Blank ] * Build-depend on ipxe-qemu instead of ipxe. (closes: #665070) * Don't longer use a4wide latex package. * Use ucf for /etc/default/xen. * Remove handling for old udev rules link and xenstored directory. * Rename xend init script to xen. [ Lionel Elie Mamane ] * Fix toolstack script to work with old dash. (closes: #648029) -- Bastian Blank Mon, 16 Apr 2012 08:47:29 +0000 xen (4.1.2-3) unstable; urgency=low * Merge xen-common source package. * Remove xend wrapper, it should not be called by users. * Support xl in init script. * Restart xen daemons on upgrade. * Restart and stop xenconsoled in init script. * Load xen-gntdev module. * Create /var/lib/xen. (closes: #658101) * Cleanup udev rules. (closes: #657745) -- Bastian Blank Wed, 01 Feb 2012 19:28:28 +0100 xen (4.1.2-2ubuntu2) precise; urgency=low * etherboot: Change the config back to include the 8086100e.rom (LP: #948333) -- Stefan Bader Tue, 06 Mar 2012 20:58:14 +0100 xen (4.1.2-2ubuntu1) precise; urgency=low * Merge from Debian testing. Remaining changes: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. - Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. - Dropped: - debian/patches/upstream-23044:d4ca456c0c25 - debian/patches/upstream-23104:1976adbf2b80 - debian/patches/upstream-changeset-23146.patch - debian/patches/upstream-changeset-23147.patch - debian/patches/xen-pirq-resubmit-irq.patch -- Chuck Short Thu, 22 Dec 2011 04:53:35 +0000 xen (4.1.2-2) unstable; urgency=low [ Jon Ludlam ] * Import (partially reworked) upstream changes for OCaml support. - Rename the ocamlfind packages. - Remove uuid and log libraries. - Fix 2 bit-twiddling bugs and an off-by-one * Fix build of OCaml libraries. * Add OCaml library and development package. * Include some missing headers. -- Bastian Blank Sat, 10 Dec 2011 19:13:25 +0000 xen (4.1.2-1) unstable; urgency=low * New upstream release. * Build-depend on pkg-config. * Add package libxen-4.1. Includes some shared libs. -- Bastian Blank Sat, 26 Nov 2011 18:28:06 +0100 xen (4.1.1-3ubuntu1) precise; urgency=low * Merge from Debian testing. Remaining changes: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. - Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. - debian/patches/upstream-changeset-23146.patch, debian/patches/upstream-changeset-23147.patch: Fix booting with hvm domU. (LP: #832207) - debian/patches/xen-pirq-resubmit-irq.patch: Retrigger pirq events when asserted while processing. (LP: #854829) -- Chuck Short Sun, 06 Nov 2011 05:51:08 +0000 xen (4.1.1-3) unstable; urgency=low [ Julien Danjou ] * Remove Julien Danjou from the Uploaders field. (closes: #590439) [ Bastian Blank ] * Use current version of python. (closes: #646660) * Build-depend against liblzma-dev, it is used if available. (closes: #646694) * Update Standards-Version to 3.9.2. No changes. * Don't use brace-expansion in debhelper install files. -- Bastian Blank Wed, 26 Oct 2011 14:42:33 +0200 xen (4.1.1-2ubuntu4.1) oneiric-proposed; urgency=low * debian/patches/xen-pirq-resubmit-irq.patch: Retrigger pirq events when asserted while processing. Thanks to Stefan Bader (LP: #854829) -- Chuck Short Mon, 10 Oct 2011 19:30:09 -0400 xen (4.1.1-2ubuntu4) oneiric; urgency=low * Rebuild to drop build records on armel and powerpc. LP: #823714. -- Matthias Klose Thu, 06 Oct 2011 14:15:35 +0200 xen (4.1.1-2ubuntu2) oneiric; urgency=low * Clean up patches. * debian/patches/upstream-changeset-23146.patch, debian/patches/upstream-changeset-23147.patch: Fix booting with hvm domU. (LP: #832207) -- Chuck Short Thu, 01 Sep 2011 13:13:47 -0400 xen (4.1.1-2ubuntu1) oneiric; urgency=low * Merge from debian unstable. Remaining changes: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. + Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. -- Chuck Short Thu, 11 Aug 2011 14:18:41 +0000 xen (4.1.1-2) unstable; urgency=low * Fix hvmloader with gcc 4.6. -- Bastian Blank Fri, 05 Aug 2011 23:58:36 +0200 xen (4.1.1-1ubuntu1) oneiric; urgency=low * Merge from debian unstable. Remaining changes: + Xen 3.3 -> Xen 4.1 migration: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-utils: Conflict and replaces libxen3. - xen-utils-4.1: Conflict and replaces libxen3, python-xen-3.3, and xen-utils-4.1. + Make sure the LDFLAGS value passed is suitable for use by ld rather than gcc. + Dropped upstream patches: - debian/patches/disable-unused-but-not-set-error.patch: Applied upstream. - debian/patches/xc-dom-restore-set-but-not-used.patch: Applied upstream. - debian/patches/xc-dom-restore-set-but-not-used.patch: Applied upstream. -- Chuck Short Tue, 19 Jul 2011 00:11:08 +0000 xen (4.1.1-1) unstable; urgency=low * New upstream release. * Don't use qemu-dm if it is not needed. (Backport from xen-unstable.) * Use dh_python2. -- Bastian Blank Mon, 18 Jul 2011 19:38:38 +0200 xen (4.1.0-3ubuntu4) oneiric; urgency=low * Fix xen 3.3 -> xen 4.1 migration. -- Chuck Short Sat, 04 Jun 2011 15:37:17 -0400 xen (4.1.0-3ubuntu3) oneiric; urgency=low * debian/control: Use python2.7 as a build dependency. -- Chuck Short Tue, 31 May 2011 14:50:03 -0400 xen (4.1.0-3ubuntu2) oneiric; urgency=low * debian/control: + Move to python 2.7. + Xen 3.3 -> Xen4.1 migration: - libxenstore3.0: Conflict and replaces libxen3. - libxen-dev: Conflict and replaces libxen3-dev. - xenstore-tuils: Conflict and replaces libxen3 - xen-utils-4.1: Confflict and replaces libxen3, python-xen3.3, and xen-utils-3.3 -- Chuck Short Tue, 31 May 2011 13:15:08 -0400 xen (4.1.0-3ubuntu1) oneiric; urgency=low * Make sure the LDFLAGS value passed is suitable for use by ld, rather than gcc. * Import a set of gcc 4.6 related build fixes from upstream hg. (disable-unused-but-not-set-error.patch, ioapic-uninitialised-variables.patch, patches/xc-dom-restore-set-but-not-used.patch, xc-tmem-set-but-not-used.patch) -- Soren Hansen Thu, 26 May 2011 14:27:18 +0200 xen (4.1.0-3) unstable; urgency=low * Add ghostscript to build-deps. * Enable qemu-dm build. - Add qemu as another orig tar. - Remove blktap1, bluetooth and sdl support from qemu. - Recommend qemu-keymaps and qemu-utils. -- Bastian Blank Thu, 28 Apr 2011 15:20:45 +0200 xen (4.1.0-2) unstable; urgency=low * Re-enable hvmloader: - Use packaged ipxe. * Workaround incompatibility with xenstored of Xen 4.0. -- Bastian Blank Fri, 15 Apr 2011 11:38:25 +0200 xen (4.1.0-1) unstable; urgency=low * New upstream release. -- Bastian Blank Sun, 27 Mar 2011 18:09:28 +0000 xen (4.1.0~rc6-1) unstable; urgency=low * New upstream release candidate. * Build documentation using pdflatex. * Use python 2.6. (closes: #596545) * Fix lintian override. * Install new tools: xl, xenpaging. * Enable blktap2. - Use own md5 implementation. - Fix includes. - Fix linking of blktap2 binaries. - Remove optimization setting. * Temporarily disable hvmloader, wants to download ipxe. * Remove xenstored pid check from xl. -- Bastian Blank Thu, 17 Mar 2011 16:12:45 +0100 xen (4.0.1-2) unstable; urgency=low * Fix races in memory management. * Make sure that frame-table compression leaves enough alligned. * Disable XSAVE support. (closes: #595490) * Check for dying domain instead of raising an assertion. * Add C6 state with EOI errata for Intel. * Make some memory management interrupt safe. Unsure if really needed. * Raise bar for inter-socket migrations on mostly-idle systems. * Fix interrupt handling for legacy routed interrupts. * Allow to set maximal domain memory even during a running change. * Support new partition name in pygrub. (closes: #599243) * Fix some comparisions "< 0" that may be optimized away. * Check for MWAIT support before using it. * Fix endless loop on interrupts on Nehalem cpus. * Don't crash upon direct GDT/LDT access. (closes: #609531) CVE-2010-4255 * Don't loose timer ticks after domain restore. * Reserve some space for IOMMU area in dom0. (closes: #608715) * Fix hypercall arguments after trace callout. * Fix some error paths in vtd support. Memory leak. * Reinstate ACPI DMAR table. -- Bastian Blank Wed, 12 Jan 2011 15:01:40 +0100 xen (4.0.1-1) unstable; urgency=low * New upstream release. - Fix IOAPIC S3 with interrupt remapping enabled. -- Bastian Blank Fri, 03 Sep 2010 17:14:28 +0200 xen (4.0.1~rc6-1) unstable; urgency=low * New upstream release candidate. - Add some missing locks for page table walk. - Fix NMU injection into guest. - Fix ioapic updates for vt-d. - Add check for GRUB2 commandline behaviour. - Fix handling of invalid kernel images. - Allow usage of powernow. * Remove lowlevel python modules usage from pygrub. (closes: #588811) -- Bastian Blank Tue, 17 Aug 2010 23:15:34 +0200 xen (4.0.1~rc5-1) unstable; urgency=low * New upstream release candidate. -- Bastian Blank Mon, 02 Aug 2010 17:06:27 +0200 xen (4.0.1~rc3-1) unstable; urgency=low * New upstream release candidate. * Call dh_pyversion with the correct version. * Restart xen daemon on upgrade. -- Bastian Blank Wed, 30 Jun 2010 16:30:47 +0200 xen (4.0.0-2) unstable; urgency=low * Fix python dependency. (closes: #586666) - Use python-support. - Hardcode to use python 2.5 for now. -- Bastian Blank Mon, 21 Jun 2010 17:23:16 +0200 xen (4.0.0-1) unstable; urgency=low * Update to unstable. * Fix spelling in README. * Remove unnecessary build-depends. * Fixup xend to use different filename lookup. -- Bastian Blank Thu, 17 Jun 2010 11:16:55 +0200 xen (4.0.0-1~experimental.2) experimental; urgency=low * Merge changes from 3.4.3-1. -- Bastian Blank Fri, 28 May 2010 12:58:12 +0200 xen (4.0.0-1~experimental.1) experimental; urgency=low * New upstream version. * Rename source package to xen. * Build depend against iasl and uuid-dev. * Disable blktap2 support, it links against OpenSSL. * Update copyright file. -- Bastian Blank Thu, 06 May 2010 15:47:38 +0200 xen-3 (3.4.3-1) unstable; urgency=low * New upstream version. * Disable blktap support, it is unusable with current kernels. * Disable libaio, was only used by blktap. * Drop device creation support. (closes: #583283) -- Bastian Blank Fri, 28 May 2010 11:43:18 +0200 xen-3 (3.4.3~rc6-1) unstable; urgency=low * New upstream release candidate. - Relocate multiboot modules. (closes: #580045) - Support grub2 in pygrub. (closes: #573311) -- Bastian Blank Sat, 08 May 2010 11:32:29 +0200 xen-3 (3.4.3~rc3-2) unstable; urgency=low * Again list the complete version in the hypervisor. * Fix path detection for bootloader, document it. (closes: #481105) * Rewrite README. -- Bastian Blank Thu, 08 Apr 2010 16:14:58 +0200 xen-3 (3.4.3~rc3-1) unstable; urgency=low * New upstream release candidate. * Use 3.0 (quilt) source format. * Always use current python version. -- Bastian Blank Mon, 01 Mar 2010 22:14:22 +0100 xen-3 (3.4.2-2) unstable; urgency=low * Remove Jeremy T. Bouse from uploaders. * Export blktap lib and headers. * Build amd64 hypervisor on i386. (closes: #366315) -- Bastian Blank Sun, 22 Nov 2009 16:54:47 +0100 xen-3 (3.4.2-1) unstable; urgency=low * New upstream version. * Strip hvmloader by hand. * Remove extra license file from libxen-dev. -- Bastian Blank Mon, 16 Nov 2009 20:57:07 +0100 xen-3 (3.4.1-1) unstable; urgency=low * New upstream version. -- Bastian Blank Fri, 21 Aug 2009 21:34:38 +0200 xen-3 (3.4.0-2) unstable; urgency=low * Add symbols file for libxenstore3.0. (closes: #536173) * Document that ioemu is currently unsupported. (closes: #536175) * Fix location of fsimage plugins. (closes: #536174) -- Bastian Blank Sat, 18 Jul 2009 18:05:35 +0200 xen-3 (3.4.0-1) unstable; urgency=low [ Bastian Blank ] * New upstream version. * Remove ioemu for now. (closes: #490409, #496367) * Remove non-pae hypervisor. * Use debhelper compat level 7. * Make the init script start all daemons. -- Bastian Blank Tue, 30 Jun 2009 22:33:22 +0200 xen-3 (3.2.1-2) unstable; urgency=low * Use e2fslibs based ext2 support for pygrub. (closes: #476366) * Fix missing checks in pvfb code. See CVE-2008-1952. (closes: #487095) * Add support for loading bzImage files. (closes: #474509) * Enable TLS support in ioemu code. * Drop libcrypto usage because of GPL-incompatibility. * Remove AES code from blktap drivers. Considered broken. -- Bastian Blank Sat, 28 Jun 2008 11:30:43 +0200 xen-3 (3.2.1-1) unstable; urgency=low * New upstream version. * Set rpath relative to ${ORIGIN}. * Add lintian override to xen-utils package. -- Bastian Blank Thu, 22 May 2008 14:01:47 +0200 xen-3 (3.2.0-5) unstable; urgency=low * Provide correct directory to dh_pycentral. -- Bastian Blank Mon, 14 Apr 2008 21:43:49 +0200 xen-3 (3.2.0-4) unstable; urgency=low * Pull in newer xen-utils-common. * Fix missing size checks in the ioemu block driver. (closes: #469654) See: CVE-2008-0928 -- Bastian Blank Fri, 07 Mar 2008 14:21:38 +0100 xen-3 (3.2.0-3) unstable; urgency=low * Clean environment for build. * Add packages libxenstore3.0 and xenstore-utils. * Move docs package in docs section to match overwrites. * Make the hypervisor only recommend the utils. * Cleanup installation. (closes: #462989) -- Bastian Blank Tue, 12 Feb 2008 12:40:56 +0000 xen-3 (3.2.0-2) unstable; urgency=low * Fix broken patch. (closes: #462522) -- Bastian Blank Sat, 26 Jan 2008 17:21:52 +0000 xen-3 (3.2.0-1) unstable; urgency=low * New upstream version. * Add package libxen-dev. Including public headers and static libs. (closes: #402249) * Don't longer install xenfb, removed upstream. -- Bastian Blank Tue, 22 Jan 2008 12:51:49 +0000 xen-3 (3.1.2-2) unstable; urgency=low * Add missing rpath definitions. * Fix building of pae version. -- Bastian Blank Sat, 08 Dec 2007 12:07:42 +0000 xen-3 (3.1.2-1) unstable; urgency=high * New upstream release: - Move shared file into /var/run. (closes: #447795) See CVE-2007-3919. - x86: Fix various problems with debug-register handling. (closes: #451626) See CVE-2007-5906. -- Bastian Blank Sat, 24 Nov 2007 13:24:45 +0000 xen-3 (3.1.1-1) unstable; urgency=low * New upstream release: - Don't use exec with untrusted values in pygrub. (closes: #444430) See CVE-2007-4993. -- Bastian Blank Fri, 19 Oct 2007 16:02:37 +0000 xen-3 (3.1.0-2) unstable; urgency=low * Switch to texlive for documentation. * Drop unused transfig. * Drop unused latex features from documentation. * Build depend against gcc-multilib for amd64. (closes: #439662) -- Bastian Blank Fri, 31 Aug 2007 08:15:50 +0000 xen-3 (3.1.0-1) unstable; urgency=low [ Julien Danjou ] * New upstream version. [ Ralph Passgang ] * Added graphviz to Build-Indeps [ Bastian Blank ] * Upstream removed one part of the version. Do it also. * Merge utils packages. * Install blktap support. * Install pygrub. * Install xenfb tools. * xenconsoled startup is racy, wait a little bit. -- Bastian Blank Mon, 20 Aug 2007 15:05:08 +0000 xen-3.0 (3.0.4-1-1) unstable; urgency=low [ Bastian Blank ] * New upstream version (closes: #394411) [ Guido Trotter ] * Actually try to build and release xen 3.0.4 * Update build dependencies -- Guido Trotter Wed, 23 May 2007 11:57:29 +0100 xen-3.0 (3.0.3-0-2) unstable; urgency=medium [Bastian Blank] * Remove device recreate code. * Remove build dependency on linux-support-X [ Guido Trotter ] * Add missing build dependency on zlib1g-dev (closes: #396557) * Add missing build dependencies on libncurses5-dev and x11proto-core-dev (closes: #396561, #396567) -- Guido Trotter Thu, 2 Nov 2006 16:38:02 +0000 xen-3.0 (3.0.3-0-1) unstable; urgency=low * New upstream version. -- Bastian Blank Fri, 20 Oct 2006 11:04:35 +0000 xen-3.0 (3.0.3~rc4+hg11760-1) unstable; urgency=low * New upstream snapshot. * Ignore update-grub errors. (closes: #392534) -- Bastian Blank Sat, 14 Oct 2006 13:09:53 +0000 xen-3.0 (3.0.3~rc1+hg11686-1) unstable; urgency=low * New upstream snapshot. * Rename ioemu package to include the complete version. * Fix name of hypervisor. (closes: #391771) -- Bastian Blank Mon, 9 Oct 2006 12:48:13 +0000 xen-3.0 (3.0.2-3+hg9762-1) unstable; urgency=low * New upstream snapshot. * Rename hypervisor and utils packages to include the complete version. * Redo build environment. -- Bastian Blank Mon, 4 Sep 2006 18:43:12 +0000 xen-3.0 (3.0.2+hg9697-2) unstable; urgency=low [ Guido Trotter ] * Update xen-utils' README.Debian (closes: #372524) [ Bastian Blank ] * Adopt new python policy. (closes: #380990) * Add patch to make new kernels working on the hypervisor. -- Bastian Blank Tue, 15 Aug 2006 19:20:08 +0000 xen-3.0 (3.0.2+hg9697-1) unstable; urgency=low [ Guido Trotter ] * Update Standards Version * Merge upstream fixes trunk (upstream 3.0.2-3 + a couple of fixes) [ Bastian Blank ] * Add xen-ioemu-3.0 package to support HVM guests (closes: #368496) -- Guido Trotter Wed, 31 May 2006 10:50:05 +0200 xen-3.0 (3.0.2+hg9681-1) unstable; urgency=low * Update xen-hypervisor-3.0-i386 and xen-hypervisor-3.0-i386-pae descriptions, specifying what the difference between the two packages is (closes: #366019) * Merge upstream fixes trunk -- Guido Trotter Thu, 18 May 2006 15:25:02 +0200 xen-3.0 (3.0.2+hg9656-1) unstable; urgency=low * Merge upstream fixes trunk - This includes a fix for CVE-2006-1056 -- Guido Trotter Thu, 27 Apr 2006 17:34:03 +0200 xen-3.0 (3.0.2+hg9651-1) unstable; urgency=low * Merge upstream fixes trunk * Fix PAE disabled in pae build (Closes: #364875) -- Julien Danjou Wed, 26 Apr 2006 13:19:39 +0200 xen-3.0 (3.0.2+hg9646-1) unstable; urgency=low [ Guido Trotter ] * Merge upstream fixes trunk [ Bastian Blank ] * debian/patches/libdir.dpatch: Update to make xm save work -- Julien Danjou Mon, 24 Apr 2006 18:02:07 +0200 xen-3.0 (3.0.2+hg9611-1) unstable; urgency=low * Merge upstream bug fixes * Fix bug with xend init.d script -- Julien Danjou Wed, 12 Apr 2006 17:35:35 +0200 xen-3.0 (3.0.2+hg9598-1) unstable; urgency=low * New upstream release * Fix copyright file -- Julien Danjou Mon, 10 Apr 2006 17:02:55 +0200 xen-3.0 (3.0.1+hg8762-1) unstable; urgency=low * The "preserve our homes" release * Now cooperatively maintained by the Debian Xen Team * New upstream release (closes: #327493, #342249) * Build depend on transfig (closes: #321157) * Use gcc rather than gcc-3.4 to compile (closes: #323698) * Split xen-hypervisor-3.0 and xen-utils-3.0 * Build both normal and pae hypervisor packages * Change maintainer and add uploaders field * Add force-reload support for init script xendomains * Remove dependency against bash * Bump standards version to 3.6.2.2 * xen-utils-3.0 conflicts and replaces xen * Add dpatch structure to the package * Remove build-dependency on gcc (it's build essential anyway) * Make SrvServer.py not executable * Create NEWS.Debian file with important upgrade notices * Update copyright file * Remove the linux-patch-xen package * Removed useless build-dependencies: libncurses5-dev, wget * Changed xendomains config path to /etc/default * xen-utils-3.0 now provides xen-utils and xen-hypervisor-3.0-i386 & xen-hypervisor-3.0-i386-pae & xen-hypervizor-amd64 now provide xen-hypervisor * Made xen-utils-3.0.postinst more fault-tolerant, so that upgrading xen2 -> xen3 don't fail because of a running xen2 hypervisor * Updated the "Replaces & Conflicts" * Install only and correctly udev files * Compile date is no more in current locale * Add patch which add the debian version and maintainer in the version string and removes the banner. * Don't install unusable cruft in xen-utils * Remove libxen packages (no stable API/ABI) -- Julien Danjou Wed, 5 Apr 2006 16:05:07 +0200 xen (2.0.6-1) unstable; urgency=low * Patches applied upstream: non-xen-init-exit.patch, add-build.patch, python-install.patch, disable-html-docs.patch. * New upstream released. Closes: #311336. * Remove comparison to UML from xen short description. Closes: #317066. * Make packages conflicts with 1.2 doc debs. Closes: #304285. * Add iproute to xen depends, as it uses /bin/ip. Closes: #300488, #317468. -- Adam Heath Wed, 06 Jul 2005 12:35:50 -0500 xen (2.0.5-3) experimental; urgency=low * Change priority/section to match the overrides file. -- Adam Heath Fri, 18 Mar 2005 12:43:50 -0600 xen (2.0.5-2) experimental; urgency=low * Mike McCallister , Tommi Virtanen , Tom Hibbert : Fix missing '.' in update-rc.d call in xen.postinst. Closes: #299384 -- Adam Heath Fri, 18 Mar 2005 11:39:56 -0600 xen (2.0.5-1) experimental; urgency=low * New upstream. * Remove pic-lib.patch, tools-misc-TARGETS.patch, and clean-mttr.patch as they have been applied upstream(in various forms). * xend now starts at priority 20, stops at 21, while xendomains starts at 21, and stops at 20. -- Adam Heath Fri, 11 Mar 2005 14:33:33 -0600 xen (2.0.4-4) experimental; urgency=low * Bah, major booboo. Add /boot to debian/xen.install, so xen.gz will get shipped. Reported by Clint Adams . -- Adam Heath Tue, 15 Feb 2005 13:00:57 -0600 xen (2.0.4-3) experimental; urgency=low * Fix file overlap(/usr/share/doc/xen/examples/*) between xen and xen-docs. Reported by Tupshin Harper . -- Adam Heath Sun, 06 Feb 2005 01:22:45 -0600 xen (2.0.4-2) experimental; urgency=low * Fix kernel patch generation. It was broken when I integrated with debian's kernel source. I used a symlink, and diff doesn't follow those. -- Adam Heath Sat, 05 Feb 2005 18:16:35 -0600 xen (2.0.4-1) experimental; urgency=low * New upstream. * xen.deb can now install on a plain kernel; that is, the init scripts exit successfully if /proc/xen/privcmd doesn't exist. This allows for dual-boot setups. * Manpages do not yet exist xend, xenperf, xensv, xfrd, nor xm. xend xfrd are daemons, and take little if any options. I've not had a need to use xenperf nor xensv yet. xm has nice built in help(xm help). * Upstream now requires either linux 2.4.29, or 2.6.10. Since 2.4.29 is not yet in debian, disable the 2.4 patch generation. Closes: #271245. * Not certain how the kernel-patch-xen was empty. It's not now, with the repackaging. Closes: #272299. * Xen no longer produces kernel images, so problems about missing features are no longer valid. Closes: #253924. * Acknowledge nmu bugs: * No longer build-depend on gcc 3.3, as the default gcc works. Closes: #243048. -- Adam Heath Sat, 05 Feb 2005 18:04:27 -0600 xen (2.0.3-0.1) unstable; urgency=low * Changes from Tommi Virtanen: * Added dh-kpatches and libcurl3-dev to Build-Depends. * Add /etc/xen/sv/params.py and /etc/xen/xend/params.py. * Add xmexample1 and xmexample2 to xen/doc/examples. -- Adam Heath Wed, 26 Jan 2005 10:55:07 -0600 xen (2.0.3-0) unstable; urgency=low * New upstream. Closes: #280733. * Repackaged from scratch. * Using unreleased patch management system. See debian/README.build. * After extracting the .dsc, there are no special steps needed * Those wanting to change the source, use the normal procedures for any package, including using interdiff(or other tool) to send a patch to me or the bts. * No longer try to do anything fancy with regard to the layout of the built kernels. Now, only patches are distributed. Please make use of the xen support in kernel-package. * Early preview release to #debian-devel. -- Adam Heath Tue, 25 Jan 2005 13:24:54 -0600 xen (1.2-4.1) unstable; urgency=high * NMU * Remove gcc-3.2 from Build-Depends as isn't used during build (Closes: #243048) -- Frank Lichtenheld Sat, 21 Aug 2004 17:42:28 +0200 xen (1.2-4) unstable; urgency=low * Added xen-docs.README.Debian, which explains the kernel image layout, and contains references on the locations differ from what is mentioned by the upstream documentation. Closes: #230345. -- Adam Heath Fri, 26 Mar 2004 17:36:41 -0600 xen (1.2-3) unstable; urgency=low * Add kernel-source-2.4.25 and kernel-patch-debian-2.4.25 to Build-Depends-Indep. -- Adam Heath Tue, 23 Mar 2004 20:14:39 -0600 xen (1.2-2) unstable; urgency=low * xen: moved /boot/xen.gz to /usr/lib/kernels/xen-i386/images/vmlinuz * kernel-image, kernel-modules: swapped i386/xeno to xeno/i386 in /usr/lib/kernels. * Add kernel-patch-nfs-swap deb. * Apply additional patches to kernel-image-xen: * nfs-group * nfs-swap -- Adam Heath Thu, 04 Mar 2004 12:47:47 -0600 xen (1.2-1) unstable; urgency=low * Initial version. -- Adam Heath Tue, 02 Mar 2004 13:21:52 -0600 debian/xen-utils-4.4.prerm0000664000000000000000000000047212321466516012503 0ustar #!/bin/bash set -e case "$1" in remove|upgrade) if [ -x "/etc/init.d/xen" ]; then invoke-rc.d xen stop || exit $? fi ;; deconfigure|failed-upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/xenstore-utils.install0000664000000000000000000000002411201567406013563 0ustar usr/sbin/xenstore-* debian/source/0000775000000000000000000000000012212071062010461 5ustar debian/source/format0000664000000000000000000000001411343011431011665 0ustar 3.0 (quilt) debian/compat0000664000000000000000000000000211201570721010362 0ustar 7 debian/xen-utils-common.README.Debian0000664000000000000000000000200011751503221014433 0ustar Xen for Debian ============== Config behaviour ---------------- The Debian packages changes the behaviour of some config options. The options "kernel", "initrd" and "loader" searches in the Xen private boot directory (/usr/lib/xen-$version/boot) first. "bootloader" and "device_model" also searches the Xen private bin directory (/usr/lib/xen-$version/bin). This means that the following entries will properly find anything: loader = 'hvmloader' bootloader = 'pygrub' Network setup ------------- The Debian package of Xen don't change the network setup in any way. This differs from the upstream version, which overwrites the main network card (eth0) with a bridge setup and may break the network at this point.. To setup a bridge please follow the instructions in the manpage for bridge-utils-interfaces(5). You can also change the /etc/xen/xend-config.sxp file and re-enable the Xen included network setup by adding (network-script network-bridge) to the file. But please note that this may or may not work. debian/xen-utils-common.xendomains.default0000664000000000000000000000543711751534245016140 0ustar # The xendomains script can send SysRq requests to domains on shutdown. # If you don't want to MIGRATE, SAVE, or SHUTDOWN, this may be a possibility # to do a quick and dirty shutdown ("s e i u o") or at least sync the disks # of the domains ("s"). # # XENDOMAINS_SYSRQ= # Set this to a non-empty string if you want to migrate virtual machines # on shutdown. The string will be passed to the xm migrate DOMID command # as is: It should contain the target IP address of the physical machine # to migrate to and optionally parameters like --live. Leave empty if # you don't want to try virtual machine relocation on shutdown. # If migration succeeds, neither SAVE nor SHUTDOWN will be executed for # that domain. # # XENDOMAINS_MIGRATE= # Directory to save running domains to when the system (dom0) is # shut down. Will also be used to restore domains from if # XENDOMAINS_RESTORE # is set (see below). Leave empty to disable domain saving on shutdown # (e.g. because you rather shut domains down). # If domain saving does succeed, SHUTDOWN will not be executed. # XENDOMAINS_SAVE=/var/lib/xen/save # This variable determines whether saved domains from XENDOMAINS_SAVE # will be restored on system startup. # XENDOMAINS_RESTORE=true # This variable sets the directory where domains configurations # are stored that should be started on system startup automatically. # Leave empty if you don't want to start domains automatically # (or just don't place any xen domain config files in that dir). # Note that the script tries to be clever if both RESTORE and AUTO are # set: It will first restore saved domains and then only start domains # in AUTO which are not running yet. # Note that the name matching is somewhat fuzzy. # XENDOMAINS_AUTO=/etc/xen/auto # On xendomains stop, a number of xm commands (xm migrate, save, shutdown, # shutdown --all) may be executed. In the worst case, these commands may # stall forever, which will prevent a successful shutdown of the machine. # If this variable is non-zero, the script will set up a watchdog timer # for every of these xm commands and time it out after the number of seconds # specified by this variable. # Note that SHUTDOWN_ALL will not be called if no virtual machines or only # zombies are still running, so you don't need to enable this timeout just # for the zombie case. # The setting should be large enough to make sure that migrate/save/shutdown # can succeed. If you do live migrations, keep in mind that live migration # of a 1GB machine over Gigabit ethernet may actually take something like # 100s (assuming that live migration uses 10% of the network # bandwidth). # Depending on the virtual machine, a shutdown may also require a significant # amount of time. So better setup this variable to a huge number and hope the # watchdog never fires. # XENDOMAINS_STOP_MAXWAIT=300 debian/templates/0000775000000000000000000000000012212071061011156 5ustar debian/templates/xen-utils.postinst.in0000664000000000000000000000057411767451052015346 0ustar #!/bin/sh set -e case "$1" in configure) update-alternatives --remove xen-default /usr/lib/xen-@version@ if [ -x "/etc/init.d/xen" ]; then invoke-rc.d xen start || exit $? fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/templates/xen-hypervisor.postrm.in0000664000000000000000000000055310514156522016047 0ustar #!/bin/bash set -e case "$1" in remove) if command -v update-grub > /dev/null && [ -d /boot/grub ]; then update-grub || : fi ;; purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/templates/control.system.latest.in0000664000000000000000000000044412012256702016013 0ustar Package: xen-system@localversion@ Depends: xen-hypervisor-@version@@localversion@, xen-utils-@version@, ${misc:Depends} Provides: xen-system Description: Xen System on @class@ (meta-package) This package depends on the latest Xen hypervisor for use on @class@ and the Xen utils. . @desc@ debian/templates/xen-utils.lintian-overrides.in0000664000000000000000000000007611535641643017116 0ustar statically-linked-binary usr/lib/xen-@version@/boot/hvmloader debian/templates/xen-hypervisor.postinst.in0000664000000000000000000000051410514156522016403 0ustar #!/bin/bash set -e case "$1" in configure) if command -v update-grub > /dev/null && [ -d /boot/grub ]; then update-grub || : fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/templates/control.source.in0000664000000000000000000000110512201772203014466 0ustar Section: kernel Priority: optional Maintainer: Debian Xen Team Uploaders: Guido Trotter , Bastian Blank Build-Depends: debhelper (>> 7), dpkg-dev (>= 1.16.0~), lsb-release, python-dev, bcc, gcc-multilib, e2fslibs-dev, iasl, ipxe-qemu, seabios, libaio-dev, libglib2.0-dev, libgnutls-dev, liblzma-dev, libncurses5-dev, libpci-dev, libyajl-dev, libssl-dev, pkg-config, uuid-dev, zlib1g-dev, ocaml-nox, dh-ocaml, ocaml-findlib Standards-Version: 3.9.4 XS-Python-Version: current debian/templates/control.utils.in0000664000000000000000000000062512175203560014341 0ustar Package: xen-utils-@version@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, xen-utils-common (>= ${source:Version}) Recommends: bridge-utils, libc6-xen [i386], xen-hypervisor-@version@, qemu-system-x86 Provides: xen-utils Built-Using: ${misc:Built-Using} Description: XEN administrative tools The userspace tools to manage a system virtualized through the XEN virtual machine monitor. debian/templates/control.hypervisor.in0000664000000000000000000000114112173476022015410 0ustar Package: xen-hypervisor-@version@@localversion@ Depends: ${misc:Depends} Provides: xen-hypervisor, xen-hypervisor-@version@, xen-hypervisor@localversion@ Recommends: xen-utils-@version@ Description: Xen Hypervisor on @class@ The hypervisor is the "core" for XEN itself. It gets booted by the boot loader and controls cpu and memory, sharing them between your administrative domain (Domain 0) and the virtual guest systems. . @desc@ . In order to boot a XEN system along with this package you also need a kernel specifically crafted to work as the Domain 0, mediating hardware access for XEN itself. debian/templates/control.main.in0000664000000000000000000000342012173476022014124 0ustar Package: libxen-@version@ Section: libs Depends: ${shlibs:Depends}, ${misc:Depends} Description: Public libs for Xen This package contains the shared libraries for Xen. Package: libxenstore3.0 Section: libs Depends: ${shlibs:Depends}, ${misc:Depends} Description: Xenstore communications library for Xen This package contains the public libxenstore. Package: libxen-dev Section: libdevel Depends: libxen-@version@ (= ${binary:Version}), libxenstore3.0 (= ${binary:Version}), ${misc:Depends} Description: Public headers and libs for Xen This package contains the public headers and static libraries for Xen. Package: xenstore-utils Section: admin Depends: ${shlibs:Depends}, ${misc:Depends} Conflicts: xen-utils-common (<= 3.1.0-1) Replaces: xen-utils-common (<= 3.1.0-1) Description: Xenstore utilities for Xen This package contains the Xenstore utilities. Package: libxen-ocaml Section: ocaml Depends: ${shlibs:Depends}, ${misc:Depends}, ${ocaml:Depends} Provides: ${ocaml:Provides} Description: OCaml libraries for controlling Xen This package contains the runtime libraries required for the ocaml bindings to the Xen control libraries. Package: libxen-ocaml-dev Section: ocaml Depends: libxen-ocaml (= ${binary:Version}), libxen-dev (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, ${ocaml:Depends} Provides: ${ocaml:Provides} Description: OCaml libraries for controlling Xen (devel package) This package contains the ocaml findlib packages for compiling applications that are designed to control the Xen hypervisor. Package: xen-utils-common Architecture: all Depends: gawk, lsb-base, python, udev, xenstore-utils, ${misc:Depends} Description: Xen administrative tools - common files The userspace tools to manage a system virtualized through the Xen virtual machine monitor. debian/templates/xen-utils.prerm.in0000664000000000000000000000060211767451052014600 0ustar #!/bin/bash set -e case "$1" in remove|upgrade) update-alternatives --remove xen-default /usr/lib/xen-@version@ if [ -x "/etc/init.d/xen" ]; then invoke-rc.d xen stop || exit $? fi ;; deconfigure|failed-upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/patches/0000775000000000000000000000000013167435162010627 5ustar debian/patches/xsa164.patch0000664000000000000000000000230512631300071012657 0ustar MSI-X: avoid array overrun upon MSI-X table writes pt_msix_init() allocates msix->msix_entry[] to just cover msix->total_entries entries. While pci_msix_readl() resorts to reading physical memory for out of bounds reads, pci_msix_writel() so far simply accessed/corrupted unrelated memory. pt_iomem_map()'s call to cpu_register_physical_memory() registers a page granular region, which is necessary as the Pending Bit Array may share space with the MSI-X table (but nothing else is allowed to). This also explains why pci_msix_readl() actually honors out of bounds reads, but pci_msi_writel() doesn't need to. This is XSA-164. Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/qemu/hw/pt-msi.c +++ b/qemu/hw/pt-msi.c @@ -440,6 +440,13 @@ static void pci_msix_writel(void *opaque return; } + if ( addr - msix->mmio_base_addr >= msix->total_entries * 16 ) + { + PT_LOG("Error: Out of bounds write to MSI-X table," + " addr %016"PRIx64"\n", addr); + return; + } + entry_nr = (addr - msix->mmio_base_addr) / 16; entry = &msix->msix_entry[entry_nr]; offset = ((addr - msix->mmio_base_addr) % 16) / 4; debian/patches/xsa206-4.4-0015-oxenstored-replay-transaction-upon-conflict.patch0000664000000000000000000001332413104300260024324 0ustar From ce0ca538ccc5e59b9407f983babfb0dd098e1a0b Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:54:17 +0000 Subject: [PATCH 15/30] oxenstored: replay transaction upon conflict The existing transaction merge algorithm keeps track of the least upper bound (longest common prefix) of all the nodes which have been read and written, and will re-combine two stores which have disjoint upper bounds. This works well for small transactions but causes unnecessary conflicts for ones that span a large subtree, such as the following ones used by the xapi toolstack: * VM start: creates /vm/... /vss/... /local/domain/... The least upper bound of this transaction is / and so all these transactions conflict with everything. * Device hotplug: creates /local/domain/0/... /local/domain/n/... The least upper bound of this transaction is /local/domain so all these transactions conflict with each other. If the existing merge algorithm cannot merge and commit, we attempt a /replay/ of the failed transaction against the new store. When we replay the requests we check whether the response sent to the client is the same as during the first attempt at the transaction. If the responses are all the same then the transaction replay can be committed. If any differ then the transaction replay must be aborted and the client must retry. This algorithm uses the intuition that the transactions made by the toolstack are designed to be for separate domains, and should fundamentally not conflict in the sense that they don't read or write any shared keys. By replaying the transaction on the server side we do what the client would have to do anyway, only we can do it quickly without allowing any other requests to interfere. Performing 300 parallel simulated VM start and shutdowns without this code: 300 parallel starts and shutdowns: 268.92 Performing 300 parallel simulated VM start and shutdowns with this code: 300 parallel starts and shutdowns: 3.80 Reported-by: Juergen Gross Signed-off-by: Dave Scott Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/connection.ml | 5 ++++- tools/ocaml/xenstored/packet.ml | 5 +++++ tools/ocaml/xenstored/process.ml | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml index 807fc00..15ff2b3 100644 --- a/tools/ocaml/xenstored/connection.ml +++ b/tools/ocaml/xenstored/connection.ml @@ -212,7 +212,10 @@ let end_transaction con tid commit = let trans = Hashtbl.find con.transactions tid in Hashtbl.remove con.transactions tid; Logging.end_transaction ~tid ~con:(get_domstr con); - if commit then Transaction.commit ~con:(get_domstr con) trans else true + match commit with + | None -> true + | Some transaction_replay_f -> + Transaction.commit ~con:(get_domstr con) trans || transaction_replay_f con trans let get_transaction con tid = Hashtbl.find con.transactions tid diff --git a/tools/ocaml/xenstored/packet.ml b/tools/ocaml/xenstored/packet.ml index 22cae1d..aeae0a4 100644 --- a/tools/ocaml/xenstored/packet.ml +++ b/tools/ocaml/xenstored/packet.ml @@ -9,3 +9,8 @@ type response = | Ack of (unit -> unit) (* function is the action to execute after sending the ack *) | Reply of string | Error of string + +let response_equal a b = + match (a, b) with + | (Ack _, Ack _) -> true (* just consider the response, not the post-response action *) + | (x, y) -> x = y diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 77660bd..3ade42d 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -275,6 +275,38 @@ let input_handle_error ~cons ~doms ~fct ~con ~t ~req = | (Failure "int_of_string") -> reply_error "EINVAL" | Define.Unknown_operation -> reply_error "ENOSYS" +(* Replay a stored transaction against a fresh store, check the responses are + all equivalent: if so, commit the transaction. Otherwise send the abort to + the client. *) +let transaction_replay c t doms cons = + match t.Transaction.ty with + | Transaction.No -> + error "attempted to replay a non-full transaction"; + false + | Transaction.Full(id, oldroot, cstore) -> + let tid = Connection.start_transaction c cstore in + let new_t = Transaction.make tid cstore in + let con = sprintf "r(%d):%s" id (Connection.get_domstr c) in + let perform_exn (request, response) = + let fct = function_of_type_simple_op request.Packet.ty in + let response' = input_handle_error ~cons ~doms ~fct ~con:c ~t:new_t ~req:request in + if not(Packet.response_equal response response') then raise Transaction_again in + finally + (fun () -> + try + Logging.start_transaction ~con ~tid; + List.iter perform_exn (Transaction.get_operations t); + Logging.end_transaction ~con ~tid; + + Transaction.commit ~con new_t + with e -> + info "transaction_replay %d caught: %s" tid (Printexc.to_string e); + false + ) + (fun () -> + Connection.end_transaction c tid None + ) + let do_watch con t domains cons data = let (node, token) = match (split None '\000' data) with @@ -307,6 +339,7 @@ let do_transaction_end con t domains cons data = | _ -> raise Invalid_Cmd_Args in let success = + let commit = if commit then Some (fun con trans -> transaction_replay con trans domains cons) else None in Connection.end_transaction con (Transaction.get_id t) commit in if not success then raise Transaction_again; -- 2.1.4 debian/patches/xsa198.patch0000664000000000000000000000421513035177327012707 0ustar From 71a389ae940bc52bf897a6e5becd73fd8ede94c5 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 3 Nov 2016 16:37:40 +0000 Subject: [PATCH] pygrub: Properly quote results, when returning them to the caller: * When the caller wants sexpr output, use `repr()' This is what Xend expects. The returned S-expressions are now escaped and quoted by Python, generally using '...'. Previously kernel and ramdisk were unquoted and args was quoted with "..." but without proper escaping. This change may break toolstacks which do not properly dequote the returned S-expressions. * When the caller wants "simple" output, crash if the delimiter is contained in the returned value. With --output-format=simple it does not seem like this could ever happen, because the bootloader config parsers all take line-based input from the various bootloader config files. With --output-format=simple0, this can happen if the bootloader config file contains nul bytes. This is XSA-198. Signed-off-by: Ian Jackson Tested-by: Ian Jackson Reviewed-by: Andrew Cooper --- tools/pygrub/src/pygrub | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index 40f9584..dd0c8f7 100755 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -721,14 +721,17 @@ def sniff_netware(fs, cfg): return cfg def format_sxp(kernel, ramdisk, args): - s = "linux (kernel %s)" % kernel + s = "linux (kernel %s)" % repr(kernel) if ramdisk: - s += "(ramdisk %s)" % ramdisk + s += "(ramdisk %s)" % repr(ramdisk) if args: - s += "(args \"%s\")" % args + s += "(args %s)" % repr(args) return s def format_simple(kernel, ramdisk, args, sep): + for check in (kernel, ramdisk, args): + if check is not None and sep in check: + raise RuntimeError, "simple format cannot represent delimiter-containing value" s = ("kernel %s" % kernel) + sep if ramdisk: s += ("ramdisk %s" % ramdisk) + sep -- 2.1.4 debian/patches/xsa128-qemut.patch0000664000000000000000000001126212571016372014025 0ustar xen: properly gate host writes of modified PCI CFG contents The old logic didn't work as intended when an access spanned multiple fields (for example a 32-bit access to the location of the MSI Message Data field with the high 16 bits not being covered by any known field). Remove it and derive which fields not to write to from the accessed fields' emulation masks: When they're all ones, there's no point in doing any host write. This fixes a secondary issue at once: We obviously shouldn't make any host write attempt when already the host read failed. This is XSA-128. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -454,7 +454,7 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_INTEL_OPREGION, .size = 4, .init_val = 0, - .no_wb = 1, + .emu_mask = 0xFFFFFFFF, .u.dw.read = pt_intel_opregion_read, .u.dw.write = pt_intel_opregion_write, .u.dw.restore = NULL, @@ -657,7 +657,6 @@ static struct pt_reg_info_tbl pt_emu_reg .init_val = 0x00000000, .ro_mask = 0x00000003, .emu_mask = 0xFFFFFFFF, - .no_wb = 1, .init = pt_common_reg_init, .u.dw.read = pt_long_reg_read, .u.dw.write = pt_msgaddr32_reg_write, @@ -670,7 +669,6 @@ static struct pt_reg_info_tbl pt_emu_reg .init_val = 0x00000000, .ro_mask = 0x00000000, .emu_mask = 0xFFFFFFFF, - .no_wb = 1, .init = pt_msgaddr64_reg_init, .u.dw.read = pt_long_reg_read, .u.dw.write = pt_msgaddr64_reg_write, @@ -683,7 +681,6 @@ static struct pt_reg_info_tbl pt_emu_reg .init_val = 0x0000, .ro_mask = 0x0000, .emu_mask = 0xFFFF, - .no_wb = 1, .init = pt_msgdata_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_msgdata_reg_write, @@ -696,7 +693,6 @@ static struct pt_reg_info_tbl pt_emu_reg .init_val = 0x0000, .ro_mask = 0x0000, .emu_mask = 0xFFFF, - .no_wb = 1, .init = pt_msgdata_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_msgdata_reg_write, @@ -1524,7 +1520,7 @@ static void pt_pci_write_config(PCIDevic uint32_t find_addr = address; uint32_t real_offset = 0; uint32_t valid_mask = 0xFFFFFFFF; - uint32_t read_val = 0; + uint32_t read_val = 0, wb_mask; uint8_t *ptr_val = NULL; int emul_len = 0; int index = 0; @@ -1597,7 +1593,10 @@ static void pt_pci_write_config(PCIDevic { PT_LOG("Error: pci_read_block failed. return value[%d].\n", ret); memset((uint8_t *)&read_val, 0xff, len); + wb_mask = 0; } + else + wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); /* pass directly to libpci for passthrough type register group */ if (reg_grp_entry == NULL) @@ -1620,6 +1619,11 @@ static void pt_pci_write_config(PCIDevic valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3)); valid_mask <<= ((find_addr - real_offset) << 3); ptr_val = ((uint8_t *)&val + (real_offset & 3)); + if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { + wb_mask &= ~((reg->emu_mask + >> ((find_addr - real_offset) << 3)) + << ((len - emul_len) << 3)); + } /* do emulation depend on register size */ switch (reg->size) { @@ -1677,8 +1681,19 @@ static void pt_pci_write_config(PCIDevic val >>= ((address & 3) << 3); out: - if (!(reg && reg->no_wb)) { /* unknown regs are passed through */ - ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len); + for (index = 0; wb_mask; index += len) { + /* unknown regs are passed through */ + while (!(wb_mask & 0xff)) { + index++; + wb_mask >>= 8; + } + len = 0; + do { + len++; + wb_mask >>= 8; + } while (wb_mask & 0xff); + ret = pci_write_block(pci_dev, address + index, + (uint8_t *)&val + index, len); if (!ret) PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret); --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -372,8 +372,6 @@ struct pt_reg_info_tbl { uint32_t ro_mask; /* reg emulate field mask (ON:emu, OFF:passthrough) */ uint32_t emu_mask; - /* no write back allowed */ - uint32_t no_wb; /* emul reg initialize method */ conf_reg_init init; union { debian/patches/tools-xenstore-prefix.diff0000664000000000000000000000362612276137133015765 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstore/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstore/Makefile 2014-02-10 12:53:56.266056614 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstore/Makefile 2014-02-10 12:56:11.026715430 +0100 @@ -58,10 +58,10 @@ endif init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest) init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE) - $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(call LDFLAGS_RPATH,../lib) -o $@ $(APPEND_LDFLAGS) xenstored: $(XENSTORED_OBJS) - $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) $(call LDFLAGS_RPATH,../lib) -o $@ $(APPEND_LDFLAGS) xenstored.a: $(XENSTORED_OBJS) $(AR) cr $@ $^ @@ -109,17 +109,17 @@ tarball: clean .PHONY: install install: all - $(INSTALL_DIR) $(DESTDIR)$(BINDIR) + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xenstore-compat $(INSTALL_DIR) $(DESTDIR)/var/run/xenstored $(INSTALL_DIR) $(DESTDIR)/var/lib/xenstored - $(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR) - $(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR) + $(INSTALL_PROG) xenstored $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) xenstore-control $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) xenstore $(DESTDIR)$(SBINDIR) set -e ; for c in $(CLIENTS) ; do \ - ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \ + ln -f xenstore $(DESTDIR)$(SBINDIR)/$${c} ; \ done $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) $(INSTALL_PROG) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) debian/patches/tools-pygrub-prefix.diff0000664000000000000000000000241212276137124015416 0ustar Index: xen-4.4.0~rc3+20140210/tools/pygrub/src/pygrub =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/pygrub/src/pygrub 2014-02-10 12:53:57.034060369 +0100 +++ xen-4.4.0~rc3+20140210/tools/pygrub/src/pygrub 2014-02-10 12:56:04.486683459 +0100 @@ -22,6 +22,8 @@ import xen.lowlevel.xc import curses, _curses, curses.wrapper, curses.textpad, curses.ascii import getopt +sys.path.insert(1, sys.path[0] + '/../lib/python') + import fsimage import grub.GrubConf import grub.LiloConf Index: xen-4.4.0~rc3+20140210/tools/pygrub/setup.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/pygrub/setup.py 2014-02-10 12:53:57.050060447 +0100 +++ xen-4.4.0~rc3+20140210/tools/pygrub/setup.py 2014-02-10 12:56:04.486683459 +0100 @@ -4,11 +4,13 @@ import os import sys extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ] +extra_link_args = [ "-Wl,-rpath,${ORIGIN}/.." ] XEN_ROOT = "../.." fsimage = Extension("fsimage", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ], library_dirs = [ XEN_ROOT + "/tools/libfsimage/common/" ], libraries = ["fsimage"], debian/patches/tools-libxc-abiname.diff0000664000000000000000000000755712305357553015330 0ustar Index: xen-4.4.0~rc3+20140210/tools/libxc/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libxc/Makefile 2014-02-10 12:53:58.162065886 +0100 +++ xen-4.4.0~rc3+20140210/tools/libxc/Makefile 2014-02-10 12:55:56.690645342 +0100 @@ -1,9 +1,6 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 4.4 -MINOR = 0 - CTRL_SRCS-y := CTRL_SRCS-y += xc_core.c CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c @@ -110,12 +107,12 @@ OSDEP_PIC_OBJS := $(patsubst %.c,%.opic, LIB := libxenctrl.a ifneq ($(stubdom),y) -LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR) +LIB += libxenctrl.so libxenctrl-$(XEN_VERSION).so endif LIB += libxenguest.a ifneq ($(stubdom),y) -LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR) +LIB += libxenguest.so libxenguest-$(XEN_VERSION).so endif ifneq ($(stubdom),y) @@ -136,15 +133,13 @@ libs: $(LIB) install: build $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_PROG) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) + $(INSTALL_PROG) libxenctrl-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(LIBDIR) - ln -sf libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so.$(MAJOR) - ln -sf libxenctrl.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenctrl.so + ln -sf libxenctrl-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR)/libxenctrl.so $(INSTALL_DATA) xenctrl.h xenctrlosdep.h xentoollog.h $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_PROG) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) + $(INSTALL_PROG) libxenguest-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) libxenguest.a $(DESTDIR)$(LIBDIR) - ln -sf libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenguest.so.$(MAJOR) - ln -sf libxenguest.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenguest.so + ln -sf libxenguest-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR)/libxenguest.so $(INSTALL_DATA) xenguest.h $(DESTDIR)$(INCLUDEDIR) .PHONY: TAGS @@ -173,22 +168,18 @@ rpm: build libxenctrl.a: $(CTRL_LIB_OBJS) $(AR) rc $@ $^ -libxenctrl.so: libxenctrl.so.$(MAJOR) - ln -sf $< $@ -libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR) +libxenctrl.so: libxenctrl-$(XEN_VERSION).so ln -sf $< $@ -libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS) - $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) +libxenctrl-$(XEN_VERSION).so: $(CTRL_PIC_OBJS) + $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $^ $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) # libxenguest libxenguest.a: $(GUEST_LIB_OBJS) $(AR) rc $@ $^ -libxenguest.so: libxenguest.so.$(MAJOR) - ln -sf $< $@ -libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR) +libxenguest.so: libxenguest-$(XEN_VERSION).so ln -sf $< $@ ifeq ($(CONFIG_MiniOS),y) @@ -200,9 +191,9 @@ endif xc_dom_bzimageloader.o: CFLAGS += $(call zlib-options,D) xc_dom_bzimageloader.opic: CFLAGS += $(call zlib-options,D) -libxenguest.so.$(MAJOR).$(MINOR): COMPRESSION_LIBS = $(call zlib-options,l) -libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) +libxenguest-$(XEN_VERSION).so: COMPRESSION_LIBS = $(call zlib-options,l) +libxenguest-$(XEN_VERSION).so: $(GUEST_PIC_OBJS) libxenctrl-$(XEN_VERSION).so + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) xenctrl_osdep_ENOSYS.so: $(OSDEP_PIC_OBJS) libxenctrl.so $(CC) -g $(LDFLAGS) $(SHLIB_LDFLAGS) -o $@ $(OSDEP_PIC_OBJS) $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) debian/patches/ubuntu-tools-hotplug-disable-xend-rules.patch0000664000000000000000000000237612276137154021505 0ustar From: Stefan Bader Date: Tue, 17 Dec 2013 15:28:40 +0100 Subject: [UBUNTU] Disable xend udev socket rules The udev version used in Ubuntu (from systemd) does not support piping messages into named sockets. Since this is not working anyway and only produces ugly messages, disable the rules for now. Note: Not meant for upstream which actually will deprecate xm/xend in the coming 4.4 release. Signed-off-by: Stefan Bader Index: xen-4.4.0~rc3+20140210/tools/hotplug/Linux/xend.rules =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/hotplug/Linux/xend.rules 2014-02-10 12:53:53.630043730 +0100 +++ xen-4.4.0~rc3+20140210/tools/hotplug/Linux/xend.rules 2014-02-10 12:56:28.030798554 +0100 @@ -1,4 +1,4 @@ -SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event" -SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event" -SUBSYSTEM=="usb", RUN+="socket:/org/xen/xend/udev_event" +#SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event" +#SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event" +#SUBSYSTEM=="usb", RUN+="socket:/org/xen/xend/udev_event" #SUBSYSTEM=="net", KERNEL!="vif[0-9]*.[0-9]*|tap[0-9]*.[0-9]*", RUN+="socket:/org/xen/xend/udev_event" debian/patches/qemu-prefix.diff0000664000000000000000000000310412276137151013716 0ustar Index: xen-4.4.0~rc3+20140210/qemu/xen-hooks.mak =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/xen-hooks.mak 2014-02-10 12:53:54.058045822 +0100 +++ xen-4.4.0~rc3+20140210/qemu/xen-hooks.mak 2014-02-10 12:56:25.594786651 +0100 @@ -20,7 +20,7 @@ CFLAGS += $(CMDLINE_CFLAGS) LIBS += -L$(XEN_ROOT)/tools/libxc -lxenctrl -lxenguest LIBS += -L$(XEN_ROOT)/tools/xenstore -lxenstore -LDFLAGS := $(CFLAGS) $(LDFLAGS) +LDFLAGS := $(CFLAGS) $(LDFLAGS) -Wl,-rpath,'$${ORIGIN}/../lib' OBJS += piix4acpi.o OBJS += xenstore.o @@ -81,7 +81,6 @@ OBJS := $(filter-out $(BAD_OBJS), $(OBJS EXESUF=-xen -datadir := $(subst qemu,xen/qemu,$(datadir)) docdir := $(subst qemu,xen/qemu,$(docdir)) mandir := $(subst share/man,share/xen/man,$(mandir)) Index: xen-4.4.0~rc3+20140210/qemu/xen-setup =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/xen-setup 2014-02-10 12:53:54.086045960 +0100 +++ xen-4.4.0~rc3+20140210/qemu/xen-setup 2014-02-10 12:56:25.594786651 +0100 @@ -28,7 +28,7 @@ ln -sf ${QEMU_ROOT:-..}/Makefile.target ln -sf ${QEMU_ROOT:-..}/xen-config.mak $target/config.mak cat ${QEMU_ROOT:-.}/xen-config-host.mak >>config-host.mak -sed -e 's,qemu,xen/qemu,' config-host.h >config-host.h.new +cat config-host.h >config-host.h.new echo "#define DEFAULT_NETWORK_SCRIPT \"${XEN_SCRIPT_DIR}/qemu-ifup\"" >>config-host.h.new echo "#define DEFAULT_NETWORK_DOWN_SCRIPT \"${XEN_SCRIPT_DIR}/qemu-ifdown\"" >>config-host.h.new echo '#include "xen-config-host.h"' >>config-host.h.new debian/patches/ubuntu-qemu-upstream-location.patch0000664000000000000000000000242712276137153017607 0ustar From: Stefan Bader Date: Mon, 15 Jul 2013 14:29:52 +0200 Subject: Change qemu-system-i386 paths used to point to the default one Signed-off-by: Stefan Bader Index: xen-4.4.0~rc3+20140210/tools/hotplug/Linux/init.d/sysconfig.xencommons =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/hotplug/Linux/init.d/sysconfig.xencommons 2014-02-10 12:53:53.690044019 +0100 +++ xen-4.4.0~rc3+20140210/tools/hotplug/Linux/init.d/sysconfig.xencommons 2014-02-10 12:56:27.498795960 +0100 @@ -30,4 +30,4 @@ #XENBACKENDD_DEBUG=[yes|on|1] # qemu path -#QEMU_XEN=/usr/lib/xen/bin/qemu-system-i386 +#QEMU_XEN=/usr/bin/qemu-system-i386 Index: xen-4.4.0~rc3+20140210/tools/libxl/libxl_dm.c =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libxl/libxl_dm.c 2014-02-10 12:53:53.710044122 +0100 +++ xen-4.4.0~rc3+20140210/tools/libxl/libxl_dm.c 2014-02-10 12:56:27.498795960 +0100 @@ -38,7 +38,7 @@ static const char *qemu_xen_path(libxl__ #ifdef QEMU_XEN_PATH return QEMU_XEN_PATH; #else - return libxl__abs_path(gc, "qemu-system-i386", libxl__libexec_path()); + return libxl__abs_path(gc, "qemu-system-i386", "/usr/bin"); #endif } debian/patches/xsa240-4.4-0002-x86-mm-Disable-PV-linear-pagetables-by-default.patch0000664000000000000000000000677313167430223024106 0ustar From 7444f8a6c1a8df082c23a0c1acc542defcffc0ad Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Fri, 22 Sep 2017 11:46:55 +0100 Subject: [PATCH 2/2] x86/mm: Disable PV linear pagetables by default Allowing pagetables to point to other pagetables of the same level (often called 'linear pagetables') has been included in Xen since its inception. But it is not used by the most common PV guests (Linux, NetBSD, minios), and has been the source of a number of subtle reference-counting bugs. Add a command-line option to control whether PV linear pagetables are allowed (disabled by default). Signed-off-by: George Dunlap Reviewed-by: Andrew Cooper --- Changes since v2: - s/_/-/; in command-line option - Added __read_mostly --- Index: xen-4.4.2/docs/misc/xen-command-line.markdown =================================================================== --- xen-4.4.2.orig/docs/misc/xen-command-line.markdown +++ xen-4.4.2/docs/misc/xen-command-line.markdown @@ -808,6 +808,21 @@ This option can be specified more than o ### ple\_window > `= ` +### pv-linear-pt +> `= ` + +> Default: `false` + +Allow PV guests to have pagetable entries pointing to other pagetables +of the same level (i.e., allowing L2 PTEs to point to other L2 pages). +This technique is often called "linear pagetables", and is sometimes +used to allow operating systems a simple way to consistently map the +current process's pagetables into its own virtual address space. + +None of the most common PV operating systems (Linux, NetBSD, MiniOS) +use this technique, but there may be custom operating systems which +do. + ### reboot > `= t[riple] | k[bd] | n[o] [, [w]arm | [c]old]` Index: xen-4.4.2/xen/arch/x86/mm.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm.c +++ xen-4.4.2/xen/arch/x86/mm.c @@ -741,6 +741,9 @@ static void dec_linear_uses(struct page_ * frame if it is mapped by a different root table. This is sufficient and * also necessary to allow validation of a root table mapping itself. */ +static bool_t __read_mostly pv_linear_pt_enable = 0; +boolean_param("pv-linear-pt", pv_linear_pt_enable); + #define define_get_linear_pagetable(level) \ static int \ get_##level##_linear_pagetable( \ @@ -750,6 +753,13 @@ get_##level##_linear_pagetable( struct page_info *page; \ unsigned long pfn; \ \ + if ( !pv_linear_pt_enable ) \ + { \ + gdprintk(XENLOG_WARNING, \ + "Attempt to create linear p.t. (feature disabled)\n"); \ + return 0; \ + } \ + \ if ( (level##e_get_flags(pde) & _PAGE_RW) ) \ { \ MEM_LOG("Attempt to create linear p.t. with write perms"); \ debian/patches/xsa235-4.5.patch0000664000000000000000000000276613167425663013221 0ustar From: Jan Beulich Subject: arm/mm: release grant lock on xenmem_add_to_physmap_one() error paths Commit 55021ff9ab ("xen/arm: add_to_physmap_one: Avoid to map mfn 0 if an error occurs") introduced error paths not releasing the grant table lock. Replace them by a suitable check after the lock was dropped. This is XSA-235. Reported-by: Wei Liu Signed-off-by: Jan Beulich Reviewed-by: Julien Grall --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -1052,7 +1052,7 @@ int xenmem_add_to_physmap_one( if ( idx < nr_status_frames(d->grant_table) ) mfn = virt_to_mfn(d->grant_table->status[idx]); else - return -EINVAL; + mfn = INVALID_MFN; } else { @@ -1063,14 +1063,21 @@ int xenmem_add_to_physmap_one( if ( idx < nr_grant_frames(d->grant_table) ) mfn = virt_to_mfn(d->grant_table->shared_raw[idx]); else - return -EINVAL; + mfn = INVALID_MFN; } - d->arch.grant_table_gpfn[idx] = gpfn; + if ( mfn != INVALID_MFN ) + { + d->arch.grant_table_gpfn[idx] = gpfn; - t = p2m_ram_rw; + t = p2m_ram_rw; + } spin_unlock(&d->grant_table->lock); + + if ( mfn == INVALID_MFN ) + return -EINVAL; + break; case XENMAPSPACE_shared_info: if ( idx != 0 ) debian/patches/tools-ocaml-fix-build.diff0000664000000000000000000001111712276137146015575 0ustar From: Debian Xen Team Date: Tue, 29 Nov 2011 11:45:27 +0000 Subject: tools-ocaml-fix-build.diff Fix the build of the ocaml libraries Signed-off-by: Jon Ludlam --- tools/Rules.mk | 2 ++ tools/ocaml/Makefile.rules | 10 ++-------- tools/ocaml/libs/eventchn/Makefile | 1 + tools/ocaml/libs/xc/Makefile | 3 ++- tools/ocaml/xenstored/Makefile | 4 +++- 5 files changed, 10 insertions(+), 10 deletions(-) Index: xen-4.4.0~rc3+20140210/tools/Rules.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Rules.mk 2014-02-10 12:56:16.154740499 +0100 +++ xen-4.4.0~rc3+20140210/tools/Rules.mk 2014-02-10 12:56:21.822768211 +0100 @@ -23,10 +23,12 @@ CFLAGS_xeninclude = -I$(XEN_INCLUDE) CFLAGS_libxenctrl = -I$(XEN_LIBXC) $(CFLAGS_xeninclude) LDLIBS_libxenctrl = $(XEN_LIBXC)/libxenctrl.so +LDLIBS_libxenctrl_SYSTEM = -lxenctrl-$(XEN_VERSION) SHLIB_libxenctrl = -Wl,-rpath-link=$(XEN_LIBXC) CFLAGS_libxenguest = -I$(XEN_LIBXC) $(CFLAGS_xeninclude) LDLIBS_libxenguest = $(XEN_LIBXC)/libxenguest.so +LDLIBS_libxenguest_SYSTEM = -lxenguest-$(XEN_VERSION) SHLIB_libxenguest = -Wl,-rpath-link=L$(XEN_LIBXC) CFLAGS_libxenstore = -I$(XEN_XENSTORE) $(CFLAGS_xeninclude) Index: xen-4.4.0~rc3+20140210/tools/ocaml/Makefile.rules =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/ocaml/Makefile.rules 2014-02-10 12:53:54.458047776 +0100 +++ xen-4.4.0~rc3+20140210/tools/ocaml/Makefile.rules 2014-02-10 12:56:21.822768211 +0100 @@ -58,14 +58,8 @@ mk-caml-lib-stubs = \ # define a library target .cmxa and .cma define OCAML_LIBRARY_template - $(1).cmxa: lib$(1)_stubs.a $(foreach obj,$($(1)_OBJS),$(obj).cmx) - $(call mk-caml-lib-native,$$@, -cclib -l$(1)_stubs $(foreach lib,$(LIBS_$(1)),-cclib $(lib)), $(foreach obj,$($(1)_OBJS),$(obj).cmx)) - $(1).cma: $(foreach obj,$($(1)_OBJS),$(obj).cmo) - $(call mk-caml-lib-bytecode,$$@, -dllib dll$(1)_stubs.so -cclib -l$(1)_stubs, $$+) - $(1)_stubs.a: $(foreach obj,$$($(1)_C_OBJS),$(obj).o) - $(call mk-caml-stubs,$$@, $$+) - lib$(1)_stubs.a: $(foreach obj,$($(1)_C_OBJS),$(obj).o) - $(call mk-caml-lib-stubs,$$@, $$+) + $(1).cma: $(foreach obj,$($(1)_OBJS),$(obj).cmx $(obj).cmo) $(foreach obj,$($(1)_C_OBJS),$(obj).o) + $(OCAMLMKLIB) -o $1 -oc $(1)_stubs $(foreach obj,$($(1)_OBJS),$(obj).cmx $(obj).cmo) $(foreach obj,$($(1)_C_OBJS),$(obj).o) $(foreach lib, $(LIBS_$(1)_SYSTEM), -cclib $(lib)) $(foreach arg,$(LIBS_$(1)),-ldopt $(arg)) endef define OCAML_NOC_LIBRARY_template Index: xen-4.4.0~rc3+20140210/tools/ocaml/libs/eventchn/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/ocaml/libs/eventchn/Makefile 2014-02-10 12:53:54.410047542 +0100 +++ xen-4.4.0~rc3+20140210/tools/ocaml/libs/eventchn/Makefile 2014-02-10 12:56:21.822768211 +0100 @@ -9,6 +9,7 @@ INTF = $(foreach obj, $(OBJS),$(obj).cmi LIBS = xeneventchn.cma xeneventchn.cmxa LIBS_xeneventchn = $(LDLIBS_libxenctrl) +LIBS_xeneventchn_SYSTEM = $(LDLIBS_libxenctrl_SYSTEM) all: $(INTF) $(LIBS) $(PROGRAMS) Index: xen-4.4.0~rc3+20140210/tools/ocaml/libs/xc/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/ocaml/libs/xc/Makefile 2014-02-10 12:53:54.394047466 +0100 +++ xen-4.4.0~rc3+20140210/tools/ocaml/libs/xc/Makefile 2014-02-10 12:56:21.822768211 +0100 @@ -10,6 +10,7 @@ INTF = xenctrl.cmi LIBS = xenctrl.cma xenctrl.cmxa LIBS_xenctrl = $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) +LIBS_xenctrl_SYSTEM = $(LDLIBS_libxenctrl_SYSTEM) $(LDLIBS_libxenguest_SYSTEM) xenctrl_OBJS = $(OBJS) xenctrl_C_OBJS = xenctrl_stubs Index: xen-4.4.0~rc3+20140210/tools/ocaml/xenstored/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/ocaml/xenstored/Makefile 2014-02-10 12:53:54.430047638 +0100 +++ xen-4.4.0~rc3+20140210/tools/ocaml/xenstored/Makefile 2014-02-10 12:56:21.826768226 +0100 @@ -43,7 +43,9 @@ XENSTOREDLIBS = \ -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/eventchn $(OCAML_TOPLEVEL)/libs/eventchn/xeneventchn.cmxa \ -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/xc $(OCAML_TOPLEVEL)/libs/xc/xenctrl.cmxa \ -ccopt -L -ccopt $(OCAML_TOPLEVEL)/libs/xb $(OCAML_TOPLEVEL)/libs/xb/xenbus.cmxa \ - -ccopt -L -ccopt $(XEN_ROOT)/tools/libxc + -ccopt -L -ccopt $(XEN_ROOT)/tools/libxc \ + $(foreach obj, $(LDLIBS_libxenctrl), -ccopt $(obj)) \ + $(foreach obj, $(LDLIBS_libxenguest), -ccopt $(obj)) PROGRAMS = oxenstored debian/patches/xsa201-2.patch0000664000000000000000000001450413035177767013041 0ustar From: Wei Chen Subject: arm64: handle async aborts delivered while at EL2 If EL1 generates an asynchronous abort and then traps into EL2 (by HVC or IRQ) before the abort has been delivered, the hypervisor could not catch it, because the PSTATE.A bit is masked all the time in hypervisor. So this asynchronous abort may be slipped to next running guest with PSTATE.A bit unmasked. In order to avoid this, it is necessary to take the abort at EL2, by clearing the PSTATE.A bit. In this patch, we unmask the PSTATE.A bit to open a window to catch guest-generated asynchronous abort in all EL1 -> EL2 swich paths. If we catched such asynchronous abort in checking window, the hyp_error exception will be triggered and the abort source guest will be crashed. This is CVE-2016-9816, part of XSA-201. Signed-off-by: Wei Chen Reviewed-by: Julien Grall --- a/xen/arch/arm/arm64/entry.S +++ b/xen/arch/arm/arm64/entry.S @@ -173,6 +173,43 @@ hyp_error_invalid: entry hyp=1 invalid BAD_ERROR +hyp_error: + /* + * Only two possibilities: + * 1) Either we come from the exit path, having just unmasked + * PSTATE.A: change the return code to an EL2 fault, and + * carry on, as we're already in a sane state to handle it. + * 2) Or we come from anywhere else, and that's a bug: we panic. + */ + entry hyp=1 + msr daifclr, #2 + + /* + * The ELR_EL2 may be modified by an interrupt, so we have to use the + * saved value in cpu_user_regs to check whether we come from 1) or + * not. + */ + ldr x0, [sp, #UREGS_PC] + adr x1, abort_guest_exit_start + cmp x0, x1 + adr x1, abort_guest_exit_end + ccmp x0, x1, #4, ne + mov x0, sp + mov x1, #BAD_ERROR + + /* + * Not equal, the exception come from 2). It's a bug, we have to + * panic the hypervisor. + */ + b.ne do_bad_mode + + /* + * Otherwise, the exception come from 1). It happened because of + * the guest. Crash this guest. + */ + bl do_trap_guest_error + exit hyp=1 + /* Traps taken in Current EL with SP_ELx */ hyp_sync: entry hyp=1 @@ -189,15 +226,29 @@ hyp_irq: guest_sync: entry hyp=0, compat=0 + bl check_pending_vserror + /* + * If x0 is Non-zero, a vSError took place, the initial exception + * doesn't have any significance to be handled. Exit ASAP + */ + cbnz x0, 1f msr daifclr, #2 mov x0, sp bl do_trap_hypervisor +1: exit hyp=0, compat=0 guest_irq: entry hyp=0, compat=0 + bl check_pending_vserror + /* + * If x0 is Non-zero, a vSError took place, the initial exception + * doesn't have any significance to be handled. Exit ASAP + */ + cbnz x0, 1f mov x0, sp bl do_trap_irq +1: exit hyp=0, compat=0 guest_fiq_invalid: @@ -213,15 +264,29 @@ guest_error: guest_sync_compat: entry hyp=0, compat=1 + bl check_pending_vserror + /* + * If x0 is Non-zero, a vSError took place, the initial exception + * doesn't have any significance to be handled. Exit ASAP + */ + cbnz x0, 1f msr daifclr, #2 mov x0, sp bl do_trap_hypervisor +1: exit hyp=0, compat=1 guest_irq_compat: entry hyp=0, compat=1 + bl check_pending_vserror + /* + * If x0 is Non-zero, a vSError took place, the initial exception + * doesn't have any significance to be handled. Exit ASAP + */ + cbnz x0, 1f mov x0, sp bl do_trap_irq +1: exit hyp=0, compat=1 guest_fiq_invalid_compat: @@ -270,6 +335,62 @@ return_from_trap: eret /* + * This function is used to check pending virtual SError in the gap of + * EL1 -> EL2 world switch. + * The x0 register will be used to indicate the results of detection. + * x0 -- Non-zero indicates a pending virtual SError took place. + * x0 -- Zero indicates no pending virtual SError took place. + */ +check_pending_vserror: + /* + * Save elr_el2 to check whether the pending SError exception takes + * place while we are doing this sync exception. + */ + mrs x0, elr_el2 + + /* Synchronize against in-flight ld/st */ + dsb sy + + /* + * Unmask PSTATE asynchronous abort bit. If there is a pending + * SError, the EL2 error exception will happen after PSTATE.A + * is cleared. + */ + msr daifclr, #4 + + /* + * This is our single instruction exception window. A pending + * SError is guaranteed to occur at the earliest when we unmask + * it, and at the latest just after the ISB. + * + * If a pending SError occurs, the program will jump to EL2 error + * exception handler, and the elr_el2 will be set to + * abort_guest_exit_start or abort_guest_exit_end. + */ +abort_guest_exit_start: + + isb + +abort_guest_exit_end: + /* Mask PSTATE asynchronous abort bit, close the checking window. */ + msr daifset, #4 + + /* + * Compare elr_el2 and the saved value to check whether we are + * returning from a valid exception caused by pending SError. + */ + mrs x1, elr_el2 + cmp x0, x1 + + /* + * Not equal, the pending SError exception took place, set + * x0 to non-zero. + */ + cset x0, ne + + ret + +/* * Exception vectors. */ .macro ventry label @@ -287,7 +408,7 @@ ENTRY(hyp_traps_vector) ventry hyp_sync // Synchronous EL2h ventry hyp_irq // IRQ EL2h ventry hyp_fiq_invalid // FIQ EL2h - ventry hyp_error_invalid // Error EL2h + ventry hyp_error // Error EL2h ventry guest_sync // Synchronous 64-bit EL0/EL1 ventry guest_irq // IRQ 64-bit EL0/EL1 debian/patches/tools-xenmon-install.diff0000664000000000000000000000214512276137144015570 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenmon/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenmon/Makefile 2014-02-10 12:56:08.110701169 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenmon/Makefile 2014-02-10 12:56:20.234760447 +0100 @@ -13,6 +13,10 @@ XEN_ROOT=$(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk +DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path) +PYTHON_PATH ?= $(DEFAULT_PYTHON_PATH) +INSTALL_PYTHON_PROG = $(XEN_ROOT)/tools/python/install-wrap "$(PYTHON_PATH)" $(INSTALL_PROG) + CFLAGS += -Werror CFLAGS += $(CFLAGS_libxenctrl) LDLIBS += $(LDLIBS_libxenctrl) @@ -31,7 +35,7 @@ install: build $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_PROG) xenbaked $(DESTDIR)$(PRIVATE_BINDIR)/xenbaked $(INSTALL_PROG) xentrace_setmask $(DESTDIR)$(PRIVATE_BINDIR)/xentrace_setmask - $(INSTALL_PROG) xenmon.py $(DESTDIR)$(PRIVATE_BINDIR)/xenmon.py + $(INSTALL_PYTHON_PROG) xenmon.py $(DESTDIR)$(PRIVATE_BINDIR)/xenmon $(INSTALL_DIR) $(DESTDIR)$(DOCDIR) $(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.xenmon debian/patches/tools-misc-prefix.diff0000664000000000000000000000344712276137123015051 0ustar Index: xen-4.4.0~rc3+20140210/tools/misc/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/misc/Makefile 2014-02-10 12:53:57.242061388 +0100 +++ xen-4.4.0~rc3+20140210/tools/misc/Makefile 2014-02-10 12:56:03.094676653 +0100 @@ -41,12 +41,8 @@ build: $(TARGETS) .PHONY: install install: build - $(INSTALL_DIR) $(DESTDIR)$(BINDIR) - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) - $(INSTALL_PYTHON_PROG) $(INSTALL_BIN) $(DESTDIR)$(BINDIR) - $(INSTALL_PYTHON_PROG) $(INSTALL_SBIN) $(DESTDIR)$(SBINDIR) - $(INSTALL_PYTHON_PROG) $(INSTALL_PRIVBIN) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PYTHON_PROG) $(INSTALL_BIN) $(INSTALL_SBIN) $(INSTALL_PRIVBIN) $(DESTDIR)$(PRIVATE_BINDIR) set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d install-recurse; done .PHONY: clean Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/xend =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/xend 2014-02-10 12:53:57.266061512 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/xend 2014-02-10 12:56:03.094676653 +0100 @@ -33,6 +33,8 @@ import signal import time import commands +sys.path.insert(1, sys.path[0] + '/../lib/python') + from xen.xend.server import SrvDaemon class CheckError(ValueError): Index: xen-4.4.0~rc3+20140210/tools/python/xen/xm/xm =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xm/xm 2014-02-10 12:53:57.302061683 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xm/xm 2014-02-10 12:56:03.094676653 +0100 @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- mode: python; -*- import sys, os.path +sys.path.insert(1, sys.path[0] + '/../lib/python') from xen.xm import main debian/patches/tools-misc-rpath.diff0000664000000000000000000000100712276137123014660 0ustar Index: xen-4.4.0~rc3+20140210/tools/misc/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/misc/Makefile 2014-02-10 12:56:03.094676653 +0100 +++ xen-4.4.0~rc3+20140210/tools/misc/Makefile 2014-02-10 12:56:03.794680069 +0100 @@ -32,6 +32,8 @@ INSTALL_PRIVBIN := $(INSTALL_PRIVBIN-y) # Include configure output (config.h) to headers search path CFLAGS += -I$(XEN_ROOT)/tools +APPEND_LDFLAGS += $(call LDFLAGS_RPATH,../lib) + .PHONY: all all: build debian/patches/xsa185.patch0000664000000000000000000000244012775454612012706 0ustar From 30aba4992b18245c436f16df7326a16c01a51570 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 8 Aug 2016 10:58:12 +0100 Subject: x86/32on64: don't allow recursive page tables from L3 L3 entries are special in PAE mode, and hence can't reasonably be used for setting up recursive (and hence linear) page table mappings. Since abuse is possible when the guest in fact gets run on 4-level page tables, this needs to be excluded explicitly. This is XSA-185. Reported-by: Jérémie Boutoille Reported-by: 栾尚聪(好风) Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- xen/arch/x86/mm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 109b8be..69b8b8d 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1122,7 +1122,9 @@ get_page_from_l3e( rc = get_page_and_type_from_pagenr( l3e_get_pfn(l3e), PGT_l2_page_table, d, partial, 1); - if ( unlikely(rc == -EINVAL) && get_l3_linear_pagetable(l3e, pfn, d) ) + if ( unlikely(rc == -EINVAL) && + !is_pv_32bit_domain(d) && + get_l3_linear_pagetable(l3e, pfn, d) ) rc = 0; return rc; -- 2.1.4 debian/patches/xsa131-qemut-4.patch0000664000000000000000000002446512571017471014172 0ustar xen/pt: split out calculation of throughable mask in PCI config space handling This is just to avoid having to adjust that calculation later in multiple places. Note that including ->ro_mask in get_throughable_mask()'s calculation is only an apparent (i.e. benign) behavioral change: For r/o fields it doesn't matter > whether they get passed through - either the same flag is also set in emu_mask (then there's no change at all) or the field is r/o in hardware (and hence a write won't change it anyway). This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich Acked-by: Stefano Stabellini Reviewed-by: Anthony PERARD --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -3442,6 +3442,15 @@ static int pt_bar_reg_read(struct pt_dev } +static uint32_t get_throughable_mask(const struct pt_dev *ptdev, + const struct pt_reg_info_tbl *reg, + uint32_t valid_mask) +{ + uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); + + return throughable_mask & valid_mask; +} + /* write byte size emulate register */ static int pt_byte_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -3449,14 +3458,13 @@ static int pt_byte_reg_write(struct pt_d { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint8_t writable_mask = 0; - uint8_t throughable_mask = 0; + uint8_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3469,14 +3477,13 @@ static int pt_word_reg_write(struct pt_d { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3489,14 +3496,13 @@ static int pt_long_reg_write(struct pt_d { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; + uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; @@ -3509,7 +3515,7 @@ static int pt_cmd_reg_write(struct pt_de { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t wr_value = *value; /* modify emulate register */ @@ -3517,8 +3523,6 @@ static int pt_cmd_reg_write(struct pt_de cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - if (*value & PCI_COMMAND_DISABLE_INTx) { if (ptdev->msi_trans_en) @@ -3564,7 +3568,6 @@ static int pt_bar_reg_write(struct pt_de PCIDevice *d = (PCIDevice *)&ptdev->dev; PCIIORegion *r; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t bar_emu_mask = 0; uint32_t bar_ro_mask = 0; uint32_t new_addr, last_addr; @@ -3691,8 +3694,7 @@ static int pt_bar_reg_write(struct pt_de exit: /* create value for writing to I/O device register */ - throughable_mask = ~bar_emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* After BAR reg update, we need to remap BAR*/ reg_grp_entry = pt_find_reg_grp(ptdev, PCI_COMMAND); @@ -3719,9 +3721,8 @@ static int pt_exp_rom_bar_reg_write(stru PCIDevice *d = (PCIDevice *)&ptdev->dev; PCIIORegion *r; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; + uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint32_t r_size = 0; - uint32_t bar_emu_mask = 0; uint32_t bar_ro_mask = 0; r = &d->io_regions[PCI_ROM_SLOT]; @@ -3731,7 +3732,6 @@ static int pt_exp_rom_bar_reg_write(stru PT_GET_EMUL_SIZE(base->bar_flag, r_size); /* set emulate mask and read-only mask */ - bar_emu_mask = reg->emu_mask; bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; /* modify emulate register */ @@ -3751,7 +3751,6 @@ static int pt_exp_rom_bar_reg_write(stru r->addr = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~bar_emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* After BAR reg update, we need to remap BAR*/ @@ -3776,7 +3775,7 @@ static int pt_pmcsr_reg_write(struct pt_ struct pt_reg_info_tbl *reg = cfg_entry->reg; PCIDevice *d = &ptdev->dev; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); struct pt_pm_info *pm_state = ptdev->pm_state; uint16_t read_val = 0; @@ -3785,7 +3784,6 @@ static int pt_pmcsr_reg_write(struct pt_ cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS, throughable_mask); @@ -3894,7 +3892,7 @@ static int pt_msgctrl_reg_write(struct p { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t old_ctrl = cfg_entry->data; PCIDevice *pd = (PCIDevice *)ptdev; uint16_t val; @@ -3906,8 +3904,10 @@ static int pt_msgctrl_reg_write(struct p /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; /* also emulate MSI_ENABLE bit for MSI-INTx translation */ - if (ptdev->msi_trans_en) + if (ptdev->msi_trans_en) { writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask; + throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; + } cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->flags |= cfg_entry->data & @@ -3915,10 +3915,6 @@ static int pt_msgctrl_reg_write(struct p /* create value for writing to I/O device register */ val = *value; - throughable_mask = ~reg->emu_mask & valid_mask; - /* don't pass through MSI_ENABLE bit for MSI-INTx translation */ - if (ptdev->msi_trans_en) - throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ @@ -3972,7 +3968,6 @@ static int pt_msgaddr32_reg_write(struct { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t old_addr = cfg_entry->data; /* modify emulate register */ @@ -3982,8 +3977,7 @@ static int pt_msgaddr32_reg_write(struct ptdev->msi->addr_lo = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_addr) @@ -4002,7 +3996,6 @@ static int pt_msgaddr64_reg_write(struct { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint32_t writable_mask = 0; - uint32_t throughable_mask = 0; uint32_t old_addr = cfg_entry->data; /* check whether the type is 64 bit or not */ @@ -4020,8 +4013,7 @@ static int pt_msgaddr64_reg_write(struct ptdev->msi->addr_hi = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_addr) @@ -4041,7 +4033,6 @@ static int pt_msgdata_reg_write(struct p { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; uint16_t old_data = cfg_entry->data; uint32_t flags = ptdev->msi->flags; uint32_t offset = reg->offset; @@ -4062,8 +4053,7 @@ static int pt_msgdata_reg_write(struct p ptdev->msi->data = cfg_entry->data; /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value, 0); /* update MSI */ if (cfg_entry->data != old_data) @@ -4082,7 +4072,7 @@ static int pt_msixctrl_reg_write(struct { struct pt_reg_info_tbl *reg = cfg_entry->reg; uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; + uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); uint16_t old_ctrl = cfg_entry->data; /* modify emulate register */ @@ -4090,7 +4080,6 @@ static int pt_msixctrl_reg_write(struct cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI-X */ debian/patches/xsa221.patch0000664000000000000000000002007313126666673012702 0ustar From: Jan Beulich Subject: evtchn: avoid NULL derefs Commit fbbd5009e6 ("evtchn: refactor low-level event channel port ops") added a de-reference of the struct evtchn pointer for a port without first making sure the bucket pointer is non-NULL. This de-reference is actually entirely unnecessary, as all relevant callers (beyond the problematic do_poll()) already hold the port number in their hands, and the actual leaf functions need nothing else. For FIFO event channels there's a second problem in that the ordering of reads and updates to ->num_evtchns and ->event_array[] was so far undefined (the read side isn't always holding the domain's event lock). Add respective barriers. This is XSA-221. Reported-by: Ankur Arora Signed-off-by: Jan Beulich Index: xen-4.4.2/xen/arch/x86/irq.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/irq.c +++ xen-4.4.2/xen/arch/x86/irq.c @@ -1475,7 +1475,7 @@ int pirq_guest_unmask(struct domain *d) { pirq = pirqs[i]->pirq; if ( pirqs[i]->masked && - !evtchn_port_is_masked(d, evtchn_from_port(d, pirqs[i]->evtchn)) ) + !evtchn_port_is_masked(d, pirqs[i]->evtchn) ) pirq_guest_eoi(pirqs[i]); } } while ( ++pirq < d->nr_pirqs && n == ARRAY_SIZE(pirqs) ); @@ -2222,7 +2222,6 @@ static void dump_irqs(unsigned char key) int i, irq, pirq; struct irq_desc *desc; irq_guest_action_t *action; - struct evtchn *evtchn; struct domain *d; const struct pirq *info; unsigned long flags; @@ -2265,11 +2264,10 @@ static void dump_irqs(unsigned char key) d = action->guest[i]; pirq = domain_irq_to_pirq(d, irq); info = pirq_info(d, pirq); - evtchn = evtchn_from_port(d, info->evtchn); printk("%u:%3d(%c%c%c)", d->domain_id, pirq, - (evtchn_port_is_pending(d, evtchn) ? 'P' : '-'), - (evtchn_port_is_masked(d, evtchn) ? 'M' : '-'), + evtchn_port_is_pending(d, info->evtchn) ? 'P' : '-', + evtchn_port_is_masked(d, info->evtchn) ? 'M' : '-', (info->masked ? 'M' : '-')); if ( i != action->nr_guests ) printk(","); Index: xen-4.4.2/xen/common/event_2l.c =================================================================== --- xen-4.4.2.orig/xen/common/event_2l.c +++ xen-4.4.2/xen/common/event_2l.c @@ -62,16 +62,20 @@ static void evtchn_2l_unmask(struct doma } } -static bool_t evtchn_2l_is_pending(struct domain *d, - const struct evtchn *evtchn) +static bool_t evtchn_2l_is_pending(struct domain *d, evtchn_port_t port) { - return test_bit(evtchn->port, &shared_info(d, evtchn_pending)); + unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d); + + ASSERT(port < max_ports); + return port < max_ports && test_bit(port, &shared_info(d, evtchn_pending)); } -static bool_t evtchn_2l_is_masked(struct domain *d, - const struct evtchn *evtchn) +static bool_t evtchn_2l_is_masked(struct domain *d, evtchn_port_t port) { - return test_bit(evtchn->port, &shared_info(d, evtchn_mask)); + unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d); + + ASSERT(port < max_ports); + return port >= max_ports || test_bit(port, &shared_info(d, evtchn_mask)); } static void evtchn_2l_print_state(struct domain *d, Index: xen-4.4.2/xen/common/event_channel.c =================================================================== --- xen-4.4.2.orig/xen/common/event_channel.c +++ xen-4.4.2/xen/common/event_channel.c @@ -1359,8 +1359,8 @@ static void domain_dump_evtchn_info(stru printk(" %4u [%d/%d/", port, - !!evtchn_port_is_pending(d, chn), - !!evtchn_port_is_masked(d, chn)); + evtchn_port_is_pending(d, port), + evtchn_port_is_masked(d, port)); evtchn_port_print_state(d, chn); printk("]: s=%d n=%d x=%d", chn->state, chn->notify_vcpu_id, chn->xen_consumer); Index: xen-4.4.2/xen/common/event_fifo.c =================================================================== --- xen-4.4.2.orig/xen/common/event_fifo.c +++ xen-4.4.2/xen/common/event_fifo.c @@ -28,6 +28,12 @@ static inline event_word_t *evtchn_fifo_ if ( unlikely(port >= d->evtchn_fifo->num_evtchns) ) return NULL; + /* + * Callers aren't required to hold d->event_lock, so we need to synchronize + * with add_page_to_event_array(). + */ + smp_rmb(); + p = port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE; w = port % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE; @@ -289,24 +295,22 @@ static void evtchn_fifo_unmask(struct do evtchn_fifo_set_pending(v, evtchn); } -static bool_t evtchn_fifo_is_pending(struct domain *d, - const struct evtchn *evtchn) +static bool_t evtchn_fifo_is_pending(struct domain *d, evtchn_port_t port) { event_word_t *word; - word = evtchn_fifo_word_from_port(d, evtchn->port); + word = evtchn_fifo_word_from_port(d, port); if ( unlikely(!word) ) return 0; return test_bit(EVTCHN_FIFO_PENDING, word); } -static bool_t evtchn_fifo_is_masked(struct domain *d, - const struct evtchn *evtchn) +static bool_t evtchn_fifo_is_masked(struct domain *d, evtchn_port_t port) { event_word_t *word; - word = evtchn_fifo_word_from_port(d, evtchn->port); + word = evtchn_fifo_word_from_port(d, port); if ( unlikely(!word) ) return 1; @@ -583,6 +587,10 @@ static int add_page_to_event_array(struc return rc; d->evtchn_fifo->event_array[slot] = virt; + + /* Synchronize with evtchn_fifo_word_from_port(). */ + smp_wmb(); + d->evtchn_fifo->num_evtchns += EVTCHN_FIFO_EVENT_WORDS_PER_PAGE; /* Index: xen-4.4.2/xen/common/schedule.c =================================================================== --- xen-4.4.2.orig/xen/common/schedule.c +++ xen-4.4.2/xen/common/schedule.c @@ -760,7 +760,7 @@ static long do_poll(struct sched_poll *s goto out; rc = 0; - if ( evtchn_port_is_pending(d, evtchn_from_port(d, port)) ) + if ( evtchn_port_is_pending(d, port) ) goto out; } Index: xen-4.4.2/xen/include/xen/event.h =================================================================== --- xen-4.4.2.orig/xen/include/xen/event.h +++ xen-4.4.2/xen/include/xen/event.h @@ -136,8 +136,8 @@ struct evtchn_port_ops { void (*set_pending)(struct vcpu *v, struct evtchn *evtchn); void (*clear_pending)(struct domain *d, struct evtchn *evtchn); void (*unmask)(struct domain *d, struct evtchn *evtchn); - bool_t (*is_pending)(struct domain *d, const struct evtchn *evtchn); - bool_t (*is_masked)(struct domain *d, const struct evtchn *evtchn); + bool_t (*is_pending)(struct domain *d, evtchn_port_t port); + bool_t (*is_masked)(struct domain *d, evtchn_port_t port); int (*set_priority)(struct domain *d, struct evtchn *evtchn, unsigned int priority); void (*print_state)(struct domain *d, const struct evtchn *evtchn); @@ -168,15 +168,15 @@ static inline void evtchn_port_unmask(st } static inline bool_t evtchn_port_is_pending(struct domain *d, - const struct evtchn *evtchn) + evtchn_port_t port) { - return d->evtchn_port_ops->is_pending(d, evtchn); + return d->evtchn_port_ops->is_pending(d, port); } static inline bool_t evtchn_port_is_masked(struct domain *d, - const struct evtchn *evtchn) + evtchn_port_t port) { - return d->evtchn_port_ops->is_masked(d, evtchn); + return d->evtchn_port_ops->is_masked(d, port); } static inline int evtchn_port_set_priority(struct domain *d, debian/patches/xsa178-xen4.4-0006-libxl-Do-not-trust-backend-for-disk-in-getinfo.patch0000664000000000000000000000266212725542005025067 0ustar From 2dbe3631693ac13c74d31c6e30c12447d4c62854 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 19:10:45 +0100 Subject: [PATCH 06/16] libxl: Do not trust backend for disk in getinfo Do not read the frontend path out of the backend. We have it in our hand. Likewise the guest (frontend) domid was one of our parameters (!) This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index cab98e0..01d41b1 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2480,9 +2480,8 @@ int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/ring-ref", fe_path)); diskinfo->rref = val ? strtoul(val, NULL, 10) : -1; diskinfo->frontend = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/frontend", diskinfo->backend), NULL); - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend-id", diskinfo->backend)); - diskinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + GCSPRINTF("%s/frontend", libxl_path), NULL); + diskinfo->frontend_id = domid; GC_FREE; return 0; -- 1.9.1 debian/patches/xsa178-xen4.4-0002-libxl-Do-not-trust-backend-for-vtpm-in-getinfo-uuid.patch0000664000000000000000000000354612725542005026065 0ustar From 17d70465f9ad590b8443322d2045ea9dfaed2a7f Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 16:57:14 +0100 Subject: [PATCH 02/16] libxl: Do not trust backend for vtpm in getinfo (uuid) Use uuid from /libxl, rather than from backend. I think the backend is not supposed to change the uuid, since it seems to be set by libxl during setup. If in fact the backend is supposed to be able to change the uuid, this patch needs to be dropped and replaced by a patch which makes the vtpm uuid lookup tolerate bad or missing data. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index b4ed33f..19c3d90 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1906,7 +1906,7 @@ libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *n &vtpm->backend_domid); if (rc) return NULL; - tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/uuid", be_path)); + tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/uuid", libxl_path)); if (tmp) { if(libxl_uuid_from_string(&(vtpm->uuid), tmp)) { LOG(ERROR, "%s/uuid is a malformed uuid?? (%s) Probably a bug!!\n", be_path, tmp); @@ -1966,7 +1966,7 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, vtpminfo->frontend_id = domid; val = libxl__xs_read(gc, XBT_NULL, - GCSPRINTF("%s/uuid", vtpminfo->backend)); + GCSPRINTF("%s/uuid", libxl_path)); if(val == NULL) { LOG(ERROR, "%s/uuid does not exist!\n", vtpminfo->backend); goto err; -- 1.9.1 debian/patches/xsa227-4.5.patch0000664000000000000000000000361613147037613013205 0ustar From 3aab881c7331cf93ffd8d2f2dd9adfd18ed4fc99 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 20 Jun 2017 19:18:54 +0100 Subject: [PATCH] x86/grant: Disallow misaligned PTEs Pagetable entries must be aligned to function correctly. Disallow attempts from the guest to have a grant PTE created at a misaligned address, which would result in corruption of the L1 table with largely-guest-controlled values. This is XSA-227 Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- xen/arch/x86/mm.c | 13 +++++++++++++ xen/include/xen/config.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 70bf52f60a..70dfec5af1 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3781,6 +3781,9 @@ static int create_grant_pte_mapping( l1_pgentry_t ol1e; struct domain *d = v->domain; + if ( !IS_ALIGNED(pte_addr, sizeof(nl1e)) ) + return GNTST_general_error; + adjust_guest_l1e(nl1e, d); gmfn = pte_addr >> PAGE_SHIFT; @@ -3838,6 +3841,16 @@ static int destroy_grant_pte_mapping( struct page_info *page; l1_pgentry_t ol1e; + /* + * addr comes from Xen's active_entry tracking so isn't guest controlled, + * but it had still better be PTE-aligned. + */ + if ( !IS_ALIGNED(addr, sizeof(ol1e)) ) + { + ASSERT_UNREACHABLE(); + return GNTST_general_error; + } + gmfn = addr >> PAGE_SHIFT; page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); diff --git a/xen/include/xen/config.h b/xen/include/xen/config.h index 7bef8a648d..a3aa1d4832 100644 --- a/xen/include/xen/config.h +++ b/xen/include/xen/config.h @@ -82,6 +82,8 @@ #endif /* !__ASSEMBLY__ */ +#define IS_ALIGNED(val, align) (((val) & ((align) - 1)) == 0) + #define __STR(...) #__VA_ARGS__ #define STR(...) __STR(__VA_ARGS__) -- 2.13.2 debian/patches/xsa134.patch0000664000000000000000000000143012571020043012653 0ustar From: Jan Beulich Subject: gnttab: add missing version check to GNTTABOP_swap_grant_ref handling ... avoiding NULL derefs when the version to use wasn't set yet (via GNTTABOP_setup_table or GNTTABOP_set_version). This is XSA-134. Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -2592,6 +2592,9 @@ __gnttab_swap_grant_ref(grant_ref_t ref_ spin_lock(>->lock); + if ( gt->gt_version == 0 ) + PIN_FAIL(out, GNTST_general_error, "grant table not yet set up\n"); + /* Bounds check on the grant refs */ if ( unlikely(ref_a >= nr_grant_entries(d->grant_table))) PIN_FAIL(out, GNTST_bad_gntref, "Bad ref-a (%d).\n", ref_a); debian/patches/xsa131-qemut-6.patch0000664000000000000000000000606112571017513014161 0ustar xen/pt: mark reserved bits in PCI config space fields The adjustments are solely to make the subsequent patches work right (and hence make the patch set consistent), namely if permissive mode (introduced by the last patch) gets used (as both reserved registers and reserved fields must be similarly protected from guest access in default mode, but the guest should be allowed access to them in permissive mode). This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -283,7 +283,7 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_COMMAND, .size = 2, .init_val = 0x0000, - .ro_mask = 0xF880, + .res_mask = 0xF880, .emu_mask = 0x0743, .init = pt_common_reg_init, .u.w.read = pt_word_reg_read, @@ -310,7 +310,8 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_STATUS, .size = 2, .init_val = 0x0000, - .ro_mask = 0x06FF, + .res_mask = 0x0007, + .ro_mask = 0x06F8, .emu_mask = 0x0010, .init = pt_status_reg_init, .u.w.read = pt_word_reg_read, @@ -496,7 +497,8 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_PM_CTRL, .size = 2, .init_val = 0x0008, - .ro_mask = 0xE1FC, + .res_mask = 0x00F0, + .ro_mask = 0xE10C, .emu_mask = 0x8100, .init = pt_pmcsr_reg_init, .u.w.read = pt_word_reg_read, @@ -508,7 +510,8 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_PM_CTRL, .size = 2, .init_val = 0x0008, - .ro_mask = 0xE1FC, + .res_mask = 0x00F0, + .ro_mask = 0xE10C, .emu_mask = 0x810B, .init = pt_pmcsr_reg_init, .u.w.read = pt_word_reg_read, @@ -656,7 +659,8 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_MSI_FLAGS, // 2 .size = 2, .init_val = 0x0000, - .ro_mask = 0xFF8E, + .res_mask = 0xFE00, + .ro_mask = 0x018E, .emu_mask = 0x017E, .init = pt_msgctrl_reg_init, .u.w.read = pt_word_reg_read, @@ -779,7 +783,8 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_MSI_FLAGS, // 2 .size = 2, .init_val = 0x0000, - .ro_mask = 0x3FFF, + .res_mask = 0x3800, + .ro_mask = 0x07FF, .emu_mask = 0x0000, .init = pt_msixctrl_reg_init, .u.w.read = pt_word_reg_read, --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -376,6 +376,8 @@ struct pt_reg_info_tbl { uint32_t size; /* reg initial value */ uint32_t init_val; + /* reg reserved field mask (ON:reserved, OFF:defined) */ + uint32_t res_mask; /* reg read only field mask (ON:RO/ROS, OFF:other) */ uint32_t ro_mask; /* reg emulate field mask (ON:emu, OFF:passthrough) */ debian/patches/tools-python-shebang.diff0000664000000000000000000002114212276137145015545 0ustar Index: xen-4.4.0~rc3+20140210/tools/python/xen/util/bugtool.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/util/bugtool.py 2014-02-10 12:53:54.838049632 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/util/bugtool.py 2014-02-10 12:56:21.282765569 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public # License as published by the Free Software Foundation. Index: xen-4.4.0~rc3+20140210/tools/python/xen/util/pci.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/util/pci.py 2014-02-10 12:53:54.818049544 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/util/pci.py 2014-02-10 12:56:21.282765569 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # PCI Device Information Class # - Helps obtain information about which I/O resources a PCI device needs # Index: xen-4.4.0~rc3+20140210/tools/python/xen/util/vscsi_util.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/util/vscsi_util.py 2014-02-10 12:53:54.798049444 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/util/vscsi_util.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- mode: python; -*- #============================================================================ Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendBase.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendBase.py 2014-02-10 12:53:54.602048484 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendBase.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendClient.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendClient.py 2014-02-10 12:53:54.666048792 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendClient.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/env python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendLocalStorageRepo.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendLocalStorageRepo.py 2014-02-10 12:53:54.622048578 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendLocalStorageRepo.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendQCoWStorageRepo.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendQCoWStorageRepo.py 2014-02-10 12:53:54.702048974 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendQCoWStorageRepo.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendStorageRepository.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendStorageRepository.py 2014-02-10 12:53:54.586048406 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendStorageRepository.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendVDI.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendVDI.py 2014-02-10 12:53:54.774049327 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendVDI.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/arch.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/arch.py 2014-02-10 12:53:54.574048343 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/arch.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public # License as published by the Free Software Foundation. Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/osdep.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/osdep.py 2014-02-10 12:53:54.754049226 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/osdep.py 2014-02-10 12:56:21.286765584 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public # License as published by the Free Software Foundation. Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/sxp.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/sxp.py 2014-02-10 12:53:54.650048722 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/sxp.py 2014-02-10 12:56:21.290765608 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/env python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/xm/xenapi_create.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xm/xenapi_create.py 2014-02-10 12:53:54.858049739 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xm/xenapi_create.py 2014-02-10 12:56:21.290765608 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python #============================================================================ # This library is free software; you can redistribute it and/or # modify it under the terms of version 2.1 of the GNU Lesser General Public Index: xen-4.4.0~rc3+20140210/tools/python/xen/remus/save.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/remus/save.py 2014-02-10 12:53:54.542048192 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/remus/save.py 2014-02-10 12:56:21.290765608 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os, select, socket, threading, time, signal, xmlrpclib from xen.xend.XendClient import server Index: xen-4.4.0~rc3+20140210/tools/python/xen/remus/vm.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/remus/vm.py 2014-02-10 12:53:54.558048268 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/remus/vm.py 2014-02-10 12:56:21.290765608 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import xmlrpclib from xen.xend.XendClient import server Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendSXPDev.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendSXPDev.py 2014-02-10 12:53:54.730049105 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendSXPDev.py 2014-02-10 12:56:21.290765608 +0100 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Helper functions for dealing with the sxp representation of devices import types debian/patches/xsa158-4.4.patch0000664000000000000000000001634512631300012013171 0ustar memory: split and tighten maximum order permitted in memops Introduce and enforce separate limits for ordinary DomU, DomU with pass-through device(s), control domain, and hardware domain. The DomU defaults were determined based on what so far was allowed by multipage_allocation_permitted(). The x86 hwdom default was chosen based on linux-2.6.18-xen.hg c/s 1102:82782f1361a9 indicating 2Mb is not enough, plus some slack. The ARM hwdom default was chosen to allow 2Mb (order-9) mappings, plus a little bit of slack. This is XSA-158. Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -653,6 +653,17 @@ which data structures should be delibera so the crash kernel may find find them. Should be used in combination with **crashinfo_maxaddr**. +### memop-max-order +> `= [][,[][,[][,]]]` + +> x86 default: `9,18,12,12` +> ARM default: `9,18,10,10` + +Change the maximum order permitted for allocation (or allocation-like) +requests issued by the various kinds of domains (in this order: +ordinary DomU, control domain, hardware domain, and - when supported +by the platform - DomU with pass-through device assigned). + ### max\_cstate > `= ` --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -46,6 +46,50 @@ struct memop_args { int preempted; /* Was the hypercall preempted? */ }; +#ifndef CONFIG_CTLDOM_MAX_ORDER +#define CONFIG_CTLDOM_MAX_ORDER CONFIG_PAGEALLOC_MAX_ORDER +#endif +#ifndef CONFIG_PTDOM_MAX_ORDER +#define CONFIG_PTDOM_MAX_ORDER CONFIG_HWDOM_MAX_ORDER +#endif + +static unsigned int __read_mostly domu_max_order = CONFIG_DOMU_MAX_ORDER; +static unsigned int __read_mostly ctldom_max_order = CONFIG_CTLDOM_MAX_ORDER; +static unsigned int __read_mostly hwdom_max_order = CONFIG_HWDOM_MAX_ORDER; +#ifdef HAS_PASSTHROUGH +static unsigned int __read_mostly ptdom_max_order = CONFIG_PTDOM_MAX_ORDER; +#else +# define ptdom_max_order domu_max_order +#endif +static void __init parse_max_order(const char *s) +{ + if ( *s != ',' ) + domu_max_order = simple_strtoul(s, &s, 0); + if ( *s == ',' && *++s != ',' ) + ctldom_max_order = simple_strtoul(s, &s, 0); + if ( *s == ',' && *++s != ',' ) + hwdom_max_order = simple_strtoul(s, &s, 0); +#ifdef HAS_PASSTHROUGH + if ( *s == ',' && *++s != ',' ) + ptdom_max_order = simple_strtoul(s, &s, 0); +#endif +} +custom_param("memop-max-order", parse_max_order); + +static unsigned int max_order(const struct domain *d) +{ + unsigned int order = cache_flush_permitted(d) ? domu_max_order + : ptdom_max_order; + + if ( is_control_domain(d) && order < ctldom_max_order ) + order = ctldom_max_order; + + if ( is_hardware_domain(d) && order < hwdom_max_order ) + order = hwdom_max_order; + + return min(order, MAX_ORDER + 0U); +} + static void increase_reservation(struct memop_args *a) { struct page_info *page; @@ -58,7 +102,7 @@ static void increase_reservation(struct a->nr_extents-1) ) return; - if ( !multipage_allocation_permitted(current->domain, a->extent_order) ) + if ( a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -103,8 +147,8 @@ static void populate_physmap(struct memo a->nr_extents-1) ) return; - if ( a->memflags & MEMF_populate_on_demand ? a->extent_order > MAX_ORDER : - !multipage_allocation_permitted(current->domain, a->extent_order) ) + if ( a->extent_order > (a->memflags & MEMF_populate_on_demand ? MAX_ORDER : + max_order(current->domain)) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -269,7 +313,7 @@ static void decrease_reservation(struct if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, a->nr_extents-1) || - a->extent_order > MAX_ORDER ) + a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -334,13 +378,17 @@ static long memory_exchange(XEN_GUEST_HA if ( copy_from_guest(&exch, arg, 1) ) return -EFAULT; + if ( max(exch.in.extent_order, exch.out.extent_order) > + max_order(current->domain) ) + { + rc = -EPERM; + goto fail_early; + } + /* Various sanity checks. */ if ( (exch.nr_exchanged > exch.in.nr_extents) || /* Input and output domain identifiers match? */ (exch.in.domid != exch.out.domid) || - /* Extent orders are sensible? */ - (exch.in.extent_order > MAX_ORDER) || - (exch.out.extent_order > MAX_ORDER) || /* Sizes of input and output lists do not overflow a long? */ ((~0UL >> exch.in.extent_order) < exch.in.nr_extents) || ((~0UL >> exch.out.extent_order) < exch.out.nr_extents) || @@ -359,16 +407,6 @@ static long memory_exchange(XEN_GUEST_HA goto fail_early; } - /* Only privileged guests can allocate multi-page contiguous extents. */ - if ( !multipage_allocation_permitted(current->domain, - exch.in.extent_order) || - !multipage_allocation_permitted(current->domain, - exch.out.extent_order) ) - { - rc = -EPERM; - goto fail_early; - } - if ( exch.in.extent_order <= exch.out.extent_order ) { in_chunk_order = exch.out.extent_order - exch.in.extent_order; --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -37,6 +37,10 @@ #define CONFIG_VIDEO 1 +#define CONFIG_PAGEALLOC_MAX_ORDER 18 +#define CONFIG_DOMU_MAX_ORDER 9 +#define CONFIG_HWDOM_MAX_ORDER 10 + #define OPT_CONSOLE_STR "dtuart" #ifdef MAX_PHYS_CPUS --- a/xen/include/asm-arm/iocap.h +++ b/xen/include/asm-arm/iocap.h @@ -4,10 +4,6 @@ #define cache_flush_permitted(d) \ (!rangeset_is_empty((d)->iomem_caps)) -#define multipage_allocation_permitted(d, order) \ - (((order) <= 9) || /* allow 2MB superpages */ \ - !rangeset_is_empty((d)->iomem_caps)) - #endif /* --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -29,9 +29,12 @@ #define CONFIG_NUMA 1 #define CONFIG_DISCONTIGMEM 1 #define CONFIG_NUMA_EMU 1 -#define CONFIG_PAGEALLOC_MAX_ORDER (2 * PAGETABLE_ORDER) #define CONFIG_DOMAIN_PAGE 1 +#define CONFIG_PAGEALLOC_MAX_ORDER (2 * PAGETABLE_ORDER) +#define CONFIG_DOMU_MAX_ORDER PAGETABLE_ORDER +#define CONFIG_HWDOM_MAX_ORDER 12 + /* Intel P4 currently has largest cache line (L2 line size is 128 bytes). */ #define CONFIG_X86_L1_CACHE_SHIFT 7 --- a/xen/include/asm-x86/iocap.h +++ b/xen/include/asm-x86/iocap.h @@ -18,9 +18,4 @@ (!rangeset_is_empty((d)->iomem_caps) || \ !rangeset_is_empty((d)->arch.ioport_caps)) -#define multipage_allocation_permitted(d, order) \ - (((order) <= 9) || /* allow 2MB superpages */ \ - !rangeset_is_empty((d)->iomem_caps) || \ - !rangeset_is_empty((d)->arch.ioport_caps)) - #endif /* __X86_IOCAP_H__ */ debian/patches/xsa206-4.4-0011-oxenstored-remove-some-unused-parameters.patch0000664000000000000000000000471413104300260023626 0ustar From 7b5f1b6957edbcf514a74a38b6d5d810b3d9dcda Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:40:08 +0000 Subject: [PATCH 11/30] oxenstored: remove some unused parameters Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/process.ml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 8be2ff1..7026727 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -119,7 +119,7 @@ let do_getperms con t domains cons data = let perms = Transaction.getperms t (Connection.get_perm con) path in Perms.Node.to_string perms ^ "\000" -let do_watch con t rid domains cons data = +let do_watch con t domains cons data = let (node, token) = match (split None '\000' data) with | [node; token; ""] -> node, token @@ -294,25 +294,25 @@ let send_response ty con t rid response = | Packet.Error e -> Connection.send_error con (Transaction.get_id t) rid e -let reply_ack fct ty con t rid doms cons data = +let reply_ack fct con t doms cons data = fct con t doms cons data; Packet.Ack (fun () -> if Transaction.get_id t = Transaction.none then process_watch (Transaction.get_ops t) cons ) -let reply_data fct ty con t rid doms cons data = +let reply_data fct con t doms cons data = let ret = fct con t doms cons data in Packet.Reply ret -let reply_data_or_ack fct ty con t rid doms cons data = +let reply_data_or_ack fct con t doms cons data = match fct con t doms cons data with | Some ret -> Packet.Reply ret | None -> Packet.Ack (fun () -> ()) -let reply_none fct ty con t rid doms cons data = +let reply_none fct con t doms cons data = (* let the function reply *) - fct con t rid doms cons data + fct con t doms cons data let function_of_type ty = match ty with @@ -342,7 +342,7 @@ let input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data = let reply_error e = Packet.Error e in try - fct ty con t rid doms cons data + fct con t doms cons data with | Define.Invalid_path -> reply_error "EINVAL" | Define.Already_exist -> reply_error "EEXIST" -- 2.1.4 debian/patches/xsa178-xen4.4-0015-libxl-Fix-NULL-pointer-due-to-XSA-178-fix-wrong-XS-n.patch0000664000000000000000000000513312726265163025234 0ustar From ec5925c72cfd7544b86fc6273937c9cc7e21e580 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 8 Jun 2016 15:42:19 +0100 Subject: [PATCH] libxl: Fix NULL pointer due to XSA-178 fix wrong XS nodename In "libxl: Do not trust backend for disk eject vdev" (c69871a2fb26 on xen.git#staging) we changed libxl_evenable_disk_eject to read the device vdev out of xenstore from the /libxl path, rather than the backend path, and to read it during setup rather than on each event. However, the patch has a mistake: - GCSPRINTF("%s/dev", backend), NULL); + GCSPRINTF("%s/vdev", libxl_path), &configured_vdev); ^ Spot the extra "v". This causes configured_vdev always to be NULL. configured_vdev is passed to [libxl__]strdup. In Xen 4.6 and later libxl__strdup is used and tolerates NULL. evg->vdev is set to NULL. This propagates to the `vdev' field in the generated event. This may or may not cause further trouble, depending on the calling application. In our osstest test cases it does not cause any trouble, so the bug goes undetected. In Xen 4.5 and earlier, the strdup does not tolerate NULL, and libxl crashes immediately. This has been detected by osstest as a regression in Xen 4.5. IMO this patch should be applied immediately to xen.git#staging-4.5 (to check that it fixes the osstest regression) xen.git#staging (to check that it does not break master Subject to passes, it should then be propagated to all supported stable trees and also be mentioned in an update to XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu CC: security@xenproject.org CC: Jan Beulich CC: Wei Liu (cherry picked from commit 62b4d4769ca39fd5263da20d786a7b9a80a22d9a) (cherry picked from commit 8b7a356409023f60f80e9f4b00bba16ad56cd77b) (cherry picked from commit 6d272988fb3bdcc2578c5ee6d8a408628d1f0c0e) Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 30b6878..4083393 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1228,7 +1228,7 @@ int libxl_evenable_disk_eject(libxl_ctx *ctx, uint32_t guest_domid, const char *configured_vdev; rc = libxl__xs_read_checked(gc, XBT_NULL, - GCSPRINTF("%s/vdev", libxl_path), &configured_vdev); + GCSPRINTF("%s/dev", libxl_path), &configured_vdev); if (rc) goto out; evg->vdev = libxl__strdup(NOGC, configured_vdev); -- 1.9.1 debian/patches/xsa176.patch0000664000000000000000000000273512725265045012710 0ustar x86/mm: fully honor PS bits in guest page table walks In L4 entries it is currently unconditionally reserved (and hence should, when set, always result in a reserved bit page fault), and is reserved on hardware not supporting 1Gb pages (and hence should, when set, similarly cause a reserved bit page fault on such hardware). This is CVE-2016-4480 / XSA-176. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Tested-by: Andrew Cooper --- a/xen/arch/x86/mm/guest_walk.c +++ b/xen/arch/x86/mm/guest_walk.c @@ -226,6 +226,11 @@ guest_walk_tables(struct vcpu *v, struct rc |= _PAGE_PRESENT; goto out; } + if ( gflags & _PAGE_PSE ) + { + rc |= _PAGE_PSE | _PAGE_INVALID_BIT; + goto out; + } rc |= ((gflags & mflags) ^ mflags); /* Map the l3 table */ @@ -247,7 +252,7 @@ guest_walk_tables(struct vcpu *v, struct } rc |= ((gflags & mflags) ^ mflags); - pse1G = (gflags & _PAGE_PSE) && guest_supports_1G_superpages(v); + pse1G = !!(gflags & _PAGE_PSE); if ( pse1G ) { @@ -267,6 +272,8 @@ guest_walk_tables(struct vcpu *v, struct /* _PAGE_PSE_PAT not set: remove _PAGE_PAT from flags. */ flags &= ~_PAGE_PAT; + if ( !guest_supports_1G_superpages(v) ) + rc |= _PAGE_PSE | _PAGE_INVALID_BIT; if ( gfn_x(start) & GUEST_L3_GFN_MASK & ~0x1 ) rc |= _PAGE_INVALID_BITS; debian/patches/xsa138-qemut-1.patch0000664000000000000000000000432712571017646014175 0ustar From 510952d4c33ee69574167ce30829b21c815a165b Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 3 Jun 2015 14:13:31 +0200 Subject: [PATCH 1/2] ide: Check array bounds before writing to io_buffer (CVE-2015-5154) If the end_transfer_func of a command is called because enough data has been read or written for the current PIO transfer, and it fails to correctly call the command completion functions, the DRQ bit in the status register and s->end_transfer_func may remain set. This allows the guest to access further bytes in s->io_buffer beyond s->data_end, and eventually overflowing the io_buffer. One case where this currently happens is emulation of the ATAPI command START STOP UNIT. This patch fixes the problem by adding explicit array bounds checks before accessing the buffer instead of relying on end_transfer_func to function correctly. Cc: qemu-stable@nongnu.org Signed-off-by: Kevin Wolf --- hw/ide.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/ide.c b/hw/ide.c index 791666b..211ec88 100644 --- a/qemu/hw/ide.c +++ b/qemu/hw/ide.c @@ -3002,6 +3002,10 @@ static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) buffered_pio_write(s, addr, 2); p = s->data_ptr; + if (p + 2 > s->data_end) { + return; + } + *(uint16_t *)p = le16_to_cpu(val); p += 2; s->data_ptr = p; @@ -3021,6 +3025,10 @@ static uint32_t ide_data_readw(void *opaque, uint32_t addr) buffered_pio_read(s, addr, 2); p = s->data_ptr; + if (p + 2 > s->data_end) { + return 0; + } + ret = cpu_to_le16(*(uint16_t *)p); p += 2; s->data_ptr = p; @@ -3040,6 +3048,10 @@ static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) buffered_pio_write(s, addr, 4); p = s->data_ptr; + if (p + 4 > s->data_end) { + return; + } + *(uint32_t *)p = le32_to_cpu(val); p += 4; s->data_ptr = p; @@ -3059,6 +3071,10 @@ static uint32_t ide_data_readl(void *opaque, uint32_t addr) buffered_pio_read(s, addr, 4); p = s->data_ptr; + if (p + 4 > s->data_end) { + return 0; + } + ret = cpu_to_le32(*(uint32_t *)p); p += 4; s->data_ptr = p; -- 2.1.4 debian/patches/tools-blktap2-prefix.diff0000664000000000000000000001150012276137117015445 0ustar Index: xen-4.4.0~rc3+20140210/tools/blktap2/vhd/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/blktap2/vhd/Makefile 2014-02-10 12:53:57.810064163 +0100 +++ xen-4.4.0~rc3+20140210/tools/blktap2/vhd/Makefile 2014-02-10 12:55:59.530659228 +0100 @@ -12,6 +12,7 @@ CFLAGS += -Werror CFLAGS += -Wno-unused CFLAGS += -I../include CFLAGS += -D_GNU_SOURCE +CFLAGS += $(CFLAGS_libxenctrl) ifeq ($(CONFIG_X86_64),y) CFLAGS += -fPIC Index: xen-4.4.0~rc3+20140210/tools/blktap2/vhd/lib/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/blktap2/vhd/lib/Makefile 2014-02-10 12:53:57.786064048 +0100 +++ xen-4.4.0~rc3+20140210/tools/blktap2/vhd/lib/Makefile 2014-02-10 12:55:59.530659228 +0100 @@ -2,26 +2,20 @@ XEN_ROOT=$(CURDIR)/../../../.. BLKTAP_ROOT := ../.. include $(XEN_ROOT)/tools/Rules.mk -LIBVHD-MAJOR = 1.0 -LIBVHD-MINOR = 0 -LIBVHD-SONAME = libvhd.so.$(LIBVHD-MAJOR) - LVM-UTIL-OBJ := $(BLKTAP_ROOT)/lvm/lvm-util.o -LIBVHD-BUILD := libvhd.a - -INST-DIR = $(LIBDIR) - CFLAGS += -Werror CFLAGS += -Wno-unused CFLAGS += -I../../include CFLAGS += -D_GNU_SOURCE CFLAGS += -fPIC CFLAGS += -g +CFLAGS += $(CFLAGS_libxenctrl) ifeq ($(CONFIG_Linux),y) LIBS := -luuid endif +LDFLAGS += $(LDFLAGS_libxenctrl) $(call LDFLAGS_RPATH) ifeq ($(CONFIG_LIBICONV),y) LIBS += -liconv @@ -51,27 +45,22 @@ LIB-OBJS += $(LVM-UTIL-OBJ) LIB-PICOBJS = $(patsubst %.o,%.opic,$(LIB-OBJS)) -LIBVHD = libvhd.a libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) +LIBVHD = libvhd.a libvhd.so all: build -build: libvhd.a libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) +build: libvhd.a libvhd.so libvhd.a: $(LIB-OBJS) $(AR) rc $@ $^ -libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR): $(LIB-PICOBJS) - $(CC) -Wl,$(SONAME_LDFLAG),$(LIBVHD-SONAME) $(SHLIB_LDFLAGS) \ - $(LDFLAGS) -o libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) $^ $(LIBS) - ln -sf libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) libvhd.so.$(LIBVHD-MAJOR) - ln -sf libvhd.so.$(LIBVHD-MAJOR) libvhd.so +libvhd.so: $(LIB-PICOBJS) + $(CC) $(SHLIB_LDFLAGS) $(LDFLAGS) -o libvhd.so $^ $(LIBS) install: all - $(INSTALL_DIR) -p $(DESTDIR)$(INST-DIR) - $(INSTALL_DATA) libvhd.a $(DESTDIR)$(INST-DIR) - $(INSTALL_PROG) libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) $(DESTDIR)$(INST-DIR) - ln -sf libvhd.so.$(LIBVHD-MAJOR).$(LIBVHD-MINOR) $(DESTDIR)$(INST-DIR)/libvhd.so.$(LIBVHD-MAJOR) - ln -sf libvhd.so.$(LIBVHD-MAJOR) $(DESTDIR)$(INST-DIR)/libvhd.so + $(INSTALL_DIR) -p $(DESTDIR)$(LIBDIR) + $(INSTALL_DATA) libvhd.a $(DESTDIR)$(LIBDIR) + $(INSTALL_PROG) libvhd.so $(DESTDIR)$(LIBDIR) clean: rm -rf *.a *.so* *.o *.opic *~ $(DEPS) $(LIBVHD) Index: xen-4.4.0~rc3+20140210/tools/blktap2/control/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/blktap2/control/Makefile 2014-02-10 12:53:57.766063952 +0100 +++ xen-4.4.0~rc3+20140210/tools/blktap2/control/Makefile 2014-02-10 12:55:59.530659228 +0100 @@ -1,10 +1,7 @@ XEN_ROOT := $(CURDIR)/../../../ include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 1.0 -MINOR = 0 LIBNAME = libblktapctl -LIBSONAME = $(LIBNAME).so.$(MAJOR) IBIN = tap-ctl @@ -38,39 +35,32 @@ OBJS = $(CTL_OBJS) tap-ctl.o PICS = $(CTL_PICS) LIB_STATIC = $(LIBNAME).a -LIB_SHARED = $(LIBSONAME).$(MINOR) +LIB_SHARED = $(LIBNAME).so IBIN = tap-ctl all: build build: $(IBIN) $(LIB_STATIC) $(LIB_SHARED) -$(LIBNAME).so: $(LIBSONAME) - ln -sf $< $@ - -$(LIBSONAME): $(LIB_SHARED) - ln -sf $< $@ - tap-ctl: tap-ctl.o $(LIBNAME).so - $(CC) $(LDFLAGS) -o $@ $^ + $(CC) $(LDFLAGS) $(call LDFLAGS_RPATH,../lib) -o $@ $^ $(LIB_STATIC): $(CTL_OBJS) $(AR) r $@ $^ $(LIB_SHARED): $(CTL_PICS) - $(CC) $(LDFLAGS) -fPIC -Wl,$(SONAME_LDFLAG) -Wl,$(LIBSONAME) $(SHLIB_LDFLAGS) -rdynamic $^ -o $@ + $(CC) $(LDFLAGS) -fPIC $(SHLIB_LDFLAGS) -rdynamic $^ -o $@ install: $(IBIN) $(LIB_STATIC) $(LIB_SHARED) - $(INSTALL_DIR) -p $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(SBINDIR) + $(INSTALL_DIR) -p $(DESTDIR)$(IBDIR) + $(INSTALL_DIR) -p $(DESTDIR)$(PRIVATE_LIBDIR) + $(INSTALL_DIR) -p $(DESTDIR)$(PRIVATE_SBINDIR) + $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_DATA) $(LIB_STATIC) $(DESTDIR)$(LIBDIR) - $(INSTALL_PROG) $(LIB_SHARED) $(DESTDIR)$(LIBDIR) - ln -sf $(LIBSONAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME).so - ln -sf $(LIB_SHARED) $(DESTDIR)$(LIBDIR)/$(LIBSONAME) + $(INSTALL_PROG) $(LIB_SHARED) $(DESTDIR)$(PRIVATE_LIBDIR) clean: rm -f $(OBJS) $(PICS) $(DEPS) $(IBIN) $(LIB_STATIC) $(LIB_SHARED) - rm -f $(LIBNAME).so $(LIBSONAME) rm -f *~ .PHONY: all build clean install debian/patches/xsa206-4.4-0013-oxenstored-keep-track-of-each-transaction-s-operatio.patch0000664000000000000000000001377613104300260025671 0ustar From 7f3129ec15c1c459962401d2edcd9e693c698a09 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:40:35 +0000 Subject: [PATCH 13/30] oxenstored: keep track of each transaction's operations A list of (request, response) pairs from the operations performed within the transaction will be useful to support transaction replay. Since this consumes memory, the number of requests per transaction must not be left unbounded. Hence a new quota for this is introduced. This quota, configured via the configuration key 'quota-maxrequests', limits the size of transactions initiated by domUs. After the maximum number of requests has been exhausted, any further requests will result in EQUOTA errors. The client may then choose to end the transaction; a successful commit will result in the retention of only the prior requests. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/define.ml | 1 + tools/ocaml/xenstored/oxenstored.conf | 1 + tools/ocaml/xenstored/process.ml | 13 +++++++++++-- tools/ocaml/xenstored/transaction.ml | 21 +++++++++++++++------ tools/ocaml/xenstored/xenstored.ml | 1 + 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml index 89a6aac..d60861c 100644 --- a/tools/ocaml/xenstored/define.ml +++ b/tools/ocaml/xenstored/define.ml @@ -27,6 +27,7 @@ let default_config_dir = "/etc/xen" let maxwatch = ref (50) let maxtransaction = ref (20) +let maxrequests = ref (-1) (* maximum requests per transaction *) let domid_self = 0x7FF0 diff --git a/tools/ocaml/xenstored/oxenstored.conf b/tools/ocaml/xenstored/oxenstored.conf index dd20eda..ac60f49 100644 --- a/tools/ocaml/xenstored/oxenstored.conf +++ b/tools/ocaml/xenstored/oxenstored.conf @@ -18,6 +18,7 @@ quota-maxentity = 1000 quota-maxsize = 2048 quota-maxwatch = 100 quota-transaction = 10 +quota-maxrequests = 1024 # Activate filed base backend persistent = false diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index b8bcb46..34fb66c 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -155,7 +155,7 @@ let do_transaction_end con t domains cons data = if not success then raise Transaction_again; if commit then - process_watch (List.rev (Transaction.get_ops t)) cons + process_watch (List.rev (Transaction.get_paths t)) cons let do_introduce con t domains cons data = if not (Connection.is_dom0 con) @@ -298,7 +298,7 @@ let reply_ack fct con t doms cons data = fct con t doms cons data; Packet.Ack (fun () -> if Transaction.get_id t = Transaction.none then - process_watch (Transaction.get_ops t) cons + process_watch (Transaction.get_paths t) cons ) let reply_data fct con t doms cons data = @@ -378,6 +378,15 @@ let process_packet ~store ~cons ~doms ~con ~req = in let response = input_handle_error ~cons ~doms ~fct ~con ~t ~req in + let response = try + if tid <> Transaction.none then + (* Remember the request and response for this operation in case we need to replay the transaction *) + Transaction.add_operation ~perm:(Connection.get_perm con) t req response; + response + with Quota.Limit_reached -> + Packet.Error "EQUOTA" + in + (* Put the response on the wire *) send_response ty con t rid response with exn -> diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index 77de4e8..6b37fc2 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -75,7 +75,8 @@ type t = { ty: ty; store: Store.t; quota: Quota.t; - mutable ops: (Xenbus.Xb.Op.operation * Store.Path.t) list; + mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list; + mutable operations: (Packet.request * Packet.response) list; mutable read_lowpath: Store.Path.t option; mutable write_lowpath: Store.Path.t option; } @@ -86,16 +87,24 @@ let make id store = ty = ty; store = if id = none then store else Store.copy store; quota = Quota.copy store.Store.quota; - ops = []; + paths = []; + operations = []; read_lowpath = None; write_lowpath = None; } let get_id t = match t.ty with No -> none | Full (id, _, _) -> id let get_store t = t.store -let get_ops t = t.ops - -let add_wop t ty path = t.ops <- (ty, path) :: t.ops +let get_paths t = t.paths + +let add_wop t ty path = t.paths <- (ty, path) :: t.paths +let add_operation ~perm t request response = + if !Define.maxrequests >= 0 + && not (Perms.Connection.is_dom0 perm) + && List.length t.operations >= !Define.maxrequests + then raise Quota.Limit_reached; + t.operations <- (request, response) :: t.operations +let get_operations t = List.rev t.operations let set_read_lowpath t path = t.read_lowpath <- get_lowest path t.read_lowpath let set_write_lowpath t path = t.write_lowpath <- get_lowest path t.write_lowpath @@ -141,7 +150,7 @@ let getperms t perm path = r let commit ~con t = - let has_write_ops = List.length t.ops > 0 in + let has_write_ops = List.length t.paths > 0 in let has_coalesced = ref false in let has_commited = match t.ty with diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 58a1ffc..656a79b 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -95,6 +95,7 @@ let parse_config filename = ("quota-transaction", Config.Set_int Define.maxtransaction); ("quota-maxentity", Config.Set_int Quota.maxent); ("quota-maxsize", Config.Set_int Quota.maxsize); + ("quota-maxrequests", Config.Set_int Define.maxrequests); ("test-eagain", Config.Set_bool Transaction.test_eagain); ("persistent", Config.Set_bool Disk.enable); ("xenstored-log-file", Config.String Logging.set_xenstored_log_destination); -- 2.1.4 debian/patches/xsa206-4.4-0017-oxenstored-allow-compilation-prior-to-OCaml-3.12.0.patch0000664000000000000000000000255113104300260024644 0ustar From 88f59d22230b304ac861cea9759bd8861a6c3867 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:54:35 +0000 Subject: [PATCH 17/30] oxenstored: allow compilation prior to OCaml 3.12.0 Commit 363ae55c8 used an OCaml feature called record field punning. This broke the build on compilers prior to OCaml 3.12.0. This patch makes no semantic change but now uses backwards-compatible syntax. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reported-by: Boris Ostrovsky Tested-by: Boris Ostrovsky --- tools/ocaml/xenstored/process.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 10b7357..9cf2b46 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -472,7 +472,7 @@ let do_input store cons doms con = if newpacket then ( let packet = Connection.pop_in con in let tid, rid, ty, data = Xenbus.Xb.Packet.unpack packet in - let req = {Packet.tid; Packet.rid; Packet.ty; Packet.data} in + let req = {Packet.tid=tid; Packet.rid=rid; Packet.ty=ty; Packet.data=data} in (* As we don't log IO, do not call an unnecessary sanitize_data info "[%s] -> [%d] %s \"%s\"" -- 2.1.4 debian/patches/xsa131-qemut-8.patch0000664000000000000000000001231712571017533014166 0ustar xen/pt: unknown PCI config space fields should be read-only ... by default. Add a per-device "permissive" mode similar to pciback's to allow restoring previous behavior (and hence break security again, i.e. should be used only for trusted guests). This is part of XSA-131. Signed-off-by: Jan Beulich Acked-by: Stefano Stabellini Reviewed-by: Anthony PERARD ) --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -1613,10 +1613,10 @@ static void pt_pci_write_config(PCIDevic uint32_t find_addr = address; uint32_t real_offset = 0; uint32_t valid_mask = 0xFFFFFFFF; - uint32_t read_val = 0, wb_mask; + uint32_t read_val = 0, wb_mask, wp_mask; uint8_t *ptr_val = NULL; int emul_len = 0; - int index = 0; + int index = 0, wp_flag = 0; int ret = 0; #ifdef PT_DEBUG_PCI_CONFIG_ACCESS @@ -1695,7 +1695,14 @@ static void pt_pci_write_config(PCIDevic /* pass directly to libpci for passthrough type register group */ if (reg_grp_entry == NULL) + { + if (!assigned_device->permissive) + { + wb_mask = 0; + wp_flag = 1; + } goto out; + } /* adjust the read and write value to appropriate CFC-CFF window */ read_val <<= ((address & 3) << 3); @@ -1714,11 +1721,12 @@ static void pt_pci_write_config(PCIDevic valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3)); valid_mask <<= ((find_addr - real_offset) << 3); ptr_val = ((uint8_t *)&val + (real_offset & 3)); - if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { - wb_mask &= ~((reg->emu_mask - >> ((find_addr - real_offset) << 3)) + wp_mask = reg->emu_mask | reg->ro_mask; + if (!assigned_device->permissive) + wp_mask |= reg->res_mask; + if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) + wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) << ((len - emul_len) << 3)); - } /* do emulation depend on register size */ switch (reg->size) { @@ -1767,6 +1775,16 @@ static void pt_pci_write_config(PCIDevic /* nothing to do with passthrough type register, * continue to find next byte */ + if (!assigned_device->permissive) + { + wb_mask &= ~(0xff << ((len - emul_len) << 3)); + /* Unused BARs will make it here, but we don't want to issue + * warnings for writes to them (bogus writes get dealt with + * above). + */ + if (index < 0) + wp_flag = 1; + } emul_len--; find_addr++; } @@ -1776,6 +1794,15 @@ static void pt_pci_write_config(PCIDevic val >>= ((address & 3) << 3); out: + if (wp_flag && !assigned_device->permissive_warned) + { + assigned_device->permissive_warned = 1; + PT_LOG("Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", + addr, len * 2, wb_mask); + PT_LOG("If device %02x:%02x.%o doesn't work, try enabling permissive\n", + pci_bus_num(d->bus), PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); + PT_LOG("mode (unsafe) and if it helps report the problem to xen-devel\n"); + } for (index = 0; wb_mask; index += len) { /* unknown regs are passed through */ while (!(wb_mask & 0xff)) { @@ -3484,6 +3511,9 @@ static uint32_t get_throughable_mask(con { uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); + if (!ptdev->permissive) + throughable_mask &= ~reg->res_mask; + return throughable_mask & valid_mask; } @@ -4322,7 +4352,7 @@ static struct pt_dev * register_real_dev uint8_t e_device, e_intx; uint16_t cmd = 0; char *key, *val; - int msi_translate, power_mgmt; + int msi_translate, power_mgmt, permissive = 0; PT_LOG("Assigning real physical device %02x:%02x.%x ...\n", r_bus, r_dev, r_func); @@ -4366,6 +4396,8 @@ static struct pt_dev * register_real_dev else PT_LOG("Error: unrecognized value for msitranslate=\n"); } + else if (strcmp(key, "permissive") == 0) + permissive = 1; else if (strcmp(key, "power_mgmt") == 0) { if (strcmp(val, "0") == 0) @@ -4403,6 +4435,7 @@ static struct pt_dev * register_real_dev assigned_device->msi_trans_cap = msi_translate; assigned_device->power_mgmt = power_mgmt; assigned_device->is_virtfn = pt_dev_is_virtfn(pci_dev); + assigned_device->permissive = permissive; pt_iomul_init(assigned_device, r_bus, r_dev, r_func); /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -242,6 +242,8 @@ struct pt_dev { unsigned power_mgmt:1; struct pt_pm_info *pm_state; /* PM virtualization */ unsigned is_virtfn:1; + unsigned permissive:1; + unsigned permissive_warned:1; /* io port multiplexing */ #define PCI_IOMUL_INVALID_FD (-1) debian/patches/xsa222-1-4.6.patch0000664000000000000000000000741113126715466013342 0ustar From: Andrew Cooper Subject: xen/memory: Fix return value handing of guest_remove_page() Despite the description in mm.h, guest_remove_page() previously returned 0 for paging errors. Switch guest_remove_page() to having regular 0/-error semantics, and propagate the return values from clear_mmio_p2m_entry() and mem_sharing_unshare_page() to the callers (although decrease_reservation() is the only caller which currently cares). This is part of XSA-222. Reported-by: Julien Grall Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Index: xen-4.4.2/xen/common/memory.c =================================================================== --- xen-4.4.2.orig/xen/common/memory.c +++ xen-4.4.2/xen/common/memory.c @@ -229,6 +229,7 @@ int guest_remove_page(struct domain *d, struct page_info *page; #ifdef CONFIG_X86 p2m_type_t p2mt; + int rc; #endif unsigned long mfn; @@ -248,7 +249,8 @@ int guest_remove_page(struct domain *d, put_page(page); } p2m_mem_paging_drop_page(d, gmfn, p2mt); - return 1; + + return 0; } #else mfn = gmfn_to_mfn(d, gmfn); @@ -258,21 +260,25 @@ int guest_remove_page(struct domain *d, put_gfn(d, gmfn); gdprintk(XENLOG_INFO, "Domain %u page number %lx invalid\n", d->domain_id, gmfn); - return 0; + + return -EINVAL; } #ifdef CONFIG_X86 if ( p2m_is_shared(p2mt) ) { - /* Unshare the page, bail out on error. We unshare because - * we might be the only one using this shared page, and we - * need to trigger proper cleanup. Once done, this is - * like any other page. */ - if ( mem_sharing_unshare_page(d, gmfn, 0) ) + /* + * Unshare the page, bail out on error. We unshare because we + * might be the only one using this shared page, and we need to + * trigger proper cleanup. Once done, this is like any other page. + */ + rc = mem_sharing_unshare_page(d, gmfn, 0); + if ( rc ) { put_gfn(d, gmfn); (void)mem_sharing_notify_enomem(d, gmfn, 0); - return 0; + + return rc; } /* Maybe the mfn changed */ mfn = mfn_x(get_gfn_query_unlocked(d, gmfn, &p2mt)); @@ -285,7 +291,8 @@ int guest_remove_page(struct domain *d, { put_gfn(d, gmfn); gdprintk(XENLOG_INFO, "Bad page free for domain %u\n", d->domain_id); - return 0; + + return -ENXIO; } if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) @@ -299,7 +306,7 @@ int guest_remove_page(struct domain *d, put_page(page); put_gfn(d, gmfn); - return 1; + return 0; } static void decrease_reservation(struct memop_args *a) @@ -350,7 +357,7 @@ static void decrease_reservation(struct continue; for ( j = 0; j < (1 << a->extent_order); j++ ) - if ( !guest_remove_page(a->domain, gmfn + j) ) + if ( guest_remove_page(a->domain, gmfn + j) ) goto out; } Index: xen-4.4.2/xen/include/xen/mm.h =================================================================== --- xen-4.4.2.orig/xen/include/xen/mm.h +++ xen-4.4.2/xen/include/xen/mm.h @@ -360,8 +360,7 @@ int xenmem_add_to_physmap_one(struct dom domid_t foreign_domid, unsigned long idx, xen_pfn_t gpfn); -/* Returns 1 on success, 0 on error, negative if the ring - * for event propagation is full in the presence of paging */ +/* Returns 0 on success, or negative on error. */ int guest_remove_page(struct domain *d, unsigned long gmfn); #define RAM_TYPE_CONVENTIONAL 0x00000001 debian/patches/xsa178-xen4.4-0004-libxl-Do-not-trust-backend-for-disk-eject-vdev.patch0000664000000000000000000000514312725542005025057 0ustar From 35343222aef036cf65ab850ba9ba73cd36a916d7 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 16:23:35 +0100 Subject: [PATCH 04/16] libxl: Do not trust backend for disk eject vdev For disk eject, use configured vdev from /libxl, not backend. The backend directory is writeable by driver domains. This means that a malicious driver domain could cause libxl to see a wrong vdev, confusing the user or the toolstack. Use the vdev from the /libxl space, rather than the backend. For convenience, we read the vdev from the /libxl space into the evg during setup and copy it on each event, rather than reading it afresh each time (which would in any case involve generating or saving a copy of the relevant /libxl path). This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 2f043a7..df62bcc 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1186,8 +1186,7 @@ static void disk_eject_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *w, disk->pdev_path = strdup(""); /* xxx fixme malloc failure */ disk->format = LIBXL_DISK_FORMAT_EMPTY; /* this value is returned to the user: do not free right away */ - disk->vdev = xs_read(CTX->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/dev", backend), NULL); + disk->vdev = libxl__strdup(NOGC, evg->vdev); disk->removable = 1; disk->readwrite = 0; disk->is_cdrom = 1; @@ -1210,9 +1209,6 @@ int libxl_evenable_disk_eject(libxl_ctx *ctx, uint32_t guest_domid, evg->domid = guest_domid; LIBXL_LIST_INSERT_HEAD(&CTX->disk_eject_evgens, evg, entry); - evg->vdev = strdup(vdev); - if (!evg->vdev) { rc = ERROR_NOMEM; goto out; } - uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid); if (!domid) @@ -1230,6 +1226,13 @@ int libxl_evenable_disk_eject(libxl_ctx *ctx, uint32_t guest_domid, devid); evg->be_ptr_path = libxl__sprintf(NOGC, "%s/backend", libxl_path); + const char *configured_vdev; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/vdev", libxl_path), &configured_vdev); + if (rc) goto out; + + evg->vdev = libxl__strdup(NOGC, configured_vdev); + rc = libxl__ev_xswatch_register(gc, &evg->watch, disk_eject_xswatch_callback, path); if (rc) goto out; -- 1.9.1 debian/patches/xsa190-4.5.patch0000664000000000000000000001214712775454777013227 0ustar x86emul: honor guest CR0.TS and CR0.EM We must not emulate any instructions accessing respective registers when either of these flags is set in the guest view of the register, or else we may do so on data not belonging to the guest's current task. Being architecturally required behavior, the logic gets placed in the instruction emulator instead of hvmemul_get_fpu(). It should be noted, though, that hvmemul_get_fpu() being the only current handler for the get_fpu() callback, we don't have an active problem with CR4: Both CR4.OSFXSR and CR4.OSXSAVE get handled as necessary by that function. This is XSA-190. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -129,6 +129,22 @@ static inline uint64_t xgetbv(uint32_t x (ebx & (1U << 5)) != 0; \ }) +static int read_cr( + unsigned int reg, + unsigned long *val, + struct x86_emulate_ctxt *ctxt) +{ + /* Fake just enough state for the emulator's _get_fpu() to be happy. */ + switch ( reg ) + { + case 0: + *val = 0x00000001; /* PE */ + return X86EMUL_OKAY; + } + + return X86EMUL_UNHANDLEABLE; +} + int get_fpu( void (*exception_callback)(void *, struct cpu_user_regs *), void *exception_callback_arg, @@ -160,6 +176,7 @@ static struct x86_emulate_ops emulops = .write = write, .cmpxchg = cmpxchg, .cpuid = cpuid, + .read_cr = read_cr, .get_fpu = get_fpu, }; --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -1192,6 +1192,7 @@ static int hvmemul_get_fpu( switch ( type ) { case X86EMUL_FPU_fpu: + case X86EMUL_FPU_wait: break; case X86EMUL_FPU_mmx: if ( !cpu_has_mmx ) @@ -1199,7 +1200,6 @@ static int hvmemul_get_fpu( break; case X86EMUL_FPU_xmm: if ( !cpu_has_xmm || - (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_EM) || !(curr->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSFXSR) ) return X86EMUL_UNHANDLEABLE; break; --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -373,6 +373,9 @@ typedef union { /* Control register flags. */ #define CR0_PE (1<<0) +#define CR0_MP (1<<1) +#define CR0_EM (1<<2) +#define CR0_TS (1<<3) #define CR4_TSD (1<<2) /* EFLAGS bit definitions. */ @@ -400,6 +403,7 @@ typedef union { #define EXC_OF 4 #define EXC_BR 5 #define EXC_UD 6 +#define EXC_NM 7 #define EXC_TS 10 #define EXC_NP 11 #define EXC_SS 12 @@ -684,10 +688,45 @@ static void fpu_handle_exception(void *_ regs->eip += fic->insn_bytes; } +static int _get_fpu( + enum x86_emulate_fpu_type type, + struct fpu_insn_ctxt *fic, + struct x86_emulate_ctxt *ctxt, + const struct x86_emulate_ops *ops) +{ + int rc; + + fic->exn_raised = 0; + + fail_if(!ops->get_fpu); + rc = ops->get_fpu(fpu_handle_exception, fic, type, ctxt); + + if ( rc == X86EMUL_OKAY ) + { + unsigned long cr0; + + fail_if(!ops->read_cr); + rc = ops->read_cr(0, &cr0, ctxt); + if ( rc != X86EMUL_OKAY ) + return rc; + if ( cr0 & CR0_EM ) + { + generate_exception_if(type == X86EMUL_FPU_fpu, EXC_NM, -1); + generate_exception_if(type == X86EMUL_FPU_mmx, EXC_UD, -1); + generate_exception_if(type == X86EMUL_FPU_xmm, EXC_UD, -1); + } + generate_exception_if((cr0 & CR0_TS) && + (type != X86EMUL_FPU_wait || (cr0 & CR0_MP)), + EXC_NM, -1); + } + + done: + return rc; +} + #define get_fpu(_type, _fic) \ -do{ (_fic)->exn_raised = 0; \ - fail_if(ops->get_fpu == NULL); \ - rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \ +do { \ + rc = _get_fpu(_type, _fic, ctxt, ops); \ if ( rc ) goto done; \ } while (0) #define put_fpu(_fic) \ @@ -2491,8 +2530,14 @@ x86_emulate( } case 0x9b: /* wait/fwait */ - emulate_fpu_insn("fwait"); + { + struct fpu_insn_ctxt fic = { .insn_bytes = 1 }; + + get_fpu(X86EMUL_FPU_wait, &fic); + asm volatile ( "fwait" ::: "memory" ); + put_fpu(&fic); break; + } case 0x9c: /* pushf */ src.val = _regs.eflags; --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -114,6 +114,7 @@ struct __packed segment_register { /* FPU sub-types which may be requested via ->get_fpu(). */ enum x86_emulate_fpu_type { X86EMUL_FPU_fpu, /* Standard FPU coprocessor instruction set */ + X86EMUL_FPU_wait, /* WAIT/FWAIT instruction */ X86EMUL_FPU_mmx, /* MMX instruction set (%mm0-%mm7) */ X86EMUL_FPU_xmm, /* SSE instruction set (%xmm0-%xmm7/15) */ X86EMUL_FPU_ymm /* AVX/XOP instruction set (%ymm0-%ymm7/15) */ debian/patches/xsa243-4.5-2.patch0000664000000000000000000001022313167430306013330 0ustar From: Andrew Cooper Subject: x86/shadow: Don't create self-linear shadow mappings for 4-level translated guests When initially creating a monitor table for 4-level translated guests, don't install a shadow-linear mapping. This mapping is actually self-linear, and trips up the writeable heuristic logic into following Xen's mappings, not the guests' shadows it was expecting to follow. A consequence of this is that sh_guess_wrmap() needs to cope with there being no shadow-linear mapping present, which in practice occurs once each time a vcpu switches to 4-level paging from a different paging mode. An appropriate shadow-linear slot will be inserted into the monitor table either while constructing lower level monitor tables, or by sh_update_cr3(). While fixing this, clarify the safety of the other mappings. Despite appearing unsafe, it is correct to create a guest-linear mapping for translated domains; this is self-linear and doesn't point into the translated domain. Drop a dead clause for translate != external guests. This is part of XSA-243. Signed-off-by: Andrew Cooper Acked-by: Tim Deegan diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index e16bf1b..948c86a 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -1453,26 +1453,38 @@ void sh_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn) shadow_l4e_from_mfn(page_to_mfn(d->arch.perdomain_l3_pg), __PAGE_HYPERVISOR); - /* Shadow linear mapping for 4-level shadows. N.B. for 3-level - * shadows on 64-bit xen, this linear mapping is later replaced by the - * monitor pagetable structure, which is built in make_monitor_table - * and maintained by sh_update_linear_entries. */ - sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = - shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR); - - /* Self linear mapping. */ - if ( shadow_mode_translate(v->domain) && !shadow_mode_external(v->domain) ) - { - // linear tables may not be used with translated PV guests - sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = + /* + * Linear mapping slots: + * + * Calling this function with gl4mfn == sl4mfn is used to construct a + * monitor table for translated domains. In this case, gl4mfn forms the + * self-linear mapping (i.e. not pointing into the translated domain), and + * the shadow-linear slot is skipped. The shadow-linear slot is either + * filled when constructing lower level monitor tables, or via + * sh_update_cr3() for 4-level guests. + * + * Calling this function with gl4mfn != sl4mfn is used for non-translated + * guests, where the shadow-linear slot is actually self-linear, and the + * guest-linear slot points into the guests view of its pagetables. + */ + if ( shadow_mode_translate(d) ) + { + ASSERT(mfn_x(gl4mfn) == mfn_x(sl4mfn)); + + sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = shadow_l4e_empty(); } else { - sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = - shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR); + ASSERT(mfn_x(gl4mfn) != mfn_x(sl4mfn)); + + sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = + shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR); } + sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = + shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR); + sh_unmap_domain_page(sl4e); } #endif @@ -4243,6 +4255,11 @@ static int sh_guess_wrmap(struct vcpu *v, unsigned long vaddr, mfn_t gmfn) /* Carefully look in the shadow linear map for the l1e we expect */ #if SHADOW_PAGING_LEVELS >= 4 + /* Is a shadow linear map is installed in the first place? */ + sl4p = v->arch.paging.shadow.guest_vtable; + sl4p += shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START); + if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) ) + return 0; sl4p = sh_linear_l4_table(v) + shadow_l4_linear_offset(vaddr); if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) ) return 0; debian/patches/xsa206-4.4-0024-oxenstored-discard-old-commit-history-on-txn-end.patch0000664000000000000000000001273013104300260025066 0ustar From c9fb09ca7384fa1952de7a470c52d93c5b4d2eea Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Thu, 23 Mar 2017 14:25:16 +0000 Subject: [PATCH 24/30] oxenstored: discard old commit-history on txn end The history of commits is to be used for working out which historical commit(s) (including atomic writes) caused conflicts with a currently-failing commit of a transaction. Any commit that was made before the current transaction started cannot be relevant. Therefore we never need to keep history from before the start of the longest-running transaction that is open at any given time: whenever a transaction ends (with or without a commit) then if it was the longest-running open transaction we can delete history up until start of the the next-longest-running open transaction. Some transactions might stay open for a very long time, so if any transaction exceeds conflict_max_history_seconds then we remove it from consideration in this context, and will not guarantee to keep remembering about historical commits made during such a transaction. We implement this by keeping a list of all open transactions that have not been open too long. When a transaction ends, we remove it from the list, along with any that have been open longer than the maximum; then we delete any history from before the start of the longest-running transaction remaining in the list. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/history.ml | 17 +++++++++++++++++ tools/ocaml/xenstored/process.ml | 4 ++-- tools/ocaml/xenstored/transaction.ml | 29 +++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml index e4b4d70..6f7a282 100644 --- a/tools/ocaml/xenstored/history.ml +++ b/tools/ocaml/xenstored/history.ml @@ -36,6 +36,23 @@ let mark_symbols () = ) !history +(* Keep only enough commit-history to protect the running transactions that we are still tracking *) +(* There is scope for optimisation here, replacing List.filter with something more efficient, + * probably on a different list-like structure. *) +let trim () = + history := match Transaction.oldest_short_running_transaction () with + | None -> [] (* We have no open transaction, so no history is needed *) + | Some (_, txn) -> ( + (* keep records with finish_count recent enough to be relevant *) + List.filter (fun r -> r.finish_count > txn.Transaction.start_count) !history + ) + +let end_transaction txn con tid commit = + let success = Connection.end_transaction con tid commit in + Transaction.end_transaction txn; + trim (); + success + let push (x: history_record) = let dom = x.con.Connection.dom in match dom with diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 502e1d6..f95992d 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -307,7 +307,7 @@ let transaction_replay c t doms cons = false | Transaction.Full(id, oldstore, cstore) -> let tid = Connection.start_transaction c cstore in - let new_t = Transaction.make tid cstore in + let new_t = Transaction.make ~internal:true tid cstore in let con = sprintf "r(%d):%s" id (Connection.get_domstr c) in let perform_exn (request, response) = write_access_log ~ty:request.Packet.ty ~tid ~con ~data:request.Packet.data; @@ -364,7 +364,7 @@ let do_transaction_end con t domains cons data = in let success = let commit = if commit then Some (fun con trans -> transaction_replay con trans domains cons) else None in - Connection.end_transaction con (Transaction.get_id t) commit in + History.end_transaction t con (Transaction.get_id t) commit in if not success then raise Transaction_again; if commit then begin diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index b1791b3..edd1178 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -87,12 +87,29 @@ type t = { mutable read_lowpath: Store.Path.t option; mutable write_lowpath: Store.Path.t option; } +let get_id t = match t.ty with No -> none | Full (id, _, _) -> id let counter = ref 0L -let make id store = +(* Scope for optimisation: different data-structure and functions to search/filter it *) +let short_running_txns = ref [] + +let oldest_short_running_transaction () = + let rec last = function + | [] -> None + | [x] -> Some x + | x :: xs -> last xs + in last !short_running_txns + +let end_transaction txn = + let cutoff = Unix.gettimeofday () -. !Define.conflict_max_history_seconds in + short_running_txns := List.filter + (function (start_time, tx) -> start_time >= cutoff && tx != txn) + !short_running_txns + +let make ?(internal=false) id store = let ty = if id = none then No else Full(id, Store.copy store, store) in - { + let txn = { ty = ty; start_count = !counter; store = if id = none then store else Store.copy store; @@ -101,9 +118,13 @@ let make id store = operations = []; read_lowpath = None; write_lowpath = None; - } + } in + if id <> none && not internal then ( + let now = Unix.gettimeofday () in + short_running_txns := (now, txn) :: !short_running_txns + ); + txn -let get_id t = match t.ty with No -> none | Full (id, _, _) -> id let get_store t = t.store let get_paths t = t.paths -- 2.1.4 debian/patches/xsa155-xen-0002-blktap2-Use-RING_COPY_REQUEST.patch0000664000000000000000000000407612631307731020735 0ustar From fdd6f8cd7553e7ae8922637cb3b93eb7fcade207 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 20 Nov 2015 12:16:02 -0500 Subject: [PATCH 2/3] blktap2: Use RING_COPY_REQUEST Instead of RING_GET_REQUEST. Using a local copy of the ring (and also with proper memory barriers) will mean we can do not have to worry about the compiler optimizing the code and doing a double-fetch in the shared memory space. This is part of XSA155. Signed-off-by: Konrad Rzeszutek Wilk --- tools/blktap2/drivers/block-log.c | 3 ++- tools/blktap2/drivers/tapdisk-vbd.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/blktap2/drivers/block-log.c b/tools/blktap2/drivers/block-log.c index 5330cdc..5f3bd35 100644 --- a/tools/blktap2/drivers/block-log.c +++ b/tools/blktap2/drivers/block-log.c @@ -494,11 +494,12 @@ static int ctl_kick(struct tdlog_state* s, int fd) reqstart = s->bring.req_cons; reqend = s->sring->req_prod; + xen_mb(); BDPRINTF("ctl: ring kicked (start = %u, end = %u)", reqstart, reqend); while (reqstart != reqend) { /* XXX actually submit these! */ - memcpy(&req, RING_GET_REQUEST(&s->bring, reqstart), sizeof(req)); + RING_COPY_REQUEST(&s->bring, reqstart, &req); BDPRINTF("ctl: read request %"PRIu64":%u", req.sector, req.count); s->bring.req_cons = ++reqstart; diff --git a/tools/blktap2/drivers/tapdisk-vbd.c b/tools/blktap2/drivers/tapdisk-vbd.c index 6d1d94a..77f2854 100644 --- a/tools/blktap2/drivers/tapdisk-vbd.c +++ b/tools/blktap2/drivers/tapdisk-vbd.c @@ -1555,7 +1555,7 @@ tapdisk_vbd_pull_ring_requests(td_vbd_t *vbd) int idx; RING_IDX rp, rc; td_ring_t *ring; - blkif_request_t *req; + blkif_request_t req; td_vbd_request_t *vreq; ring = &vbd->ring; @@ -1566,7 +1566,7 @@ tapdisk_vbd_pull_ring_requests(td_vbd_t *vbd) xen_rmb(); for (rc = ring->fe_ring.req_cons; rc != rp; rc++) { - req = RING_GET_REQUEST(&ring->fe_ring, rc); + RING_COPY_REQUEST(&ring->fe_ring, rc, &req); ++ring->fe_ring.req_cons; idx = req->id; -- 2.1.0 debian/patches/tools-ocaml-disable-test.patch0000664000000000000000000000145112305652413016451 0ustar From: Stefan Bader Date: Wed, 05 Mar 2014 17:44:11 +0100 Subject: tools/ocaml: Disable test target This currently breaks the build because some xenlight symbols are not found. Might be related to some older ocaml build fix. Before 4.4 libxenlight likely not linked to from ocaml. Signed-off-by: Stefan Bader Index: xen-4.4.0/tools/ocaml/Makefile =================================================================== --- xen-4.4.0.orig/tools/ocaml/Makefile 2014-02-24 17:28:17.000000000 +0100 +++ xen-4.4.0/tools/ocaml/Makefile 2014-03-05 17:43:30.912352382 +0100 @@ -1,7 +1,7 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -SUBDIRS_PROGRAMS = xenstored test +SUBDIRS_PROGRAMS = xenstored SUBDIRS = libs $(SUBDIRS_PROGRAMS) debian/patches/xsa207-4.4.patch0000664000000000000000000000203413104305261013161 0ustar From: Oleksandr Tyshchenko Subject: IOMMU: always call teardown callback There is a possible scenario when (d)->need_iommu remains unset during guest domain execution. For example, when no devices were assigned to it. Taking into account that teardown callback is not called when (d)->need_iommu is unset we might have unreleased resourses after destroying domain. So, always call teardown callback to roll back actions that were performed in init callback. This is XSA-207. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Jan Beulich Tested-by: Jan Beulich Tested-by: Julien Grall --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -418,8 +418,7 @@ void iommu_domain_destroy(struct domain if ( !iommu_enabled || !hd->platform_ops ) return; - if ( need_iommu(d) ) - iommu_teardown(d); + iommu_teardown(d); list_for_each_safe ( ioport_list, tmp, &hd->g2m_ioport_list ) { debian/patches/xsa158-fix.patch0000664000000000000000000000275012632305013013454 0ustar memory: fix XSA-158 fix For one the uses of domu_max_order and ptdom_max_order were swapped. And then gcc warns about an unused result of a __must_check function in the control part of a conditional expression when both other expressions can be determined by the compiler to produce the same value (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68039), which happens when HAS_PASSTHROUGH is undefined (i.e. for ARM on 4.4 and older). Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -55,8 +55,6 @@ static unsigned int __read_mostly ctldom_max_order = CONFIG_CTLDOM_MAX_ORDER; static unsigned int __read_mostly hwdom_max_order = CONFIG_HWDOM_MAX_ORDER; #ifdef HAS_PASSTHROUGH static unsigned int __read_mostly ptdom_max_order = CONFIG_PTDOM_MAX_ORDER; -#else -# define ptdom_max_order domu_max_order #endif static void __init parse_max_order(const char *s) { @@ -75,8 +73,12 @@ custom_param("memop-max-order", parse_max_order); static unsigned int max_order(const struct domain *d) { - unsigned int order = cache_flush_permitted(d) ? domu_max_order - : ptdom_max_order; + unsigned int order = domu_max_order; + +#ifdef HAS_PASSTHROUGH + if ( cache_flush_permitted(d) && order < ptdom_max_order ) + order = ptdom_max_order; +#endif if ( is_control_domain(d) && order < ctldom_max_order ) order = ctldom_max_order; debian/patches/tools-xcutils-rpath.diff0000664000000000000000000000104412276137126015424 0ustar Index: xen-4.4.0~rc3+20140210/tools/xcutils/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xcutils/Makefile 2014-02-10 12:53:56.798059220 +0100 +++ xen-4.4.0~rc3+20140210/tools/xcutils/Makefile 2014-02-10 12:56:06.634693953 +0100 @@ -20,6 +20,8 @@ CFLAGS_xc_save.o := $(CFLAGS_libxenct CFLAGS_readnotes.o := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) CFLAGS_lsevtchn.o := $(CFLAGS_libxenctrl) +APPEND_LDFLAGS += $(call LDFLAGS_RPATH,../lib) + .PHONY: all all: build debian/patches/xsa206-4.4-0002-xenstored-Log-when-the-write-transaction-rate-limit-.patch0000664000000000000000000000704413104300257025607 0ustar From 8153049d49e5669418dd1ee88b2d793ccbabede6 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 18 Mar 2017 17:13:27 +0000 Subject: [PATCH 02/30] xenstored: Log when the write transaction rate limit bites Reported-by: Juergen Gross Signed-off-by: Ian Jackson --- tools/xenstore/xenstored_core.c | 1 + tools/xenstore/xenstored_domain.c | 25 +++++++++++++++++++++++++ tools/xenstore/xenstored_domain.h | 2 ++ 3 files changed, 28 insertions(+) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index beb630b..55d4b3b 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -363,6 +363,7 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx, POLLIN|POLLPRI); wrl_gettime_now(&now); + wrl_log_periodic(now); list_for_each_entry(conn, &connections, list) { if (conn->domain) { diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 16c303e..ca0fa76 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "utils.h" #include "talloc.h" @@ -80,6 +81,7 @@ struct domain /* write rate limit */ wrl_creditt wrl_credit; /* [ -wrl_config_writecost, +_dburst ] */ struct wrl_timestampt wrl_timestamp; + bool wrl_delay_logged; }; static LIST_HEAD(domains); @@ -771,6 +773,7 @@ long wrl_ntransactions; static long wrl_ndomains; static wrl_creditt wrl_reserve; /* [-wrl_config_newdoms_dburst, +_gburst ] */ +static time_t wrl_log_last_warning; /* 0: no previous warning */ void wrl_gettime_now(struct wrl_timestampt *now_wt) { @@ -920,6 +923,9 @@ void wrl_check_timeout(struct domain *domain, wakeup); } +#define WRL_LOG(now, ...) \ + (syslog(LOG_WARNING, "write rate limit: " __VA_ARGS__)) + void wrl_apply_debit_actual(struct domain *domain) { struct wrl_timestampt now; @@ -935,6 +941,25 @@ void wrl_apply_debit_actual(struct domain *domain) trace("wrl: domain %u credit=%ld (reserve=%ld)\n", domain->domid, (long)domain->wrl_credit, (long)wrl_reserve); + + if (domain->wrl_credit < 0) { + if (!domain->wrl_delay_logged++) { + WRL_LOG(now, "domain %ld is affected", + (long)domain->domid); + } else if (!wrl_log_last_warning) { + WRL_LOG(now, "rate limiting restarts"); + } + wrl_log_last_warning = now.sec; + } +} + +void wrl_log_periodic(struct wrl_timestampt now) +{ + if (wrl_log_last_warning && + (now.sec - wrl_log_last_warning) > WRL_LOGEVERY) { + WRL_LOG(now, "not in force recently"); + wrl_log_last_warning = 0; + } } void wrl_apply_debit_direct(struct connection *conn) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index a008554..a9650cc 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -73,6 +73,7 @@ int domain_watch(struct connection *conn); #define WRL_DBURST 10 #define WRL_GBURST 1000 #define WRL_NEWDOMS 5 +#define WRL_LOGEVERY 120 /* seconds */ struct wrl_timestampt { time_t sec; @@ -88,6 +89,7 @@ void wrl_credit_update(struct domain *domain, struct wrl_timestampt now); void wrl_check_timeout(struct domain *domain, struct wrl_timestampt now, int *ptimeout); +void wrl_log_periodic(struct wrl_timestampt now); void wrl_apply_debit_direct(struct connection *conn); void wrl_apply_debit_trans_commit(struct connection *conn); -- 2.1.4 debian/patches/tools-examples-xend-disable-network.diff0000664000000000000000000000114712276137140020457 0ustar Index: xen-4.4.0~rc3+20140210/tools/examples/xend-config.sxp =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/examples/xend-config.sxp 2014-02-10 12:53:55.558053158 +0100 +++ xen-4.4.0~rc3+20140210/tools/examples/xend-config.sxp 2014-02-10 12:56:16.794743624 +0100 @@ -132,6 +132,11 @@ #(console-limit 1024) ## +# NOTE: +# Please read /usr/share/doc/xen-utils-common/README.Debian for Debian specific +# informations about the network setup. + +## # To bridge network traffic, like this: # # dom0: ----------------- bridge -> real eth0 -> the network debian/patches/xsa206-4.4-0012-oxenstored-refactor-request-processing.patch0000664000000000000000000000653213104300260023374 0ustar From 37102e74b4e974348d62082d6f68eb4313207f27 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:40:27 +0000 Subject: [PATCH 12/30] oxenstored: refactor request processing Encapsulate the request in a record that is passed from do_input to process_packet and input_handle_error. This will be helpful when keeping track of the requests made as part of a transaction. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/packet.ml | 7 +++++++ tools/ocaml/xenstored/process.ml | 15 ++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/ocaml/xenstored/packet.ml b/tools/ocaml/xenstored/packet.ml index c8ecfe5..22cae1d 100644 --- a/tools/ocaml/xenstored/packet.ml +++ b/tools/ocaml/xenstored/packet.ml @@ -1,3 +1,10 @@ +type request = { + tid: int; + rid: int; + ty: Xenbus.Xb.Op.operation; + data: string; +} + type response = | Ack of (unit -> unit) (* function is the action to execute after sending the ack *) | Reply of string diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 7026727..b8bcb46 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -338,11 +338,11 @@ let function_of_type ty = | Xenbus.Xb.Op.Invalid -> reply_ack do_error | _ -> reply_ack do_error -let input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data = +let input_handle_error ~cons ~doms ~fct ~con ~t ~req = let reply_error e = Packet.Error e in try - fct con t doms cons data + fct con t doms cons req.Packet.data with | Define.Invalid_path -> reply_error "EINVAL" | Define.Already_exist -> reply_error "EEXIST" @@ -364,7 +364,10 @@ let input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data = (** * Nothrow guarantee. *) -let process_packet ~store ~cons ~doms ~con ~tid ~rid ~ty ~data = +let process_packet ~store ~cons ~doms ~con ~req = + let ty = req.Packet.ty in + let tid = req.Packet.tid in + let rid = req.Packet.rid in try let fct = function_of_type ty in let t = @@ -373,7 +376,7 @@ let process_packet ~store ~cons ~doms ~con ~tid ~rid ~ty ~data = else Connection.get_transaction con tid in - let response = input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data in + let response = input_handle_error ~cons ~doms ~fct ~con ~t ~req in (* Put the response on the wire *) send_response ty con t rid response @@ -401,11 +404,13 @@ let do_input store cons doms con = if newpacket then ( let packet = Connection.pop_in con in let tid, rid, ty, data = Xenbus.Xb.Packet.unpack packet in + let req = {Packet.tid; Packet.rid; Packet.ty; Packet.data} in + (* As we don't log IO, do not call an unnecessary sanitize_data info "[%s] -> [%d] %s \"%s\"" (Connection.get_domstr con) tid (Xenbus.Xb.Op.to_string ty) (sanitize_data data); *) - process_packet ~store ~cons ~doms ~con ~tid ~rid ~ty ~data; + process_packet ~store ~cons ~doms ~con ~req; write_access_log ~ty ~tid ~con ~data; Connection.incr_ops con; ) -- 2.1.4 debian/patches/xsa206-4.4-0022-oxenstored-support-commit-history-tracking.patch0000664000000000000000000001357413104300260024235 0ustar From 4d0479387d5abd326810a0e6af17cbed50641ca9 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Tue, 14 Mar 2017 13:20:07 +0000 Subject: [PATCH 22/30] oxenstored: support commit history tracking Add ability to track xenstore tree operations -- either non-transactional operations or committed transactions. For now, the call to actually retain commits is commented out because history can grow without bound. For now, we call record_commit for all non-transactional operations. A subsequent patch will make it retain only the ones with side-effects. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Signed-off-by: Thomas Sanders Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/Makefile | 1 + tools/ocaml/xenstored/history.ml | 43 ++++++++++++++++++++++++++++++++++++++ tools/ocaml/xenstored/process.ml | 24 +++++++++++++++++++-- tools/ocaml/xenstored/xenstored.ml | 1 + 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tools/ocaml/xenstored/history.ml diff --git a/tools/ocaml/xenstored/Makefile b/tools/ocaml/xenstored/Makefile index 7a4c317..ff3eed9 100644 --- a/tools/ocaml/xenstored/Makefile +++ b/tools/ocaml/xenstored/Makefile @@ -31,6 +31,7 @@ OBJS = define \ domains \ connection \ connections \ + history \ parse_arg \ process \ xenstored diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml new file mode 100644 index 0000000..e4b4d70 --- /dev/null +++ b/tools/ocaml/xenstored/history.ml @@ -0,0 +1,43 @@ +(* + * Copyright (c) 2017 Citrix Systems Ltd. + * + * This program 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 only. with the special + * exception on linking described in file LICENSE. + * + * This program 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. + *) + +type history_record = { + con: Connection.t; (* connection that made a change *) + tid: int; (* transaction id of the change (may be Transaction.none) *) + before: Store.t; (* the store before the change *) + after: Store.t; (* the store after the change *) + finish_count: int64; (* the commit-count at which the transaction finished *) +} + +let history : history_record list ref = ref [] + +(* Called from periodic_ops to ensure we don't discard symbols that are still needed. *) +(* There is scope for optimisation here, since in consecutive commits one commit's `after` + * is the same thing as the next commit's `before`, but not all commits in history are + * consecutive. *) +let mark_symbols () = + (* There are gaps where dom0's commits are missing. Otherwise we could assume that + * each element's `before` is the same thing as the next element's `after` + * since the next element is the previous commit *) + List.iter (fun hist_rec -> + Store.mark_symbols hist_rec.before; + Store.mark_symbols hist_rec.after; + ) + !history + +let push (x: history_record) = + let dom = x.con.Connection.dom in + match dom with + | None -> () (* treat socket connections as always free to conflict *) + | Some d -> if not (Domain.is_free_to_conflict d) then history := x :: !history diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index ff5fc24..b48df05 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -287,6 +287,16 @@ let write_response_log ~ty ~tid ~con ~response = | Packet.Reply x -> write_answer_log ~ty ~tid ~con ~data:x | Packet.Error e -> write_answer_log ~ty:(Xenbus.Xb.Op.Error) ~tid ~con ~data:e +let record_commit ~con ~tid ~before ~after = + let inc r = r := Int64.add 1L !r in + let finish_count = inc Transaction.counter; !Transaction.counter in + (* This call would leak memory if historic activity is retained forever + so can only be uncommented if history is guaranteed not to grow + unboundedly. + History.push {History.con=con; tid=tid; before=before; after=after; finish_count=finish_count} + *) + () + (* Replay a stored transaction against a fresh store, check the responses are all equivalent: if so, commit the transaction. Otherwise send the abort to the client. *) @@ -357,8 +367,14 @@ let do_transaction_end con t domains cons data = Connection.end_transaction con (Transaction.get_id t) commit in if not success then raise Transaction_again; - if commit then - process_watch (List.rev (Transaction.get_paths t)) cons + if commit then begin + process_watch (List.rev (Transaction.get_paths t)) cons; + match t.Transaction.ty with + | Transaction.No -> + () (* no need to record anything *) + | Transaction.Full(id, oldstore, cstore) -> + record_commit ~con ~tid:id ~before:oldstore ~after:cstore + end let do_introduce con t domains cons data = if not (Connection.is_dom0 con) @@ -441,7 +457,11 @@ let process_packet ~store ~cons ~doms ~con ~req = else Connection.get_transaction con tid in + + let before = Store.copy store in let response = input_handle_error ~cons ~doms ~fct ~con ~t ~req in + let after = Store.copy store in + if tid = Transaction.none then record_commit ~con ~tid ~before ~after; let response = try if tid <> Transaction.none then diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 9480b21..c009701 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -384,6 +384,7 @@ let _ = Symbol.mark_all_as_unused (); Store.mark_symbols store; Connections.iter cons Connection.mark_symbols; + History.mark_symbols (); Symbol.garbage () end; -- 2.1.4 debian/patches/xsa201-1.patch0000664000000000000000000000634113035723115013020 0ustar From: Wei Chen Subject: arm64: handle guest-generated EL1 asynchronous abort In current code, when the hypervisor receives an asynchronous abort from a guest, the hypervisor will do panic, the host will be down. We have to prevent such security issue, so, in this patch we crash the guest, when the hypervisor receives an asynchronous abort from the guest. This is CVE-2016-9815, part of XSA-201. Signed-off-by: Wei Chen Reviewed-by: Stefano Stabellini Reviewed-by: Steve Capper Reviewed-by: Julien Grall Index: xen-4.4.2/xen/arch/arm/arm64/entry.S =================================================================== --- xen-4.4.2.orig/xen/arch/arm/arm64/entry.S +++ xen-4.4.2/xen/arch/arm/arm64/entry.S @@ -204,9 +204,12 @@ guest_fiq_invalid: entry hyp=0, compat=0 invalid BAD_FIQ -guest_error_invalid: +guest_error: entry hyp=0, compat=0 - invalid BAD_ERROR + msr daifclr, #2 + mov x0, sp + bl do_trap_guest_error + exit hyp=0, compat=0 guest_sync_compat: entry hyp=0, compat=1 @@ -225,9 +228,12 @@ guest_fiq_invalid_compat: entry hyp=0, compat=1 invalid BAD_FIQ -guest_error_invalid_compat: +guest_error_compat: entry hyp=0, compat=1 - invalid BAD_ERROR + msr daifclr, #2 + mov x0, sp + bl do_trap_guest_error + exit hyp=0, compat=1 ENTRY(return_to_new_vcpu32) exit hyp=0, compat=1 @@ -286,12 +292,12 @@ ENTRY(hyp_traps_vector) ventry guest_sync // Synchronous 64-bit EL0/EL1 ventry guest_irq // IRQ 64-bit EL0/EL1 ventry guest_fiq_invalid // FIQ 64-bit EL0/EL1 - ventry guest_error_invalid // Error 64-bit EL0/EL1 + ventry guest_error // Error 64-bit EL0/EL1 ventry guest_sync_compat // Synchronous 32-bit EL0/EL1 ventry guest_irq_compat // IRQ 32-bit EL0/EL1 ventry guest_fiq_invalid_compat // FIQ 32-bit EL0/EL1 - ventry guest_error_invalid_compat // Error 32-bit EL0/EL1 + ventry guest_error_compat // Error 32-bit EL0/EL1 /* * struct vcpu *__context_switch(struct vcpu *prev, struct vcpu *next) Index: xen-4.4.2/xen/arch/arm/traps.c =================================================================== --- xen-4.4.2.orig/xen/arch/arm/traps.c +++ xen-4.4.2/xen/arch/arm/traps.c @@ -1914,6 +1914,19 @@ asmlinkage void do_trap_hypervisor(struc } } +asmlinkage void do_trap_guest_error(struct cpu_user_regs *regs) +{ + /* + * Currently, to ensure hypervisor safety, when we received a + * guest-generated vSerror/vAbort, we just crash the guest to protect + * the hypervisor. In future we can better handle this by injecting + * a vSerror/vAbort to the guest. + */ + gdprintk(XENLOG_WARNING, "Guest(Dom-%u) will be crashed by vSError\n", + current->domain->domain_id); + domain_crash_synchronous(); +} + asmlinkage void do_trap_irq(struct cpu_user_regs *regs) { gic_interrupt(regs, 0); debian/patches/xsa197-4.5-qemut.patch0000664000000000000000000000363413035177242014343 0ustar From: Jan Beulich Subject: xen: fix ioreq handling Avoid double fetches and bounds check size to avoid overflowing internal variables. This is XSA-197. Reported-by: yanghongke Signed-off-by: Jan Beulich Reviewed-by: Ian Jackson --- a/qemu/i386-dm/helper2.c +++ b/qemu/i386-dm/helper2.c @@ -374,6 +374,11 @@ static void cpu_ioreq_pio(CPUState *env, { uint32_t i; + if (req->size > sizeof(unsigned long)) { + fprintf(stderr, "PIO: bad size (%u)\n", req->size); + exit(-1); + } + if (req->dir == IOREQ_READ) { if (!req->data_is_ptr) { req->data = do_inp(env, req->addr, req->size); @@ -403,6 +408,11 @@ static void cpu_ioreq_move(CPUState *env { uint32_t i; + if (req->size > sizeof(req->data)) { + fprintf(stderr, "MMIO: bad size (%u)\n", req->size); + exit(-1); + } + if (!req->data_is_ptr) { if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { @@ -506,11 +516,13 @@ static int __handle_buffered_iopage(CPUS req.df = 1; req.type = buf_req->type; req.data_is_ptr = 0; + xen_rmb(); qw = (req.size == 8); if (qw) { buf_req = &buffered_io_page->buf_ioreq[ (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM]; req.data |= ((uint64_t)buf_req->data) << 32; + xen_rmb(); } __handle_ioreq(env, &req); @@ -543,7 +555,11 @@ static void cpu_handle_ioreq(void *opaqu __handle_buffered_iopage(env); if (req) { - __handle_ioreq(env, req); + ioreq_t copy = *req; + + xen_rmb(); + __handle_ioreq(env, ©); + req->data = copy.data; if (req->state != STATE_IOREQ_INPROCESS) { fprintf(logfile, "Badness in I/O request ... not in service?!: " debian/patches/xsa155-xen-0001-xen-Add-RING_COPY_REQUEST.patch0000664000000000000000000000354612631307713020124 0ustar From 8937a9c6cdfd39b4e4a3ef5b3f9b5b21e614779d Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 20 Nov 2015 11:59:05 -0500 Subject: [PATCH 1/3] xen: Add RING_COPY_REQUEST() Using RING_GET_REQUEST() on a shared ring is easy to use incorrectly (i.e., by not considering that the other end may alter the data in the shared ring while it is being inspected). Safe usage of a request generally requires taking a local copy. Provide a RING_COPY_REQUEST() macro to use instead of RING_GET_REQUEST() and an open-coded memcpy(). This takes care of ensuring that the copy is done correctly regardless of any possible compiler optimizations. Use a volatile source to prevent the compiler from reordering or omitting the copy. This is part of XSA155. Signed-off-by: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk --- xen/include/public/io/ring.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/xen/include/public/io/ring.h b/xen/include/public/io/ring.h index ba9401b..f40cf35 100644 --- a/xen/include/public/io/ring.h +++ b/xen/include/public/io/ring.h @@ -212,6 +212,17 @@ typedef struct __name##_back_ring __name##_back_ring_t #define RING_GET_REQUEST(_r, _idx) \ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) +/* + * Get a local copy of a request. + * + * Use this in preference to RING_GET_REQUEST() so all processing is + * done on a local copy that cannot be modified by the other end. + */ +#define RING_COPY_REQUEST(_r, _idx, _req) do { \ + /* Use volatile to force the copy into _req. */ \ + *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \ +} while (0) + #define RING_GET_RESPONSE(_r, _idx) \ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp)) -- 2.1.0 debian/patches/toolchain.diff0000664000000000000000000000211712276137150013436 0ustar Index: xen-4.4.0~rc3+20140210/tools/debugger/gdbsx/xg/xg_main.c =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/debugger/gdbsx/xg/xg_main.c 2014-02-10 12:53:54.238046699 +0100 +++ xen-4.4.0~rc3+20140210/tools/debugger/gdbsx/xg/xg_main.c 2014-02-10 12:56:23.874778237 +0100 @@ -180,7 +180,7 @@ _domctl_hcall(uint32_t cmd, / 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; @@ -220,7 +220,7 @@ _check_hyp(int guest_bitness) 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); debian/patches/xsa206-4.4-0026-oxenstored-blame-the-connection-that-caused-a-transa.patch0000664000000000000000000001317713104300260025636 0ustar From a6edf151e5eb4f401745e13a803e713accd22bee Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 14:28:16 +0000 Subject: [PATCH 26/30] oxenstored: blame the connection that caused a transaction conflict Blame each connection found to have made a commit that would cause this transaction to fail. Each blamed connection is penalised by having its conflict-credit decremented. Note the change in semantics for the replay function: we no longer stop after finding the first operation that can't be replayed. This allows us to identify all operations that conflicted with this transaction, not just the one that conflicted first. Signed-off-by: Jonathan Davies Signed-off-by: Thomas Sanders v1 Reviewed-by: Christian Lindig Changes since v1: * use correct log levels for informational messages Changes since v2: * fix the blame algorithm and improve logging (fix was reviewed by Jonathan Davies) Reported-by: Juergen Gross Signed-off-by: Thomas Sanders --- tools/ocaml/xenstored/history.ml | 12 ++++++++++ tools/ocaml/xenstored/process.ml | 50 ++++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml index 6f7a282..e941e2b 100644 --- a/tools/ocaml/xenstored/history.ml +++ b/tools/ocaml/xenstored/history.ml @@ -58,3 +58,15 @@ let push (x: history_record) = match dom with | None -> () (* treat socket connections as always free to conflict *) | Some d -> if not (Domain.is_free_to_conflict d) then history := x :: !history + +(* Find the connections from records since commit-count [since] for which [f record] returns [true] *) +let filter_connections ~since ~f = + (* The "mem" call is an optimisation, to avoid calling f if we have picked con already. *) + (* Using a hash table rather than a list is to optimise the "mem" call. *) + List.fold_left (fun acc hist_rec -> + if hist_rec.finish_count > since + && not (Hashtbl.mem acc hist_rec.con) + && f hist_rec + then Hashtbl.replace acc hist_rec.con (); + acc + ) (Hashtbl.create 1023) !history diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 706b8a0..698a456 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -16,6 +16,7 @@ let error fmt = Logging.error "process" fmt let info fmt = Logging.info "process" fmt +let debug fmt = Logging.debug "process" fmt open Printf open Stdext @@ -25,6 +26,7 @@ exception Transaction_nested exception Domain_not_match exception Invalid_Cmd_Args +(* This controls the do_debug fn in this module, not the debug logging-function. *) let allow_debug = ref false let c_int_of_string s = @@ -302,23 +304,51 @@ let transaction_replay c t doms cons = false | Transaction.Full(id, oldstore, cstore) -> let tid = Connection.start_transaction c cstore in - let new_t = Transaction.make ~internal:true tid cstore in + let replay_t = Transaction.make ~internal:true tid cstore in let con = sprintf "r(%d):%s" id (Connection.get_domstr c) in - let perform_exn (request, response) = - write_access_log ~ty:request.Packet.ty ~tid ~con ~data:request.Packet.data; + + let perform_exn ~wlog txn (request, response) = + if wlog then write_access_log ~ty:request.Packet.ty ~tid ~con ~data:request.Packet.data; let fct = function_of_type_simple_op request.Packet.ty in - let response' = input_handle_error ~cons ~doms ~fct ~con:c ~t:new_t ~req:request in - write_response_log ~ty:request.Packet.ty ~tid ~con ~response:response'; - if not(Packet.response_equal response response') then raise Transaction_again in + let response' = input_handle_error ~cons ~doms ~fct ~con:c ~t:txn ~req:request in + if wlog then write_response_log ~ty:request.Packet.ty ~tid ~con ~response:response'; + if not(Packet.response_equal response response') then raise Transaction_again + in finally (fun () -> try Logging.start_transaction ~con ~tid; - List.iter perform_exn (Transaction.get_operations t); - Logging.end_transaction ~con ~tid; + List.iter (perform_exn ~wlog:true replay_t) (Transaction.get_operations t); (* May throw EAGAIN *) - Transaction.commit ~con new_t - with e -> + Logging.end_transaction ~con ~tid; + Transaction.commit ~con replay_t + with + | Transaction_again -> ( + let victim_domstr = Connection.get_domstr c in + debug "Apportioning blame for EAGAIN in txn %d, domain=%s" id victim_domstr; + let punish guilty_con = + debug "Blaming domain %s for conflict with domain %s txn %d" + (Connection.get_domstr guilty_con) victim_domstr id; + Connection.decr_conflict_credit doms guilty_con + in + let judge_and_sentence hist_rec = ( + let can_apply_on store = ( + let store = Store.copy store in + let trial_t = Transaction.make ~internal:true Transaction.none store in + try List.iter (perform_exn ~wlog:false trial_t) (Transaction.get_operations t); + true + with Transaction_again -> false + ) in + if can_apply_on hist_rec.History.before + && not (can_apply_on hist_rec.History.after) + then (punish hist_rec.History.con; true) + else false + ) in + let guilty_cons = History.filter_connections ~since:t.Transaction.start_count ~f:judge_and_sentence in + if Hashtbl.length guilty_cons = 0 then debug "Found no culprit for conflict in %s: must be self or not in history." con; + false + ) + | e -> info "transaction_replay %d caught: %s" tid (Printexc.to_string e); false ) -- 2.1.4 debian/patches/config-prefix.diff0000664000000000000000000000302512276137112014213 0ustar Index: xen-4.4.0~rc3+20140210/config/StdGNU.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/config/StdGNU.mk 2014-02-10 12:53:58.398067043 +0100 +++ xen-4.4.0~rc3+20140210/config/StdGNU.mk 2014-02-10 12:55:54.674635489 +0100 @@ -30,16 +30,19 @@ INSTALL_PROG = $(INSTALL) -m0755 -p PREFIX ?= /usr BINDIR = $(PREFIX)/bin INCLUDEDIR = $(PREFIX)/include -LIBEXEC = $(PREFIX)/lib/xen/bin +LIBDIR = $(PREFIX)/lib SHAREDIR = $(PREFIX)/share MANDIR = $(SHAREDIR)/man MAN1DIR = $(MANDIR)/man1 MAN8DIR = $(MANDIR)/man8 SBINDIR = $(PREFIX)/sbin -XENFIRMWAREDIR = $(PREFIX)/lib/xen/boot -PRIVATE_PREFIX = $(LIBDIR)/xen +PRIVATE_PREFIX = $(LIBDIR)/xen-$(XEN_VERSION) PRIVATE_BINDIR = $(PRIVATE_PREFIX)/bin +PRIVATE_LIBDIR = $(PRIVATE_PREFIX)/lib + +LIBEXEC = $(PRIVATE_BINDIR) +XENFIRMWAREDIR = $(PRIVATE_PREFIX)/boot CONFIG_DIR = /etc XEN_LOCK_DIR = /var/lock Index: xen-4.4.0~rc3+20140210/Config.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/Config.mk 2014-02-10 12:55:53.522629857 +0100 +++ xen-4.4.0~rc3+20140210/Config.mk 2014-02-10 12:55:54.674635489 +0100 @@ -84,7 +84,7 @@ EXTRA_LIB += $(EXTRA_PREFIX)/lib endif PYTHON ?= python -PYTHON_PREFIX_ARG ?= --prefix="$(PREFIX)" +PYTHON_PREFIX_ARG ?= --home="$(PRIVATE_PREFIX)" # The above requires that PREFIX contains *no spaces*. This variable is here # to permit the user to set PYTHON_PREFIX_ARG to '' to workaround this bug: # https://bugs.launchpad.net/ubuntu/+bug/362570 debian/patches/xsa146.patch0000664000000000000000000000234012616222056012667 0ustar xen: arm: rate-limit logging from unimplemented PHYSDEVOP and HVMOP. These are guest accessible and should therefore be rate-limited. Moreover, include them only in debug builds. This is XSA-146. Signed-off-by: Ian Campbell Reviewed-by: Jan Beulich diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c index 471c4cd..1de290f 100644 --- a/xen/arch/arm/hvm.c +++ b/xen/arch/arm/hvm.c @@ -57,7 +57,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) default: { - printk("%s: Bad HVM op %ld.\n", __func__, op); + gdprintk(XENLOG_DEBUG, "HVMOP op=%lu: not implemented\n", op); rc = -ENOSYS; break; } diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c index 61b4a18..b1ba22e 100644 --- a/xen/arch/arm/physdev.c +++ b/xen/arch/arm/physdev.c @@ -8,12 +8,13 @@ #include #include #include +#include #include int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) { - printk("%s %d cmd=%d: not implemented yet\n", __func__, __LINE__, cmd); + gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: not implemented\n", cmd); return -ENOSYS; } debian/patches/xsa178-xen4.4-0003-libxl-cdrom-eject-and-insert-write-to-libxl.patch0000664000000000000000000000506712725542005024527 0ustar From 64282177f44fccf8fa9d8df7e1ab72d59a0fb0c8 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 19:15:13 +0100 Subject: [PATCH 03/16] libxl: cdrom eject and insert: write to /libxl Copy the new type and params values to /libxl, so that the information in /libxl is kept up to date. This is needed so that we can return this trustworthy information, rather than trusting the backend-writeable parts of xenstore. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 19c3d90..2f043a7 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2496,7 +2496,8 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, int rc, dm_ver; libxl__device device; - const char * path; + const char *path, *libxl_path; + xs_transaction_t t = XBT_NULL; char * tmp; flexarray_t *insert = NULL; @@ -2557,6 +2558,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, } path = libxl__device_backend_path(gc, &device); + libxl_path = libxl__device_libxl_path(gc, &device); /* Sanity check: make sure the backend exists before writing here */ tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend", path)); @@ -2581,9 +2583,22 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, else flexarray_append_pair(insert, "params", ""); - rc = libxl__xs_writev_atonce(gc, path, - libxl__xs_kvs_of_flexarray(gc, insert, insert->count)); - if (rc) goto out; + char **kvs = libxl__xs_kvs_of_flexarray(gc, insert, insert->count); + + for (;;) { + rc = libxl__xs_transaction_start(gc, &t); + if (rc) goto out; + + rc = libxl__xs_writev(gc, t, path, kvs); + if (rc) goto out; + + rc = libxl__xs_writev(gc, t, libxl_path, kvs); + if (rc) goto out; + + rc = libxl__xs_transaction_commit(gc, &t); + if (!rc) break; + if (rc<0) goto out; + } /* success, no actual async */ libxl__ao_complete(egc, ao, 0); @@ -2595,6 +2610,8 @@ out: libxl_device_disk_dispose(&disks[i]); free(disks); + libxl__xs_transaction_abort(gc, &t); + if (rc) return AO_ABORT(rc); return AO_INPROGRESS; } -- 1.9.1 debian/patches/tools-python-rpath.diff0000664000000000000000000000736212276137126015263 0ustar Index: xen-4.4.0~rc3+20140210/tools/python/setup.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/setup.py 2014-02-10 12:53:56.854059490 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/setup.py 2014-02-10 12:56:05.922690473 +0100 @@ -5,6 +5,7 @@ import os, sys XEN_ROOT = "../.." extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ] +extra_link_args = [ "-Wl,-rpath,${ORIGIN}/../../.." ] PATH_XEN = XEN_ROOT + "/tools/include" PATH_LIBXC = XEN_ROOT + "/tools/libxc" @@ -13,6 +14,7 @@ PATH_XENSTORE = XEN_ROOT + "/tools/xenst xc = Extension("xc", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/xc" ], library_dirs = [ PATH_LIBXC ], libraries = [ "xenctrl", "xenguest" ], @@ -21,6 +23,7 @@ xc = Extension("xc", xs = Extension("xs", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ PATH_XEN, PATH_XENSTORE, "xen/lowlevel/xs" ], library_dirs = [ PATH_XENSTORE ], libraries = [ "xenstore" ], @@ -29,6 +32,7 @@ xs = Extension("xs", scf = Extension("scf", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ "xen/lowlevel/scf" ], library_dirs = [ ], libraries = [ ], @@ -37,6 +41,7 @@ scf = Extension("scf", process = Extension("process", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ "xen/lowlevel/process" ], library_dirs = [ ], libraries = [ "contract" ], @@ -45,6 +50,7 @@ process = Extension("process", flask = Extension("flask", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/flask" ], library_dirs = [ PATH_LIBXC ], libraries = [ "xenctrl" ], @@ -53,6 +59,7 @@ flask = Extension("flask", ptsname = Extension("ptsname", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ "ptsname" ], library_dirs = [ ], libraries = [ ], @@ -61,6 +68,7 @@ ptsname = Extension("ptsname", checkpoint = Extension("checkpoint", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ PATH_XEN, PATH_LIBXC, PATH_XENSTORE ], library_dirs = [ PATH_LIBXC, PATH_XENSTORE ], libraries = [ "xenctrl", "xenguest", "xenstore", "rt" ], @@ -72,6 +80,7 @@ checkpoint = Extension("checkpoint", netlink = Extension("netlink", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ ], library_dirs = [ ], libraries = [ ], @@ -81,6 +90,7 @@ netlink = Extension("netlink", xl = Extension("xl", extra_compile_args = extra_compile_args, + extra_link_args = extra_link_args, include_dirs = [ PATH_XEN, PATH_LIBXL, PATH_LIBXC, "xen/lowlevel/xl" ], library_dirs = [ PATH_LIBXL ], libraries = [ "xenlight" ], debian/patches/xsa206-4.4-0005-oxenstored-catch-the-error-when-a-connection-is-alre.patch0000664000000000000000000000313513104300257025566 0ustar From 63e01804c4ba80816af7f5a12786fb45ee2d194b Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Fri, 24 Mar 2017 17:01:08 +0000 Subject: [PATCH 05/30] oxenstored: catch the error when a connection is already deleted The function process_fdset_with is called on the read set connections first. During the process, it might destroy a connection and remove it from the connections database if some errors occur. However, a reference to the same connection might still exist in the write set, which is awaiting to be processed next. In this case, a Not_found error will be raised and the process is aborted. This patch changes the logic to ignore connections just missing from the connection database and continue the rest part of the work. Reported-by: Juergen Gross Signed-off-by: Zheng Li Reviewed-by: David Scott --- tools/ocaml/xenstored/xenstored.ml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 438ecb9..d74846c 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -43,8 +43,11 @@ let process_connection_fds store cons domains rset wset = debug "closing socket connection" in let process_fdset_with fds fct = - List.iter (fun fd -> try_fct fct (Connections.find cons fd)) fds - in + List.iter + (fun fd -> + try try_fct fct (Connections.find cons fd) + with Not_found -> () + ) fds in process_fdset_with rset Process.do_input; process_fdset_with wset Process.do_output -- 2.1.4 debian/patches/xsa206-4.4-0020-oxenstored-ignore-domains-with-no-conflict-credit.patch0000664000000000000000000001777013104300260025301 0ustar From c72a4976b66887b12126810d240fdd2d3f74ec0a Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Tue, 14 Mar 2017 12:15:52 +0000 Subject: [PATCH 20/30] oxenstored: ignore domains with no conflict-credit When processing connections, skip those from domains with no remaining conflict-credit. Also, issue a point of conflict-credit at regular intervals, the period being set by the configuration option "conflict-max-history- seconds". When issuing conflict-credit, we give a point either to every domain at once (one each) or only to the single domain at the front of the queue, depending on the configuration option "conflict-rate-limit-is-aggregate". Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/connections.ml | 14 ++++---- tools/ocaml/xenstored/define.ml | 1 + tools/ocaml/xenstored/domains.ml | 4 +-- tools/ocaml/xenstored/oxenstored.conf | 2 +- tools/ocaml/xenstored/xenstored.ml | 65 ++++++++++++++++++++++++++--------- 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml index f9bc225..ae76928 100644 --- a/tools/ocaml/xenstored/connections.ml +++ b/tools/ocaml/xenstored/connections.ml @@ -44,12 +44,14 @@ let add_domain cons dom = | Some p -> Hashtbl.add cons.ports p con; | None -> () -let select cons = - Hashtbl.fold - (fun _ con (ins, outs) -> - let fd = Connection.get_fd con in - (fd :: ins, if Connection.has_output con then fd :: outs else outs)) - cons.anonymous ([], []) +let select ?(only_if = (fun _ -> true)) cons = + Hashtbl.fold (fun _ con (ins, outs) -> + if (only_if con) then ( + let fd = Connection.get_fd con in + (fd :: ins, if Connection.has_output con then fd :: outs else outs) + ) else (ins, outs) + ) + cons.anonymous ([], []) let find cons = Hashtbl.find cons.anonymous diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml index df1e91c..016ef18 100644 --- a/tools/ocaml/xenstored/define.ml +++ b/tools/ocaml/xenstored/define.ml @@ -30,6 +30,7 @@ let maxtransaction = ref (20) let maxrequests = ref (-1) (* maximum requests per transaction *) let conflict_burst_limit = ref 5.0 +let conflict_max_history_seconds = ref 0.05 let conflict_rate_limit_is_aggregate = ref true let domid_self = 0x7FF0 diff --git a/tools/ocaml/xenstored/domains.ml b/tools/ocaml/xenstored/domains.ml index 041d222..63c6ad5 100644 --- a/tools/ocaml/xenstored/domains.ml +++ b/tools/ocaml/xenstored/domains.ml @@ -39,12 +39,12 @@ type domains = { mutable n_paused: int; } -let init eventchn = { +let init eventchn on_first_conflict_pause = { eventchn = eventchn; table = Hashtbl.create 10; doms_conflict_paused = Queue.create (); doms_with_conflict_penalty = Queue.create (); - on_first_conflict_pause = (fun () -> ()); (* Dummy value for now, pending subsequent commit. *) + on_first_conflict_pause = on_first_conflict_pause; n_paused = 0; } let del doms id = Hashtbl.remove doms.table id diff --git a/tools/ocaml/xenstored/oxenstored.conf b/tools/ocaml/xenstored/oxenstored.conf index a100936..dd9649b 100644 --- a/tools/ocaml/xenstored/oxenstored.conf +++ b/tools/ocaml/xenstored/oxenstored.conf @@ -22,7 +22,7 @@ conflict-burst-limit = 5.0 # The conflict-credit is replenished over time: # one point is issued after each conflict-max-history-seconds, so this # is the minimum pause-time during which a domain will be ignored. -# conflict-max-history-seconds = 0.05 +conflict-max-history-seconds = 0.05 # If the conflict-rate-limit-is-aggregate flag is true then after each # tick one point of conflict-credit is given to just one domain: the diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index ea511de..9480b21 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -53,14 +53,16 @@ let process_connection_fds store cons domains rset wset = let process_domains store cons domains = let do_io_domain domain = - if not (Domain.is_bad_domain domain) then - let io_credit = Domain.get_io_credit domain in - if io_credit > 0 then ( - let con = Connections.find_domain cons (Domain.get_id domain) in - Process.do_input store cons domains con; - Process.do_output store cons domains con; - Domain.decr_io_credit domain; - ) in + if Domain.is_bad_domain domain + || Domain.get_io_credit domain <= 0 + || Domain.is_paused_for_conflict domain + then () (* nothing to do *) + else ( + let con = Connections.find_domain cons (Domain.get_id domain) in + Process.do_input store cons domains con; + Process.do_output store cons domains con; + Domain.decr_io_credit domain + ) in Domains.iter domains do_io_domain let sigusr1_handler store = @@ -90,6 +92,7 @@ let parse_config filename = let options = [ ("merge-activate", Config.Set_bool Transaction.do_coalesce); ("conflict-burst-limit", Config.Set_float Define.conflict_burst_limit); + ("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds); ("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate); ("perms-activate", Config.Set_bool Perms.activate); ("quota-activate", Config.Set_bool Quota.activate); @@ -262,7 +265,22 @@ let _ = let store = Store.create () in let eventchn = Event.init () in - let domains = Domains.init eventchn in + let next_frequent_ops = ref 0. in + let advance_next_frequent_ops () = + next_frequent_ops := (Unix.gettimeofday () +. !Define.conflict_max_history_seconds) + in + let delay_next_frequent_ops_by duration = + next_frequent_ops := !next_frequent_ops +. duration + in + let domains = Domains.init eventchn advance_next_frequent_ops in + + (* For things that need to be done periodically but more often + * than the periodic_ops function *) + let frequent_ops () = + if Unix.gettimeofday () > !next_frequent_ops then ( + Domains.incr_conflict_credit domains; + advance_next_frequent_ops () + ) in let cons = Connections.create () in let quit = ref false in @@ -393,23 +411,34 @@ let _ = gc.Gc.heap_words gc.Gc.heap_chunks gc.Gc.live_words gc.Gc.live_blocks gc.Gc.free_words gc.Gc.free_blocks - ) - in + ); + let elapsed = Unix.gettimeofday () -. now in + delay_next_frequent_ops_by elapsed + in - let period_ops_interval = 15. in - let period_start = ref 0. in + let period_ops_interval = 15. in + let period_start = ref 0. in let main_loop () = - + let is_peaceful c = + match Connection.get_domain c with + | None -> true (* Treat socket-connections as exempt, and free to conflict. *) + | Some dom -> not (Domain.is_paused_for_conflict dom) + in + frequent_ops (); let mw = Connections.has_more_work cons in + let peaceful_mw = List.filter is_peaceful mw in List.iter (fun c -> match Connection.get_domain c with | None -> () | Some d -> Domain.incr_io_credit d) - mw; + peaceful_mw; + let start_time = Unix.gettimeofday () in let timeout = - if List.length mw > 0 then 0. else period_ops_interval in - let inset, outset = Connections.select cons in + let until_next_activity = min (max 0. (!next_frequent_ops -. start_time)) period_ops_interval in + if peaceful_mw <> [] then 0. else until_next_activity + in + let inset, outset = Connections.select ~only_if:is_peaceful cons in let rset, wset, _ = try Unix.select (spec_fds @ inset) outset [] timeout @@ -419,6 +448,7 @@ let _ = List.partition (fun fd -> List.mem fd spec_fds) rset in if List.length sfds > 0 then process_special_fds sfds; + if List.length cfds > 0 || List.length wset > 0 then process_connection_fds store cons domains cfds wset; if timeout <> 0. then ( @@ -426,6 +456,7 @@ let _ = if now > !period_start +. period_ops_interval then (period_start := now; periodic_ops now) ); + process_domains store cons domains in -- 2.1.4 debian/patches/upstream-x86-hvm-do-not-set-msr_tsc_adjust-on-hvm_set_guest_t.patch0000664000000000000000000001021613061741465025542 0ustar From 163543ac31e90bdc7da589c63c5a997004ee11c9 Mon Sep 17 00:00:00 2001 From: Joao Martins Date: Thu, 9 Feb 2017 10:35:58 +0100 Subject: [PATCH] x86/hvm: do not set msr_tsc_adjust on hvm_set_guest_tsc_fixed Commit 6e03363 ("x86: Implement TSC adjust feature for HVM guest") implemented TSC_ADJUST MSR for hvm guests. Though while booting an HVM guest the boot CPU would have a value set with delta_tsc - guest tsc while secondary CPUS would have 0. For example one can observe: $ xen-hvmctx 17 | grep tsc_adjust TSC_ADJUST: tsc_adjust ff9377dfef47fe66 TSC_ADJUST: tsc_adjust 0 TSC_ADJUST: tsc_adjust 0 TSC_ADJUST: tsc_adjust 0 Upcoming Linux 4.10 now validates whether this MSR is correct and adjusts them accordingly under the following conditions: values of < 0 (our case for CPU 0) or != 0 or values > 7FFFFFFF. In this conditions it will force set to 0 and for the CPUs that the value doesn't match all together. If this msr is not correct we would see messages such as: [Firmware Bug]: TSC ADJUST: CPU0: -30517044286984129 force to 0 And on HVM guests supporting TSC_ADJUST (requiring at least Haswell Intel) it won't boot. Our current vCPU 0 values are incorrect and according to Intel SDM which on section "Time-Stamp Counter Adjustment" states that "On RESET, the value of the IA32_TSC_ADJUST MSR is 0." hence we should set it 0 and be consistent across multiple vCPUs. Perhaps this MSR should be only changed by the guest which already happens through hvm_set_guest_tsc_adjust(..) routines (see below). After this patch guests running Linux 4.10 will see a valid IA32_TSC_ADJUST msr of value 0 for all CPUs and are able to boot. On the same section of the spec ("Time-Stamp Counter Adjustment") it is also stated: "If an execution of WRMSR to the IA32_TIME_STAMP_COUNTER MSR adds (or subtracts) value X from the TSC, the logical processor also adds (or subtracts) value X from the IA32_TSC_ADJUST MSR. Unlike the TSC, the value of the IA32_TSC_ADJUST MSR changes only in response to WRMSR (either to the MSR itself, or to the IA32_TIME_STAMP_COUNTER MSR). Its value does not otherwise change as time elapses. Software seeking to adjust the TSC can do so by using WRMSR to write the same value to the IA32_TSC_ADJUST MSR on each logical processor." This suggests these MSRs values should only be changed through guest i.e. throught write intercept msrs. We keep IA32_TSC MSR logic such that writes accomodate adjustments to TSC_ADJUST, hence no functional change in the msr_tsc_adjust for IA32_TSC msr. Though, we do that in a separate routine namely hvm_set_guest_tsc_msr instead of through hvm_set_guest_tsc(...). Signed-off-by: Joao Martins Reviewed-by: Jan Beulich BugLink: https://bugs.launchpad.net/bugs/1671760 (backported from commit 98297f09bd07bb63407909aae1d309d8adeb572e) Signed-off-by: Stefan Bader --- xen/arch/x86/hvm/hvm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) Index: xen-4.4.2/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/hvm/hvm.c +++ xen-4.4.2/xen/arch/x86/hvm/hvm.c @@ -264,13 +264,20 @@ void hvm_set_guest_tsc(struct vcpu *v, u } delta_tsc = guest_tsc - tsc; - v->arch.hvm_vcpu.msr_tsc_adjust += delta_tsc - - v->arch.hvm_vcpu.cache_tsc_offset; v->arch.hvm_vcpu.cache_tsc_offset = delta_tsc; hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset); } +static void hvm_set_guest_tsc_msr(struct vcpu *v, u64 guest_tsc) +{ + uint64_t tsc_offset = v->arch.hvm_vcpu.cache_tsc_offset; + + hvm_set_guest_tsc(v, guest_tsc); + v->arch.hvm_vcpu.msr_tsc_adjust += v->arch.hvm_vcpu.cache_tsc_offset + - tsc_offset; +} + void hvm_set_guest_tsc_adjust(struct vcpu *v, u64 tsc_adjust) { v->arch.hvm_vcpu.cache_tsc_offset += tsc_adjust @@ -3143,7 +3150,7 @@ int hvm_msr_write_intercept(unsigned int break; case MSR_IA32_TSC: - hvm_set_guest_tsc(v, msr_content); + hvm_set_guest_tsc_msr(v, msr_content); break; case MSR_IA32_TSC_ADJUST: debian/patches/xsa206-4.4-0030-oxenstored-transaction-conflicts-improve-logging.patch0000664000000000000000000001447113104300260025342 0ustar From cc5c2188f39bd707fd8b29df5d488c47aab189ca Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Mon, 27 Mar 2017 14:36:34 +0100 Subject: [PATCH 30/30] oxenstored transaction conflicts: improve logging For information related to transaction conflicts, potentially frequent logging at "info" priority has been changed to "debug" priority, and once per two minutes there is an "info" priority summary. Additional detailed logging has been added at "debug" priority. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders --- tools/ocaml/xenstored/domain.ml | 8 ++++++++ tools/ocaml/xenstored/domains.ml | 5 +++++ tools/ocaml/xenstored/process.ml | 6 +++++- tools/ocaml/xenstored/transaction.ml | 5 +++++ tools/ocaml/xenstored/xenstored.ml | 6 ++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml index e677aa3..4515650 100644 --- a/tools/ocaml/xenstored/domain.ml +++ b/tools/ocaml/xenstored/domain.ml @@ -34,6 +34,7 @@ type t = mutable conflict_credit: float; (* Must be positive to perform writes; a commit that later causes conflict with another domain's transaction costs credit. *) + mutable caused_conflicts: int64; } let is_dom0 d = d.id = 0 @@ -93,4 +94,11 @@ let make id mfn remote_port interface eventchn = { bad_client = false; io_credit = 0; conflict_credit = !Define.conflict_burst_limit; + caused_conflicts = 0L; } + +let log_and_reset_conflict_stats logfn dom = + if dom.caused_conflicts > 0L then ( + logfn dom.id dom.caused_conflicts; + dom.caused_conflicts <- 0L + ) diff --git a/tools/ocaml/xenstored/domains.ml b/tools/ocaml/xenstored/domains.ml index 25fd592..ca749fa 100644 --- a/tools/ocaml/xenstored/domains.ml +++ b/tools/ocaml/xenstored/domains.ml @@ -148,8 +148,10 @@ let create0 fake doms = dom let decr_conflict_credit doms dom = + dom.Domain.caused_conflicts <- Int64.add 1L dom.Domain.caused_conflicts; let before = dom.Domain.conflict_credit in let after = max (-1.0) (before -. 1.0) in + debug "decr_conflict_credit dom%d %F -> %F" (Domain.get_id dom) before after; dom.Domain.conflict_credit <- after; let newly_penalised = before >= !Define.conflict_burst_limit @@ -180,7 +182,9 @@ let decr_conflict_credit doms dom = let incr_conflict_credit_from_queue doms = let process_queue q requeue_test = let d = pop q in + let before = d.Domain.conflict_credit in (* just for debug-logging *) d.Domain.conflict_credit <- min (d.Domain.conflict_credit +. 1.0) !Define.conflict_burst_limit; + debug "incr_conflict_credit_from_queue: dom%d: %F -> %F" (Domain.get_id d) before d.Domain.conflict_credit; if requeue_test d.Domain.conflict_credit then ( push d q (* Make it queue up again for its next point of credit. *) ) @@ -202,6 +206,7 @@ let incr_conflict_credit doms = let before = dom.Domain.conflict_credit in let after = min (before +. 1.0) !Define.conflict_burst_limit in dom.Domain.conflict_credit <- after; + debug "incr_conflict_credit dom%d: %F -> %F" (Domain.get_id dom) before after; if before <= 0.0 && after > 0.0 then doms.n_paused <- doms.n_paused - 1; diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index a983b49..b7fb75d 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -324,6 +324,7 @@ let transaction_replay c t doms cons = Transaction.commit ~con replay_t with | Transaction_again -> ( + Transaction.failed_commits := Int64.add !Transaction.failed_commits 1L; let victim_domstr = Connection.get_domstr c in debug "Apportioning blame for EAGAIN in txn %d, domain=%s" id victim_domstr; let punish guilty_con = @@ -345,7 +346,10 @@ let transaction_replay c t doms cons = else false ) in let guilty_cons = History.filter_connections ~ignore:c ~since:t.Transaction.start_count ~f:judge_and_sentence in - if Hashtbl.length guilty_cons = 0 then debug "Found no culprit for conflict in %s: must be self or not in history." con; + if Hashtbl.length guilty_cons = 0 then ( + debug "Found no culprit for conflict in %s: must be self or not in history." con; + Transaction.failed_commits_no_culprit := Int64.add !Transaction.failed_commits_no_culprit 1L + ); false ) | e -> diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index 8f95301..da4a3e3 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -90,6 +90,11 @@ type t = { let get_id t = match t.ty with No -> none | Full (id, _, _) -> id let counter = ref 0L +let failed_commits = ref 0L +let failed_commits_no_culprit = ref 0L +let reset_conflict_stats () = + failed_commits := 0L; + failed_commits_no_culprit := 0L (* Scope for optimisation: different data-structure and functions to search/filter it *) let short_running_txns = ref [] diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 8c82fe9..979b769 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -375,6 +375,7 @@ let _ = let last_scan_time = ref 0. in let periodic_ops now = + debug "periodic_ops starting"; (* we garbage collect the string->int dictionary after a sizeable amount of operations, * there's no need to be really fast even if we got loose * objects since names are often reuse. @@ -394,7 +395,11 @@ let _ = (* make sure we don't print general stats faster than 2 min *) if now > (!last_stat_time +. 120.) then ( + info "Transaction conflict statistics for last %F seconds:" (now -. !last_stat_time); last_stat_time := now; + Domains.iter domains (Domain.log_and_reset_conflict_stats (info "Dom%d caused %Ld conflicts")); + info "%Ld failed transactions; of these no culprit was found for %Ld" !Transaction.failed_commits !Transaction.failed_commits_no_culprit; + Transaction.reset_conflict_stats (); let gc = Gc.stat () in let (lanon, lanon_ops, lanon_watchs, @@ -414,6 +419,7 @@ let _ = gc.Gc.free_words gc.Gc.free_blocks ); let elapsed = Unix.gettimeofday () -. now in + debug "periodic_ops took %F seconds." elapsed; delay_next_frequent_ops_by elapsed in -- 2.1.4 debian/patches/xsa204-4.5.patch0000664000000000000000000000527213035200776013176 0ustar From: Andrew Cooper Date: Sun, 18 Dec 2016 15:42:59 +0000 Subject: [PATCH] x86/emul: Correct the handling of eflags with SYSCALL A singlestep #DB is determined by the resulting eflags value from the execution of SYSCALL, not the original eflags value. By using the original eflags value, we negate the guest kernels attempt to protect itself from a privilege escalation by masking TF. Introduce a tf boolean and have the SYSCALL emulation recalculate it after the instruction is complete. This is XSA-204 Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- xen/arch/x86/x86_emulate/x86_emulate.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) Index: xen-4.4.2/xen/arch/x86/x86_emulate/x86_emulate.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/x86_emulate/x86_emulate.c +++ xen-4.4.2/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1388,6 +1388,7 @@ x86_emulate( union vex vex = {}; unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; bool_t lock_prefix = 0; + bool_t tf = !!(ctxt->regs->eflags & EFLG_TF); int override_seg = -1, rc = X86EMUL_OKAY; struct operand src, dst; DECLARE_ALIGNED(mmval_t, mmval); @@ -3713,9 +3714,8 @@ x86_emulate( break; } - /* Inject #DB if single-step tracing was enabled at instruction start. */ - if ( (ctxt->regs->eflags & EFLG_TF) && (rc == X86EMUL_OKAY) && - (ops->inject_hw_exception != NULL) ) + /* Should a singlestep #DB be raised? */ + if ( tf && (rc == X86EMUL_OKAY) && (ops->inject_hw_exception != NULL) ) rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION; /* Commit shadow register state. */ @@ -3900,6 +3900,23 @@ x86_emulate( (rc = ops->write_segment(x86_seg_ss, &ss, ctxt)) ) goto done; + /* + * SYSCALL (unlike most instructions) evaluates its singlestep action + * based on the resulting EFLG_TF, not the starting EFLG_TF. + * + * As the #DB is raised after the CPL change and before the OS can + * switch stack, it is a large risk for privilege escalation. + * + * 64bit kernels should mask EFLG_TF in MSR_FMASK to avoid any + * vulnerability. Running the #DB handler on an IST stack is also a + * mitigation. + * + * 32bit kernels have no ability to mask EFLG_TF at all. Their only + * mitigation is to use a task gate for handling #DB (or to not use + * enable EFER.SCE to start with). + */ + tf = !!(_regs.eflags & EFLG_TF); + break; } debian/patches/tools-xenstore-rpath.diff0000664000000000000000000000110112276137133015570 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstore/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstore/Makefile 2014-02-10 12:56:11.026715430 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstore/Makefile 2014-02-10 12:56:11.758719005 +0100 @@ -8,6 +8,8 @@ CFLAGS += -Werror CFLAGS += -I. CFLAGS += $(CFLAGS_libxenctrl) +LDFLAGS_libxenctrl += $(call LDFLAGS_RPATH,../lib) + CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod CLIENTS += xenstore-write xenstore-ls xenstore-watch debian/patches/xsa211-qemut-4.5.patch0000664000000000000000000001776413104310512014321 0ustar From dc4eee43ac608337ae96a174e0a5c1278168bd56 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 9 Mar 2017 11:14:55 +0000 Subject: [PATCH] cirrus/vnc: zap drop bitblit support from console code. From: Gerd Hoffmann There is a special code path (dpy_gfx_copy) to allow graphic emulation notify user interface code about bitblit operations carryed out by guests. It is supported by cirrus and vnc server. The intended purpose is to optimize display scrolls and just send over the scroll op instead of a full display update. This is rarely used these days though because modern guests simply don't use the cirrus blitter any more. Any linux guest using the cirrus drm driver doesn't. Any windows guest newer than winxp doesn't ship with a cirrus driver any more and thus uses the cirrus as simple framebuffer. So this code tends to bitrot and bugs can go unnoticed for a long time. See for example commit "3e10c3e vnc: fix qemu crash because of SIGSEGV" which fixes a bug lingering in the code for almost a year, added by commit "c7628bf vnc: only alloc server surface with clients connected". Also the vnc server will throttle the frame rate in case it figures the network can't keep up (send buffers are full). This doesn't work with dpy_gfx_copy, for any copy operation sent to the vnc client we have to send all outstanding updates beforehand, otherwise the vnc client might run the client side blit on outdated data and thereby corrupt the display. So this dpy_gfx_copy "optimization" might even make things worse on slow network links. Lets kill it once for all. Signed-off-by: Gerd Hoffmann These changes (dropping dpy_copy and all its references and implementations) reimplemented for qemu-xen-traditional. This is XSA-211. Signed-off-by: Ian Jackson Conflicts: qemu/hw/cirrus_vga.c --- console.c | 8 -------- console.h | 16 ---------------- hw/cirrus_vga.c | 15 +++++---------- hw/vmware_vga.c | 1 + vnc.c | 35 ----------------------------------- 5 files changed, 6 insertions(+), 69 deletions(-) diff --git a/qemu/console.c b/qemu/console.c index 9984d6f..33c8bac 100644 --- a/qemu/console.c +++ b/qemu/console.c @@ -1398,14 +1398,6 @@ void qemu_console_resize(DisplayState *ds, int width, int height) } } -void qemu_console_copy(DisplayState *ds, int src_x, int src_y, - int dst_x, int dst_y, int w, int h) -{ - if (is_graphic_console()) { - dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h); - } -} - PixelFormat qemu_different_endianness_pixelformat(int bpp) { PixelFormat pf; diff --git a/qemu/console.h b/qemu/console.h index 14b42f3..8306cc4 100644 --- a/qemu/console.h +++ b/qemu/console.h @@ -98,8 +98,6 @@ struct DisplayChangeListener { void (*dpy_resize)(struct DisplayState *s); void (*dpy_setdata)(struct DisplayState *s); void (*dpy_refresh)(struct DisplayState *s); - void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, - int dst_x, int dst_y, int w, int h); void (*dpy_fill)(struct DisplayState *s, int x, int y, int w, int h, uint32_t c); void (*dpy_text_cursor)(struct DisplayState *s, int x, int y); @@ -211,18 +209,6 @@ static inline void dpy_refresh(DisplayState *s) } } -static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y, - int dst_x, int dst_y, int w, int h) { - struct DisplayChangeListener *dcl = s->listeners; - while (dcl != NULL) { - if (dcl->dpy_copy) - dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h); - else /* TODO */ - dcl->dpy_update(s, dst_x, dst_y, w, h); - dcl = dcl->next; - } -} - static inline void dpy_fill(struct DisplayState *s, int x, int y, int w, int h, uint32_t c) { struct DisplayChangeListener *dcl = s->listeners; @@ -297,8 +283,6 @@ void text_consoles_set_display(DisplayState *ds); void console_select(unsigned int index); void console_color_init(DisplayState *ds); void qemu_console_resize(DisplayState *ds, int width, int height); -void qemu_console_copy(DisplayState *ds, int src_x, int src_y, - int dst_x, int dst_y, int w, int h); /* sdl.c */ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame, int opengl_enabled); diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index d4bb462..3f941d1 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -793,11 +793,6 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src) notify = 0; - /* we have to flush all pending changes so that the copy - is generated at the appropriate moment in time */ - if (notify) - vga_hw_update(); - (*s->cirrus_rop) (s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), s->vram_ptr + @@ -806,13 +801,13 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) s->cirrus_blt_width, s->cirrus_blt_height); if (notify) - qemu_console_copy(s->ds, - sx, sy, dx, dy, - s->cirrus_blt_width / depth, - s->cirrus_blt_height); + dpy_update(s->ds, + dx, dy, + s->cirrus_blt_width / depth, + s->cirrus_blt_height); /* we don't have to notify the display that this portion has - changed since qemu_console_copy implies this */ + changed since dpy_update implies this */ cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, s->cirrus_blt_dstpitch, s->cirrus_blt_width, diff --git a/qemu/hw/vmware_vga.c b/qemu/hw/vmware_vga.c index d1cba28..c38e43c 100644 --- a/qemu/hw/vmware_vga.c +++ b/qemu/hw/vmware_vga.c @@ -383,6 +383,7 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s, # ifdef DIRECT_VRAM if (s->ds->dpy_copy) +# error This configuration is not supported. See XSA-211. qemu_console_copy(s->ds, x0, y0, x1, y1, w, h); else # endif diff --git a/qemu/vnc.c b/qemu/vnc.c index 61d1555..0e61197 100644 --- a/qemu/vnc.c +++ b/qemu/vnc.c @@ -572,36 +572,6 @@ static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) send_framebuffer_update_raw(vs, x, y, w, h); } -static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h) -{ - VncState *vs = ds->opaque; - int updating_client = 1; - - if (!vs->update_requested || - src_x < vs->visible_x || src_y < vs->visible_y || - dst_x < vs->visible_x || dst_y < vs->visible_y || - (src_x + w) > (vs->visible_x + vs->visible_w) || - (src_y + h) > (vs->visible_y + vs->visible_h) || - (dst_x + w) > (vs->visible_x + vs->visible_w) || - (dst_y + h) > (vs->visible_y + vs->visible_h)) - updating_client = 0; - - if (updating_client) - _vnc_update_client(vs); - - if (updating_client && vs->csock != -1 && !vs->has_update) { - vnc_write_u8(vs, 0); /* msg id */ - vnc_write_u8(vs, 0); - vnc_write_u16(vs, 1); /* number of rects */ - vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1); - vnc_write_u16(vs, src_x); - vnc_write_u16(vs, src_y); - vnc_flush(vs); - vs->update_requested--; - } else - framebuffer_set_updated(vs, dst_x, dst_y, w, h); -} - static int find_update_height(VncState *vs, int y, int maxy, int last_x, int x) { int h; @@ -1543,16 +1513,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->has_pointer_type_change = 0; vs->has_WMVi = 0; vs->absolute = -1; - dcl->dpy_copy = NULL; for (i = n_encodings - 1; i >= 0; i--) { switch (encodings[i]) { case 0: /* Raw */ vs->has_hextile = 0; break; - case 1: /* CopyRect */ - dcl->dpy_copy = vnc_copy; - break; case 5: /* Hextile */ vs->has_hextile = 1; break; @@ -2459,7 +2425,6 @@ static void vnc_listen_read(void *opaque) vs->has_resize = 0; vs->has_hextile = 0; vs->update_requested = 0; - dcl->dpy_copy = NULL; vnc_timer_init(vs); } } -- 2.1.4 debian/patches/xsa132.patch0000664000000000000000000000152112524660657012675 0ustar domctl/sysctl: don't leak hypervisor stack to toolstacks This is XSA-132. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -884,7 +884,7 @@ long arch_do_domctl( case XEN_DOMCTL_gettscinfo: { - xen_guest_tsc_info_t info; + xen_guest_tsc_info_t info = { 0 }; ret = -EINVAL; if ( d == current->domain ) /* no domain_pause() */ --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -76,7 +76,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_SYSCTL_getdomaininfolist: { struct domain *d; - struct xen_domctl_getdomaininfo info; + struct xen_domctl_getdomaininfo info = { 0 }; u32 num_domains = 0; rcu_read_lock(&domlist_read_lock); debian/patches/xsa187-4.4-0002-x86-segment-Bounds-check-accesses-to-emulation-ctx.patch0000664000000000000000000001307412775471422025161 0ustar From: Andrew Cooper Subject: x86/segment: Bounds check accesses to emulation ctxt->seg_reg[] HVM HAP codepaths have space for all segment registers in the seg_reg[] cache (with x86_seg_none still risking an array overrun), while the shadow codepaths only have space for the user segments. Range check the input segment of *_get_seg_reg() against the size of the array used to cache the results, to avoid overruns in the case that the callers don't filter their input suitably. Subsume the is_x86_user_segment(seg) checks from the shadow code, which were an incomplete attempt at range checking, and are now superceeded. Make hvm_get_seg_reg() static, as it is not used outside of shadow/common.c No functional change, but far easier to reason that no overflow is possible. Reported-by: Andrew Cooper Signed-off-by: Andrew Cooper Acked-by: Tim Deegan Acked-by: Jan Beulich Index: xen-4.4.2/xen/arch/x86/hvm/emulate.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/hvm/emulate.c 2016-10-06 17:51:37.120009197 +0200 +++ xen-4.4.2/xen/arch/x86/hvm/emulate.c 2016-10-06 17:51:37.116009197 +0200 @@ -424,6 +424,8 @@ static int hvmemul_virtual_to_linear( *reps = min_t(unsigned long, *reps, 4096); reg = hvmemul_get_seg_reg(seg, hvmemul_ctxt); + if ( IS_ERR(reg) ) + return -PTR_ERR(reg); if ( (hvmemul_ctxt->ctxt.regs->eflags & X86_EFLAGS_DF) && (*reps > 1) ) { @@ -908,6 +910,10 @@ static int hvmemul_read_segment( struct hvm_emulate_ctxt *hvmemul_ctxt = container_of(ctxt, struct hvm_emulate_ctxt, ctxt); struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt); + + if ( IS_ERR(sreg) ) + return -PTR_ERR(sreg); + memcpy(reg, sreg, sizeof(struct segment_register)); return X86EMUL_OKAY; } @@ -921,6 +927,9 @@ static int hvmemul_write_segment( container_of(ctxt, struct hvm_emulate_ctxt, ctxt); struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt); + if ( IS_ERR(sreg) ) + return -PTR_ERR(sreg); + memcpy(sreg, reg, sizeof(struct segment_register)); __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty); @@ -1284,10 +1293,17 @@ void hvm_emulate_writeback( } } +/* + * Callers which pass a known in-range x86_segment can rely on the return + * pointer being valid. Other callers must explicitly check for errors. + */ struct segment_register *hvmemul_get_seg_reg( enum x86_segment seg, struct hvm_emulate_ctxt *hvmemul_ctxt) { + if ( seg < 0 || seg >= ARRAY_SIZE(hvmemul_ctxt->seg_reg) ) + return ERR_PTR(-X86EMUL_UNHANDLEABLE); + if ( !__test_and_set_bit(seg, &hvmemul_ctxt->seg_reg_accessed) ) hvm_get_segment_register(current, seg, &hvmemul_ctxt->seg_reg[seg]); return &hvmemul_ctxt->seg_reg[seg]; Index: xen-4.4.2/xen/arch/x86/mm/shadow/common.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm/shadow/common.c 2016-10-06 17:51:37.120009197 +0200 +++ xen-4.4.2/xen/arch/x86/mm/shadow/common.c 2016-10-06 17:51:37.116009197 +0200 @@ -120,10 +120,19 @@ __initcall(shadow_audit_key_init); /* x86 emulator support for the shadow code */ +/* + * Callers which pass a known in-range x86_segment can rely on the return + * pointer being valid. Other callers must explicitly check for errors. + */ struct segment_register *hvm_get_seg_reg( enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt) { - struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg]; + struct segment_register *seg_reg; + + if ( seg < 0 || seg >= ARRAY_SIZE(sh_ctxt->seg_reg) ) + return ERR_PTR(-X86EMUL_UNHANDLEABLE); + + seg_reg = &sh_ctxt->seg_reg[seg]; if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) ) hvm_get_segment_register(current, seg, seg_reg); return seg_reg; @@ -140,14 +149,9 @@ static int hvm_translate_linear_addr( struct segment_register *reg; int okay; - /* - * Can arrive here with non-user segments. However, no such cirucmstance - * is part of a legitimate pagetable update, so fail the emulation. - */ - if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; - reg = hvm_get_seg_reg(seg, sh_ctxt); + if ( IS_ERR(reg) ) + return -PTR_ERR(reg); okay = hvm_virtual_to_linear_addr( seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr); @@ -249,9 +253,6 @@ hvm_emulate_write(enum x86_segment seg, unsigned long addr; int rc; - if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; - /* How many emulations could we save if we unshadowed on stack writes? */ if ( seg == x86_seg_ss ) perfc_incr(shadow_fault_emulate_stack); @@ -279,9 +280,6 @@ hvm_emulate_cmpxchg(enum x86_segment seg unsigned long addr, old[2], new[2]; int rc; - if ( !is_x86_user_segment(seg) ) - return X86EMUL_UNHANDLEABLE; - rc = hvm_translate_linear_addr( seg, offset, bytes, hvm_access_write, sh_ctxt, &addr); if ( rc ) Index: xen-4.4.2/xen/include/asm-x86/hvm/emulate.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-x86/hvm/emulate.h 2016-10-06 17:51:37.120009197 +0200 +++ xen-4.4.2/xen/include/asm-x86/hvm/emulate.h 2016-10-06 17:51:37.116009197 +0200 @@ -13,6 +13,7 @@ #define __ASM_X86_HVM_EMULATE_H__ #include +#include #include struct hvm_emulate_ctxt { debian/patches/xsa179-qemut-4.4-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch0000664000000000000000000000605212725551547026722 0ustar From 0b0cf8110e97b0cbd0da73d11163e26978822757 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 26 Apr 2016 14:48:06 +0200 Subject: [PATCH 5/5] vga: make sure vga register setup for vbe stays intact (CVE-2016-3712). Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT registers, to make sure the vga registers will always have the values needed by vbe mode. This makes sure the sanity checks applied by vbe_fixup_regs() are effective. Without this guests can muck with shift_control, can turn on planar vga modes or text mode emulation while VBE is active, making qemu take code paths meant for CGA compatibility, but with the very large display widths and heigts settable using VBE registers. Which is good for one or another buffer overflow. Not that critical as they typically read overflows happening somewhere in the display code. So guests can DoS by crashing qemu with a segfault, but it is probably not possible to break out of the VM. Fixes: CVE-2016-3712 Reported-by: Zuozhi Fzz Reported-by: P J P Signed-off-by: Gerd Hoffmann [Backport to qemu-xen-tradition] Signed-off-by: Andrew Cooper --- hw/vga.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c index b1b501b..5778c7d 100644 --- a/qemu/hw/vga.c +++ b/qemu/hw/vga.c @@ -160,6 +160,8 @@ static uint32_t expand4[256]; static uint16_t expand2[256]; static uint8_t expand4to8[16]; +static void vbe_update_vgaregs(VGAState *s); + static inline bool vbe_enabled(VGAState *s) { return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; @@ -449,6 +451,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); #endif s->sr[s->sr_index] = val & sr_mask[s->sr_index]; + vbe_update_vgaregs(s); if (s->sr_index == 1) s->update_retrace_info(s); break; case 0x3c7: @@ -477,6 +480,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); #endif s->gr[s->gr_index] = val & gr_mask[s->gr_index]; + vbe_update_vgaregs(s); break; case 0x3b4: case 0x3d4: @@ -490,8 +494,10 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) /* handle CR0-7 protection */ if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) { /* can always write bit 4 of CR7 */ - if (s->cr_index == 7) + if (s->cr_index == 7) { s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10); + vbe_update_vgaregs(s); + } return; } switch(s->cr_index) { @@ -507,6 +513,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) s->cr[s->cr_index] = val; break; } + vbe_update_vgaregs(s); switch(s->cr_index) { case 0x00: -- 2.1.4 debian/patches/tools-include-install.diff0000664000000000000000000000176712430112537015707 0ustar Index: xen-4.4.1/tools/include/Makefile =================================================================== --- xen-4.4.1.orig/tools/include/Makefile 2014-11-10 11:36:48.588116597 +0100 +++ xen-4.4.1/tools/include/Makefile 2014-11-10 11:36:48.584116597 +0100 @@ -11,7 +11,6 @@ xen-foreign: xen/.dir: @rm -rf xen mkdir -p xen/libelf - ln -sf $(XEN_ROOT)/xen/include/public/COPYING xen ln -sf $(wildcard $(XEN_ROOT)/xen/include/public/*.h) xen ln -sf $(addprefix $(XEN_ROOT)/xen/include/public/,arch-x86 arch-arm hvm io xsm) xen ln -sf ../xen-sys/$(XEN_OS) xen/sys @@ -30,7 +29,6 @@ install: all $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/io $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/sys $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xen/xsm - $(INSTALL_DATA) xen/COPYING $(DESTDIR)$(INCLUDEDIR)/xen $(INSTALL_DATA) xen/*.h $(DESTDIR)$(INCLUDEDIR)/xen $(INSTALL_DATA) xen/arch-x86/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86 $(INSTALL_DATA) xen/arch-x86/hvm/*.h $(DESTDIR)$(INCLUDEDIR)/xen/arch-x86/hvm debian/patches/xsa166-4.4.patch0000664000000000000000000000356412633765672013224 0ustar x86/HVM: avoid reading ioreq state more than once Otherwise, especially when the compiler chooses to translate the switch() to a jump table, unpredictable behavior (and in the jump table case arbitrary code execution) can result. This is XSA-166. Signed-off-by: Jan Beulich Acked-by: Ian Campbell Index: xen-4.4.2/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/hvm/hvm.c 2015-12-10 15:20:13.930495756 +0100 +++ xen-4.4.2/xen/arch/x86/hvm/hvm.c 2015-12-10 15:20:13.926495756 +0100 @@ -348,6 +348,7 @@ void hvm_migrate_pirqs(struct vcpu *v) void hvm_do_resume(struct vcpu *v) { ioreq_t *p; + unsigned int state; check_wakeup_from_wait(); @@ -358,9 +359,10 @@ void hvm_do_resume(struct vcpu *v) if ( !(p = get_ioreq(v)) ) goto check_inject_trap; - while ( p->state != STATE_IOREQ_NONE ) + while ( (state = p->state) != STATE_IOREQ_NONE ) { - switch ( p->state ) + rmb(); + switch ( state ) { case STATE_IORESP_READY: /* IORESP_READY -> NONE */ hvm_io_assist(p); @@ -368,11 +370,10 @@ void hvm_do_resume(struct vcpu *v) case STATE_IOREQ_READY: /* IOREQ_{READY,INPROCESS} -> IORESP_READY */ case STATE_IOREQ_INPROCESS: wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port, - (p->state != STATE_IOREQ_READY) && - (p->state != STATE_IOREQ_INPROCESS)); + p->state != state); break; default: - gdprintk(XENLOG_ERR, "Weird HVM iorequest state %d.\n", p->state); + gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state); domain_crash(v->domain); return; /* bail */ } debian/patches/xsa242-4.9.patch0000664000000000000000000000266313167430257013212 0ustar From: Jan Beulich Subject: x86: don't allow page_unlock() to drop the last type reference Only _put_page_type() does the necessary cleanup, and hence not all domain pages can be released during guest cleanup (leaving around zombie domains) if we get this wrong. This is XSA-242. Signed-off-by: Jan Beulich --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1923,7 +1923,11 @@ void page_unlock(struct page_info *page) do { x = y; + ASSERT((x & PGT_count_mask) && (x & PGT_locked)); + nx = x - (1 | PGT_locked); + /* We must not drop the last reference here. */ + ASSERT(nx & PGT_count_mask); } while ( (y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x ); } @@ -2611,6 +2615,17 @@ static int _put_page_type(struct page_in (page->count_info & PGC_page_table)) ) page_set_tlbflush_timestamp(page); } + else if ( unlikely((nx & (PGT_locked | PGT_count_mask)) == + (PGT_locked | 1)) ) + { + /* + * We must not drop the second to last reference when the page is + * locked, as page_unlock() doesn't do any cleanup of the type. + */ + cpu_relax(); + y = page->u.inuse.type_info; + continue; + } if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) break; debian/patches/xsa226-4.5-0001-gnttab-dont-use-possibly-unbounded-tail-calls.patch0000664000000000000000000000765513147037555024455 0ustar From: Jan Beulich Subject: gnttab: don't use possibly unbounded tail calls There is no guarantee that the compiler would actually translate them to branches instead of calls, so only ones with a known recursion limit are okay: - __release_grant_for_copy() can call itself only once, as __acquire_grant_for_copy() won't permit use of multi-level transitive grants, - __acquire_grant_for_copy() is fine to call itself with the last argument false, as that prevents further recursion, - __acquire_grant_for_copy() must not call itself to recover from an observed change to the active entry's pin count This is part of CVE-2017-12135 / XSA-226. Signed-off-by: Jan Beulich --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1860,8 +1860,10 @@ __release_grant_for_copy( if ( td != rd ) { - /* Recursive calls, but they're tail calls, so it's - okay. */ + /* + * Recursive calls, but they're bounded (acquire permits only a single + * level of transitivity), so it's okay. + */ if ( released_write ) __release_grant_for_copy(td, trans_gref, 0); else if ( released_read ) @@ -1997,19 +1999,19 @@ __acquire_grant_for_copy( return rc; } - /* We dropped the lock, so we have to check that nobody - else tried to pin (or, for that matter, unpin) the - reference in *this* domain. If they did, just give up - and try again. */ + /* + * We dropped the lock, so we have to check that nobody else tried + * to pin (or, for that matter, unpin) the reference in *this* + * domain. If they did, just give up and tell the caller to retry. + */ if ( act->pin != old_pin ) { __fixup_status_for_copy_pin(act, status); rcu_unlock_domain(td); spin_unlock(&rgt->lock); put_page(*page); - return __acquire_grant_for_copy(rd, gref, ldom, readonly, - frame, page, page_off, length, - allow_transitive); + *page = NULL; + return ERESTART; } /* The actual remote remote grant may or may not be a @@ -2089,7 +2091,7 @@ __acquire_grant_for_copy( return rc; } -static void +static bool_t __gnttab_copy( struct gnttab_copy *op) { @@ -2213,9 +2215,20 @@ __gnttab_copy( rcu_unlock_domain(sd); if ( dd ) rcu_unlock_domain(dd); + if ( rc > 0 ) + return 0; op->status = rc; + return 1; } +/* + * gnttab_copy(), other than the various other helpers of + * do_grant_table_op(), returns (besides possible error indicators) + * "count - i" rather than "i" to ensure that even if no progress + * was made at all (perhaps due to gnttab_copy_one() returning a + * positive value) a non-zero value is being handed back (zero needs + * to be avoided, as that means "success, all done"). + */ static long gnttab_copy( XEN_GUEST_HANDLE_PARAM(gnttab_copy_t) uop, unsigned int count) @@ -2226,10 +2239,11 @@ gnttab_copy( for ( i = 0; i < count; i++ ) { if (i && hypercall_preempt_check()) - return i; + return count - i; if ( unlikely(__copy_from_guest(&op, uop, 1)) ) return -EFAULT; - __gnttab_copy(&op); + if ( !__gnttab_copy(&op) ) + return count - i; if ( unlikely(__copy_field_to_guest(uop, &op, status)) ) return -EFAULT; guest_handle_add_offset(uop, 1); @@ -2727,6 +2741,7 @@ do_grant_table_op( rc = gnttab_copy(copy, count); if ( rc > 0 ) { + rc = count - rc; guest_handle_add_offset(copy, rc); uop = guest_handle_cast(copy, void); } debian/patches/xsa165-4.5.patch0000664000000000000000000000437412631300106013173 0ustar x86: don't leak ST(n)/XMMn values to domains first using them FNINIT doesn't alter these registers, and hence using it is insufficient to initialize a guest's initial state. This is XSA-165. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -798,6 +798,17 @@ int arch_set_info_guest( if ( v->arch.xsave_area ) v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE; } + else if ( v->arch.xsave_area ) + memset(&v->arch.xsave_area->xsave_hdr, 0, + sizeof(v->arch.xsave_area->xsave_hdr)); + else + { + typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt; + + memset(fpu_sse, 0, sizeof(*fpu_sse)); + fpu_sse->fcw = FCW_DEFAULT; + fpu_sse->mxcsr = MXCSR_DEFAULT; + } if ( !compat ) { --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -17,19 +17,6 @@ #include #include -static void fpu_init(void) -{ - unsigned long val; - - asm volatile ( "fninit" ); - if ( cpu_has_xmm ) - { - /* load default value into MXCSR control/status register */ - val = MXCSR_DEFAULT; - asm volatile ( "ldmxcsr %0" : : "m" (val) ); - } -} - /*******************************/ /* FPU Restore Functions */ /*******************************/ @@ -248,15 +235,8 @@ void vcpu_restore_fpu_lazy(struct vcpu * if ( cpu_has_xsave ) fpu_xrstor(v, XSTATE_LAZY); - else if ( v->fpu_initialised ) - { - if ( cpu_has_fxsr ) - fpu_fxrstor(v); - else - fpu_frstor(v); - } else - fpu_init(); + fpu_fxrstor(v); v->fpu_initialised = 1; v->fpu_dirtied = 1; @@ -317,7 +297,14 @@ int vcpu_init_fpu(struct vcpu *v) else { v->arch.fpu_ctxt = _xzalloc(sizeof(v->arch.xsave_area->fpu_sse), 16); - if ( !v->arch.fpu_ctxt ) + if ( v->arch.fpu_ctxt ) + { + typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt; + + fpu_sse->fcw = FCW_DEFAULT; + fpu_sse->mxcsr = MXCSR_DEFAULT; + } + else { rc = -ENOMEM; goto done; debian/patches/xsa206-4.4-0014-oxenstored-move-functions-that-process-simple-operat.patch0000664000000000000000000002504513104300260026076 0ustar From c8a7bd3fff923dd7747a45aa5f5b3222921f9728 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:53:03 +0000 Subject: [PATCH 14/30] oxenstored: move functions that process simple operations Separate the functions which process operations that can be done as part of a transaction. Specifically, these operations are: read, write, rm, getperms, setperms, getdomainpath, directory, mkdir. Also split function_of_type into two functions: one for processing the simple operations and one for processing the rest. This will help allow replay of transactions, allowing us to invoke the functions that process the simple operations as part of the processing of transaction_end. Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott Backporting to 4.5: - Removed references to Reset_watches, which was introduced in 4.6. Reported-by: Juergen Gross Signed-off-by: George Dunlap --- tools/ocaml/xenstored/process.ml | 220 +++++++++++++++++++++------------------ 1 file changed, 119 insertions(+), 101 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 34fb66c..77660bd 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -119,94 +119,6 @@ let do_getperms con t domains cons data = let perms = Transaction.getperms t (Connection.get_perm con) path in Perms.Node.to_string perms ^ "\000" -let do_watch con t domains cons data = - let (node, token) = - match (split None '\000' data) with - | [node; token; ""] -> node, token - | _ -> raise Invalid_Cmd_Args - in - let watch = Connections.add_watch cons con node token in - Packet.Ack (fun () -> Connection.fire_single_watch watch) - -let do_unwatch con t domains cons data = - let (node, token) = - match (split None '\000' data) with - | [node; token; ""] -> node, token - | _ -> raise Invalid_Cmd_Args - in - Connections.del_watch cons con node token - -let do_transaction_start con t domains cons data = - if Transaction.get_id t <> Transaction.none then - raise Transaction_nested; - let store = Transaction.get_store t in - string_of_int (Connection.start_transaction con store) ^ "\000" - -let do_transaction_end con t domains cons data = - let commit = - match (split None '\000' data) with - | "T" :: _ -> true - | "F" :: _ -> false - | x :: _ -> raise (Invalid_argument x) - | _ -> raise Invalid_Cmd_Args - in - let success = - Connection.end_transaction con (Transaction.get_id t) commit in - if not success then - raise Transaction_again; - if commit then - process_watch (List.rev (Transaction.get_paths t)) cons - -let do_introduce con t domains cons data = - if not (Connection.is_dom0 con) - then raise Define.Permission_denied; - let (domid, mfn, port) = - match (split None '\000' data) with - | domid :: mfn :: port :: _ -> - int_of_string domid, Nativeint.of_string mfn, int_of_string port - | _ -> raise Invalid_Cmd_Args; - in - let dom = - if Domains.exist domains domid then - Domains.find domains domid - else try - let ndom = Xenctrl.with_intf (fun xc -> - Domains.create xc domains domid mfn port) in - Connections.add_domain cons ndom; - Connections.fire_spec_watches cons "@introduceDomain"; - ndom - with _ -> raise Invalid_Cmd_Args - in - if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then - raise Domain_not_match - -let do_release con t domains cons data = - if not (Connection.is_dom0 con) - then raise Define.Permission_denied; - let domid = - match (split None '\000' data) with - | [domid;""] -> int_of_string domid - | _ -> raise Invalid_Cmd_Args - in - let fire_spec_watches = Domains.exist domains domid in - Domains.del domains domid; - Connections.del_domain cons domid; - if fire_spec_watches - then Connections.fire_spec_watches cons "@releaseDomain" - else raise Invalid_Cmd_Args - -let do_resume con t domains cons data = - if not (Connection.is_dom0 con) - then raise Define.Permission_denied; - let domid = - match (split None '\000' data) with - | domid :: _ -> int_of_string domid - | _ -> raise Invalid_Cmd_Args - in - if Domains.exist domains domid - then Domains.resume domains domid - else raise Invalid_Cmd_Args - let do_getdomainpath con t domains cons data = let domid = match (split None '\000' data) with @@ -314,28 +226,30 @@ let reply_none fct con t doms cons data = (* let the function reply *) fct con t doms cons data -let function_of_type ty = +(* Functions for 'simple' operations that cannot be part of a transaction *) +let function_of_type_simple_op ty = match ty with - | Xenbus.Xb.Op.Debug -> reply_data_or_ack do_debug + | Xenbus.Xb.Op.Debug + | Xenbus.Xb.Op.Watch + | Xenbus.Xb.Op.Unwatch + | Xenbus.Xb.Op.Transaction_start + | Xenbus.Xb.Op.Transaction_end + | Xenbus.Xb.Op.Introduce + | Xenbus.Xb.Op.Release + | Xenbus.Xb.Op.Isintroduced + | Xenbus.Xb.Op.Resume + | Xenbus.Xb.Op.Set_target + | Xenbus.Xb.Op.Restrict + | Xenbus.Xb.Op.Invalid -> error "called function_of_type_simple_op on operation %s" (Xenbus.Xb.Op.to_string ty); + raise (Invalid_argument (Xenbus.Xb.Op.to_string ty)) | Xenbus.Xb.Op.Directory -> reply_data do_directory | Xenbus.Xb.Op.Read -> reply_data do_read | Xenbus.Xb.Op.Getperms -> reply_data do_getperms - | Xenbus.Xb.Op.Watch -> reply_none do_watch - | Xenbus.Xb.Op.Unwatch -> reply_ack do_unwatch - | Xenbus.Xb.Op.Transaction_start -> reply_data do_transaction_start - | Xenbus.Xb.Op.Transaction_end -> reply_ack do_transaction_end - | Xenbus.Xb.Op.Introduce -> reply_ack do_introduce - | Xenbus.Xb.Op.Release -> reply_ack do_release | Xenbus.Xb.Op.Getdomainpath -> reply_data do_getdomainpath | Xenbus.Xb.Op.Write -> reply_ack do_write | Xenbus.Xb.Op.Mkdir -> reply_ack do_mkdir | Xenbus.Xb.Op.Rm -> reply_ack do_rm | Xenbus.Xb.Op.Setperms -> reply_ack do_setperms - | Xenbus.Xb.Op.Isintroduced -> reply_data do_isintroduced - | Xenbus.Xb.Op.Resume -> reply_ack do_resume - | Xenbus.Xb.Op.Set_target -> reply_ack do_set_target - | Xenbus.Xb.Op.Restrict -> reply_ack do_restrict - | Xenbus.Xb.Op.Invalid -> reply_ack do_error | _ -> reply_ack do_error let input_handle_error ~cons ~doms ~fct ~con ~t ~req = @@ -361,6 +275,110 @@ let input_handle_error ~cons ~doms ~fct ~con ~t ~req = | (Failure "int_of_string") -> reply_error "EINVAL" | Define.Unknown_operation -> reply_error "ENOSYS" +let do_watch con t domains cons data = + let (node, token) = + match (split None '\000' data) with + | [node; token; ""] -> node, token + | _ -> raise Invalid_Cmd_Args + in + let watch = Connections.add_watch cons con node token in + Packet.Ack (fun () -> Connection.fire_single_watch watch) + +let do_unwatch con t domains cons data = + let (node, token) = + match (split None '\000' data) with + | [node; token; ""] -> node, token + | _ -> raise Invalid_Cmd_Args + in + Connections.del_watch cons con node token + +let do_transaction_start con t domains cons data = + if Transaction.get_id t <> Transaction.none then + raise Transaction_nested; + let store = Transaction.get_store t in + string_of_int (Connection.start_transaction con store) ^ "\000" + +let do_transaction_end con t domains cons data = + let commit = + match (split None '\000' data) with + | "T" :: _ -> true + | "F" :: _ -> false + | x :: _ -> raise (Invalid_argument x) + | _ -> raise Invalid_Cmd_Args + in + let success = + Connection.end_transaction con (Transaction.get_id t) commit in + if not success then + raise Transaction_again; + if commit then + process_watch (List.rev (Transaction.get_paths t)) cons + +let do_introduce con t domains cons data = + if not (Connection.is_dom0 con) + then raise Define.Permission_denied; + let (domid, mfn, port) = + match (split None '\000' data) with + | domid :: mfn :: port :: _ -> + int_of_string domid, Nativeint.of_string mfn, int_of_string port + | _ -> raise Invalid_Cmd_Args; + in + let dom = + if Domains.exist domains domid then + Domains.find domains domid + else try + let ndom = Xenctrl.with_intf (fun xc -> + Domains.create xc domains domid mfn port) in + Connections.add_domain cons ndom; + Connections.fire_spec_watches cons "@introduceDomain"; + ndom + with _ -> raise Invalid_Cmd_Args + in + if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then + raise Domain_not_match + +let do_release con t domains cons data = + if not (Connection.is_dom0 con) + then raise Define.Permission_denied; + let domid = + match (split None '\000' data) with + | [domid;""] -> int_of_string domid + | _ -> raise Invalid_Cmd_Args + in + let fire_spec_watches = Domains.exist domains domid in + Domains.del domains domid; + Connections.del_domain cons domid; + if fire_spec_watches + then Connections.fire_spec_watches cons "@releaseDomain" + else raise Invalid_Cmd_Args + +let do_resume con t domains cons data = + if not (Connection.is_dom0 con) + then raise Define.Permission_denied; + let domid = + match (split None '\000' data) with + | domid :: _ -> int_of_string domid + | _ -> raise Invalid_Cmd_Args + in + if Domains.exist domains domid + then Domains.resume domains domid + else raise Invalid_Cmd_Args + +let function_of_type ty = + match ty with + | Xenbus.Xb.Op.Debug -> reply_data_or_ack do_debug + | Xenbus.Xb.Op.Watch -> reply_none do_watch + | Xenbus.Xb.Op.Unwatch -> reply_ack do_unwatch + | Xenbus.Xb.Op.Transaction_start -> reply_data do_transaction_start + | Xenbus.Xb.Op.Transaction_end -> reply_ack do_transaction_end + | Xenbus.Xb.Op.Introduce -> reply_ack do_introduce + | Xenbus.Xb.Op.Release -> reply_ack do_release + | Xenbus.Xb.Op.Isintroduced -> reply_data do_isintroduced + | Xenbus.Xb.Op.Resume -> reply_ack do_resume + | Xenbus.Xb.Op.Set_target -> reply_ack do_set_target + | Xenbus.Xb.Op.Restrict -> reply_ack do_restrict + | Xenbus.Xb.Op.Invalid -> reply_ack do_error + | _ -> function_of_type_simple_op ty + (** * Nothrow guarantee. *) -- 2.1.4 debian/patches/xsa130-qemut.patch0000664000000000000000000000105312571017423014011 0ustar xen/MSI-X: disable logging by default ... to avoid allowing the guest to cause the control domain's disk to fill. This is XSA-130. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -27,7 +27,7 @@ #include "qemu-timer.h" /* Log acesss */ -#define PT_LOGGING_ENABLED +/* #define PT_LOGGING_ENABLED */ /* Print errors even if logging is disabled */ #define PT_ERR(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a) debian/patches/xsa138-qemut-2.patch0000664000000000000000000000406412571017654014173 0ustar From 1ac0f60d558b7fca55c69a61ab4c4538af1f02f9 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 3 Jun 2015 14:41:27 +0200 Subject: [PATCH 2/2] ide: Clear DRQ after handling all expected accesses This is additional hardening against an end_transfer_func that fails to clear the DRQ status bit. The bit must be unset as soon as the PIO transfer has completed, so it's better to do this in a central place instead of duplicating the code in all commands (and forgetting it in some). Signed-off-by: Kevin Wolf --- hw/ide.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/hw/ide.c b/hw/ide.c index 211ec88..7b84d1b 100644 --- a/qemu/hw/ide.c +++ b/qemu/hw/ide.c @@ -3009,8 +3009,10 @@ static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) *(uint16_t *)p = le16_to_cpu(val); p += 2; s->data_ptr = p; - if (p >= s->data_end) + if (p >= s->data_end) { + s->status &= ~DRQ_STAT; s->end_transfer_func(s); + } } static uint32_t ide_data_readw(void *opaque, uint32_t addr) @@ -3032,8 +3034,10 @@ static uint32_t ide_data_readw(void *opaque, uint32_t addr) ret = cpu_to_le16(*(uint16_t *)p); p += 2; s->data_ptr = p; - if (p >= s->data_end) + if (p >= s->data_end) { + s->status &= ~DRQ_STAT; s->end_transfer_func(s); + } return ret; } @@ -3055,8 +3059,10 @@ static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) *(uint32_t *)p = le32_to_cpu(val); p += 4; s->data_ptr = p; - if (p >= s->data_end) + if (p >= s->data_end) { + s->status &= ~DRQ_STAT; s->end_transfer_func(s); + } } static uint32_t ide_data_readl(void *opaque, uint32_t addr) @@ -3078,8 +3084,10 @@ static uint32_t ide_data_readl(void *opaque, uint32_t addr) ret = cpu_to_le32(*(uint32_t *)p); p += 4; s->data_ptr = p; - if (p >= s->data_end) + if (p >= s->data_end) { + s->status &= ~DRQ_STAT; s->end_transfer_func(s); + } return ret; } -- 2.1.4 debian/patches/xsa175-4.4-0008-libxl-Do-not-trust-frontend-for-vtpm-in-getinfo.patch0000664000000000000000000000406412725264607024646 0ustar From 593d796c753fea1c4cdc365273de777aff798fe9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 16:00:20 +0100 Subject: [PATCH 08/10] libxl: Do not trust frontend for vtpm in getinfo libxl_device_vtpm_getinfo needs to examine devices without trusting frontend-controlled data. So: * Use /libxl to find the backend path. * Parse the backend path to find the backend domid, rather than reading it from the frontend. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 0886d92..a0aeb50 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1928,7 +1928,7 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, libxl_vtpminfo *vtpminfo) { GC_INIT(ctx); - char *dompath, *vtpmpath; + char *libxl_path, *dompath, *vtpmpath; char *val; int rc = 0; @@ -1937,8 +1937,10 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, vtpminfo->devid = vtpm->devid; vtpmpath = GCSPRINTF("%s/device/vtpm/%d", dompath, vtpminfo->devid); + libxl_path = GCSPRINTF("%s/device/vtpm/%d", + libxl__xs_libxl_path(gc, domid), vtpminfo->devid); vtpminfo->backend = xs_read(ctx->xsh, XBT_NULL, - GCSPRINTF("%s/backend", vtpmpath), NULL); + GCSPRINTF("%s/backend", libxl_path), NULL); if (!vtpminfo->backend) { goto err; } @@ -1946,9 +1948,9 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, goto err; } - val = libxl__xs_read(gc, XBT_NULL, - GCSPRINTF("%s/backend-id", vtpmpath)); - vtpminfo->backend_id = val ? strtoul(val, NULL, 10) : -1; + rc = libxl__backendpath_parse_domid(gc, vtpminfo->backend, + &vtpminfo->backend_id); + if (rc) goto exit; val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", vtpmpath)); -- 2.1.4 debian/patches/xsa178-xen4.4-0014-libxl-Cleanup-use-libxl__backendpath_parse_domid-in-.patch0000664000000000000000000000240012725543547026416 0ustar From 8ce712fc84bc9054424a60bc7600dd3163f0fc1d Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 16:08:19 +0100 Subject: [PATCH 15/16] libxl: Cleanup: use libxl__backendpath_parse_domid in libxl__device_disk_from_xs_be Rather than an open-coded sscanf. No functional change with correct input. This is a followup to XSA-175 and XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 88c85d6..30b6878 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2293,10 +2293,10 @@ static int libxl__device_disk_from_xenstore(libxl__gc *gc, goto out; } - rc = sscanf(backend_path, "/local/domain/%d/", &disk->backend_domid); - if (rc != 1) { + rc = libxl__backendpath_parse_domid(gc, backend_path, &disk->backend_domid); + if (rc) { LOG(ERROR, "Unable to fetch device backend domid from %s", backend_path); - goto cleanup; + goto out; } /* "params" may not be present; but everything else must be. */ -- 1.9.1 debian/patches/xsa150.patch0000664000000000000000000001515712616222115012670 0ustar x86/PoD: Eager sweep for zeroed pages Based on the contents of a guests physical address space, p2m_pod_emergency_sweep() could degrade into a linear memcmp() from 0 to max_gfn, which runs non-preemptibly. As p2m_pod_emergency_sweep() runs behind the scenes in a number of contexts, making it preemptible is not feasible. Instead, a different approach is taken. Recently-populated pages are eagerly checked for reclaimation, which amortises the p2m_pod_emergency_sweep() operation across each p2m_pod_demand_populate() operation. Note that in the case that a 2M superpage can't be reclaimed as a superpage, it is shattered if 4K pages of zeros can be reclaimed. This is unfortunate but matches the previous behaviour, and is required to avoid regressions (domain crash from PoD exhaustion) with VMs configured close to the limit. This is CVE-2015-7970 / XSA-150. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Reviewed-by: George Dunlap --- a/xen/arch/x86/mm/p2m-pod.c +++ b/xen/arch/x86/mm/p2m-pod.c @@ -920,28 +920,6 @@ p2m_pod_zero_check(struct p2m_domain *p2 } #define POD_SWEEP_LIMIT 1024 - -/* When populating a new superpage, look at recently populated superpages - * hoping that they've been zeroed. This will snap up zeroed pages as soon as - * the guest OS is done with them. */ -static void -p2m_pod_check_last_super(struct p2m_domain *p2m, unsigned long gfn_aligned) -{ - unsigned long check_gfn; - - ASSERT(p2m->pod.last_populated_index < POD_HISTORY_MAX); - - check_gfn = p2m->pod.last_populated[p2m->pod.last_populated_index]; - - p2m->pod.last_populated[p2m->pod.last_populated_index] = gfn_aligned; - - p2m->pod.last_populated_index = - ( p2m->pod.last_populated_index + 1 ) % POD_HISTORY_MAX; - - p2m_pod_zero_check_superpage(p2m, check_gfn); -} - - #define POD_SWEEP_STRIDE 16 static void p2m_pod_emergency_sweep(struct p2m_domain *p2m) @@ -982,7 +960,7 @@ p2m_pod_emergency_sweep(struct p2m_domai * NB that this is a zero-sum game; we're increasing our cache size * by re-increasing our 'debt'. Since we hold the pod lock, * (entry_count - count) must remain the same. */ - if ( p2m->pod.count > 0 && i < limit ) + if ( i < limit && (p2m->pod.count > 0 || hypercall_preempt_check()) ) break; } @@ -994,6 +972,58 @@ p2m_pod_emergency_sweep(struct p2m_domai } +static void pod_eager_reclaim(struct p2m_domain *p2m) +{ + struct pod_mrp_list *mrp = &p2m->pod.mrp; + unsigned int i = 0; + + /* + * Always check one page for reclaimation. + * + * If the PoD pool is empty, keep checking some space is found, or all + * entries have been exhaused. + */ + do + { + unsigned int idx = (mrp->idx + i++) % ARRAY_SIZE(mrp->list); + unsigned long gfn = mrp->list[idx]; + + if ( gfn != INVALID_GFN ) + { + if ( gfn & POD_LAST_SUPERPAGE ) + { + gfn &= ~POD_LAST_SUPERPAGE; + + if ( p2m_pod_zero_check_superpage(p2m, gfn) == 0 ) + { + unsigned int x; + + for ( x = 0; x < SUPERPAGE_PAGES; ++x, ++gfn ) + p2m_pod_zero_check(p2m, &gfn, 1); + } + } + else + p2m_pod_zero_check(p2m, &gfn, 1); + + mrp->list[idx] = INVALID_GFN; + } + + } while ( (p2m->pod.count == 0) && (i < ARRAY_SIZE(mrp->list)) ); +} + +static void pod_eager_record(struct p2m_domain *p2m, + unsigned long gfn, unsigned int order) +{ + struct pod_mrp_list *mrp = &p2m->pod.mrp; + + ASSERT(mrp->list[mrp->idx] == INVALID_GFN); + ASSERT(gfn != INVALID_GFN); + + mrp->list[mrp->idx++] = + gfn | (order == PAGE_ORDER_2M ? POD_LAST_SUPERPAGE : 0); + mrp->idx %= ARRAY_SIZE(mrp->list); +} + int p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn, unsigned int order, @@ -1034,6 +1064,8 @@ p2m_pod_demand_populate(struct p2m_domai return 0; } + pod_eager_reclaim(p2m); + /* Only sweep if we're actually out of memory. Doing anything else * causes unnecessary time and fragmentation of superpages in the p2m. */ if ( p2m->pod.count == 0 ) @@ -1070,6 +1102,8 @@ p2m_pod_demand_populate(struct p2m_domai p2m->pod.entry_count -= (1 << order); BUG_ON(p2m->pod.entry_count < 0); + pod_eager_record(p2m, gfn_aligned, order); + if ( tb_init_done ) { struct { @@ -1085,12 +1119,6 @@ p2m_pod_demand_populate(struct p2m_domai __trace_var(TRC_MEM_POD_POPULATE, 0, sizeof(t), &t); } - /* Check the last guest demand-populate */ - if ( p2m->pod.entry_count > p2m->pod.count - && (order == PAGE_ORDER_2M) - && (q & P2M_ALLOC) ) - p2m_pod_check_last_super(p2m, gfn_aligned); - pod_unlock(p2m); return 0; out_of_memory: --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -58,6 +58,7 @@ boolean_param("hap_2mb", opt_hap_2mb); /* Init the datastructures for later use by the p2m code */ static int p2m_initialise(struct domain *d, struct p2m_domain *p2m) { + unsigned int i; int ret = 0; mm_rwlock_init(&p2m->lock); @@ -73,6 +74,9 @@ static int p2m_initialise(struct domain p2m->np2m_base = P2M_BASE_EADDR; + for ( i = 0; i < ARRAY_SIZE(p2m->pod.mrp.list); ++i ) + p2m->pod.mrp.list[i] = INVALID_GFN; + if ( hap_enabled(d) && cpu_has_vmx ) ret = ept_p2m_init(p2m); else --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -292,10 +292,20 @@ struct p2m_domain { entry_count; /* # of pages in p2m marked pod */ unsigned long reclaim_single; /* Last gpfn of a scan */ unsigned long max_guest; /* gpfn of max guest demand-populate */ -#define POD_HISTORY_MAX 128 - /* gpfn of last guest superpage demand-populated */ - unsigned long last_populated[POD_HISTORY_MAX]; - unsigned int last_populated_index; + + /* + * Tracking of the most recently populated PoD pages, for eager + * reclamation. + */ + struct pod_mrp_list { +#define NR_POD_MRP_ENTRIES 32 + +/* Encode ORDER_2M superpage in top bit of GFN */ +#define POD_LAST_SUPERPAGE (INVALID_GFN & ~(INVALID_GFN >> 1)) + + unsigned long list[NR_POD_MRP_ENTRIES]; + unsigned int idx; + } mrp; mm_lock_t lock; /* Locking of private pod structs, * * not relying on the p2m lock. */ } pod; debian/patches/xsa202-4.4.patch0000664000000000000000000000433113035200750013156 0ustar From: Jan Beulich Subject: x86: force EFLAGS.IF on when exiting to PV guests Guest kernels modifying instructions in the process of being emulated for another of their vCPU-s may effect EFLAGS.IF to be cleared upon next exiting to guest context, by converting the being emulated instruction to CLI (at the right point in time). Prevent any such bad effects by always forcing EFLAGS.IF on. And to cover hypothetical other similar issues, also force EFLAGS.{IOPL,NT,VM} to zero. This is XSA-202. Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -173,6 +173,10 @@ compat_bad_hypercall: /* %rbx: struct vcpu, interrupts disabled */ ENTRY(compat_restore_all_guest) ASSERT_INTERRUPTS_DISABLED + mov $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),%r11d + and UREGS_eflags(%rsp),%r11d + or $X86_EFLAGS_IF,%r11 + mov %r11d,UREGS_eflags(%rsp) RESTORE_ALL adj=8 compat=1 .Lft0: iretq --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -41,28 +41,29 @@ restore_all_guest: testw $TRAP_syscall,4(%rsp) jz iret_exit_to_guest + movq 24(%rsp),%r11 # RFLAGS + andq $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),%r11 + orq $X86_EFLAGS_IF,%r11 + /* Don't use SYSRET path if the return address is not canonical. */ movq 8(%rsp),%rcx sarq $47,%rcx incl %ecx cmpl $1,%ecx - ja .Lforce_iret + movq 8(%rsp),%rcx # RIP + ja iret_exit_to_guest cmpw $FLAT_USER_CS32,16(%rsp)# CS - movq 8(%rsp),%rcx # RIP - movq 24(%rsp),%r11 # RFLAGS movq 32(%rsp),%rsp # RSP je 1f sysretq 1: sysretl -.Lforce_iret: - /* Mimic SYSRET behavior. */ - movq 8(%rsp),%rcx # RIP - movq 24(%rsp),%r11 # RFLAGS ALIGN /* No special register assumptions. */ iret_exit_to_guest: + andl $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),24(%rsp) + orl $X86_EFLAGS_IF,24(%rsp) addq $8,%rsp .Lft0: iretq debian/patches/config-etherboot.diff0000664000000000000000000000115012276137111014705 0ustar Index: xen-4.4.0~rc3+20140210/Config.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/Config.mk 2014-02-10 12:53:58.490067486 +0100 +++ xen-4.4.0~rc3+20140210/Config.mk 2014-02-10 12:55:53.522629857 +0100 @@ -239,7 +239,7 @@ SEABIOS_UPSTREAM_TAG ?= rel-1.7.3.1 # Fri Aug 2 14:12:09 2013 -0400 # Fix bug in CBFS file walking with compressed files. -ETHERBOOT_NICS ?= rtl8139 8086100e +ETHERBOOT_NICS ?= rtl8139 e1000_82540 # 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. debian/patches/xsa175-4.4-0002-libxl-Provide-libxl__backendpath_parse_domid.patch0000664000000000000000000000416612725264607024453 0ustar From 35a740847bea0a2aede72de7b2b8b49eef36e4eb Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 27 Apr 2016 16:34:19 +0100 Subject: [PATCH 02/10] libxl: Provide libxl__backendpath_parse_domid Multiple places in libxl need to figure out the backend domid of a device. This can be discovered easily by looking at the backend path, which always starts /local/domain/$backend_domid/. There are no call sites yet. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl_device.c | 15 +++++++++++++++ tools/libxl/libxl_internal.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index e9d2424..b500264 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -270,6 +270,21 @@ static int disk_try_backend(disk_try_backend_args *a, return 0; } +int libxl__backendpath_parse_domid(libxl__gc *gc, const char *be_path, + libxl_domid *domid_out) { + int r; + unsigned int domid_sc; + char delim_sc; + + r = sscanf(be_path, "/local/domain/%u%c", &domid_sc, &delim_sc); + if (!(r==2 && delim_sc=='/')) { + LOG(ERROR, "internal error: backend path %s unparseable!", be_path); + return ERROR_FAIL; + } + *domid_out = domid_sc; + return 0; +} + int libxl__device_disk_set_backend(libxl__gc *gc, libxl_device_disk *disk) { libxl_disk_backend ok; disk_try_backend_args a; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 801e95d..3fc9997 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -574,6 +574,8 @@ _hidden bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, _hidden char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid); +_hidden int libxl__backendpath_parse_domid(libxl__gc *gc, const char *be_path, + libxl_domid *domid_out); /*----- "checked" xenstore access functions -----*/ /* Each of these functions will check that it succeeded; if it -- 2.1.4 debian/patches/xsa137.patch0000664000000000000000000001770412571017632012703 0ustar From 593fe52faa1b85567a7ec20c69d8cfbc7368ae5b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 15 Jun 2015 14:50:42 +0100 Subject: [PATCH] xl: Sane handling of extra config file arguments Various xl sub-commands take additional parameters containing = as additional config fragments. The handling of these config fragments has a number of bugs: 1. Use of a static 1024-byte buffer. (If truncation would occur, with semi-trusted input, a security risk arises due to quotes being lost.) 2. Mishandling of the return value from snprintf, so that if truncation occurs, the to-write pointer is updated with the wanted-to-write length, resulting in stack corruption. (This is XSA-137.) 3. Clone-and-hack of the code for constructing the appended config file. These are fixed here, by introducing a new function `string_realloc_append' and using it everywhere. The `extra_info' buffers are replaced by pointers, which start off NULL and are explicitly freed on all return paths. The separate variable which will become dom_info.extra_config is abolished (which involves moving the clearing of dom_info). Additional bugs I observe, not fixed here: 4. The functions which now call string_realloc_append use ad-hoc error returns, with multiple calls to `return'. This currently necessitates multiple new calls to `free'. 5. Many of the paths in xl call exit(-rc) where rc is a libxl status code. This is a ridiculous exit status `convention'. 6. The loops for handling extra config data are clone-and-hacks. 7. Once the extra config buffer is accumulated, it must be combined with the appropriate main config file. The code to do this combining is clone-and-hacked too. Signed-off-by: Ian Jackson Tested-by: Ian Jackson Acked-by: Ian Campbell --- v2: Use SSIZE_MAX, not INT_MAX. Check *accumulate for NULL, not accumulate. Move memset of dom_info. --- tools/libxl/xl_cmdimpl.c | 64 +++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index c858068..c01a851 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -151,7 +151,7 @@ struct domain_create { int console_autoconnect; int checkpointed_stream; const char *config_file; - const char *extra_config; /* extra config string */ + char *extra_config; /* extra config string */ const char *restore_file; int migrate_fd; /* -1 means none */ char **migration_domname_r; /* from malloc */ @@ -4805,11 +4805,25 @@ int main_vm_list(int argc, char **argv) return 0; } +static void string_realloc_append(char **accumulate, const char *more) +{ + /* Appends more to accumulate. Accumulate is either NULL, or + * points (always) to a malloc'd nul-terminated string. */ + + size_t oldlen = *accumulate ? strlen(*accumulate) : 0; + size_t morelen = strlen(more) + 1/*nul*/; + if (oldlen > SSIZE_MAX || morelen > SSIZE_MAX - oldlen) { + fprintf(stderr,"Additional config data far too large\n"); + exit(-ERROR_FAIL); + } + + *accumulate = xrealloc(*accumulate, oldlen + morelen); + memcpy(*accumulate + oldlen, more, morelen); +} + int main_create(int argc, char **argv) { const char *filename = NULL; - char *p; - char extra_config[1024]; struct domain_create dom_info; int paused = 0, debug = 0, daemonize = 1, console_autoconnect = 0, quiet = 0, monitor = 1, vnc = 0, vncautopass = 0; @@ -4824,6 +4838,8 @@ int main_create(int argc, char **argv) {0, 0, 0, 0} }; + dom_info.extra_config = NULL; + if (argv[1] && argv[1][0] != '-' && !strchr(argv[1], '=')) { filename = argv[1]; argc--; argv++; @@ -4863,20 +4879,21 @@ int main_create(int argc, char **argv) break; } - extra_config[0] = '\0'; - for (p = extra_config; optind < argc; optind++) { + memset(&dom_info, 0, sizeof(dom_info)); + + for (; optind < argc; optind++) { if (strchr(argv[optind], '=') != NULL) { - p += snprintf(p, sizeof(extra_config) - (p - extra_config), - "%s\n", argv[optind]); + string_realloc_append(&dom_info.extra_config, argv[optind]); + string_realloc_append(&dom_info.extra_config, "\n"); } else if (!filename) { filename = argv[optind]; } else { help("create"); + free(dom_info.extra_config); return 2; } } - memset(&dom_info, 0, sizeof(dom_info)); dom_info.debug = debug; dom_info.daemonize = daemonize; dom_info.monitor = monitor; @@ -4884,16 +4901,18 @@ int main_create(int argc, char **argv) dom_info.dryrun = dryrun_only; dom_info.quiet = quiet; dom_info.config_file = filename; - dom_info.extra_config = extra_config; dom_info.migrate_fd = -1; dom_info.vnc = vnc; dom_info.vncautopass = vncautopass; dom_info.console_autoconnect = console_autoconnect; rc = create_domain(&dom_info); - if (rc < 0) + if (rc < 0) { + free(dom_info.extra_config); return -rc; + } + free(dom_info.extra_config); return 0; } @@ -4901,8 +4920,7 @@ int main_config_update(int argc, char **argv) { uint32_t domid; const char *filename = NULL; - char *p; - char extra_config[1024]; + char *extra_config = NULL; void *config_data = 0; int config_len = 0; libxl_domain_config d_config; @@ -4940,15 +4958,15 @@ int main_config_update(int argc, char **argv) break; } - extra_config[0] = '\0'; - for (p = extra_config; optind < argc; optind++) { + for (; optind < argc; optind++) { if (strchr(argv[optind], '=') != NULL) { - p += snprintf(p, sizeof(extra_config) - (p - extra_config), - "%s\n", argv[optind]); + string_realloc_append(&extra_config, argv[optind]); + string_realloc_append(&extra_config, "\n"); } else if (!filename) { filename = argv[optind]; } else { help("create"); + free(extra_config); return 2; } } @@ -4957,7 +4975,8 @@ int main_config_update(int argc, char **argv) rc = libxl_read_file_contents(ctx, filename, &config_data, &config_len); if (rc) { fprintf(stderr, "Failed to read config file: %s: %s\n", - filename, strerror(errno)); return ERROR_FAIL; } + filename, strerror(errno)); + free(extra_config); return ERROR_FAIL; } if (strlen(extra_config)) { if (config_len > INT_MAX - (strlen(extra_config) + 2 + 1)) { fprintf(stderr, "Failed to attach extra configration\n"); @@ -4998,7 +5017,7 @@ int main_config_update(int argc, char **argv) libxl_domain_config_dispose(&d_config); free(config_data); - + free(extra_config); return 0; } @@ -7255,7 +7274,7 @@ int main_cpupoolcreate(int argc, char **argv) { const char *filename = NULL, *config_src=NULL; const char *p; - char extra_config[1024]; + char *extra_config = NULL; int opt; static struct option opts[] = { {"defconfig", 1, 0, 'f'}, @@ -7289,13 +7308,10 @@ int main_cpupoolcreate(int argc, char **argv) break; } - memset(extra_config, 0, sizeof(extra_config)); while (optind < argc) { if ((p = strchr(argv[optind], '='))) { - if (strlen(extra_config) + 1 + strlen(argv[optind]) < sizeof(extra_config)) { - strcat(extra_config, "\n"); - strcat(extra_config, argv[optind]); - } + string_realloc_append(&extra_config, "\n"); + string_realloc_append(&extra_config, argv[optind]); } else if (!filename) { filename = argv[optind]; } else { -- 1.7.10.4 debian/patches/xsa206-4.4-0021-oxenstored-add-transaction-info-relevant-to-history-.patch0000664000000000000000000000634513104300260025747 0ustar From 38e49e8b7d270ce641cfaee649f24e506a2b3ff8 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Tue, 14 Mar 2017 12:17:38 +0000 Subject: [PATCH 21/30] oxenstored: add transaction info relevant to history-tracking Specifically: * retain the original store (not just the root) in full transactions * store commit count at the time of the start of the transaction Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Thomas Sanders Reviewed-by: Ian Jackson Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/process.ml | 2 +- tools/ocaml/xenstored/transaction.ml | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 9cf2b46..ff5fc24 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -295,7 +295,7 @@ let transaction_replay c t doms cons = | Transaction.No -> error "attempted to replay a non-full transaction"; false - | Transaction.Full(id, oldroot, cstore) -> + | Transaction.Full(id, oldstore, cstore) -> let tid = Connection.start_transaction c cstore in let new_t = Transaction.make tid cstore in let con = sprintf "r(%d):%s" id (Connection.get_domstr c) in diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index 6f758ff..b1791b3 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -73,12 +73,13 @@ let can_coalesce oldroot currentroot path = type ty = No | Full of ( int * (* Transaction id *) - Store.Node.t * (* Original root *) + Store.t * (* Original store *) Store.t (* A pointer to the canonical store: its root changes on each transaction-commit *) ) type t = { ty: ty; + start_count: int64; store: Store.t; (* This is the store that we change in write operations. *) quota: Quota.t; mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list; @@ -87,10 +88,13 @@ type t = { mutable write_lowpath: Store.Path.t option; } +let counter = ref 0L + let make id store = - let ty = if id = none then No else Full(id, Store.get_root store, store) in + let ty = if id = none then No else Full(id, Store.copy store, store) in { ty = ty; + start_count = !counter; store = if id = none then store else Store.copy store; quota = Quota.copy store.Store.quota; paths = []; @@ -161,7 +165,7 @@ let commit ~con t = let has_commited = match t.ty with | No -> true - | Full (id, oldroot, cstore) -> (* "cstore" meaning current canonical store *) + | Full (id, oldstore, cstore) -> (* "cstore" meaning current canonical store *) let commit_partial oldroot cstore store = (* get the lowest path of the query and verify that it hasn't been modified by others transactions. *) @@ -204,7 +208,7 @@ let commit ~con t = if !test_eagain && Random.int 3 = 0 then false else - try_commit oldroot cstore t.store + try_commit (Store.get_root oldstore) cstore t.store in if has_commited && has_write_ops then Disk.write t.store; -- 2.1.4 debian/patches/tools-xenstat-rpath.diff0000664000000000000000000000124112276137132015413 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstat/xentop/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstat/xentop/Makefile 2014-02-10 12:56:09.582708372 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstat/xentop/Makefile 2014-02-10 12:56:10.330712027 +0100 @@ -19,7 +19,9 @@ all install xentop: else CFLAGS += -DGCC_PRINTF -Wall -Werror $(CFLAGS_libxenstat) +LDFLAGS += $(call LDFLAGS_RPATH,../lib) LDLIBS += $(LDLIBS_libxenstat) $(CURSES_LIBS) $(SOCKET_LIBS) +LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) CFLAGS += -DHOST_$(XEN_OS) # Include configure output (config.h) to headers search path debian/patches/xsa237-4.5-0001-x86-dont-allow-MSI-pIRQ-mapping-on-unowned-device.patch0000664000000000000000000000145013167425741024500 0ustar From: Jan Beulich Subject: x86: don't allow MSI pIRQ mapping on unowned device MSI setup should be permitted only for existing devices owned by the respective guest (the operation may still be carried out by the domain controlling that guest). This is part of XSA-237. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1961,7 +1961,10 @@ int map_domain_pirq( if ( !cpu_has_apic ) goto done; - pdev = pci_get_pdev(msi->seg, msi->bus, msi->devfn); + pdev = pci_get_pdev_by_domain(d, msi->seg, msi->bus, msi->devfn); + if ( !pdev ) + goto done; + ret = pci_enable_msi(msi, &msi_desc); if ( ret ) { debian/patches/tools-rpath.diff0000664000000000000000000000112312276137117013731 0ustar Index: xen-4.4.0~rc3+20140210/tools/Rules.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Rules.mk 2014-02-10 12:53:57.902064617 +0100 +++ xen-4.4.0~rc3+20140210/tools/Rules.mk 2014-02-10 12:55:58.834655821 +0100 @@ -9,6 +9,8 @@ include $(XEN_ROOT)/Config.mk export _INSTALL := $(INSTALL) INSTALL = $(XEN_ROOT)/tools/cross-install +LDFLAGS_RPATH = -Wl,-rpath,'$${ORIGIN}$(if $(1),/$(1))' + XEN_INCLUDE = $(XEN_ROOT)/tools/include XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl debian/patches/xsa224-4.5-0004-gnttab-__gnttab_unmap_common_complete-is-all-or-noth.patch0000664000000000000000000002545313126670757026032 0ustar From 414d97feb2e28ed131da33546ea81a919c30e285 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Jun 2017 15:51:58 +0100 Subject: [PATCH 4/4] gnttab: __gnttab_unmap_common_complete() is all-or-nothing All failures have to be detected in __gnttab_unmap_common(), the completion function must not skip part of its processing. In particular the GNTMAP_device_map related putting of page references and adjustment of pin count must not occur if __gnttab_unmap_common() signaled an error. Furthermore the function must not make adjustments to global state (here: clearing GNTTAB_device_map) before all possibly failing operations have been performed. There's one exception for IOMMU related failures: As IOMMU manipulation occurs after GNTMAP_*_map have been cleared already, the related page reference and pin count adjustments need to be done nevertheless. A fundamental requirement for the correctness of this is that iommu_{,un}map_page() crash any affected DomU in case of failure. The version check appears to be pointless (or could perhaps be a BUG_ON() or ASSERT()), but for the moment also move it. This is part of XSA-224. Reported-by: Jan Beulich Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 105 ++++++++++++++++++-------------------- xen/include/asm-arm/grant_table.h | 2 +- xen/include/asm-x86/grant_table.h | 5 +- 3 files changed, 53 insertions(+), 59 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 9f4fc37..32c8b41 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -96,7 +96,7 @@ struct gnttab_unmap_common { int16_t status; /* Shared state beteen *_unmap and *_unmap_complete */ - u16 flags; + u16 done; unsigned long frame; struct domain *rd; grant_ref_t ref; @@ -773,7 +773,8 @@ __gnttab_map_grant_ref( refcnt++; } - if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) + if ( gnttab_host_mapping_get_page_type(op->flags & GNTMAP_readonly, + ld, rd) ) { if ( (owner == dom_cow) || !get_page_type(pg, PGT_writable_page) ) @@ -905,6 +906,7 @@ __gnttab_unmap_common( struct active_grant_entry *act; s16 rc = 0; struct grant_mapping *map; + unsigned int flags; bool_t put_handle = 0; ld = current->domain; @@ -954,8 +956,22 @@ __gnttab_unmap_common( rgt = rd->grant_table; double_gt_lock(lgt, rgt); - op->flags = map->flags; - if ( unlikely(!op->flags) || unlikely(map->domid != dom) ) + if ( rgt->gt_version == 0 ) + { + /* + * This ought to be impossible, as such a mapping should not have + * been established (see the nr_grant_entries(rgt) bounds check in + * __gnttab_map_grant_ref()). Doing this check only in + * __gnttab_unmap_common_complete() - as it used to be done - would, + * however, be too late. + */ + rc = GNTST_bad_gntref; + flags = 0; + goto unmap_out; + } + + flags = map->flags; + if ( unlikely(!flags) || unlikely(map->domid != dom) ) { gdprintk(XENLOG_WARNING, "Unstable handle %u\n", op->handle); rc = GNTST_bad_handle; @@ -968,24 +984,27 @@ __gnttab_unmap_common( op->frame = act->frame; - if ( op->dev_bus_addr ) - { - if ( unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) ) - PIN_FAIL(unmap_out, GNTST_general_error, - "Bus address doesn't match gntref (%"PRIx64" != %"PRIpaddr")\n", - op->dev_bus_addr, pfn_to_paddr(act->frame)); - - map->flags &= ~GNTMAP_device_map; - } + if ( op->dev_bus_addr && + unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) ) + PIN_FAIL(unmap_out, GNTST_general_error, + "Bus address doesn't match gntref (%"PRIx64" != %"PRIpaddr")\n", + op->dev_bus_addr, pfn_to_paddr(act->frame)); - if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) + if ( op->host_addr && (flags & GNTMAP_host_map) ) { if ( (rc = replace_grant_host_mapping(op->host_addr, op->frame, op->new_addr, - op->flags)) < 0 ) + flags)) < 0 ) goto unmap_out; map->flags &= ~GNTMAP_host_map; + op->done |= GNTMAP_host_map | (flags & GNTMAP_readonly); + } + + if ( op->dev_bus_addr && (flags & GNTMAP_device_map) ) + { + map->flags &= ~GNTMAP_device_map; + op->done |= GNTMAP_device_map | (flags & GNTMAP_readonly); } if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ) @@ -1020,7 +1039,7 @@ __gnttab_unmap_common( } /* If just unmapped a writable mapping, mark as dirtied */ - if ( rc == GNTST_okay && !(op->flags & GNTMAP_readonly) ) + if ( rc == GNTST_okay && !(flags & GNTMAP_readonly) ) gnttab_mark_dirty(rd, op->frame); op->status = rc; @@ -1037,13 +1056,9 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op) struct page_info *pg; uint16_t *status; - if ( rd == NULL ) + if ( !op->done ) { - /* - * Suggests that __gntab_unmap_common failed in - * rcu_lock_domain_by_id() or earlier, and so we have nothing - * to complete - */ + /* __gntab_unmap_common() didn't do anything - nothing to complete. */ return; } @@ -1053,9 +1068,6 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op) rgt = rd->grant_table; spin_lock(&rgt->lock); - if ( rgt->gt_version == 0 ) - goto unmap_out; - act = &active_entry(rgt, op->ref); sha = shared_entry_header(rgt, op->ref); @@ -1064,70 +1076,49 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op) else status = &status_entry(rgt, op->ref); - if ( op->dev_bus_addr && - unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) ) - { - /* - * Suggests that __gntab_unmap_common failed early and so - * nothing further to do - */ - goto unmap_out; - } - pg = mfn_to_page(op->frame); - if ( op->dev_bus_addr && (op->flags & GNTMAP_device_map) ) + if ( op->done & GNTMAP_device_map ) { if ( !is_iomem_page(act->frame) ) { - if ( op->flags & GNTMAP_readonly ) + if ( op->done & GNTMAP_readonly ) put_page(pg); else put_page_and_type(pg); } ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask)); - if ( op->flags & GNTMAP_readonly ) + if ( op->done & GNTMAP_readonly ) act->pin -= GNTPIN_devr_inc; else act->pin -= GNTPIN_devw_inc; } - if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) + if ( op->done & GNTMAP_host_map ) { - if ( op->status != 0 ) - { - /* - * Suggests that __gntab_unmap_common failed in - * replace_grant_host_mapping() or IOMMU handling, so nothing - * further to do (short of re-establishing the mapping in the - * latter case). - */ - goto unmap_out; - } - if ( !is_iomem_page(op->frame) ) { - if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) + if ( gnttab_host_mapping_get_page_type(op->done & GNTMAP_readonly, + ld, rd) ) put_page_type(pg); put_page(pg); } ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)); - if ( op->flags & GNTMAP_readonly ) + if ( op->done & GNTMAP_readonly ) act->pin -= GNTPIN_hstr_inc; else act->pin -= GNTPIN_hstw_inc; } if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) && - !(op->flags & GNTMAP_readonly) ) + !(op->done & GNTMAP_readonly) ) gnttab_clear_flag(_GTF_writing, status); if ( act->pin == 0 ) gnttab_clear_flag(_GTF_reading, status); - unmap_out: spin_unlock(&rgt->lock); rcu_unlock_domain(rd); } @@ -1142,6 +1133,7 @@ __gnttab_unmap_grant_ref( common->handle = op->handle; /* Intialise these in case common contains old state */ + common->done = 0; common->new_addr = 0; common->rd = NULL; common->frame = 0; @@ -1207,6 +1199,7 @@ __gnttab_unmap_and_replace( common->handle = op->handle; /* Intialise these in case common contains old state */ + common->done = 0; common->dev_bus_addr = 0; common->rd = NULL; common->frame = 0; @@ -2980,7 +2973,9 @@ gnttab_release_mappings( if ( gnttab_release_host_mappings(d) && !is_iomem_page(act->frame) ) { - if ( gnttab_host_mapping_get_page_type(map, d, rd) ) + if ( gnttab_host_mapping_get_page_type((map->flags & + GNTMAP_readonly), + d, rd) ) put_page_type(pg); put_page(pg); } diff --git a/xen/include/asm-arm/grant_table.h b/xen/include/asm-arm/grant_table.h index 0edad67..c6c5456 100644 --- a/xen/include/asm-arm/grant_table.h +++ b/xen/include/asm-arm/grant_table.h @@ -10,7 +10,7 @@ void gnttab_clear_flag(unsigned long nr, uint16_t *addr); int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags, unsigned int cache_flags); -#define gnttab_host_mapping_get_page_type(op, d, rd) (0) +#define gnttab_host_mapping_get_page_type(ro, ld, rd) (0) int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned long new_gpaddr, unsigned int flags); void gnttab_mark_dirty(struct domain *d, unsigned long l); diff --git a/xen/include/asm-x86/grant_table.h b/xen/include/asm-x86/grant_table.h index 8c9bbcf..9ca631c 100644 --- a/xen/include/asm-x86/grant_table.h +++ b/xen/include/asm-x86/grant_table.h @@ -58,9 +58,8 @@ static inline void gnttab_clear_flag(unsigned int nr, uint16_t *st) } /* Foreign mappings of HHVM-guest pages do not modify the type count. */ -#define gnttab_host_mapping_get_page_type(op, ld, rd) \ - (!((op)->flags & GNTMAP_readonly) && \ - (((ld) == (rd)) || !paging_mode_external(rd))) +#define gnttab_host_mapping_get_page_type(ro, ld, rd) \ + (!(ro) && (((ld) == (rd)) || !paging_mode_external(rd))) /* Done implicitly when page tables are destroyed. */ #define gnttab_release_host_mappings(domain) ( paging_mode_external(domain) ) -- 2.1.4 debian/patches/xsa135-qemut-1.patch0000664000000000000000000000661712571017601014165 0ustar pcnet: fix Negative array index read From: Gonglei s->xmit_pos maybe assigned to a negative value (-1), but in this branch variable s->xmit_pos as an index to array s->buffer. Let's add a check for s->xmit_pos. upstream-commit-id: 7b50d00911ddd6d56a766ac5671e47304c20a21b Signed-off-by: Gonglei Signed-off-by: Paolo Bonzini Reviewed-by: Jason Wang Reviewed-by: Jason Wang Signed-off-by: Stefan Hajnoczi diff --git a/hw/pcnet.c b/hw/pcnet.c index 7cc0637..9f3e1cc 100644 --- a/qemu/hw/pcnet.c +++ b/qemu/hw/pcnet.c @@ -1250,7 +1250,7 @@ static void pcnet_transmit(PCNetState *s) target_phys_addr_t xmit_cxda = 0; int count = CSR_XMTRL(s)-1; int add_crc = 0; - + int bcnt; s->xmit_pos = -1; if (!CSR_TXON(s)) { @@ -1276,34 +1276,39 @@ static void pcnet_transmit(PCNetState *s) if (BCR_SWSTYLE(s) != 1) add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS); } + + if (s->xmit_pos < 0) { + goto txdone; + } + + bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); + s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), + s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); + s->xmit_pos += bcnt; + if (!GET_FIELD(tmd.status, TMDS, ENP)) { - int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), - s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); - s->xmit_pos += bcnt; - } else if (s->xmit_pos >= 0) { - int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), - s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); - s->xmit_pos += bcnt; + goto txdone; + } #ifdef PCNET_DEBUG - printf("pcnet_transmit size=%d\n", s->xmit_pos); + printf("pcnet_transmit size=%d\n", s->xmit_pos); #endif - if (CSR_LOOP(s)) { - if (BCR_SWSTYLE(s) == 1) - add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); - s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; - pcnet_receive(s, s->buffer, s->xmit_pos); - s->looptest = 0; - } else - if (s->vc) - qemu_send_packet(s->vc, s->buffer, s->xmit_pos); - - s->csr[0] &= ~0x0008; /* clear TDMD */ - s->csr[4] |= 0x0004; /* set TXSTRT */ - s->xmit_pos = -1; + if (CSR_LOOP(s)) { + if (BCR_SWSTYLE(s) == 1) + add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); + s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; + pcnet_receive(s, s->buffer, s->xmit_pos); + s->looptest = 0; + } else { + if (s->vc) { + qemu_send_packet(s->vc, s->buffer, s->xmit_pos); + } } + s->csr[0] &= ~0x0008; /* clear TDMD */ + s->csr[4] |= 0x0004; /* set TXSTRT */ + s->xmit_pos = -1; + + txdone: SET_FIELD(&tmd.status, TMDS, OWN, 0); TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) debian/patches/xsa219-4.5.patch0000664000000000000000000001355413126666354013217 0ustar From 6926e40943eef0e0ef7acfc53cee819a41a41247 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 11 May 2017 14:47:00 +0100 Subject: [PATCH] x86/shadow: Hold references for the duration of emulated writes The (misnamed) emulate_gva_to_mfn() function translates a linear address to an mfn, but releases its page reference before returning the mfn to its caller. sh_emulate_map_dest() uses the results of one or two translations to construct a virtual mapping to the underlying frames, completes an emulated write/cmpxchg, then unmaps the virtual mappings. The page references need holding until the mappings are unmapped, or the frames can change ownership before the writes occurs. This is XSA-219 Reported-by: Andrew Cooper Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Reviewed-by: Tim Deegan --- xen/arch/x86/mm/shadow/multi.c | 58 +++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 7589d23..e16bf1b 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -4555,7 +4555,10 @@ static void sh_pagetable_dying(struct vcpu *v, paddr_t gpa) /**************************************************************************/ /* Handling HVM guest writes to pagetables */ -/* Translate a VA to an MFN, injecting a page-fault if we fail */ +/* + * Translate a VA to an MFN, injecting a page-fault if we fail. If the + * mapping succeeds, a reference will be held on the underlying page. + */ #define BAD_GVA_TO_GFN (~0UL) #define BAD_GFN_TO_MFN (~1UL) #define READONLY_GFN (~2UL) @@ -4604,14 +4607,15 @@ static mfn_t emulate_gva_to_mfn(struct vcpu *v, ASSERT(mfn_valid(mfn)); v->arch.paging.last_write_was_pt = !!sh_mfn_is_a_page_table(mfn); - /* Note shadow cannot page out or unshare this mfn, so the map won't - * disappear. Otherwise, caller must hold onto page until done. */ - put_page(page); + return mfn; } -/* Check that the user is allowed to perform this write. - * Returns a mapped pointer to write to, or NULL for error. */ +/* + * Check that the user is allowed to perform this write. If a mapping is + * returned, page references will be held on sh_ctxt->mfn1 and + * sh_ctxt->mfn2 iff !INVALID_MFN. + */ #define MAPPING_UNHANDLEABLE ((void *)(unsigned long)X86EMUL_UNHANDLEABLE) #define MAPPING_EXCEPTION ((void *)(unsigned long)X86EMUL_EXCEPTION) #define MAPPING_SILENT_FAIL ((void *)(unsigned long)X86EMUL_OKAY) @@ -4623,13 +4627,6 @@ static void *emulate_map_dest(struct vcpu *v, { void *map = NULL; - sh_ctxt->mfn1 = emulate_gva_to_mfn(v, vaddr, sh_ctxt); - if ( !mfn_valid(sh_ctxt->mfn1) ) - return ((mfn_x(sh_ctxt->mfn1) == BAD_GVA_TO_GFN) ? - MAPPING_EXCEPTION : - (mfn_x(sh_ctxt->mfn1) == READONLY_GFN) ? - MAPPING_SILENT_FAIL : MAPPING_UNHANDLEABLE); - #ifndef NDEBUG /* We don't emulate user-mode writes to page tables */ if ( hvm_get_seg_reg(x86_seg_ss, sh_ctxt)->attr.fields.dpl == 3 ) @@ -4640,6 +4637,17 @@ static void *emulate_map_dest(struct vcpu *v, } #endif + sh_ctxt->mfn1 = emulate_gva_to_mfn(v, vaddr, sh_ctxt); + if ( !mfn_valid(sh_ctxt->mfn1) ) + { + switch ( mfn_x(sh_ctxt->mfn1) ) + { + case BAD_GVA_TO_GFN: return MAPPING_EXCEPTION; + case READONLY_GFN: return MAPPING_SILENT_FAIL; + default: return MAPPING_UNHANDLEABLE; + } + } + /* Unaligned writes mean probably this isn't a pagetable */ if ( vaddr & (bytes - 1) ) sh_remove_shadows(v, sh_ctxt->mfn1, 0, 0 /* Slow, can fail */ ); @@ -4657,16 +4665,24 @@ static void *emulate_map_dest(struct vcpu *v, /* Cross-page emulated writes are only supported for HVM guests; * PV guests ought to know better */ if ( !is_hvm_vcpu(v) ) + { + put_page(mfn_to_page(sh_ctxt->mfn1)); return MAPPING_UNHANDLEABLE; + } /* This write crosses a page boundary. Translate the second page */ sh_ctxt->mfn2 = emulate_gva_to_mfn(v, (vaddr + bytes - 1) & PAGE_MASK, sh_ctxt); - if ( !mfn_valid(sh_ctxt->mfn2) ) - return ((mfn_x(sh_ctxt->mfn2) == BAD_GVA_TO_GFN) ? - MAPPING_EXCEPTION : - (mfn_x(sh_ctxt->mfn2) == READONLY_GFN) ? - MAPPING_SILENT_FAIL : MAPPING_UNHANDLEABLE); + if ( !mfn_valid(sh_ctxt->mfn2) ) + { + put_page(mfn_to_page(sh_ctxt->mfn1)); + switch ( mfn_x(sh_ctxt->mfn2) ) + { + case BAD_GVA_TO_GFN: return MAPPING_EXCEPTION; + case READONLY_GFN: return MAPPING_SILENT_FAIL; + default: return MAPPING_UNHANDLEABLE; + } + } /* Cross-page writes mean probably not a pagetable */ sh_remove_shadows(v, sh_ctxt->mfn2, 0, 0 /* Slow, can fail */ ); @@ -4675,7 +4691,11 @@ static void *emulate_map_dest(struct vcpu *v, mfns[1] = mfn_x(sh_ctxt->mfn2); map = vmap(mfns, 2); if ( !map ) + { + put_page(mfn_to_page(sh_ctxt->mfn1)); + put_page(mfn_to_page(sh_ctxt->mfn2)); return MAPPING_UNHANDLEABLE; + } map += (vaddr & ~PAGE_MASK); } @@ -4750,10 +4770,12 @@ static void emulate_unmap_dest(struct vcpu *v, } paging_mark_dirty(v->domain, mfn_x(sh_ctxt->mfn1)); + put_page(mfn_to_page(sh_ctxt->mfn1)); if ( unlikely(mfn_valid(sh_ctxt->mfn2)) ) { paging_mark_dirty(v->domain, mfn_x(sh_ctxt->mfn2)); + put_page(mfn_to_page(sh_ctxt->mfn2)); vunmap((void *)((unsigned long)addr & PAGE_MASK)); } else -- 2.1.4 debian/patches/xsa208-4.4-1-qemut.patch0000664000000000000000000001002213104307120014441 0ustar From b6946bbaa33e228c5c150498ec90ae452ba965bc Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 21 Feb 2015 17:16:42 +0000 Subject: [PATCH] CVE-2014-8106: cirrus: fix blit region check Backport of qemu-upstream: * bf25983345ca44aec3dd92c57142be45452bd38a * d3532a0db02296e687711b8cdc7791924efccea0 Signed-off-by: Andrew Cooper --- hw/cirrus_vga.c | 66 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index a26b051..00736d2 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -34,6 +34,8 @@ #include "qemu-xen.h" #include "qemu-log.h" +#include + /* * TODO: * - destination write mask support not complete (bits 5..7) @@ -223,20 +225,6 @@ #define ABS(a) ((signed)(a) > 0 ? a : -a) -#define BLTUNSAFE(s) \ - ( \ - ( /* check dst is within bounds */ \ - (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \ - + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \ - (s)->vram_size \ - ) || \ - ( /* check src is within bounds */ \ - (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \ - + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \ - (s)->vram_size \ - ) \ - ) - struct CirrusVGAState; typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, uint8_t * dst, const uint8_t * src, @@ -315,6 +303,50 @@ static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_ * ***************************************/ +static bool blit_region_is_unsafe(struct CirrusVGAState *s, + int32_t pitch, int32_t addr) +{ + if (pitch < 0) { + int64_t min = addr + + ((int64_t)s->cirrus_blt_height-1) * pitch; + int32_t max = addr + + s->cirrus_blt_width; + if (min < 0 || max >= s->vram_size) { + return true; + } + } else { + int64_t max = addr + + ((int64_t)s->cirrus_blt_height-1) * pitch + + s->cirrus_blt_width; + if (max >= s->vram_size) { + return true; + } + } + return false; +} + +static bool blit_is_unsafe(struct CirrusVGAState *s) +{ + /* should be the case, see cirrus_bitblt_start */ + assert(s->cirrus_blt_width > 0); + assert(s->cirrus_blt_height > 0); + + if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) { + return true; + } + + if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, + s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { + return true; + } + if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, + s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { + return true; + } + + return false; +} + static void cirrus_bitblt_rop_nop(CirrusVGAState *s, uint8_t *dst,const uint8_t *src, int dstpitch,int srcpitch, @@ -676,7 +708,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); - if (BLTUNSAFE(s)) + if (blit_is_unsafe(s)) return 0; (*s->cirrus_rop) (s, dst, src, @@ -694,7 +726,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) { cirrus_fill_t rop_func; - if (BLTUNSAFE(s)) + if (blit_is_unsafe(s)) return 0; rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), @@ -790,7 +822,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) { - if (BLTUNSAFE(s)) + if (blit_is_unsafe(s)) return 0; cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr, -- 2.1.4 debian/patches/xsa154-4.4.patch0000664000000000000000000003317612662601763013213 0ustar x86: enforce consistent cachability of MMIO mappings We've been told by Intel that inconsistent cachability between multiple mappings of the same page can affect system stability only when the affected page is an MMIO one. Since the stale data issue is of no relevance to the hypervisor (since all guest memory accesses go through proper accessors and validation), handling of RAM pages remains unchanged here. Any MMIO mapped by domains however needs to be done consistently (all cachable mappings or all uncachable ones), in order to avoid Machine Check exceptions. Since converting existing cachable mappings to uncachable (at the time an uncachable mapping gets established) would in the PV case require tracking all mappings, allow MMIO to only get mapped uncachable (UC, UC-, or WC). This also implies that in the PV case we mustn't use the L1 PTE update fast path when cachability flags get altered. Since in the HVM case at least for now we want to continue honoring pinned cachability attributes for pages not mapped by the hypervisor, special case handling of r/o MMIO pages (forcing UC) gets added there. Arguably the counterpart change to p2m-pt.c may not be necessary, since UC- (which already gets enforced there) is probably strict enough. Note that the shadow code changes include fixing the write protection of r/o MMIO ranges: shadow_l1e_remove_flags() and its siblings, other than l1e_remove_flags() and alike, return the new PTE (and hence ignoring their return values makes them no-ops). This is CVE-2016-2270 / XSA-154. Signed-off-by: Jan Beulich Acked-by: Andrew Cooper Index: xen-4.4.2/docs/misc/xen-command-line.markdown =================================================================== --- xen-4.4.2.orig/docs/misc/xen-command-line.markdown 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/docs/misc/xen-command-line.markdown 2016-02-19 14:24:22.432623351 +0100 @@ -690,6 +690,15 @@ limit is ignored by Xen. Specify if the MMConfig space should be enabled. +### mmio-relax +> `= | all` + +> Default: `false` + +By default, domains may not create cached mappings to MMIO regions. +This option relaxes the check for Domain 0 (or when using `all`, all PV +domains), to permit the use of cacheable MMIO mappings. + ### msi > `= ` Index: xen-4.4.2/xen/arch/x86/hvm/mtrr.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/hvm/mtrr.c 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/arch/x86/hvm/mtrr.c 2016-02-19 14:24:22.432623351 +0100 @@ -693,8 +693,12 @@ uint8_t epte_get_entry_emt(struct domain if ( v->domain != d ) v = d->vcpu ? d->vcpu[0] : NULL; - if ( !mfn_valid(mfn_x(mfn)) ) + if ( !mfn_valid(mfn_x(mfn)) || + rangeset_contains_singleton(mmio_ro_ranges, mfn_x(mfn)) ) + { + *ipat = 1; return MTRR_TYPE_UNCACHABLE; + } if ( hvm_get_mem_pinned_cacheattr(d, gfn, &type) ) return type; Index: xen-4.4.2/xen/arch/x86/mm/p2m-pt.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm/p2m-pt.c 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/arch/x86/mm/p2m-pt.c 2016-02-19 14:24:22.432623351 +0100 @@ -93,6 +93,8 @@ static unsigned long p2m_type_to_flags(p case p2m_mmio_direct: if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn_x(mfn)) ) flags |= _PAGE_RW; + else + flags |= _PAGE_PWT; return flags | P2M_BASE_FLAGS | _PAGE_PCD; } } Index: xen-4.4.2/xen/arch/x86/mm/shadow/multi.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm/shadow/multi.c 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/arch/x86/mm/shadow/multi.c 2016-02-19 14:24:22.432623351 +0100 @@ -521,6 +521,7 @@ _sh_propagate(struct vcpu *v, gfn_t target_gfn = guest_l1e_get_gfn(guest_entry); u32 pass_thru_flags; u32 gflags, sflags; + bool_t mmio_mfn; /* We don't shadow PAE l3s */ ASSERT(GUEST_PAGING_LEVELS > 3 || level != 3); @@ -561,7 +562,10 @@ _sh_propagate(struct vcpu *v, // mfn means that we can not usefully shadow anything, and so we // return early. // - if ( !mfn_valid(target_mfn) + mmio_mfn = !mfn_valid(target_mfn) + || (level == 1 + && page_get_owner(mfn_to_page(target_mfn)) == dom_io); + if ( mmio_mfn && !(level == 1 && (!shadow_mode_refcounts(d) || p2mt == p2m_mmio_direct)) ) { @@ -579,7 +583,7 @@ _sh_propagate(struct vcpu *v, _PAGE_RW | _PAGE_PRESENT); if ( guest_supports_nx(v) ) pass_thru_flags |= _PAGE_NX_BIT; - if ( !shadow_mode_refcounts(d) && !mfn_valid(target_mfn) ) + if ( level == 1 && !shadow_mode_refcounts(d) && mmio_mfn ) pass_thru_flags |= _PAGE_PAT | _PAGE_PCD | _PAGE_PWT; sflags = gflags & pass_thru_flags; @@ -676,10 +680,14 @@ _sh_propagate(struct vcpu *v, } /* Read-only memory */ - if ( p2m_is_readonly(p2mt) || - (p2mt == p2m_mmio_direct && - rangeset_contains_singleton(mmio_ro_ranges, mfn_x(target_mfn))) ) + if ( p2m_is_readonly(p2mt) ) sflags &= ~_PAGE_RW; + else if ( p2mt == p2m_mmio_direct && + rangeset_contains_singleton(mmio_ro_ranges, mfn_x(target_mfn)) ) + { + sflags &= ~(_PAGE_RW | _PAGE_PAT); + sflags |= _PAGE_PCD | _PAGE_PWT; + } // protect guest page tables // @@ -1201,22 +1209,28 @@ static int shadow_set_l1e(struct vcpu *v && !sh_l1e_is_magic(new_sl1e) ) { /* About to install a new reference */ - if ( shadow_mode_refcounts(d) ) { + if ( shadow_mode_refcounts(d) ) + { +#define PAGE_FLIPPABLE (_PAGE_RW | _PAGE_PWT | _PAGE_PCD | _PAGE_PAT) + int rc; + TRACE_SHADOW_PATH_FLAG(TRCE_SFLAG_SHADOW_L1_GET_REF); - switch ( shadow_get_page_from_l1e(new_sl1e, d, new_type) ) + switch ( rc = shadow_get_page_from_l1e(new_sl1e, d, new_type) ) { default: /* Doesn't look like a pagetable. */ flags |= SHADOW_SET_ERROR; new_sl1e = shadow_l1e_empty(); break; - case 1: - shadow_l1e_remove_flags(new_sl1e, _PAGE_RW); + case PAGE_FLIPPABLE & -PAGE_FLIPPABLE ... PAGE_FLIPPABLE: + ASSERT(!(rc & ~PAGE_FLIPPABLE)); + new_sl1e = shadow_l1e_flip_flags(new_sl1e, rc); /* fall through */ case 0: shadow_vram_get_l1e(new_sl1e, sl1e, sl1mfn, d); break; } +#undef PAGE_FLIPPABLE } } Index: xen-4.4.2/xen/arch/x86/mm/shadow/types.h =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm/shadow/types.h 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/arch/x86/mm/shadow/types.h 2016-02-19 14:24:22.436623351 +0100 @@ -100,6 +100,9 @@ static inline u32 shadow_l4e_get_flags(s static inline shadow_l1e_t shadow_l1e_remove_flags(shadow_l1e_t sl1e, u32 flags) { l1e_remove_flags(sl1e, flags); return sl1e; } +static inline shadow_l1e_t +shadow_l1e_flip_flags(shadow_l1e_t sl1e, u32 flags) +{ l1e_flip_flags(sl1e, flags); return sl1e; } static inline shadow_l1e_t shadow_l1e_empty(void) { return l1e_empty(); } Index: xen-4.4.2/xen/arch/x86/mm.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm.c 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/arch/x86/mm.c 2016-02-19 14:24:22.436623351 +0100 @@ -188,6 +188,18 @@ static uint32_t base_disallow_mask; is_pv_domain(d)) ? \ L1_DISALLOW_MASK : (L1_DISALLOW_MASK & ~PAGE_CACHE_ATTRS)) +static s8 __read_mostly opt_mmio_relax; +static void __init parse_mmio_relax(const char *s) +{ + if ( !*s ) + opt_mmio_relax = 1; + else + opt_mmio_relax = parse_bool(s); + if ( opt_mmio_relax < 0 && strcmp(s, "all") ) + opt_mmio_relax = 0; +} +custom_param("mmio-relax", parse_mmio_relax); + static void __init init_frametable_chunk(void *start, void *end) { unsigned long s = (unsigned long)start; @@ -773,6 +785,8 @@ get_page_from_l1e( if ( !mfn_valid(mfn) || (real_pg_owner = page_get_owner_and_reference(page)) == dom_io ) { + int flip = 0; + /* Only needed the reference to confirm dom_io ownership. */ if ( mfn_valid(mfn) ) put_page(page); @@ -805,13 +819,41 @@ get_page_from_l1e( return -EINVAL; } - if ( !(l1f & _PAGE_RW) || - !rangeset_contains_singleton(mmio_ro_ranges, mfn) ) - return 0; - dprintk(XENLOG_G_WARNING, - "d%d: Forcing read-only access to MFN %lx\n", - l1e_owner->domain_id, mfn); - return 1; + if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn) ) + { + /* MMIO pages must not be mapped cachable unless requested so. */ + switch ( opt_mmio_relax ) + { + case 0: + break; + case 1: + if ( is_hardware_domain(l1e_owner) ) + case -1: + return 0; + default: + ASSERT_UNREACHABLE(); + } + } + else if ( l1f & _PAGE_RW ) + { + dprintk(XENLOG_G_WARNING, + "d%d: Forcing read-only access to MFN %lx\n", + l1e_owner->domain_id, mfn); + flip = _PAGE_RW; + } + + switch ( l1f & PAGE_CACHE_ATTRS ) + { + case 0: /* WB */ + flip |= _PAGE_PWT | _PAGE_PCD; + break; + case _PAGE_PWT: /* WT */ + case _PAGE_PWT | _PAGE_PAT: /* WP */ + flip |= _PAGE_PCD | (l1f & _PAGE_PAT); + break; + } + + return flip; } if ( unlikely( (real_pg_owner != pg_owner) && @@ -1210,8 +1252,9 @@ static int alloc_l1_table(struct page_in goto fail; case 0: break; - case 1: - l1e_remove_flags(pl1e[i], _PAGE_RW); + case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS: + ASSERT(!(ret & ~(_PAGE_RW | PAGE_CACHE_ATTRS))); + l1e_flip_flags(pl1e[i], ret); break; } @@ -1706,8 +1749,9 @@ static int mod_l1_entry(l1_pgentry_t *pl return -EINVAL; } - /* Fast path for identical mapping, r/w and presence. */ - if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) ) + /* Fast path for identical mapping, r/w, presence, and cachability. */ + if ( !l1e_has_changed(ol1e, nl1e, + PAGE_CACHE_ATTRS | _PAGE_RW | _PAGE_PRESENT) ) { adjust_guest_l1e(nl1e, pt_dom); if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, @@ -1730,8 +1774,9 @@ static int mod_l1_entry(l1_pgentry_t *pl return rc; case 0: break; - case 1: - l1e_remove_flags(nl1e, _PAGE_RW); + case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS: + ASSERT(!(rc & ~(_PAGE_RW | PAGE_CACHE_ATTRS))); + l1e_flip_flags(nl1e, rc); rc = 0; break; } @@ -4926,6 +4971,7 @@ static int ptwr_emulated_update( l1_pgentry_t pte, ol1e, nl1e, *pl1e; struct vcpu *v = current; struct domain *d = v->domain; + int ret; /* Only allow naturally-aligned stores within the original %cr2 page. */ if ( unlikely(((addr^ptwr_ctxt->cr2) & PAGE_MASK) || (addr & (bytes-1))) ) @@ -4973,7 +5019,7 @@ static int ptwr_emulated_update( /* Check the new PTE. */ nl1e = l1e_from_intpte(val); - switch ( get_page_from_l1e(nl1e, d, d) ) + switch ( ret = get_page_from_l1e(nl1e, d, d) ) { default: if ( is_pv_32bit_domain(d) && (bytes == 4) && (unaligned_addr & 4) && @@ -4997,8 +5043,9 @@ static int ptwr_emulated_update( break; case 0: break; - case 1: - l1e_remove_flags(nl1e, _PAGE_RW); + case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS: + ASSERT(!(ret & ~(_PAGE_RW | PAGE_CACHE_ATTRS))); + l1e_flip_flags(nl1e, ret); break; } Index: xen-4.4.2/xen/include/asm-x86/page.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-x86/page.h 2016-02-19 14:24:22.440623351 +0100 +++ xen-4.4.2/xen/include/asm-x86/page.h 2016-02-19 14:24:22.436623351 +0100 @@ -157,6 +157,9 @@ static inline l4_pgentry_t l4e_from_padd #define l3e_remove_flags(x, flags) ((x).l3 &= ~put_pte_flags(flags)) #define l4e_remove_flags(x, flags) ((x).l4 &= ~put_pte_flags(flags)) +/* Flip flags in an existing L1 PTE. */ +#define l1e_flip_flags(x, flags) ((x).l1 ^= put_pte_flags(flags)) + /* Check if a pte's page mapping or significant access flags have changed. */ #define l1e_has_changed(x,y,flags) \ ( !!(((x).l1 ^ (y).l1) & ((PADDR_MASK&PAGE_MASK)|put_pte_flags(flags))) ) Index: xen-4.4.2/xen/include/xen/lib.h =================================================================== --- xen-4.4.2.orig/xen/include/xen/lib.h 2015-03-19 16:06:48.000000000 +0100 +++ xen-4.4.2/xen/include/xen/lib.h 2016-02-22 13:49:52.062915443 +0100 @@ -41,9 +41,11 @@ do { #ifndef NDEBUG #define ASSERT(p) \ do { if ( unlikely(!(p)) ) assert_failed(#p); } while (0) +#define ASSERT_UNREACHABLE() assert_failed("unreachable") #define debug_build() 1 #else #define ASSERT(p) do { if ( 0 && (p) ); } while (0) +#define ASSERT_UNREACHABLE() do { } while (0) #define debug_build() 0 #endif debian/patches/series0000664000000000000000000002300413167432435012043 0ustar version.patch config-etherboot.diff config-prefix.diff tools-libfsimage-abiname.diff tools-libxc-abiname.diff tools-libxl-abiname.diff tools-xenstat-abiname.diff tools-rpath.diff tools-blktap2-prefix.diff tools-console-prefix.diff tools-libfsimage-prefix.diff tools-libfsimage-rpath.diff tools-libxl-prefix.diff tools-misc-prefix.diff tools-misc-rpath.diff tools-pygrub-prefix.diff tools-python-prefix.diff tools-python-rpath.diff tools-xcutils-rpath.diff tools-xenmon-prefix.diff tools-xenmon-rpath.diff tools-xenpaging-prefix.diff tools-xenstat-prefix.diff tools-xenstat-rpath.diff tools-xenstore-prefix.diff tools-xenstore-rpath.diff tools-xentrace-prefix.diff tools-xentrace-rpath.diff tools-flags.diff tools-python-xen-relative-path.diff tools-misc-xend-startup.diff tools-disable.diff tools-examples-xend-disable-network.diff tools-examples-xend-disable-relocation.diff tools-firmware-etherboot-packaged.diff tools-firmware-seabios-packaged.diff tools-pygrub-remove-static-solaris-support.patch tools-include-install.diff tools-xenmon-install.diff tools-hotplug-udevrules.diff tools-python-shebang.diff tools-ocaml-fix-build.diff tools-xenstore-compatibility.diff # FIXME tools-ocaml-disable-test.patch # # Dropped in debian but ulong usage in gdbsx would still break the build. # toolchain.diff # # PXE boot fix for e1000 and ROM paths (likely only Ubuntu) # ubuntu-tools-firmware-etherboot-kvm-ipxe.diff # # Only for Ubuntu: stick with qemu-dm # qemu-prefix.diff qemu-disable-blktap.diff ubuntu-qemu-disable-qemu-upstream.diff ubuntu-qemu-upstream-location.patch # # Disable udev rules using the "socket:" feature unsupported in the # systemd version of udev. # ubuntu-tools-hotplug-disable-xend-rules.patch # # Enable Arm builds # ubuntu-tools-armhf-without-ocaml.patch ubuntu-arm64-enablement.patch # # Security fixes not in Debian, yet # xsa127-4.x.patch xsa126-qemut.patch xsa125-4.4.patch xsa132.patch xsa133-qemut.patch xsa128-qemut.patch xsa129-qemut.patch xsa130-qemut.patch xsa131-qemut-1.patch xsa131-qemut-2.patch xsa131-qemut-3.patch xsa131-qemut-4.patch xsa131-qemut-5.patch xsa131-qemut-6.patch xsa131-qemut-7.patch xsa131-qemut-8.patch xsa134.patch xsa135-qemut-1.patch xsa135-qemut-2.patch xsa136.patch xsa137.patch xsa138-qemut-1.patch xsa138-qemut-2.patch xsa140-backport.patch xsa141.patch xsa142-4.5.patch xsa145.patch xsa146.patch xsa147.patch xsa148-4.4.patch xsa149.patch xsa150.patch xsa151.patch xsa152-4.5.patch xsa153-libxl.patch xsa156-4.4.patch xsa155-qemut-xenfb.patch xsa155-qemut-qdisk-double-access.patch xsa155-xen-0001-xen-Add-RING_COPY_REQUEST.patch xsa155-xen-0002-blktap2-Use-RING_COPY_REQUEST.patch xsa155-xen-0003-libvchan-Read-prod-cons-only-once.patch xsa158-4.4.patch xsa158-fix.patch xsa159.patch xsa160-4.4.patch xsa162-qemut.patch xsa164.patch xsa165-4.5.patch xsa166-4.4.patch xsa167-4.4.patch xsa168.patch xsa169.patch xsa170-4.5.patch xsa154-4.4.patch xsa172.patch xsa173-4.4.patch xsa175-4.4-0001-libxl-Record-backend-frontend-paths-in-libxl-DOMID.patch xsa175-4.4-0002-libxl-Provide-libxl__backendpath_parse_domid.patch xsa175-4.4-0003-libxl-Do-not-trust-frontend-in-libxl__devices_destro.patch xsa175-4.4-0004-libxl-Do-not-trust-frontend-in-libxl__device_nextid.patch xsa175-4.4-0005-libxl-Do-not-trust-frontend-for-disk-eject-event.patch xsa175-4.4-0006-libxl-Do-not-trust-frontend-for-disk-in-getinfo.patch xsa175-4.4-0007-libxl-Do-not-trust-frontend-for-vtpm-list.patch xsa175-4.4-0008-libxl-Do-not-trust-frontend-for-vtpm-in-getinfo.patch xsa175-4.4-0009-libxl-Do-not-trust-frontend-for-nic-in-libxl_devid_t.patch xsa175-4.4-0010-libxl-Do-not-trust-frontend-for-nic-in-getinfo.patch xsa175-4.4-0011-libxl-Cleanup-Have-libxl__alloc_vdev-use-libxl.patch xsa175-4.4-0012-libxl-Document-serial-correctly.patch xsa176.patch xsa178-xen4.4-0001-libxl-Do-not-trust-backend-for-vtpm-in-getinfo-excep.patch xsa178-xen4.4-0002-libxl-Do-not-trust-backend-for-vtpm-in-getinfo-uuid.patch xsa178-xen4.4-0003-libxl-cdrom-eject-and-insert-write-to-libxl.patch xsa178-xen4.4-0004-libxl-Do-not-trust-backend-for-disk-eject-vdev.patch xsa178-xen4.4-0005-libxl-Do-not-trust-backend-for-disk-fix-driver-domai.patch xsa178-xen4.4-0006-libxl-Do-not-trust-backend-for-disk-in-getinfo.patch xsa178-xen4.4-0007-libxl-Do-not-trust-backend-for-cdrom-insert.patch xsa178-xen4.4-0008-libxl-Rename-libxl__device_nic_from_xs_be-to-_from_x.patch xsa178-xen4.4-0009-libxl-Rename-READ_BACKEND-to-READ_LIBXLDEV.patch xsa178-xen4.4-0010-libxl-Have-READ_LIBXLDEV-use-libxl_path-rather-than-.patch xsa178-xen4.4-0011-libxl-Do-not-trust-backend-in-nic-getinfo.patch xsa178-xen4.4-0012-libxl-Do-not-trust-backend-for-nic-in-devid_to_devic.patch xsa178-xen4.4-0013-libxl-Do-not-trust-backend-for-nic-in-list.patch xsa178-xen4.4-0014-libxl-Cleanup-use-libxl__backendpath_parse_domid-in-.patch xsa178-xen4.4-0015-libxl-Fix-NULL-pointer-due-to-XSA-178-fix-wrong-XS-n.patch xsa179-qemut-4.4-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch xsa179-qemut-4.4-0002-vga-add-vbe_enabled-helper.patch xsa179-qemut-4.4-0003-vga-factor-out-vga-register-setup.patch xsa179-qemut-4.4-0004-vga-update-vga-register-setup-on-vbe-changes.patch xsa179-qemut-4.4-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch xsa180-qemut.patch xsa181-4.4.patch xsa182-4.5.patch xsa184-qemut-master.patch xsa185.patch xsa187-4.7-0001-x86-shadow-Avoid-overflowing-sh_ctxt-seg.patch xsa187-4.4-0002-x86-segment-Bounds-check-accesses-to-emulation-ctx.patch xsa188.patch xsa190-4.5.patch xsa191-4.6.patch xsa192-4.5.patch xsa193-4.5.patch xsa195.patch xsa197-4.5-qemut.patch xsa198.patch xsa199-trad.patch xsa200-4.6.patch xsa201-1.patch xsa201-2.patch xsa201-3-4.4.patch xsa201-4.patch xsa202-4.4.patch xsa204-4.5.patch upstream-x86-hvm-do-not-set-msr_tsc_adjust-on-hvm_set_guest_t.patch # XSA-206 xsa206-4.4-0001-xenstored-apply-a-write-transaction-rate-limit.patch xsa206-4.4-0002-xenstored-Log-when-the-write-transaction-rate-limit-.patch xsa206-4.4-0003-oxenstored-exempt-dom0-from-domU-node-quotas.patch xsa206-4.4-0004-oxenstored-perform-a-3-way-merge-of-the-quota-after-.patch xsa206-4.4-0005-oxenstored-catch-the-error-when-a-connection-is-alre.patch xsa206-4.4-0006-oxenstored-use-hash-table-to-store-socket-connection.patch xsa206-4.4-0007-oxenstored-enable-domain-connection-indexing-based-o.patch xsa206-4.4-0008-oxenstored-only-process-domain-connections-that-noti.patch xsa206-4.4-0009-oxenstored-add-a-safe-net-mechanism-for-existing-ill.patch xsa206-4.4-0010-oxenstored-refactor-putting-response-on-wire.patch xsa206-4.4-0011-oxenstored-remove-some-unused-parameters.patch xsa206-4.4-0012-oxenstored-refactor-request-processing.patch xsa206-4.4-0013-oxenstored-keep-track-of-each-transaction-s-operatio.patch xsa206-4.4-0014-oxenstored-move-functions-that-process-simple-operat.patch xsa206-4.4-0015-oxenstored-replay-transaction-upon-conflict.patch xsa206-4.4-0016-oxenstored-log-request-and-response-during-transacti.patch xsa206-4.4-0017-oxenstored-allow-compilation-prior-to-OCaml-3.12.0.patch xsa206-4.4-0018-oxenstored-comments-explaining-some-variables.patch xsa206-4.4-0019-oxenstored-handling-of-domain-conflict-credit.patch xsa206-4.4-0020-oxenstored-ignore-domains-with-no-conflict-credit.patch xsa206-4.4-0021-oxenstored-add-transaction-info-relevant-to-history-.patch xsa206-4.4-0022-oxenstored-support-commit-history-tracking.patch xsa206-4.4-0023-oxenstored-only-record-operations-with-side-effects-.patch xsa206-4.4-0024-oxenstored-discard-old-commit-history-on-txn-end.patch xsa206-4.4-0025-oxenstored-track-commit-history.patch xsa206-4.4-0026-oxenstored-blame-the-connection-that-caused-a-transa.patch xsa206-4.4-0027-oxenstored-allow-self-conflicts.patch xsa206-4.4-0028-oxenstored-do-not-commit-read-only-transactions.patch xsa206-4.4-0029-oxenstored-don-t-wake-to-issue-no-conflict-credit.patch xsa206-4.4-0030-oxenstored-transaction-conflicts-improve-logging.patch xsa206-4.4-0031-oxenstored-trim-history-in-the-frequent_ops-function.patch # XSA-207 xsa207-4.4.patch # XSA-208 xsa208-4.4-1-qemut.patch xsa208-qemut.patch # XSA-209 xsa209-qemut.patch # XSA-211 xsa211-qemut-4.5.patch # XSA-212 xsa212.patch # XSA-213 xsa213-4.5.patch # XSA-214 xsa214.patch # XSA-215 xsa215.patch xsa217-4.5.patch xsa218-4.4-0001-IOMMU-handle-IOMMU-mapping-and-unmapping-failures.patch xsa218-4.4-0002-gnttab-fix-unmap-pin-accounting-race.patch xsa218-4.4-0003-gnttab-Avoid-potential-double-put-of-maptrack-entry.patch xsa218-4.4-0004-gnttab-correct-maptrack-table-accesses.patch xsa219-4.5.patch xsa221.patch xsa222-1-4.6.patch xsa224-4.5-0001-gnttab-Fix-handling-of-dev_bus_addr-during-unmap.patch xsa224-4.5-0002-gnttab-never-create-host-mapping-unless-asked-to.patch xsa224-4.5-0003-gnttab-correct-logic-to-get-page-references-during-m.patch xsa224-4.5-0004-gnttab-__gnttab_unmap_common_complete-is-all-or-noth.patch xsa226-4.5-0001-gnttab-dont-use-possibly-unbounded-tail-calls.patch xsa226-4.5-0002-gnttab-fix-transitive-grant-handling.patch xsa227-4.5.patch xsa230.patch xsa231-4.5.patch xsa233.patch xsa234-4.5.patch xsa235-4.5.patch xsa237-4.5-0001-x86-dont-allow-MSI-pIRQ-mapping-on-unowned-device.patch xsa237-4.5-0002-x86-enforce-proper-privilege-when-mapping-pIRQ-s.patch xsa237-4.5-0003-x86-MSI-disallow-redundant-enabling.patch xsa237-4.4-0004-x86-MSI-fix-error-handling.patch xsa237-4.5-0004-x86-IRQ-conditionally-preserve-irq-pirq-mapping-on-error.patch xsa237-4.4-0005-x86-FLASK-fix-unmap-domain-IRQ-XSM-hook.patch xsa239-4.5.patch xsa240-4.4-0001-x86-limit-linear-page-table-use-to-a-single-level.patch xsa240-4.4-0002-x86-mm-Disable-PV-linear-pagetables-by-default.patch xsa241-4.4.patch xsa242-4.9.patch xsa243-4.6-1.patch xsa243-4.5-2.patch xsa244-4.4.patch debian/patches/tools-examples-xend-disable-relocation.diff0000664000000000000000000000145512276137141021130 0ustar Index: xen-4.4.0~rc3+20140210/tools/examples/xend-config.sxp =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/examples/xend-config.sxp 2014-02-10 12:56:16.794743624 +0100 +++ xen-4.4.0~rc3+20140210/tools/examples/xend-config.sxp 2014-02-10 12:56:17.438746778 +0100 @@ -62,7 +62,6 @@ #(xend-tcp-xmlrpc-server no) #(xend-unix-xmlrpc-server yes) #(xend-relocation-server no) -(xend-relocation-server yes) #(xend-relocation-ssl-server no) #(xend-udev-event-server no) @@ -126,7 +125,6 @@ # (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$') # #(xend-relocation-hosts-allow '') -(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$') # The limit (in kilobytes) on the size of the console buffer #(console-limit 1024) debian/patches/xsa178-xen4.4-0001-libxl-Do-not-trust-backend-for-vtpm-in-getinfo-excep.patch0000664000000000000000000000376512725542005026225 0ustar From 7bd50f1bd68b1b754f67e076498a77421edb0701 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 17:18:44 +0100 Subject: [PATCH 01/16] libxl: Do not trust backend for vtpm in getinfo (except uuid) * Do not check the backend for existence. We have already read the /libxl path so know that the vtpm exists (or is supposed to); if the backend doesn't exist then that must be the backend's doing. * Get the frontend path from the /libxl directory. * The frontend domid is the guest domid, and does not need to be read from xenstore (!) We still attempt to read the uuid from the backend. This will be fixed in the next patch. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index c794d3a..b4ed33f 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1944,9 +1944,6 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, if (!vtpminfo->backend) { goto err; } - if(!libxl__xs_read(gc, XBT_NULL, vtpminfo->backend)) { - goto err; - } rc = libxl__backendpath_parse_domid(gc, vtpminfo->backend, &vtpminfo->backend_id); @@ -1965,11 +1962,8 @@ int libxl_device_vtpm_getinfo(libxl_ctx *ctx, vtpminfo->rref = val ? strtoul(val, NULL, 10) : -1; vtpminfo->frontend = xs_read(ctx->xsh, XBT_NULL, - GCSPRINTF("%s/frontend", vtpminfo->backend), NULL); - - val = libxl__xs_read(gc, XBT_NULL, - GCSPRINTF("%s/frontend-id", vtpminfo->backend)); - vtpminfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + GCSPRINTF("%s/frontend", libxl_path), NULL); + vtpminfo->frontend_id = domid; val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/uuid", vtpminfo->backend)); -- 1.9.1 debian/patches/xsa160-4.4.patch0000664000000000000000000000475312631300047013172 0ustar From 7f9fd14c80b71b4abbca36f2747d2e75dfebc289 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 18 Nov 2015 15:34:54 +0000 Subject: [PATCH] libxl: Fix bootloader-related virtual memory leak on pv build failure The bootloader may call libxl__file_reference_map(), which mmap's the pv_kernel and pv_ramdisk into process memory. This was only unmapped, however, on the success path of libxl__build_pv(). If there were a failure anywhere between libxl_bootloader.c:parse_bootloader_result() and the end of libxl__build_pv(), the calls to libxl__file_reference_unmap() would be skipped, leaking the mapped virtual memory. Ideally this would be fixed by adding the unmap calls to the destruction path for libxl__domain_build_state. Unfortunately the lifetime of the libxl__domain_build_state is opaque, and it doesn't have a proper destruction path. But, the only thing in it that isn't from the gc are these bootloader references, and they are only ever set for one libxl__domain_build_state, the one which is libxl__domain_create_state.build_state. So we can clean up in the exit path from libxl__domain_create_*, which always comes through domcreate_complete. Remove the now-redundant unmaps in libxl__build_pv's success path. This is XSA-160. Acked-by: Ian Campbell --- tools/libxl/libxl_create.c | 3 +++ tools/libxl/libxl_dom.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index e3350d5..5292c15 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -1295,6 +1295,9 @@ static void domcreate_complete(libxl__egc *egc, STATE_AO_GC(dcs->ao); libxl_domain_config *const d_config = dcs->guest_config; + libxl__file_reference_unmap(&dcs->build_state.pv_kernel); + libxl__file_reference_unmap(&dcs->build_state.pv_ramdisk); + if (!rc && d_config->b_info.exec_ssidref) rc = xc_flask_relabel_domain(CTX->xch, dcs->guest_domid, d_config->b_info.exec_ssidref); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 52bc01a..978a1eb 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -451,9 +451,6 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn); } - libxl__file_reference_unmap(&state->pv_kernel); - libxl__file_reference_unmap(&state->pv_ramdisk); - ret = 0; out: xc_dom_release(dom); -- 1.7.10.4 debian/patches/xsa215.patch0000664000000000000000000000323713104311632012662 0ustar From: Jan Beulich Subject: x86: correct create_bounce_frame We may push up to 96 bytes on the guest (kernel) stack, so we should also cover as much in the early range check. Note that this is the simplest possible patch, which has the theoretical potential of breaking a guest: We only really push 96 bytes when invoking the failsafe callback, ordinary exceptions only have 56 or 64 bytes pushed (without / with error code respectively). There is, however, no PV OS known to place a kernel stack there. This is XSA-215. Reported-by: Jann Horn Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -347,7 +347,7 @@ int80_slow_path: jmp handle_exception_saved /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK: */ -/* { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS } */ +/* { RCX, R11, [DS-GS,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS } */ /* %rdx: trap_bounce, %rbx: struct vcpu */ /* On return only %rbx and %rdx are guaranteed non-clobbered. */ create_bounce_frame: @@ -367,7 +367,7 @@ create_bounce_frame: 2: andq $~0xf,%rsi # Stack frames are 16-byte aligned. movq $HYPERVISOR_VIRT_START,%rax cmpq %rax,%rsi - movq $HYPERVISOR_VIRT_END+60,%rax + movq $HYPERVISOR_VIRT_END+12*8,%rax sbb %ecx,%ecx # In +ve address space? Then okay. cmpq %rax,%rsi adc %ecx,%ecx # Above Xen private area? Then okay. debian/patches/xsa147.patch0000664000000000000000000000303612616222065012673 0ustar xen: arm: handle races between relinquish_memory and free_domheap_pages Primarily this means XENMEM_decrease_reservation from a toolstack domain. Unlike x86 we have no requirement right now to queue such pages onto a separate list, if we hit this race then the other code has already fully accepted responsibility for freeing this page and therefore there is no more for relinquish_memory to do. This is XSA-147. Signed-off-by: Ian Campbell Reviewed-by: Julien Grall Reviewed-by: Jan Beulich diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 575745c..aac64cb 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -764,8 +764,15 @@ static int relinquish_memory(struct domain *d, struct page_list_head *list) { /* Grab a reference to the page so it won't disappear from under us. */ if ( unlikely(!get_page(page, d)) ) - /* Couldn't get a reference -- someone is freeing this page. */ - BUG(); + /* + * Couldn't get a reference -- someone is freeing this page and + * has already committed to doing so, so no more to do here. + * + * Note that the page must be left on the list, a list_del + * here will clash with the list_del done by the other + * party in the race and corrupt the list head. + */ + continue; if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) put_page(page); debian/patches/xsa179-qemut-4.4-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch0000664000000000000000000000753712725606611025402 0ustar From bebb4f580901fb638016d9851a28dbb83d44b3a6 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 26 Apr 2016 08:49:10 +0200 Subject: [PATCH 1/5] vga: fix banked access bounds checking (CVE-2016-3710) vga allows banked access to video memory using the window at 0xa00000 and it supports a different access modes with different address calculations. The VBE bochs extentions support banked access too, using the VBE_DISPI_INDEX_BANK register. The code tries to take the different address calculations into account and applies different limits to VBE_DISPI_INDEX_BANK depending on the current access mode. Which is probably effective in stopping misprogramming by accident. But from a security point of view completely useless as an attacker can easily change access modes after setting the bank register. Drop the bogus check, add range checks to vga_mem_{readb,writeb} instead. Fixes: CVE-2016-3710 Reported-by: Qinghao Tang Signed-off-by: Gerd Hoffmann [Backport to qemu-xen-tradition] Signed-off-by: Andrew Cooper --- hw/vga.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) Index: xen-4.4.2/qemu/hw/vga.c =================================================================== --- xen-4.4.2.orig/qemu/hw/vga.c 2016-06-07 20:07:57.256549955 +0200 +++ xen-4.4.2/qemu/hw/vga.c 2016-06-07 20:07:57.256549955 +0200 @@ -34,6 +34,8 @@ #include "qemu-timer.h" +#include + //#define DEBUG_VGA //#define DEBUG_VGA_MEM //#define DEBUG_VGA_REG @@ -606,11 +608,7 @@ static void vbe_ioport_write_data(void * } break; case VBE_DISPI_INDEX_BANK: - if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { - val &= (s->vbe_bank_mask >> 2); - } else { - val &= s->vbe_bank_mask; - } + val &= s->vbe_bank_mask; s->vbe_regs[s->vbe_index] = val; s->bank_offset = (val << 16); break; @@ -751,13 +749,21 @@ uint32_t vga_mem_readb(void *opaque, tar if (s->sr[4] & 0x08) { /* chain 4 mode : simplest access */ + assert(addr < s->vram_size); ret = s->vram_ptr[addr]; } else if (s->gr[5] & 0x10) { /* odd/even mode (aka text mode mapping) */ plane = (s->gr[4] & 2) | (addr & 1); - ret = s->vram_ptr[((addr & ~1) << 1) | plane]; + addr = ((addr & ~1) << 1) | plane; + if (addr >= s->vram_size) { + return 0xff; + } + ret = s->vram_ptr[addr]; } else { /* standard VGA latched access */ + if (addr * sizeof(uint32_t) >= s->vram_size) { + return 0xff; + } s->latch = ((uint32_t *)s->vram_ptr)[addr]; if (!(s->gr[5] & 0x08)) { @@ -844,6 +850,7 @@ void vga_mem_writeb(void *opaque, target plane = addr & 3; mask = (1 << plane); if (s->sr[2] & mask) { + assert(addr < s->vram_size); s->vram_ptr[addr] = val; #ifdef DEBUG_VGA_MEM printf("vga: chain4: [0x%x]\n", addr); @@ -857,6 +864,9 @@ void vga_mem_writeb(void *opaque, target mask = (1 << plane); if (s->sr[2] & mask) { addr = ((addr & ~1) << 1) | plane; + if (addr >= s->vram_size) { + return; + } s->vram_ptr[addr] = val; #ifdef DEBUG_VGA_MEM printf("vga: odd/even: [0x%x]\n", addr); @@ -929,6 +939,9 @@ void vga_mem_writeb(void *opaque, target mask = s->sr[2]; s->plane_updated |= mask; /* only used to detect font change */ write_mask = mask16[mask]; + if (addr * sizeof(uint32_t) >= s->vram_size) { + return; + } ((uint32_t *)s->vram_ptr)[addr] = (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | (val & write_mask); debian/patches/ubuntu-tools-firmware-etherboot-kvm-ipxe.diff0000664000000000000000000000331512276137150021500 0ustar Description: Use etherboot images from kvm-ipxe Since we do not seem to package qemu-ipxe (as Debian does) we used to build depend on ipxe. But kvm-ipxe seems to be closer to what Debian does as it only contains a small subset of all the rom files. And Xen uses only two of them. This patch changes the Xen code to look for the filenames that kvm-ipxe uses. Forwarded: not-needed Origin: vendor, created on merge Author: Stefan Bader Index: xen-4.4.0~rc3+20140210/Config.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/Config.mk 2014-02-10 12:55:54.674635489 +0100 +++ xen-4.4.0~rc3+20140210/Config.mk 2014-02-10 12:56:24.498781291 +0100 @@ -239,7 +239,7 @@ SEABIOS_UPSTREAM_TAG ?= rel-1.7.3.1 # Fri Aug 2 14:12:09 2013 -0400 # Fix bug in CBFS file walking with compressed files. -ETHERBOOT_NICS ?= rtl8139 e1000_82540 +ETHERBOOT_NICS ?= rtl8139 e1000 # 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. Index: xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/firmware/hvmloader/Makefile 2014-02-10 12:56:18.614752527 +0100 +++ xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile 2014-02-10 12:56:24.502781306 +0100 @@ -48,7 +48,7 @@ CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl else CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.cirrus.bin endif -ETHERBOOT_ROMS := $(addprefix /usr/lib/ipxe/, $(addsuffix .rom, $(ETHERBOOT_NICS))) +ETHERBOOT_ROMS := $(addprefix /usr/share/qemu/pxe-, $(addsuffix .rom, $(ETHERBOOT_NICS))) endif ROMS := debian/patches/xsa125-4.4.patch0000664000000000000000000001336012510722537013175 0ustar From df2922ce672cc35500e2f3ba041441021f44b41c Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 19 Nov 2014 12:57:11 -0500 Subject: [PATCH] Limit XEN_DOMCTL_memory_mapping hypercall to only process up to 64 GFNs (or less) Said hypercall for large BARs can take quite a while. As such we can require that the hypercall MUST break up the request in smaller values. Another approach is to add preemption to it - whether we do the preemption using hypercall_create_continuation or returning EAGAIN to userspace (and have it re-invocate the call) - either way the issue we cannot easily solve is that in 'map_mmio_regions' if we encounter an error we MUST call 'unmap_mmio_regions' for the whole BAR region. Since the preemption would re-use input fields such as nr_mfns, first_gfn, first_mfn - we would lose the original values - and only undo what was done in the current round (i.e. ignoring anything that was done prior to earlier preemptions). Unless we re-used the return value as 'EAGAIN|nr_mfns_done<<10' but that puts a limit (since the return value is a long) on the amount of nr_mfns that can provided. This patch sidesteps this problem by: - Setting an hard limit of nr_mfns having to be 64 or less. - Toolstack adjusts correspondingly to the nr_mfn limit. - If the there is an error when adding the toolstack will call the remove operation to remove the whole region. The need to break this hypercall down is for large BARs can take more than the guest (initial domain usually) time-slice. This has the negative result in that the guest is locked out for a long duration and is unable to act on any pending events. We also augment the code to return zero if nr_mfns instead of trying to the hypercall. Suggested-by: Jan Beulich Acked-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Ian Campbell --- tools/libxc/xc_domain.c | 55 ++++++++++++++++++++++++++++++++++++++++----- xen/arch/x86/domctl.c | 5 +++++ xen/include/public/domctl.h | 1 + 3 files changed, 56 insertions(+), 5 deletions(-) Index: xen-4.4.1/tools/libxc/xc_domain.c =================================================================== --- xen-4.4.1.orig/tools/libxc/xc_domain.c 2015-04-07 11:37:30.676537112 +0200 +++ xen-4.4.1/tools/libxc/xc_domain.c 2015-04-07 11:37:30.656537112 +0200 @@ -1641,6 +1641,13 @@ failed: return -1; } +#ifndef min +#define min(X, Y) ({ \ + const typeof (X) _x = (X); \ + const typeof (Y) _y = (Y); \ + (void) (&_x == &_y); \ + (_x < _y) ? _x : _y; }) +#endif int xc_domain_memory_mapping( xc_interface *xch, uint32_t domid, @@ -1650,17 +1657,55 @@ int xc_domain_memory_mapping( uint32_t add_mapping) { DECLARE_DOMCTL; + int ret = 0, err; + unsigned long done = 0, nr, max_batch_sz; + + if ( !nr_mfns ) + return 0; domctl.cmd = XEN_DOMCTL_memory_mapping; domctl.domain = domid; - domctl.u.memory_mapping.first_gfn = first_gfn; - domctl.u.memory_mapping.first_mfn = first_mfn; - domctl.u.memory_mapping.nr_mfns = nr_mfns; domctl.u.memory_mapping.add_mapping = add_mapping; + max_batch_sz = nr_mfns; + do + { + nr = min(nr_mfns - done, max_batch_sz); + domctl.u.memory_mapping.nr_mfns = nr; + domctl.u.memory_mapping.first_gfn = first_gfn + done; + domctl.u.memory_mapping.first_mfn = first_mfn + done; + err = do_domctl(xch, &domctl); + if ( err && errno == E2BIG ) + { + if ( max_batch_sz <= 1 ) + break; + max_batch_sz >>= 1; + continue; + } + /* Save the first error... */ + if ( !ret ) + ret = err; + /* .. and ignore the rest of them when removing. */ + if ( err && add_mapping != DPCI_REMOVE_MAPPING ) + break; - return do_domctl(xch, &domctl); -} + done += nr; + } while ( done < nr_mfns ); + + /* + * Undo what we have done unless unmapping, by unmapping the entire region. + * Errors here are ignored. + */ + if ( ret && add_mapping != DPCI_REMOVE_MAPPING ) + xc_domain_memory_mapping(xch, domid, first_gfn, first_mfn, nr_mfns, + DPCI_REMOVE_MAPPING); + /* We might get E2BIG so many times that we never advance. */ + if ( !done && !ret ) + ret = -1; + + return ret; +} +#undef min int xc_domain_ioport_mapping( xc_interface *xch, uint32_t domid, Index: xen-4.4.1/xen/arch/x86/domctl.c =================================================================== --- xen-4.4.1.orig/xen/arch/x86/domctl.c 2015-04-07 11:37:30.676537112 +0200 +++ xen-4.4.1/xen/arch/x86/domctl.c 2015-04-07 11:37:30.656537112 +0200 @@ -655,6 +655,11 @@ long arch_do_domctl( (gfn + nr_mfns - 1) < gfn ) /* wrap? */ break; + ret = -E2BIG; + /* Must break hypercall up as this could take a while. */ + if ( nr_mfns > 64 ) + break; + ret = -EPERM; if ( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) ) break; Index: xen-4.4.1/xen/include/public/domctl.h =================================================================== --- xen-4.4.1.orig/xen/include/public/domctl.h 2015-04-07 11:37:30.676537112 +0200 +++ xen-4.4.1/xen/include/public/domctl.h 2015-04-07 11:37:30.672537112 +0200 @@ -518,6 +518,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_ /* Bind machine I/O address range -> HVM address range. */ +/* If this returns -E2BIG lower nr_mfns value. */ /* XEN_DOMCTL_memory_mapping */ #define DPCI_ADD_MAPPING 1 #define DPCI_REMOVE_MAPPING 0 debian/patches/xsa162-qemut.patch0000664000000000000000000000331012633766046014027 0ustar net: pcnet: add check to validate receive data size(CVE-2015-7504) In loopback mode, pcnet_receive routine appends CRC code to the receive buffer. If the data size given is same as the buffer size, the appended CRC code overwrites 4 bytes after s->buffer. Added a check to avoid that. --- qemu/hw/net/pcnet.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) Index: xen-4.4.2/qemu/hw/pcnet.c =================================================================== --- xen-4.4.2.orig/qemu/hw/pcnet.c 2015-12-10 15:20:02.782496054 +0100 +++ xen-4.4.2/qemu/hw/pcnet.c 2015-12-10 15:20:02.778496054 +0100 @@ -1153,7 +1153,7 @@ static void pcnet_receive(void *opaque, uint32_t fcs = ~0; uint8_t *p = src; - while (p != &src[size-4]) + while (p != &src[size]) CRC(fcs, *p++); crc_err = (*(uint32_t *)p != htonl(fcs)); } @@ -1284,12 +1284,13 @@ static void pcnet_transmit(PCNetState *s bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); /* if multi-tmd packet outsizes s->buffer then skip it silently. - Note: this is not what real hw does */ - if (s->xmit_pos + bcnt > sizeof(s->buffer)) { - s->xmit_pos = -1; - goto txdone; + * Note: this is not what real hw does. + * Last four bytes of s->buffer are used to store CRC FCS code. + */ + if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) { + s->xmit_pos = -1; + goto txdone; } - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); s->xmit_pos += bcnt; debian/patches/tools-python-xen-relative-path.diff0000664000000000000000000002157612276137137017507 0ustar Index: xen-4.4.0~rc3+20140210/tools/python/xen/xm/create.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xm/create.py 2014-02-10 12:53:55.870054684 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xm/create.py 2014-02-10 12:56:14.734733560 +0100 @@ -695,45 +695,39 @@ def configure_image(vals): return None config_image = [ vals.builder ] if vals.kernel: + t = auxbin.path_boot(vals.kernel) if vals.bootloader: # If bootloader is specified, vals.kernel will be used # by bootloader when boots DomU. So it is needless to # check the path is existent or not. config_image.append([ 'kernel', vals.kernel ]) - elif os.path.dirname(vals.kernel) != "" and os.path.exists(vals.kernel): - config_image.append([ 'kernel', vals.kernel ]) elif vals.kernel == 'hvmloader': # Keep hvmloader w/o a path and let xend find it. # This allows guest migration to a Dom0 having different # xen install pathes. config_image.append([ 'kernel', vals.kernel ]) - elif os.path.exists(os.path.abspath(vals.kernel)): - # Keep old behaviour, if path is valid. - config_image.append([ 'kernel', os.path.abspath(vals.kernel) ]) + elif t: + config_image.append([ 'kernel', t ]) else: raise ValueError('Cannot find kernel "%s"' % vals.kernel) if vals.ramdisk: + t = auxbin.path_boot(vals.ramdisk) if vals.bootloader: # Same with 'kernel' above config_image.append([ 'ramdisk', vals.ramdisk ]) - elif os.path.dirname(vals.ramdisk) != "" and os.path.exists(vals.ramdisk): - config_image.append([ 'ramdisk', vals.ramdisk ]) - elif os.path.exists(os.path.abspath(vals.ramdisk)): - # Keep old behaviour, if path is valid. - config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ]) + elif t: + config_image.append([ 'ramdisk', t ]) else: raise ValueError('Cannot find ramdisk "%s"' % vals.ramdisk) if vals.loader: - if os.path.dirname(vals.loader) != "" and os.path.exists(vals.loader): - config_image.append([ 'loader', vals.loader ]) - elif vals.loader == 'hvmloader': + t = auxbin.path_boot(vals.loader) + if vals.loader == 'hvmloader': # Keep hvmloader w/o a path and let xend find it. # This allows guest migration to a Dom0 having different # xen install pathes. config_image.append([ 'loader', vals.loader ]) - elif os.path.exists(os.path.abspath(vals.loader)): - # Keep old behaviour, if path is valid. - config_image.append([ 'loader', os.path.abspath(vals.loader) ]) + elif t: + config_image.append([ 'loader', t ]) else: raise ValueError('Cannot find loader "%s"' % vals.loader) if vals.cmdline_ip: @@ -1032,7 +1026,7 @@ def configure_hvm(config_image, vals): args = [ 'acpi', 'apic', 'boot', 'cpuid', 'cpuid_check', - 'device_model', 'display', + 'display', 'fda', 'fdb', 'gfx_passthru', 'guest_os_type', 'hap', 'hpet', @@ -1054,6 +1048,8 @@ def configure_hvm(config_image, vals): for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: config_image.append([a, vals.__dict__[a]]) + if vals.device_model: + config_image.append(['device_model', auxbin.path_bin(vals.device_model)]) if vals.vncpasswd is not None: config_image.append(['vncpasswd', vals.vncpasswd]) @@ -1120,10 +1116,9 @@ def make_config(vals): config_image = configure_image(vals) if vals.bootloader: - if vals.bootloader == "pygrub": - vals.bootloader = auxbin.pathTo(vals.bootloader) + t = auxbin.path_boot(vals.bootloader) - config.append(['bootloader', vals.bootloader]) + config.append(['bootloader', t]) if vals.bootargs: config.append(['bootloader_args', vals.bootargs]) else: Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendCheckpoint.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendCheckpoint.py 2014-02-10 12:53:55.834054507 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendCheckpoint.py 2014-02-10 12:56:14.734733560 +0100 @@ -118,7 +118,7 @@ def save(fd, dominfo, network, live, dst # enabled. Passing "0" simply uses the defaults compiled into # libxenguest; see the comments and/or code in xc_linux_save() for # more information. - cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), + cmd = [xen.util.auxbin.path_bin(XC_SAVE), str(fd), str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] log.debug("[xc_save]: %s", string.join(cmd)) @@ -299,7 +299,7 @@ def restore(xd, fd, dominfo = None, paus superpages = restore_image.superpages - cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE), + cmd = map(str, [xen.util.auxbin.path_bin(XC_RESTORE), fd, dominfo.getDomid(), store_port, console_port, int(is_hvm), pae, apic, superpages, 1]) log.debug("[xc_restore]: %s", string.join(cmd)) Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendConfig.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendConfig.py 2014-02-10 12:53:55.850054581 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendConfig.py 2014-02-10 12:56:14.738733575 +0100 @@ -493,11 +493,11 @@ class XendConfig(dict): if self.is_hvm() or self.has_rfb(): if 'device_model' not in self['platform']: - self['platform']['device_model'] = auxbin.pathTo("qemu-dm") + self['platform']['device_model'] = auxbin.path_bin("qemu-dm") # device_model may be set to 'qemu-dm' or 'stubdom-dm' w/o a path if os.path.dirname(self['platform']['device_model']) == "": self['platform']['device_model'] = \ - auxbin.pathTo(self['platform']['device_model']) + auxbin.path_bin(self['platform']['device_model']) # If the device_model is not set the os.path.exists() would raise # an exception so we return our error message instead if applicable if not self['platform']['device_model']: @@ -528,14 +528,14 @@ class XendConfig(dict): # Old configs may have hvmloader set as PV_kernel param if self.has_key('PV_kernel') and self['PV_kernel'] != '': if self['PV_kernel'] == 'hvmloader': - self['PV_kernel'] = auxbin.pathTo("hvmloader") + self['PV_kernel'] = auxbin.path_boot("hvmloader") self['platform']['loader'] = self['PV_kernel'] self['PV_kernel'] = '' else: - self['platform']['loader'] = auxbin.pathTo("hvmloader") + self['platform']['loader'] = auxbin.path_boot("hvmloader") log.debug("Loader is %s" % str(self['platform']['loader'])) elif self['platform']['loader'] == 'hvmloader': - self['platform']['loader'] = auxbin.pathTo("hvmloader") + self['platform']['loader'] = auxbin.path_boot("hvmloader") if not os.path.exists(self['platform']['loader']): raise VmError("kernel '%s' not found" % str(self['platform']['loader'])) @@ -1653,7 +1653,7 @@ class XendConfig(dict): # is invoked for pvfb services if 'device_model' not in target['platform']: target['platform']['device_model'] = \ - auxbin.pathTo("qemu-dm") + auxbin.path_bin("qemu-dm") # Finally, if we are a pvfb, we need to make a vkbd # as well that is not really exposed to Xen API Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/XendDomainInfo.py 2014-02-10 12:53:55.818054429 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/XendDomainInfo.py 2014-02-10 12:56:14.742733594 +0100 @@ -3244,7 +3244,7 @@ class XendDomainInfo: else: # Boot using bootloader if not blexec or blexec == 'pygrub': - blexec = auxbin.pathTo('pygrub') + blexec = auxbin.path_bin('pygrub') blcfg = None disks = [x for x in self.info['vbd_refs'] debian/patches/tools-xentrace-prefix.diff0000664000000000000000000000175712276137134015733 0ustar Index: xen-4.4.0~rc3+20140210/tools/xentrace/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xentrace/Makefile 2014-02-10 12:53:56.094055779 +0100 +++ xen-4.4.0~rc3+20140210/tools/xentrace/Makefile 2014-02-10 12:56:12.526722759 +0100 @@ -20,13 +20,11 @@ build: $(BIN) $(LIBBIN) .PHONY: install install: build - $(INSTALL_DIR) $(DESTDIR)$(BINDIR) - [ -z "$(LIBBIN)" ] || $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_DIR) $(DESTDIR)$(MAN1DIR) $(INSTALL_DIR) $(DESTDIR)$(MAN8DIR) - $(INSTALL_PROG) $(BIN) $(DESTDIR)$(BINDIR) - $(INSTALL_PYTHON_PROG) $(SCRIPTS) $(DESTDIR)$(BINDIR) - [ -z "$(LIBBIN)" ] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) $(BIN) $(LIBBIN) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PYTHON_PROG) $(SCRIPTS) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_DATA) $(MAN1) $(DESTDIR)$(MAN1DIR) $(INSTALL_DATA) $(MAN8) $(DESTDIR)$(MAN8DIR) debian/patches/tools-pygrub-remove-static-solaris-support.patch0000664000000000000000000000527512276137143022271 0ustar Index: xen-4.4.0~rc3+20140210/tools/pygrub/src/pygrub =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/pygrub/src/pygrub 2014-02-10 12:56:04.486683459 +0100 +++ xen-4.4.0~rc3+20140210/tools/pygrub/src/pygrub 2014-02-10 12:56:19.170755239 +0100 @@ -17,7 +17,6 @@ import os, sys, string, struct, tempfile import copy import logging import platform -import xen.lowlevel.xc import curses, _curses, curses.wrapper, curses.textpad, curses.ascii import getopt @@ -640,51 +639,6 @@ def run_grub(file, entry, fs, cfg_args): return grubcfg -def supports64bitPVguest(): - xc = xen.lowlevel.xc.xc() - caps = xc.xeninfo()['xen_caps'].split(" ") - for cap in caps: - if cap == "xen-3.0-x86_64": - return True - return False - -# If nothing has been specified, look for a Solaris domU. If found, perform the -# necessary tweaks. -def sniff_solaris(fs, cfg): - if not fs.file_exists("/platform/i86xpv/kernel/unix") and \ - not fs.file_exists("/platform/i86xpv/kernel/amd64/unix"): - return cfg - - if not cfg["kernel"]: - if supports64bitPVguest() and \ - fs.file_exists("/platform/i86xpv/kernel/amd64/unix"): - cfg["kernel"] = "/platform/i86xpv/kernel/amd64/unix" - cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive" - elif fs.file_exists("/platform/i86xpv/kernel/unix"): - cfg["kernel"] = "/platform/i86xpv/kernel/unix" - cfg["ramdisk"] = "/platform/i86pc/boot_archive" - else: - return cfg - - # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k', - # and we need to maintain Xen properties (root= and ip=) and the kernel - # before any user args. - - xenargs = "" - userargs = "" - - if not cfg["args"]: - cfg["args"] = cfg["kernel"] - else: - for arg in cfg["args"].split(): - if re.match("^root=", arg) or re.match("^ip=", arg): - xenargs += arg + " " - elif arg != cfg["kernel"]: - userargs += arg + " " - cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs - - return cfg - def sniff_netware(fs, cfg): if not fs.file_exists("/nwserver/xnloader.sys"): return cfg @@ -858,10 +812,7 @@ if __name__ == "__main__": try: fs = fsimage.open(file, offset, bootfsoptions) - chosencfg = sniff_solaris(fs, incfg) - - if not chosencfg["kernel"]: - chosencfg = sniff_netware(fs, incfg) + chosencfg = sniff_netware(fs, incfg) if not chosencfg["kernel"]: chosencfg = run_grub(file, entry, fs, incfg["args"]) debian/patches/xsa243-4.6-1.patch0000664000000000000000000000205013167430277013336 0ustar From: Andrew Cooper Subject: x86: Disable the use of auto-translated PV guests This is a minimal backport of c/s 92942fd3d469 "x86/mm: drop guest_{map,get_eff}_l1e() hooks" from Xen 4.7, which stated: Disallow the unmaintained and presumed broken translated-but-not-external paging mode combination ... It turns out that this mode is insecure to run with, as opposed to just simply broken. This is part of XSA-243. Signed-off-by: Andrew Cooper diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index dcff4fb..945bb61 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -835,6 +835,15 @@ void paging_final_teardown(struct domain *d) * creation. */ int paging_enable(struct domain *d, u32 mode) { + switch ( mode & (PG_external | PG_translate) ) + { + case 0: + case PG_external | PG_translate: + break; + default: + return -EINVAL; + } + if ( hap_enabled(d) ) return hap_enable(d, mode | PG_HAP_enable); else debian/patches/xsa187-4.7-0001-x86-shadow-Avoid-overflowing-sh_ctxt-seg.patch0000664000000000000000000000300212775471204023316 0ustar From: Andrew Cooper Subject: x86/shadow: Avoid overflowing sh_ctxt->seg_reg[] hvm_get_seg_reg() does not perform a range check on its input segment, calls hvm_get_segment_register() and writes straight into sh_ctxt->seg_reg[]. x86_seg_none is outside the bounds of sh_ctxt->seg_reg[], and will hit a BUG() in {vmx,svm}_get_segment_register(). HVM guests running with shadow paging can end up performing a virtual to linear translation with x86_seg_none. This is used for addresses which are already linear. However, none of this is a legitimate pagetable update, so fail the emulation in such a case. This is XSA-187 Reported-by: Andrew Cooper Signed-off-by: Andrew Cooper Reviewed-by: Tim Deegan --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -140,9 +140,18 @@ static int hvm_translate_linear_addr( struct sh_emulate_ctxt *sh_ctxt, unsigned long *paddr) { - struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt); + struct segment_register *reg; int okay; + /* + * Can arrive here with non-user segments. However, no such cirucmstance + * is part of a legitimate pagetable update, so fail the emulation. + */ + if ( !is_x86_user_segment(seg) ) + return X86EMUL_UNHANDLEABLE; + + reg = hvm_get_seg_reg(seg, sh_ctxt); + okay = hvm_virtual_to_linear_addr( seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr); debian/patches/version.patch0000664000000000000000000001541012553140613013326 0ustar #! /bin/sh /usr/share/dpatch/dpatch-run ## version.dpatch by Bastian Blank ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: No description. @DPATCH@ Index: xen-4.4.2/xen/Makefile =================================================================== --- xen-4.4.2.orig/xen/Makefile 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/Makefile 2015-07-20 11:38:13.423092931 +0200 @@ -122,20 +122,19 @@ delete-unfresh-files: @mv -f $@.tmp $@ # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. -include/xen/compile.h: include/xen/compile.h.in .banner +include/xen/compile.h: include/xen/compile.h.in @sed -e 's/@@date@@/$(shell LC_ALL=C date)/g' \ -e 's/@@time@@/$(shell LC_ALL=C date +%T)/g' \ - -e 's/@@whoami@@/$(XEN_WHOAMI)/g' \ - -e 's/@@domain@@/$(XEN_DOMAIN)/g' \ - -e 's/@@hostname@@/$(shell hostname)/g' \ -e 's!@@compiler@@!$(shell $(CC) $(CFLAGS) --version 2>&1 | head -1)!g' \ -e 's/@@version@@/$(XEN_VERSION)/g' \ -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ -e 's!@@changeset@@!$(shell tools/scmversion $(XEN_ROOT) || echo "unavailable")!g' \ + -e 's/@@system_distribution@@/$(shell lsb_release -is)/g' \ + -e 's/@@system_maintainer_domain@@/$(shell cd ../../../..; dpkg-parsechangelog | sed -ne 's,^Maintainer: .[^<]*<[^@>]*@\([^>]*\)>,\1,p')/g' \ + -e 's/@@system_maintainer_local@@/$(shell cd ../../../..; dpkg-parsechangelog | sed -ne 's,^Maintainer: .[^<]*<\([^@>]*\)@.*>,\1,p')/g' \ + -e 's/@@system_version@@/$(shell cd ../../../..; dpkg-parsechangelog | awk '/^Version:/ {print $$2}')/g' \ < include/xen/compile.h.in > $@.new - @cat .banner - @$(PYTHON) tools/fig-to-oct.py < .banner >> $@.new @mv -f $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s Index: xen-4.4.2/xen/common/kernel.c =================================================================== --- xen-4.4.2.orig/xen/common/kernel.c 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/common/kernel.c 2015-07-20 11:38:13.427092930 +0200 @@ -247,8 +247,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL memset(&info, 0, sizeof(info)); safe_strcpy(info.compiler, xen_compiler()); - safe_strcpy(info.compile_by, xen_compile_by()); - safe_strcpy(info.compile_domain, xen_compile_domain()); + safe_strcpy(info.compile_by, xen_compile_system_maintainer_local()); + safe_strcpy(info.compile_domain, xen_compile_system_maintainer_domain()); safe_strcpy(info.compile_date, xen_compile_date()); if ( copy_to_guest(arg, &info, 1) ) return -EFAULT; Index: xen-4.4.2/xen/common/version.c =================================================================== --- xen-4.4.2.orig/xen/common/version.c 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/common/version.c 2015-07-20 11:38:13.427092930 +0200 @@ -11,19 +11,24 @@ const char *xen_compile_time(void) return XEN_COMPILE_TIME; } -const char *xen_compile_by(void) +const char *xen_compile_system_distribution(void) { - return XEN_COMPILE_BY; + return XEN_COMPILE_SYSTEM_DISTRIBUTION; } -const char *xen_compile_domain(void) +const char *xen_compile_system_maintainer_local(void) { - return XEN_COMPILE_DOMAIN; + return XEN_COMPILE_SYSTEM_MAINTAINER_LOCAL; } -const char *xen_compile_host(void) +const char *xen_compile_system_maintainer_domain(void) { - return XEN_COMPILE_HOST; + return XEN_COMPILE_SYSTEM_MAINTAINER_DOMAIN; +} + +const char *xen_compile_system_version(void) +{ + return XEN_COMPILE_SYSTEM_VERSION; } const char *xen_compiler(void) @@ -51,7 +56,3 @@ const char *xen_changeset(void) return XEN_CHANGESET; } -const char *xen_banner(void) -{ - return XEN_BANNER; -} Index: xen-4.4.2/xen/drivers/char/console.c =================================================================== --- xen-4.4.2.orig/xen/drivers/char/console.c 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/drivers/char/console.c 2015-07-20 11:38:13.427092930 +0200 @@ -667,14 +667,11 @@ void __init console_init_preirq(void) serial_set_rx_handler(sercon_handle, serial_rx); /* HELLO WORLD --- start-of-day banner text. */ - spin_lock(&console_lock); - __putstr(xen_banner()); - spin_unlock(&console_lock); - printk("Xen version %d.%d%s (%s@%s) (%s) debug=%c %s\n", + printk("Xen version %d.%d%s (%s %s) (%s@%s) (%s) debug=%c %s\n", xen_major_version(), xen_minor_version(), xen_extra_version(), - xen_compile_by(), xen_compile_domain(), + xen_compile_system_distribution(), xen_compile_system_version(), + xen_compile_system_maintainer_local(), xen_compile_system_maintainer_domain(), xen_compiler(), debug_build() ? 'y' : 'n', xen_compile_date()); - printk("Latest ChangeSet: %s\n", xen_changeset()); if ( opt_sync_console ) { Index: xen-4.4.2/xen/include/xen/compile.h.in =================================================================== --- xen-4.4.2.orig/xen/include/xen/compile.h.in 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/include/xen/compile.h.in 2015-07-20 11:38:13.427092930 +0200 @@ -1,8 +1,9 @@ #define XEN_COMPILE_DATE "@@date@@" #define XEN_COMPILE_TIME "@@time@@" -#define XEN_COMPILE_BY "@@whoami@@" -#define XEN_COMPILE_DOMAIN "@@domain@@" -#define XEN_COMPILE_HOST "@@hostname@@" +#define XEN_COMPILE_SYSTEM_DISTRIBUTION "@@system_distribution@@" +#define XEN_COMPILE_SYSTEM_MAINTAINER_DOMAIN "@@system_maintainer_domain@@" +#define XEN_COMPILE_SYSTEM_MAINTAINER_LOCAL "@@system_maintainer_local@@" +#define XEN_COMPILE_SYSTEM_VERSION "@@system_version@@" #define XEN_COMPILER "@@compiler@@" #define XEN_VERSION @@version@@ @@ -10,4 +11,3 @@ #define XEN_EXTRAVERSION "@@extraversion@@" #define XEN_CHANGESET "@@changeset@@" -#define XEN_BANNER \ Index: xen-4.4.2/xen/include/xen/version.h =================================================================== --- xen-4.4.2.orig/xen/include/xen/version.h 2015-07-20 11:38:13.431092930 +0200 +++ xen-4.4.2/xen/include/xen/version.h 2015-07-20 11:38:13.427092930 +0200 @@ -3,14 +3,14 @@ const char *xen_compile_date(void); const char *xen_compile_time(void); -const char *xen_compile_by(void); -const char *xen_compile_domain(void); -const char *xen_compile_host(void); +const char *xen_compile_system_distribution(void); +const char *xen_compile_system_maintainer_domain(void); +const char *xen_compile_system_maintainer_local(void); +const char *xen_compile_system_version(void); const char *xen_compiler(void); unsigned int xen_major_version(void); unsigned int xen_minor_version(void); const char *xen_extra_version(void); const char *xen_changeset(void); -const char *xen_banner(void); #endif /* __XEN_VERSION_H__ */ debian/patches/xsa169.patch0000664000000000000000000000207212661613547012707 0ustar x86: make debug output consistent in hvm_set_callback_via The unconditional printks in the switch statement of the hvm_set_callback_via function results in Xen log spam in non debug versions of Xen. The printks are for debug output only so conditionally compile the entire switch statement on debug versions of Xen only. This is XSA-169. Signed-off-by: Malcolm Crossley Reviewed-by: Jan Beulich Acked-by: Ian Campbell --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -386,7 +386,8 @@ void hvm_set_callback_via(struct domain spin_unlock(&d->arch.hvm_domain.irq_lock); - dprintk(XENLOG_G_INFO, "Dom%u callback via changed to ", d->domain_id); +#ifndef NDEBUG + printk(XENLOG_G_INFO "Dom%u callback via changed to ", d->domain_id); switch ( via_type ) { case HVMIRQ_callback_gsi: @@ -402,6 +403,7 @@ void hvm_set_callback_via(struct domain printk("None\n"); break; } +#endif } struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v) debian/patches/xsa178-xen4.4-0007-libxl-Do-not-trust-backend-for-cdrom-insert.patch0000664000000000000000000000463212725542005024506 0ustar From 98d7429a69e58b0cd58451b631ecfa4943feb590 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 19:13:17 +0100 Subject: [PATCH 07/16] libxl: Do not trust backend for cdrom insert Use the /libxl path where appropriate. Rename `path' variable to `be_path' to make sure we caught all the occurrences. Specifically, when checking that the device still exists, check the `frontend' value in /libxl, rather than anything in the backend directory. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 01d41b1..362fb22 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2500,7 +2500,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, int rc, dm_ver; libxl__device device; - const char *path, *libxl_path; + const char *be_path, *libxl_path; xs_transaction_t t = XBT_NULL; char * tmp; @@ -2561,15 +2561,15 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, if (rc) goto out; } - path = libxl__device_backend_path(gc, &device); + be_path = libxl__device_backend_path(gc, &device); libxl_path = libxl__device_libxl_path(gc, &device); - /* Sanity check: make sure the backend exists before writing here */ - tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend", path)); + /* Sanity check: make sure the device exists before writing here */ + tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend", libxl_path)); if (!tmp) { LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Internal error: %s does not exist", - libxl__sprintf(gc, "%s/frontend", path)); + libxl__sprintf(gc, "%s/frontend", libxl_path)); rc = ERROR_FAIL; goto out; } @@ -2593,7 +2593,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, rc = libxl__xs_transaction_start(gc, &t); if (rc) goto out; - rc = libxl__xs_writev(gc, t, path, kvs); + rc = libxl__xs_writev(gc, t, be_path, kvs); if (rc) goto out; rc = libxl__xs_writev(gc, t, libxl_path, kvs); -- 1.9.1 debian/patches/xsa155-qemut-xenfb.patch0000664000000000000000000000306412631277605015133 0ustar From 0ffd4547665d2fec648ab2c9ff856c5d9db9b07c Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 20 Nov 2015 10:37:08 -0500 Subject: [PATCH 2/2] xenfb: avoid reading twice the same fields from the shared page Reading twice the same field could give the guest an attack of opportunity. In the case of event->type, gcc could compile the switch statement into a jump table, effectively ending up reading the type field multiple times. This is part of XSA-155. Signed-off-by: Stefano Stabellini --- qemu/hw/xenfb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qemu/hw/xenfb.c b/qemu/hw/xenfb.c index 75b2bc2..369d45d 100644 --- a/qemu/hw/xenfb.c +++ b/qemu/hw/xenfb.c @@ -827,18 +827,20 @@ static void xenfb_invalidate(void *opaque) static void xenfb_handle_events(struct XenFB *xenfb) { - uint32_t prod, cons; + uint32_t prod, cons, out_cons; struct xenfb_page *page = xenfb->c.page; prod = page->out_prod; - if (prod == page->out_cons) + out_cons = page->out_cons; + if (prod == out_cons) return; xen_rmb(); /* ensure we see ring contents up to prod */ - for (cons = page->out_cons; cons != prod; cons++) { + for (cons = out_cons; cons != prod; cons++) { union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); + uint8_t type = event->type; int x, y, w, h; - switch (event->type) { + switch (type) { case XENFB_TYPE_UPDATE: if (xenfb->up_count == UP_QUEUE) xenfb->up_fullscreen = 1; -- 2.1.0 debian/patches/xsa206-4.4-0018-oxenstored-comments-explaining-some-variables.patch0000664000000000000000000000450413104300260024622 0ustar From 4782ccf2f68941fa591cfa72275b678613314fea Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Tue, 14 Mar 2017 12:15:52 +0000 Subject: [PATCH 18/30] oxenstored: comments explaining some variables It took a while of reading and reasoning to work out what these are for, so here are comments to make life easier for everyone reading this code in future. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies Reviewed-by: Ian Jackson Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/store.ml | 1 + tools/ocaml/xenstored/transaction.ml | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml index 223ee21..9f619b8 100644 --- a/tools/ocaml/xenstored/store.ml +++ b/tools/ocaml/xenstored/store.ml @@ -211,6 +211,7 @@ let apply rnode path fct = lookup rnode path fct end +(* The Store.t type *) type t = { mutable stat_transaction_coalesce: int; diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index 6b37fc2..51d5d6a 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -69,11 +69,15 @@ let can_coalesce oldroot currentroot path = else false -type ty = No | Full of (int * Store.Node.t * Store.t) +type ty = No | Full of ( + int * (* Transaction id *) + Store.Node.t * (* Original root *) + Store.t (* A pointer to the canonical store: its root changes on each transaction-commit *) +) type t = { ty: ty; - store: Store.t; + store: Store.t; (* This is the store that we change in write operations. *) quota: Quota.t; mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list; mutable operations: (Packet.request * Packet.response) list; @@ -155,7 +159,7 @@ let commit ~con t = let has_commited = match t.ty with | No -> true - | Full (id, oldroot, cstore) -> + | Full (id, oldroot, cstore) -> (* "cstore" meaning current canonical store *) let commit_partial oldroot cstore store = (* get the lowest path of the query and verify that it hasn't been modified by others transactions. *) -- 2.1.4 debian/patches/tools-console-prefix.diff0000664000000000000000000000163212276137120015547 0ustar Index: xen-4.4.0~rc3+20140210/tools/console/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/console/Makefile 2014-02-10 12:53:57.706063654 +0100 +++ xen-4.4.0~rc3+20140210/tools/console/Makefile 2014-02-10 12:56:00.190662456 +0100 @@ -8,6 +8,7 @@ CFLAGS += $(CFLAGS_libxenstore) LDLIBS += $(LDLIBS_libxenctrl) LDLIBS += $(LDLIBS_libxenstore) LDLIBS += $(SOCKET_LIBS) +LDFLAGS += $(call LDFLAGS_RPATH,../lib) LDLIBS_xenconsoled += $(UTIL_LIBS) LDLIBS_xenconsoled += -lrt @@ -30,9 +31,7 @@ xenconsole: $(patsubst %.c,%.o,$(wildcar .PHONY: install install: $(BIN) - $(INSTALL_DIR) $(DESTDIR)/$(SBINDIR) - $(INSTALL_PROG) xenconsoled $(DESTDIR)/$(SBINDIR) $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) - $(INSTALL_PROG) xenconsole $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) xenconsole xenconsoled $(DESTDIR)$(PRIVATE_BINDIR) -include $(DEPS) debian/patches/tools-python-prefix.diff0000664000000000000000000000313112276137125015427 0ustar Index: xen-4.4.0~rc3+20140210/tools/python/xen/util/auxbin.py =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/util/auxbin.py 2014-02-10 12:53:56.922059821 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/util/auxbin.py 2014-02-10 12:56:05.234687115 +0100 @@ -19,29 +19,31 @@ import os import os.path import sys -from xen.util.path import * +import xen.util.path + + +class _Path(object): + def __init__(self, path=[]): + self._path = path + def __call__(self, name): + for dir in self._path: + real = os.path.join(dir, name) + if os.path.exists(real): + return real + + +path_bin = _Path([xen.util.path.PRIVATE_BINDIR, '/usr/lib/xen/bin', '/usr/sbin', '/sbin', '/usr/bin', '/bin']) +path_boot = _Path([xen.util.path.XENFIRMWAREDIR, '/usr/lib/xen/boot', '/boot']) def execute(exe, args = None): - exepath = pathTo(exe) + exepath = path_bin(exe) a = [ exepath ] if args: a.extend(args) - try: - os.execv(exepath, a) - except (OSError, TypeError), exn: - print exepath, ": ", exn - sys.exit(1) - -SEARCHDIRS = [ BINDIR, SBINDIR, LIBEXEC, PRIVATE_BINDIR, XENFIRMWAREDIR ] -def pathTo(exebin): - for dir in SEARCHDIRS: - exe = os.path.join(dir, exebin) - if os.path.exists(exe): - return exe - return None + os.execv(exepath, a) def xen_configdir(): - return XEN_CONFIG_DIR + return xen.util.path.XEN_CONFIG_DIR def scripts_dir(): - return XEN_SCRIPT_DIR + return xen.util.path.XEN_SCRIPT_DIR debian/patches/xsa218-4.4-0003-gnttab-Avoid-potential-double-put-of-maptrack-entry.patch0000664000000000000000000001521513126666326025521 0ustar From d188b4bf7c6d17fae1a7d14867aaeb72f972d3ac Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Fri, 2 Jun 2017 12:40:04 +0100 Subject: [PATCH 3/4] gnttab: Avoid potential double-put of maptrack entry Each grant mapping for a particular domain is tracked by an in-Xen "maptrack" entry. This entry is is referenced by a "handle", which is given to the guest when it calls gnttab_map_grant_ref(). There are two types of mapping a particular handle can refer to: GNTMAP_host_map and GNTMAP_device_map. A given gnttab_unmap_grant_ref() call can remove either only one or both of these entries. When a particular handle has no entries left, it must be freed. gnttab_unmap_grant_ref() loops through its grant unmap request list twice. It first removes entries from any host pagetables and (if appropraite) iommus; then it does a single domain TLB flush; then it does the clean-up, including telling the granter that entries are no longer being used (if appropriate). At the moment, it's during the first pass that the maptrack flags are cleared, but the second pass that the maptrack entry is freed. Unfortunately this allows the following race, which results in a double-free: A: (pass 1) clear host_map B: (pass 1) clear device_map A: (pass 2) See that maptrack entry has no mappings, free it B: (pass 2) See that maptrack entry has no mappings, free it # Unfortunately, unlike the active entry pinning update, we can't simply move the maptrack flag changes to the second half, because the maptrack flags are used to determine if iommu entries need to be added: a domain's iommu must never have fewer permissions than the maptrack flags indicate, or a subsequent map_grant_ref() might fail to add the necessary iommu entries. Instead, free the maptrack entry in the first pass if there are no further mappings. This is part of XSA-218. Signed-off-by: George Dunlap Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 63 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 28 deletions(-) --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -77,8 +77,8 @@ /* Shared state beteen *_unmap and *_unmap_complete */ u16 flags; unsigned long frame; - struct grant_mapping *map; struct domain *rd; + grant_ref_t ref; }; /* Number of unmap operations that are done between each tlb flush */ @@ -836,6 +836,8 @@ struct grant_table *lgt, *rgt; struct active_grant_entry *act; s16 rc = 0; + struct grant_mapping *map; + bool_t put_handle = 0; ld = current->domain; lgt = ld->grant_table; @@ -849,10 +851,10 @@ return; } - op->map = &maptrack_entry(lgt, op->handle); + map = &maptrack_entry(lgt, op->handle); spin_lock(&lgt->lock); - if ( unlikely(!op->map->flags) ) + if ( unlikely(!map->flags) ) { spin_unlock(&lgt->lock); gdprintk(XENLOG_INFO, "Zero flags for handle (%d).\n", op->handle); @@ -860,7 +862,7 @@ return; } - dom = op->map->domid; + dom = map->domid; spin_unlock(&lgt->lock); if ( unlikely((rd = rcu_lock_domain_by_id(dom)) == NULL) ) @@ -884,8 +886,8 @@ rgt = rd->grant_table; double_gt_lock(lgt, rgt); - op->flags = op->map->flags; - if ( unlikely(!op->flags) || unlikely(op->map->domid != dom) ) + op->flags = map->flags; + if ( unlikely(!op->flags) || unlikely(map->domid != dom) ) { gdprintk(XENLOG_WARNING, "Unstable handle %u\n", op->handle); rc = GNTST_bad_handle; @@ -893,7 +895,8 @@ } op->rd = rd; - act = &active_entry(rgt, op->map->ref); + op->ref = map->ref; + act = &active_entry(rgt, map->ref); if ( op->frame == 0 ) { @@ -906,7 +909,7 @@ "Bad frame number doesn't match gntref. (%lx != %lx)\n", op->frame, act->frame); - op->map->flags &= ~GNTMAP_device_map; + map->flags &= ~GNTMAP_device_map; } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -916,32 +919,45 @@ op->flags)) < 0 ) goto unmap_out; - op->map->flags &= ~GNTMAP_host_map; + map->flags &= ~GNTMAP_host_map; } - if ( is_pv_domain(ld) && need_iommu(ld) ) + if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ) + { + map->flags = 0; + put_handle = 1; + } + + unmap_out: + double_gt_unlock(lgt, rgt); + + if ( put_handle ) + put_maptrack_handle(lgt, op->handle); + + if ( rc == GNTST_okay && is_pv_domain(ld) && need_iommu(ld) ) { unsigned int wrc, rdc; int err = 0; + + double_gt_lock(lgt, rgt); + BUG_ON(paging_mode_translate(ld)); mapcount(lgt, rd, op->frame, &wrc, &rdc); if ( (wrc + rdc) == 0 ) err = iommu_unmap_page(ld, op->frame); else if ( wrc == 0 ) err = iommu_map_page(ld, op->frame, op->frame, IOMMUF_readable); + + double_gt_unlock(lgt, rgt); + if ( err ) - { rc = GNTST_general_error; - goto unmap_out; - } } /* If just unmapped a writable mapping, mark as dirtied */ - if ( !(op->flags & GNTMAP_readonly) ) + if ( rc == GNTST_okay && !(op->flags & GNTMAP_readonly) ) gnttab_mark_dirty(rd, op->frame); - unmap_out: - double_gt_unlock(lgt, rgt); op->status = rc; rcu_unlock_domain(rd); } @@ -955,7 +971,6 @@ grant_entry_header_t *sha; struct page_info *pg; uint16_t *status; - bool_t put_handle = 0; if ( rd == NULL ) { @@ -976,13 +991,13 @@ if ( rgt->gt_version == 0 ) goto unmap_out; - act = &active_entry(rgt, op->map->ref); - sha = shared_entry_header(rgt, op->map->ref); + act = &active_entry(rgt, op->ref); + sha = shared_entry_header(rgt, op->ref); if ( rgt->gt_version == 1 ) status = &sha->flags; else - status = &status_entry(rgt, op->map->ref); + status = &status_entry(rgt, op->ref); if ( unlikely(op->frame != act->frame) ) { @@ -1039,9 +1054,6 @@ act->pin -= GNTPIN_hstw_inc; } - if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 ) - put_handle = 1; - if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) && !(op->flags & GNTMAP_readonly) ) gnttab_clear_flag(_GTF_writing, status); @@ -1051,11 +1063,6 @@ unmap_out: spin_unlock(&rgt->lock); - if ( put_handle ) - { - op->map->flags = 0; - put_maptrack_handle(ld->grant_table, op->handle); - } rcu_unlock_domain(rd); } debian/patches/xsa199-trad.patch0000664000000000000000000000570313035177564013646 0ustar From b73bd1edc05d1bad5c018228146930d79315a5da Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 14 Nov 2016 17:19:46 +0000 Subject: [PATCH] qemu: ioport_read, ioport_write: be defensive about 32-bit addresses On x86, ioport addresses are 16-bit. That these functions take 32-bit arguments is a mistake. Changing the argument type to 16-bit will discard the top bits of any erroneous values from elsewhere in qemu. Also, check just before use that the value is in range. (This turns an ill-advised change to MAX_IOPORTS into a possible guest crash rather than a privilege escalation vulnerability.) And, in the Xen ioreq processor, clamp incoming ioport addresses to 16-bit values. Xen will never write >16-bit values but the guest may have access to the ioreq ring. We want to defend the rest of the qemu code from wrong values. This is XSA-199. Reported-by: yanghongke Signed-off-by: Ian Jackson --- i386-dm/helper2.c | 2 ++ vl.c | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) Index: xen-4.4.2/qemu/i386-dm/helper2.c =================================================================== --- xen-4.4.2.orig/qemu/i386-dm/helper2.c +++ xen-4.4.2/qemu/i386-dm/helper2.c @@ -379,6 +379,8 @@ static void cpu_ioreq_pio(CPUState *env, exit(-1); } + req->addr &= 0x0ffffU; + if (req->dir == IOREQ_READ) { if (!req->data_is_ptr) { req->data = do_inp(env, req->addr, req->size); Index: xen-4.4.2/qemu/vl.c =================================================================== --- xen-4.4.2.orig/qemu/vl.c +++ xen-4.4.2/qemu/vl.c @@ -52,6 +52,7 @@ #include +#include #include #include #include @@ -290,26 +291,30 @@ PicState2 *isa_pic; static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; -static uint32_t ioport_read(int index, uint32_t address) +static uint32_t ioport_read(int index, uint16_t address) { static IOPortReadFunc *default_func[3] = { default_ioport_readb, default_ioport_readw, default_ioport_readl }; + if (address >= MAX_IOPORTS) + abort(); IOPortReadFunc *func = ioport_read_table[index][address]; if (!func) func = default_func[index]; return func(ioport_opaque[address], address); } -static void ioport_write(int index, uint32_t address, uint32_t data) +static void ioport_write(int index, uint16_t address, uint32_t data) { static IOPortWriteFunc *default_func[3] = { default_ioport_writeb, default_ioport_writew, default_ioport_writel }; + if (address >= MAX_IOPORTS) + abort(); IOPortWriteFunc *func = ioport_write_table[index][address]; if (!func) func = default_func[index]; debian/patches/xsa179-qemut-4.4-0003-vga-factor-out-vga-register-setup.patch0000664000000000000000000001116712725551366023321 0ustar From df228023ce39e8b72bd5a198b8703319b8b9ca23 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 26 Apr 2016 15:24:18 +0200 Subject: [PATCH 3/5] vga: factor out vga register setup When enabling vbe mode qemu will setup a bunch of vga registers to make sure the vga emulation operates in correct mode for a linear framebuffer. Move that code to a separate function so we can call it from other places too. Signed-off-by: Gerd Hoffmann [Backport to qemu-xen-tradition] Signed-off-by: Andrew Cooper --- hw/vga.c | 70 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 29 deletions(-) Index: xen-4.4.2/qemu/hw/vga.c =================================================================== --- xen-4.4.2.orig/qemu/hw/vga.c 2016-06-07 15:48:40.144789811 +0200 +++ xen-4.4.2/qemu/hw/vga.c 2016-06-07 15:58:11.440781003 +0200 @@ -528,6 +528,44 @@ static void vga_ioport_write(void *opaqu } #ifdef CONFIG_BOCHS_VBE +/* we initialize the VGA graphic mode */ +static void vbe_update_vgaregs(VGAState *s) +{ + int h, shift_control; + + if (!vbe_enabled(s)) { + /* vbe is turned off -- nothing to do */ + return; + } + + /* graphic mode + memory map 1 */ + s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; + s->cr[0x17] |= 3; /* no CGA modes */ + s->cr[0x13] = s->vbe_line_offset >> 3; + /* width */ + s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; + /* height (only meaningful if < 1024) */ + h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; + s->cr[0x12] = h; + s->cr[0x07] = (s->cr[0x07] & ~0x42) | + ((h >> 7) & 0x02) | ((h >> 3) & 0x40); + /* line compare to 1023 */ + s->cr[0x18] = 0xff; + s->cr[0x07] |= 0x10; + s->cr[0x09] |= 0x40; + + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { + shift_control = 0; + s->sr[0x01] &= ~8; /* no double line */ + } else { + shift_control = 2; + s->sr[4] |= 0x08; /* set chain 4 mode */ + s->sr[2] |= 0x0f; /* activate all planes */ + } + s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5); + s->cr[0x09] &= ~0x9f; /* no double scan */ +} + static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) { VGAState *s = opaque; @@ -619,8 +657,6 @@ static void vbe_ioport_write_data(void * break; case VBE_DISPI_INDEX_ENABLE: if ((val & VBE_DISPI_ENABLED) && !vbe_enabled(s)) { - int h, shift_control; - if (s->vram_gmfn != s->lfb_addr) { set_vram_mapping(s, s->lfb_addr, s->lfb_end); } @@ -638,40 +674,13 @@ static void vbe_ioport_write_data(void * s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); s->vbe_start_addr = 0; + vbe_update_vgaregs(s); /* clear the screen (should be done in BIOS) */ if (!(val & VBE_DISPI_NOCLEARMEM)) { memset(s->vram_ptr, 0, s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); } - - /* we initialize the VGA graphic mode (should be done - in BIOS) */ - s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */ - s->cr[0x17] |= 3; /* no CGA modes */ - s->cr[0x13] = s->vbe_line_offset >> 3; - /* width */ - s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; - /* height (only meaningful if < 1024) */ - h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; - s->cr[0x12] = h; - s->cr[0x07] = (s->cr[0x07] & ~0x42) | - ((h >> 7) & 0x02) | ((h >> 3) & 0x40); - /* line compare to 1023 */ - s->cr[0x18] = 0xff; - s->cr[0x07] |= 0x10; - s->cr[0x09] |= 0x40; - - if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { - shift_control = 0; - s->sr[0x01] &= ~8; /* no double line */ - } else { - shift_control = 2; - s->sr[4] |= 0x08; /* set chain 4 mode */ - s->sr[2] |= 0x0f; /* activate all planes */ - } - s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5); - s->cr[0x09] &= ~0x9f; /* no double scan */ } else { /* XXX: the bios should do that */ s->bank_offset = 0; debian/patches/xsa213-4.5.patch0000664000000000000000000001421313104344000013153 0ustar From: Jan Beulich Subject: multicall: deal with early exit conditions In particular changes to guest privilege level require the multicall sequence to be aborted, as hypercalls are permitted from kernel mode only. While likely not very useful in a multicall, also properly handle the return value in the HYPERVISOR_iret case (which should be the guest specified value). This is XSA-213. Reported-by: Jann Horn Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Julien Grall Index: xen-4.4.2/xen/arch/arm/traps.c =================================================================== --- xen-4.4.2.orig/xen/arch/arm/traps.c +++ xen-4.4.2/xen/arch/arm/traps.c @@ -1243,30 +1243,33 @@ static bool_t check_multicall_32bit_clea return true; } -void do_multicall_call(struct multicall_entry *multi) +enum mc_disposition do_multicall_call(struct multicall_entry *multi) { arm_hypercall_fn_t call = NULL; if ( multi->op >= ARRAY_SIZE(arm_hypercall_table) ) { multi->result = -ENOSYS; - return; + return mc_continue; } call = arm_hypercall_table[multi->op].fn; if ( call == NULL ) { multi->result = -ENOSYS; - return; + return mc_continue; } if ( is_pv32_domain(current->domain) && !check_multicall_32bit_clean(multi) ) - return; + return mc_continue; multi->result = call(multi->args[0], multi->args[1], multi->args[2], multi->args[3], multi->args[4]); + + return likely(!usr_mode(guest_cpu_user_regs())) + ? mc_continue : mc_preempt; } /* Index: xen-4.4.2/xen/common/multicall.c =================================================================== --- xen-4.4.2.orig/xen/common/multicall.c +++ xen-4.4.2/xen/common/multicall.c @@ -40,6 +40,7 @@ do_multicall( struct mc_state *mcs = ¤t->mc_state; uint32_t i; int rc = 0; + enum mc_disposition disp = mc_continue; if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) ) { @@ -50,7 +51,7 @@ do_multicall( if ( unlikely(!guest_handle_okay(call_list, nr_calls)) ) rc = -EFAULT; - for ( i = 0; !rc && i < nr_calls; i++ ) + for ( i = 0; !rc && disp == mc_continue && i < nr_calls; i++ ) { if ( i && hypercall_preempt_check() ) goto preempted; @@ -63,7 +64,7 @@ do_multicall( trace_multicall_call(&mcs->call); - do_multicall_call(&mcs->call); + disp = do_multicall_call(&mcs->call); #ifndef NDEBUG { @@ -77,7 +78,14 @@ do_multicall( } #endif - if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, result)) ) + if ( unlikely(disp == mc_exit) ) + { + if ( __copy_field_to_guest(call_list, &mcs->call, result) ) + /* nothing, best effort only */; + rc = mcs->call.result; + } + else if ( unlikely(__copy_field_to_guest(call_list, &mcs->call, + result)) ) rc = -EFAULT; else if ( test_bit(_MCSF_call_preempted, &mcs->flags) ) { @@ -93,6 +101,9 @@ do_multicall( guest_handle_add_offset(call_list, 1); } + if ( unlikely(disp == mc_preempt) && i < nr_calls ) + goto preempted; + perfc_incr(calls_to_multicall); perfc_add(calls_from_multicall, i); mcs->flags = 0; Index: xen-4.4.2/xen/include/asm-arm/multicall.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-arm/multicall.h +++ xen-4.4.2/xen/include/asm-arm/multicall.h @@ -1,7 +1,11 @@ #ifndef __ASM_ARM_MULTICALL_H__ #define __ASM_ARM_MULTICALL_H__ -extern void do_multicall_call(struct multicall_entry *call); +extern enum mc_disposition { + mc_continue, + mc_exit, + mc_preempt, +} do_multicall_call(struct multicall_entry *call); #endif /* __ASM_ARM_MULTICALL_H__ */ /* Index: xen-4.4.2/xen/include/asm-x86/multicall.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-x86/multicall.h +++ xen-4.4.2/xen/include/asm-x86/multicall.h @@ -7,8 +7,21 @@ #include +enum mc_disposition { + mc_continue, + mc_exit, + mc_preempt, +}; + +#define multicall_ret(call) \ + (unlikely((call)->op == __HYPERVISOR_iret) \ + ? mc_exit \ + : likely(guest_kernel_mode(current, \ + guest_cpu_user_regs())) \ + ? mc_continue : mc_preempt) + #define do_multicall_call(_call) \ - do { \ + ({ \ __asm__ __volatile__ ( \ " movq %c1(%0),%%rax; " \ " leaq hypercall_table(%%rip),%%rdi; " \ @@ -36,9 +49,11 @@ /* all the caller-saves registers */ \ : "rax", "rcx", "rdx", "rsi", "rdi", \ "r8", "r9", "r10", "r11" ); \ - } while ( 0 ) + multicall_ret(_call); \ + }) #define compat_multicall_call(_call) \ + ({ \ __asm__ __volatile__ ( \ " movl %c1(%0),%%eax; " \ " leaq compat_hypercall_table(%%rip),%%rdi; "\ @@ -65,6 +80,8 @@ "i" (offsetof(__typeof__(*_call), result)) \ /* all the caller-saves registers */ \ : "rax", "rcx", "rdx", "rsi", "rdi", \ - "r8", "r9", "r10", "r11" ) \ + "r8", "r9", "r10", "r11" ); \ + multicall_ret(_call); \ + }) #endif /* __ASM_X86_MULTICALL_H__ */ debian/patches/xsa241-4.4.patch0000664000000000000000000001211713167435162013177 0ustar Index: xen-4.4.2/xen/arch/x86/mm.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm.c +++ xen-4.4.2/xen/arch/x86/mm.c @@ -2352,7 +2352,7 @@ static int _put_final_page_type(struct p */ if ( !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) - page->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(page); if ( ptpg && PGT_type_equal(type, ptpg->u.inuse.type_info) ) { dec_linear_uses(page); @@ -2368,7 +2368,7 @@ static int _put_final_page_type(struct p (PGT_count_mask|PGT_validated|PGT_partial)) == 1); if ( !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) - page->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(page); wmb(); page->u.inuse.type_info |= PGT_validated; } @@ -2422,7 +2422,7 @@ static int _put_page_type(struct page_in if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) ) { /* - * page_set_tlbflush_timestamp() accesses the same union + * set_tlbflush_timestamp() accesses the same union * linear_pt_count lives in. Unvalidated page table pages, * however, should occur during domain destruction only * anyway. Updating of linear_pt_count luckily is not @@ -2443,7 +2443,7 @@ static int _put_page_type(struct page_in */ if ( !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) - page->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(page); } if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) Index: xen-4.4.2/xen/arch/x86/mm/shadow/common.c =================================================================== --- xen-4.4.2.orig/xen/arch/x86/mm/shadow/common.c +++ xen-4.4.2/xen/arch/x86/mm/shadow/common.c @@ -1583,7 +1583,7 @@ void shadow_free(struct domain *d, mfn_t * TLBs when we reuse the page. Because the destructors leave the * contents of the pages in place, we can delay TLB flushes until * just before the allocator hands the page out again. */ - sp->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(sp); perfc_decr(shadow_alloc_count); page_list_add_tail(sp, &d->arch.paging.shadow.freelist); sp = next; Index: xen-4.4.2/xen/common/page_alloc.c =================================================================== --- xen-4.4.2.orig/xen/common/page_alloc.c +++ xen-4.4.2/xen/common/page_alloc.c @@ -849,7 +849,7 @@ static void free_heap_pages( /* If a page has no owner it will need no safety TLB flush. */ pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL); if ( pg[i].u.free.need_tlbflush ) - pg[i].tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(&pg[i]); /* This page is not a guest frame any more. */ page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */ Index: xen-4.4.2/xen/include/asm-arm/flushtlb.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-arm/flushtlb.h +++ xen-4.4.2/xen/include/asm-arm/flushtlb.h @@ -2,6 +2,7 @@ #define __ASM_ARM_FLUSHTLB_H__ #include +#include /* * Filter the given set of CPUs, removing those that definitely flushed their @@ -14,6 +15,11 @@ do { #define tlbflush_current_time() (0) +static inline void page_set_tlbflush_timestamp(struct page_info *page) +{ + page->tlbflush_timestamp = tlbflush_current_time(); +} + #if defined(CONFIG_ARM_32) # include #elif defined(CONFIG_ARM_64) Index: xen-4.4.2/xen/include/asm-x86/flushtlb.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-x86/flushtlb.h +++ xen-4.4.2/xen/include/asm-x86/flushtlb.h @@ -11,6 +11,7 @@ #define __FLUSHTLB_H__ #include +#include #include #include #include @@ -23,6 +24,20 @@ DECLARE_PER_CPU(u32, tlbflush_time); #define tlbflush_current_time() tlbflush_clock +static inline void page_set_tlbflush_timestamp(struct page_info *page) +{ + /* + * Prevent storing a stale time stamp, which could happen if an update + * to tlbflush_clock plus a subsequent flush IPI happen between the + * reading of tlbflush_clock and the writing of the struct page_info + * field. + */ + ASSERT(local_irq_is_enabled()); + local_irq_disable(); + page->tlbflush_timestamp = tlbflush_current_time(); + local_irq_enable(); +} + /* * @cpu_stamp is the timestamp at last TLB flush for the CPU we are testing. * @lastuse_stamp is a timestamp taken when the PFN we are testing was last debian/patches/xsa206-4.4-0023-oxenstored-only-record-operations-with-side-effects-.patch0000664000000000000000000000547013104300260025734 0ustar From b05fcb4ee2e09991ad43226370cac2a38b41de82 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 14:20:33 +0000 Subject: [PATCH 23/30] oxenstored: only record operations with side-effects in history There is no need to record "read" operations as they will never cause another transaction to fail. Signed-off-by: Jonathan Davies Reviewed-by: Thomas Sanders Backport 4.6 -> 4.5 by removing reference to XS_RESET_WATCHES. Reported-by: Juergen Gross Signed-off-by: Ian Jackson --- tools/ocaml/xenstored/process.ml | 46 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index b48df05..502e1d6 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -443,6 +443,36 @@ let function_of_type ty = | _ -> function_of_type_simple_op ty (** + * Determines which individual (non-transactional) operations we want to retain. + * We only want to retain operations that have side-effects in the store since + * these can be the cause of transactions failing. + *) +let retain_op_in_history ty = + match ty with + | Xenbus.Xb.Op.Write + | Xenbus.Xb.Op.Mkdir + | Xenbus.Xb.Op.Rm + | Xenbus.Xb.Op.Setperms -> true + | Xenbus.Xb.Op.Debug + | Xenbus.Xb.Op.Directory + | Xenbus.Xb.Op.Read + | Xenbus.Xb.Op.Getperms + | Xenbus.Xb.Op.Watch + | Xenbus.Xb.Op.Unwatch + | Xenbus.Xb.Op.Transaction_start + | Xenbus.Xb.Op.Transaction_end + | Xenbus.Xb.Op.Introduce + | Xenbus.Xb.Op.Release + | Xenbus.Xb.Op.Getdomainpath + | Xenbus.Xb.Op.Watchevent + | Xenbus.Xb.Op.Error + | Xenbus.Xb.Op.Isintroduced + | Xenbus.Xb.Op.Resume + | Xenbus.Xb.Op.Set_target + | Xenbus.Xb.Op.Restrict + | Xenbus.Xb.Op.Invalid -> false + +(** * Nothrow guarantee. *) let process_packet ~store ~cons ~doms ~con ~req = @@ -458,10 +488,18 @@ let process_packet ~store ~cons ~doms ~con ~req = Connection.get_transaction con tid in - let before = Store.copy store in - let response = input_handle_error ~cons ~doms ~fct ~con ~t ~req in - let after = Store.copy store in - if tid = Transaction.none then record_commit ~con ~tid ~before ~after; + let execute () = input_handle_error ~cons ~doms ~fct ~con ~t ~req in + + let response = + (* Note that transactions are recorded in history separately. *) + if tid = Transaction.none && retain_op_in_history ty then begin + let before = Store.copy store in + let response = execute () in + let after = Store.copy store in + record_commit ~con ~tid ~before ~after; + response + end else execute () + in let response = try if tid <> Transaction.none then -- 2.1.4 debian/patches/xsa206-4.4-0008-oxenstored-only-process-domain-connections-that-noti.patch0000664000000000000000000000775313104300257026077 0ustar From b10466d49d925e5c9bb360847e92a8cb7f899ac9 Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Fri, 24 Mar 2017 17:03:31 +0000 Subject: [PATCH 08/30] oxenstored: only process domain connections that notify us by events Currently, upon receiving an event, oxenstored will always scan/process all the domain connections (xs rings), disregarding which domain sent that event. This is rather costy and inefficient. It also shadows and indulges client for not correctly communicating with us on message/space availability. With this patch, oxenstore will only scan/process the domain connections that have correctly notified us by events or have IO actions leftover from previous communication. Reported-by: Juergen Gross Signed-off-by: Zheng Li Reviewed-by: David Scott --- tools/ocaml/xenstored/connection.ml | 4 ++++ tools/ocaml/xenstored/connections.ml | 9 ++++----- tools/ocaml/xenstored/xenstored.ml | 13 ++++++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml index 47695f8..807fc00 100644 --- a/tools/ocaml/xenstored/connection.ml +++ b/tools/ocaml/xenstored/connection.ml @@ -223,10 +223,14 @@ let pop_in con = Xenbus.Xb.get_in_packet con.xb let has_more_input con = Xenbus.Xb.has_more_input con.xb let has_output con = Xenbus.Xb.has_output con.xb +let has_old_output con = Xenbus.Xb.has_old_output con.xb let has_new_output con = Xenbus.Xb.has_new_output con.xb let peek_output con = Xenbus.Xb.peek_output con.xb let do_output con = Xenbus.Xb.output con.xb +let has_more_work con = + has_more_input con || not (has_old_output con) && has_new_output con + let incr_ops con = con.stat_nb_ops <- con.stat_nb_ops + 1 let mark_symbols con = diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml index 1c8d911..f9bc225 100644 --- a/tools/ocaml/xenstored/connections.ml +++ b/tools/ocaml/xenstored/connections.ml @@ -98,11 +98,10 @@ let iter cons fct = iter_domains cons fct; iter_anonymous cons fct let has_more_work cons = - Hashtbl.fold (fun id con acc -> - if Connection.has_more_input con then - con :: acc - else - acc) cons.domains [] + Hashtbl.fold + (fun id con acc -> + if Connection.has_more_work con then con :: acc else acc) + cons.domains [] let key_of_str path = if path.[0] = '@' diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index d74846c..4a1d027 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -57,7 +57,10 @@ let process_domains store cons domains = let con = Connections.find_domain cons (Domain.get_id domain) in Process.do_input store cons domains con; Process.do_output store cons domains con in - Domains.iter domains do_io_domain + List.iter + (fun c -> + match Connection.get_domain c with + | Some d -> do_io_domain d | _ -> ()) let sigusr1_handler store = try @@ -303,6 +306,7 @@ let _ = Connections.add_anonymous cons cfd can_write and handle_eventchn fd = let port = Event.pending eventchn in + debug "pending port %d" (Xeneventchn.to_int port); finally (fun () -> if Some port = eventchn.Event.virq_port then ( let (notify, deaddom) = Domains.cleanup xc domains in @@ -310,7 +314,10 @@ let _ = if deaddom <> [] || notify then Connections.fire_spec_watches cons "@releaseDomain" ) - ) (fun () -> Event.unmask eventchn port); + else + let c = Connections.find_domain_by_port cons port in + process_domains store cons domains [c] + ) (fun () -> Event.unmask eventchn port) and do_if_set fd set fct = if List.mem fd set then fct fd in @@ -380,7 +387,7 @@ let _ = process_special_fds sfds; if List.length cfds > 0 || List.length wset > 0 then process_connection_fds store cons domains cfds wset; - process_domains store cons domains + process_domains store cons domains mw in while not !quit -- 2.1.4 debian/patches/xsa175-4.4-0011-libxl-Cleanup-Have-libxl__alloc_vdev-use-libxl.patch0000664000000000000000000000365412725542771024523 0ustar From 45c12108db3643cfaafad41fbeca91fdc0d73c83 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 15:25:19 +0100 Subject: [PATCH 14/16] libxl: Cleanup: Have libxl__alloc_vdev use /libxl When allocating a vdev for a new disk, look in /libxl/device, rather than the frontends directory in xenstore. This is more in line with the other parts of libxl, which ought not to trust frontends. In this case, though, there is no security bug prior to this patch because the frontend is the toolstack domain itself. If libxl__alloc_vdev were ever changed to take a frontend domain argument, this patch will fix a latent security bug. This is a followup to XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 3a7ced6..88c85d6 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2627,7 +2627,7 @@ static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user, { const char *blkdev_start = (const char *) get_vdev_user; int devid = 0, disk = 0, part = 0; - char *dompath = libxl__xs_get_dompath(gc, LIBXL_TOOLSTACK_DOMID); + char *libxl_dom_path = libxl__xs_libxl_path(gc, LIBXL_TOOLSTACK_DOMID); libxl__device_disk_dev_number(blkdev_start, &disk, &part); if (part != 0) { @@ -2642,7 +2642,7 @@ static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user, return NULL; if (libxl__xs_read(gc, t, libxl__sprintf(gc, "%s/device/vbd/%d/backend", - dompath, devid)) == NULL) { + libxl_dom_path, devid)) == NULL) { if (errno == ENOENT) return libxl__devid_to_localdev(gc, devid); else -- 1.9.1 debian/patches/xsa239-4.5.patch0000664000000000000000000000371313167430153013204 0ustar From: Jan Beulich Subject: x86/HVM: prefill partially used variable on emulation paths Certain handlers ignore the access size (vioapic_write() being the example this was found with), perhaps leading to subsequent reads seeing data that wasn't actually written by the guest. For consistency and extra safety also do this on the read path of hvm_process_io_intercept(), even if this doesn't directly affect what guests get to see, as we've supposedly already dealt with read handlers leaving data completely unitialized. This is XSA-239. Signed-off-by: Jan Beulich --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -55,6 +55,7 @@ static int hvm_mmio_access(struct vcpu * { if ( p->dir == IOREQ_READ ) { + data = 0; if ( vio->mmio_retrying ) { if ( vio->mmio_large_read_bytes != p->size ) @@ -76,6 +77,7 @@ static int hvm_mmio_access(struct vcpu * { for ( i = 0; i < p->count; i++ ) { + data = 0; if ( vio->mmio_retrying ) { if ( vio->mmio_large_read_bytes != p->size ) @@ -124,6 +126,7 @@ static int hvm_mmio_access(struct vcpu * { for ( i = 0; i < p->count; i++ ) { + data = 0; switch ( hvm_copy_from_guest_phys(&data, p->data + step * i, p->size) ) { @@ -222,6 +225,7 @@ static int process_portio_intercept(port { if ( p->dir == IOREQ_READ ) { + data = 0; if ( vio->mmio_retrying ) { if ( vio->mmio_large_read_bytes != p->size ) @@ -246,6 +250,7 @@ static int process_portio_intercept(port { for ( i = 0; i < p->count; i++ ) { + data = 0; if ( vio->mmio_retrying ) { if ( vio->mmio_large_read_bytes != p->size ) debian/patches/tools-xenstat-abiname.diff0000664000000000000000000000355312276137116015703 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstat/libxenstat/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstat/libxenstat/Makefile 2014-02-10 12:53:58.002065101 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstat/libxenstat/Makefile 2014-02-10 12:55:58.150652482 +0100 @@ -22,17 +22,13 @@ libdir=$(prefix)/lib LDCONFIG=ldconfig MAKE_LINK=ln -sf -MAJOR=0 -MINOR=0 - LIB=src/libxenstat.a -SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR) -SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so +SHLIB=src/libxenstat.so OBJECTS-y=src/xenstat.o OBJECTS-$(CONFIG_Linux) += src/xenstat_linux.o OBJECTS-$(CONFIG_SunOS) += src/xenstat_solaris.o OBJECTS-$(CONFIG_NetBSD) += src/xenstat_netbsd.o -SONAME_FLAGS=-Wl,$(SONAME_LDFLAG) -Wl,libxenstat.so.$(MAJOR) +SONAME_FLAGS=-Wl,$(SONAME_LDFLAG),libxenstat.so WARN_FLAGS=-Wall -Werror @@ -43,7 +39,7 @@ LDLIBS-y = $(LDLIBS_libxenstore) $(LDLIB LDLIBS-$(CONFIG_SunOS) += -lkstat .PHONY: all -all: $(LIB) $(SHLIB) $(SHLIB_LINKS) +all: $(LIB) $(SHLIB) $(LIB): $(OBJECTS-y) $(AR) rc $@ $^ @@ -53,19 +49,11 @@ $(SHLIB): $(OBJECTS-y) $(CC) $(LDFLAGS) $(SONAME_FLAGS) $(SHLIB_LDFLAGS) -o $@ \ $(OBJECTS-y) $(LDLIBS-y) $(APPEND_LDFLAGS) -src/libxenstat.so.$(MAJOR): $(SHLIB) - $(MAKE_LINK) $(ip_p; - ip_data_len = be16_to_cpu(ip->ip_len) - hlen; - } + goto skip_offload; + } + + hlen = IP_HEADER_LENGTH(ip); + if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { + goto skip_offload; } - if (ip) + ip_protocol = ip->ip_p; + ip_data_len = be16_to_cpu(ip->ip_len) - hlen; + + if (txdw0 & CP_TX_IPCS) { - if (txdw0 & CP_TX_IPCS) - { - DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n")); + DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n")); - if (hleneth_payload_len) {/* min header length */ - /* bad packet header len */ - /* or packet too short */ - } - else - { - ip->ip_sum = 0; - ip->ip_sum = ip_checksum(ip, hlen); - DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); - } - } + ip->ip_sum = 0; + ip->ip_sum = ip_checksum(ip, hlen); + DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); + } - if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) - { -#if defined (DEBUG_RTL8139) - int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; -#endif - DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n", - ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss)); + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) + { + /* Large enough for the TCP header? */ + if (ip_data_len < sizeof(tcp_header)) { + goto skip_offload; + } - int tcp_send_offset = 0; - int send_count = 0; + int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; - /* maximum IP header length is 60 bytes */ - uint8_t saved_ip_header[60]; + DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n", + ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss)); - /* save IP header template; data area is used in tcp checksum calculation */ - memcpy(saved_ip_header, eth_payload_data, hlen); + int tcp_send_offset = 0; + int send_count = 0; - /* a placeholder for checksum calculation routine in tcp case */ - uint8_t *data_to_checksum = eth_payload_data + hlen - 12; - // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + /* maximum IP header length is 60 bytes */ + uint8_t saved_ip_header[60]; - /* pointer to TCP header */ - tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + /* save IP header template; data area is used in tcp checksum calculation */ + memcpy(saved_ip_header, eth_payload_data, hlen); - int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + /* a placeholder for checksum calculation routine in tcp case */ + uint8_t *data_to_checksum = eth_payload_data + hlen - 12; + // size_t data_to_checksum_len = eth_payload_len - hlen + 12; - /* ETH_MTU = ip header len + tcp header len + payload */ - int tcp_data_len = ip_data_len - tcp_hlen; - int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; + /* pointer to TCP header */ + tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n", - ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size)); + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); - /* note the cycle below overwrites IP header data, - but restores it from saved_ip_header before sending packet */ + /* Invalid TCP data offset? */ + if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { + goto skip_offload; + } - int is_last_frame = 0; + /* ETH_MTU = ip header len + tcp header len + payload */ + int tcp_data_len = ip_data_len - tcp_hlen; + int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; - for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) - { - uint16_t chunk_size = tcp_chunk_size; + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n", + ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size)); - /* check if this is the last frame */ - if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) - { - is_last_frame = 1; - chunk_size = tcp_data_len - tcp_send_offset; - } + /* note the cycle below overwrites IP header data, + but restores it from saved_ip_header before sending packet */ - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq))); + int is_last_frame = 0; - /* add 4 TCP pseudoheader fields */ - /* copy IP source and destination fields */ - memcpy(data_to_checksum, saved_ip_header + 12, 8); + for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) + { + uint16_t chunk_size = tcp_chunk_size; - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size)); + /* check if this is the last frame */ + if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) + { + is_last_frame = 1; + chunk_size = tcp_data_len - tcp_send_offset; + } - if (tcp_send_offset) - { - memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); - } + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq))); - /* keep PUSH and FIN flags only for the last frame */ - if (!is_last_frame) - { - TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); - } + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); - /* recalculate TCP checksum */ - ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; - p_tcpip_hdr->zeros = 0; - p_tcpip_hdr->ip_proto = IP_PROTO_TCP; - p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size)); - p_tcp_hdr->th_sum = 0; + if (tcp_send_offset) + { + memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); + } - int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum)); + /* keep PUSH and FIN flags only for the last frame */ + if (!is_last_frame) + { + TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); + } - p_tcp_hdr->th_sum = tcp_checksum; + /* recalculate TCP checksum */ + ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; + p_tcpip_hdr->zeros = 0; + p_tcpip_hdr->ip_proto = IP_PROTO_TCP; + p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); - /* restore IP header */ - memcpy(eth_payload_data, saved_ip_header, hlen); + p_tcp_hdr->th_sum = 0; - /* set IP data length and recalculate IP checksum */ - ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); + int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum)); - /* increment IP id for subsequent frames */ - ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); + p_tcp_hdr->th_sum = tcp_checksum; - ip->ip_sum = 0; - ip->ip_sum = ip_checksum(eth_payload_data, hlen); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); + /* restore IP header */ + memcpy(eth_payload_data, saved_ip_header, hlen); - int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size)); - rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0); + /* set IP data length and recalculate IP checksum */ + ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); - /* add transferred count to TCP sequence number */ - p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); - ++send_count; - } + /* increment IP id for subsequent frames */ + ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); - /* Stop sending this frame */ - saved_size = 0; + ip->ip_sum = 0; + ip->ip_sum = ip_checksum(eth_payload_data, hlen); + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); + + int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; + DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size)); + rtl8139_transfer_frame(s, saved_buffer, tso_send_size, + 0); + + /* add transferred count to TCP sequence number */ + p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); + ++send_count; } - else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) - { - DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n")); - /* maximum IP header length is 60 bytes */ - uint8_t saved_ip_header[60]; - memcpy(saved_ip_header, eth_payload_data, hlen); + /* Stop sending this frame */ + saved_size = 0; + } + else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) + { + DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n")); - uint8_t *data_to_checksum = eth_payload_data + hlen - 12; - // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + /* maximum IP header length is 60 bytes */ + uint8_t saved_ip_header[60]; + memcpy(saved_ip_header, eth_payload_data, hlen); - /* add 4 TCP pseudoheader fields */ - /* copy IP source and destination fields */ - memcpy(data_to_checksum, saved_ip_header + 12, 8); + uint8_t *data_to_checksum = eth_payload_data + hlen - 12; + // size_t data_to_checksum_len = eth_payload_len - hlen + 12; - if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) - { - DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len)); + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); - ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; - p_tcpip_hdr->zeros = 0; - p_tcpip_hdr->ip_proto = IP_PROTO_TCP; - p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); + if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) + { + DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len)); - tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); + ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; + p_tcpip_hdr->zeros = 0; + p_tcpip_hdr->ip_proto = IP_PROTO_TCP; + p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); - p_tcp_hdr->th_sum = 0; + tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); - int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum)); + p_tcp_hdr->th_sum = 0; - p_tcp_hdr->th_sum = tcp_checksum; - } - else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) - { - DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len)); + int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); + DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum)); - ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; - p_udpip_hdr->zeros = 0; - p_udpip_hdr->ip_proto = IP_PROTO_UDP; - p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); + p_tcp_hdr->th_sum = tcp_checksum; + } + else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) + { + DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len)); - udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); + ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; + p_udpip_hdr->zeros = 0; + p_udpip_hdr->ip_proto = IP_PROTO_UDP; + p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); - p_udp_hdr->uh_sum = 0; + udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); - int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum)); + p_udp_hdr->uh_sum = 0; - p_udp_hdr->uh_sum = udp_checksum; - } + int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); + DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum)); - /* restore IP header */ - memcpy(eth_payload_data, saved_ip_header, hlen); + p_udp_hdr->uh_sum = udp_checksum; } + + /* restore IP header */ + memcpy(eth_payload_data, saved_ip_header, hlen); } } +skip_offload: /* update tally counter */ ++s->tally_counters.TxOk; debian/patches/xsa131-qemut-2.patch0000664000000000000000000001204712571017445014162 0ustar xen/pt: consolidate PM capability emu_mask There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local emu_mask variable - we can have the same effect by setting the field descriptor's emu_mask member suitably right away. Note that xen_pt_pmcsr_reg_write() is being retained in order to allow later patches to be less intrusive. This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich Acked-by: Stefano Stabellini Acked-by: Ian Campbell --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -179,9 +179,6 @@ static int pt_long_reg_read(struct pt_de static int pt_bar_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint32_t *value, uint32_t valid_mask); -static int pt_pmcsr_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t valid_mask); static int pt_byte_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint8_t *value, uint8_t dev_value, uint8_t valid_mask); @@ -494,7 +491,7 @@ static struct pt_reg_info_tbl pt_emu_reg .u.w.write = pt_word_reg_write, .u.w.restore = NULL, }, - /* PCI Power Management Control/Status reg */ + /* PCI Power Management Control/Status reg (->power_mgmt on) */ { .offset = PCI_PM_CTRL, .size = 2, @@ -502,7 +499,19 @@ static struct pt_reg_info_tbl pt_emu_reg .ro_mask = 0xE1FC, .emu_mask = 0x8100, .init = pt_pmcsr_reg_init, - .u.w.read = pt_pmcsr_reg_read, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_pmcsr_reg_write, + .u.w.restore = pt_pmcsr_reg_restore, + }, + /* PCI Power Management Control/Status reg (->power_mgmt off) */ + { + .offset = PCI_PM_CTRL, + .size = 2, + .init_val = 0x0008, + .ro_mask = 0xE1FC, + .emu_mask = 0x810B, + .init = pt_pmcsr_reg_init, + .u.w.read = pt_word_reg_read, .u.w.write = pt_pmcsr_reg_write, .u.w.restore = pt_pmcsr_reg_restore, }, @@ -2919,6 +2928,7 @@ static uint32_t pt_pmc_reg_init(struct p return reg->init_val; } +/* this function will be called twice (for ->power_mgmt on and off cases) */ /* initialize PCI Power Management Control/Status register */ static uint32_t pt_pmcsr_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) @@ -2926,8 +2936,23 @@ static uint32_t pt_pmcsr_reg_init(struct PCIDevice *d = &ptdev->dev; uint16_t cap_ver = 0; - if (!ptdev->power_mgmt) - return reg->init_val; + switch (reg->emu_mask & (PCI_PM_CTRL_STATE_MASK | + PCI_PM_CTRL_NO_SOFT_RESET)) + { + case 0: + if (!ptdev->power_mgmt) + return PT_INVALID_REG; + break; + case PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET: + if (!ptdev->power_mgmt) + return reg->init_val; + return PT_INVALID_REG; + default: + /* exit I/O emulator */ + PT_LOG("Internal error: Invalid PMCSR emulation mask %04x." + " I/O emulator exit.\n", reg->emu_mask); + exit(1); + } /* check PCI Power Management support version */ cap_ver = ptdev->pm_state->pmc_field & PCI_PM_CAP_VER_MASK; @@ -3417,24 +3442,6 @@ static int pt_bar_reg_read(struct pt_dev } -/* read Power Management Control/Status register */ -static int pt_pmcsr_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t valid_emu_mask = reg->emu_mask; - - if (!ptdev->power_mgmt) - valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; - - valid_emu_mask = valid_emu_mask & valid_mask ; - *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); - - return 0; -} - - /* write byte size emulate register */ static int pt_byte_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -3768,21 +3775,17 @@ static int pt_pmcsr_reg_write(struct pt_ { struct pt_reg_info_tbl *reg = cfg_entry->reg; PCIDevice *d = &ptdev->dev; - uint16_t emu_mask = reg->emu_mask; uint16_t writable_mask = 0; uint16_t throughable_mask = 0; struct pt_pm_info *pm_state = ptdev->pm_state; uint16_t read_val = 0; - if (!ptdev->power_mgmt) - emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; - /* modify emulate register */ - writable_mask = emu_mask & ~reg->ro_mask & valid_mask; + writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~emu_mask & valid_mask; + throughable_mask = ~reg->emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); if (!ptdev->power_mgmt) debian/patches/xsa178-xen4.4-0013-libxl-Do-not-trust-backend-for-nic-in-list.patch0000664000000000000000000000601012725542005024213 0ustar From a0b99aba04d95f4345b3d141d802c5baf8177bb1 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 16:23:57 +0100 Subject: [PATCH 13/16] libxl: Do not trust backend for nic in list libxl_device_nic_list should use the /libxl path to search for devices, and for obtaining the device information. The "type" parameter was always "vif". Abolish it. (In any case, paths in /libxl/device are named after the frontend type which is constant, not the backend type which might in future vary.) Abolish a redundant store to pnic->backend_domid. Before this commit, that store was not needed because libxl_device_nic_init (called by libxl__device_nic_from_xenstore) would zero it. Now it overwrites the correct backend domid with zero; so remove it. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index ec141b5..3a7ced6 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3100,21 +3100,20 @@ out: return rc; } -static int libxl__append_nic_list_of_type(libxl__gc *gc, +static int libxl__append_nic_list(libxl__gc *gc, uint32_t domid, - const char *type, libxl_device_nic **nics, int *nnics) { - char *be_path = NULL; + char *libxl_dir_path = NULL; char **dir = NULL; unsigned int n = 0; libxl_device_nic *pnic = NULL, *pnic_end = NULL; int rc; - be_path = libxl__sprintf(gc, "%s/backend/%s/%d", - libxl__xs_get_dompath(gc, 0), type, domid); - dir = libxl__xs_directory(gc, XBT_NULL, be_path, &n); + libxl_dir_path = GCSPRINTF("%s/device/vif", + libxl__xs_libxl_path(gc, domid)); + dir = libxl__xs_directory(gc, XBT_NULL, libxl_dir_path, &n); if (dir && n) { libxl_device_nic *tmp; tmp = realloc(*nics, sizeof (libxl_device_nic) * (*nnics + n)); @@ -3125,10 +3124,9 @@ static int libxl__append_nic_list_of_type(libxl__gc *gc, pnic_end = *nics + *nnics + n; for (; pnic < pnic_end; pnic++, dir++) { const char *p; - p = libxl__sprintf(gc, "%s/%s", be_path, *dir); + p = GCSPRINTF("%s/%s", libxl_dir_path, *dir); rc = libxl__device_nic_from_xenstore(gc, p, pnic); if (rc) goto out; - pnic->backend_domid = 0; } *nnics += n; } @@ -3146,7 +3144,7 @@ libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx, uint32_t domid, int *num *num = 0; - rc = libxl__append_nic_list_of_type(gc, domid, "vif", &nics, num); + rc = libxl__append_nic_list(gc, domid, &nics, num); if (rc) goto out_err; GC_FREE; -- 1.9.1 debian/patches/tools-libfsimage-prefix.diff0000664000000000000000000000277612276137121016222 0ustar Index: xen-4.4.0~rc3+20140210/tools/libfsimage/Rules.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libfsimage/Rules.mk 2014-02-10 12:53:57.638063322 +0100 +++ xen-4.4.0~rc3+20140210/tools/libfsimage/Rules.mk 2014-02-10 12:56:00.898665912 +0100 @@ -6,7 +6,7 @@ LDFLAGS += -L../common/ PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y)) -FSDIR = $(LIBDIR)/fs +FSDIR = $(PRIVATE_LIBDIR)/fs FSLIB = fsimage.so Index: xen-4.4.0~rc3+20140210/tools/libfsimage/common/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libfsimage/common/Makefile 2014-02-10 12:55:55.710640548 +0100 +++ xen-4.4.0~rc3+20140210/tools/libfsimage/common/Makefile 2014-02-10 12:56:00.902665936 +0100 @@ -1,6 +1,8 @@ XEN_ROOT = $(CURDIR)/../../.. include $(XEN_ROOT)/tools/libfsimage/Rules.mk +CFLAGS += -DFSDIR="\"$(PRIVATE_LIBDIR)/fs\"" + LDFLAGS-$(CONFIG_SunOS) = -Wl,-M -Wl,mapfile-SunOS LDFLAGS-$(CONFIG_Linux) = -Wl,mapfile-GNU LDFLAGS = $(LDFLAGS-y) @@ -19,9 +21,9 @@ all: $(LIB) .PHONY: install install: all - $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_LIBDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_PROG) libfsimage.so $(DESTDIR)$(LIBDIR) + $(INSTALL_PROG) libfsimage.so $(DESTDIR)$(PRIVATE_LIBDIR) $(INSTALL_DATA) fsimage.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) fsimage_plugin.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) fsimage_grub.h $(DESTDIR)$(INCLUDEDIR) debian/patches/xsa234-4.5.patch0000664000000000000000000001566213167425614013213 0ustar From: Jan Beulich Subject: gnttab: also validate PTE permissions upon destroy/replace In order for PTE handling to match up with the reference counting done by common code, presence and writability of grant mapping PTEs must also be taken into account; validating just the frame number is not enough. This is in particular relevant if a guest fiddles with grant PTEs via non-grant hypercalls. Note that the flags being passed to replace_grant_host_mapping() already happen to be those of the existing mapping, so no new function parameter is needed. This is XSA-234. Reported-by: Andrew Cooper Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3833,7 +3833,8 @@ static int create_grant_pte_mapping( } static int destroy_grant_pte_mapping( - uint64_t addr, unsigned long frame, struct domain *d) + uint64_t addr, unsigned long frame, unsigned int grant_pte_flags, + struct domain *d) { int rc = GNTST_okay; void *va; @@ -3879,16 +3880,27 @@ static int destroy_grant_pte_mapping( ol1e = *(l1_pgentry_t *)va; - /* Check that the virtual address supplied is actually mapped to frame. */ - if ( unlikely(l1e_get_pfn(ol1e) != frame) ) + /* + * Check that the PTE supplied actually maps frame (with appropriate + * permissions). + */ + if ( unlikely(l1e_get_pfn(ol1e) != frame) || + unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & + (_PAGE_PRESENT | _PAGE_RW)) ) { page_unlock(page); - MEM_LOG("PTE entry %lx for address %"PRIx64" doesn't match frame %lx", - (unsigned long)l1e_get_intpte(ol1e), addr, frame); + MEM_LOG("PTE %"PRIpte" at %"PRIx64" doesn't match grant (%"PRIpte")", + l1e_get_intpte(ol1e), addr, + l1e_get_intpte(l1e_from_pfn(frame, grant_pte_flags))); rc = GNTST_general_error; goto failed; } + if ( unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & + ~(_PAGE_AVAIL | PAGE_CACHE_ATTRS)) ) + MEM_LOG("PTE flags %x at %"PRIx64" don't match grant (%x)\n", + l1e_get_flags(ol1e), addr, grant_pte_flags); + /* Delete pagetable entry. */ if ( unlikely(!UPDATE_ENTRY (l1, @@ -3897,7 +3909,7 @@ static int destroy_grant_pte_mapping( 0)) ) { page_unlock(page); - MEM_LOG("Cannot delete PTE entry at %p", va); + MEM_LOG("Cannot delete PTE entry at %"PRIx64, addr); rc = GNTST_general_error; goto failed; } @@ -3965,7 +3977,8 @@ static int create_grant_va_mapping( } static int replace_grant_va_mapping( - unsigned long addr, unsigned long frame, l1_pgentry_t nl1e, struct vcpu *v) + unsigned long addr, unsigned long frame, unsigned int grant_pte_flags, + l1_pgentry_t nl1e, struct vcpu *v) { l1_pgentry_t *pl1e, ol1e; unsigned long gl1mfn; @@ -4001,19 +4014,30 @@ static int replace_grant_va_mapping( ol1e = *pl1e; - /* Check that the virtual address supplied is actually mapped to frame. */ - if ( unlikely(l1e_get_pfn(ol1e) != frame) ) - { - MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx", - l1e_get_pfn(ol1e), addr, frame); + /* + * Check that the virtual address supplied is actually mapped to frame + * (with appropriate permissions). + */ + if ( unlikely(l1e_get_pfn(ol1e) != frame) || + unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & + (_PAGE_PRESENT | _PAGE_RW)) ) + { + MEM_LOG("PTE %"PRIpte" for %lx doesn't match grant (%"PRIpte")", + l1e_get_intpte(ol1e), addr, + l1e_get_intpte(l1e_from_pfn(frame, grant_pte_flags))); rc = GNTST_general_error; goto unlock_and_out; } + if ( unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & + ~(_PAGE_AVAIL | PAGE_CACHE_ATTRS)) ) + MEM_LOG("PTE flags %x for %"PRIx64" don't match grant (%x)", + l1e_get_flags(ol1e), addr, grant_pte_flags); + /* Delete pagetable entry. */ if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0)) ) { - MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e); + MEM_LOG("Cannot delete PTE entry for %"PRIx64, addr); rc = GNTST_general_error; goto unlock_and_out; } @@ -4027,9 +4051,11 @@ static int replace_grant_va_mapping( } static int destroy_grant_va_mapping( - unsigned long addr, unsigned long frame, struct vcpu *v) + unsigned long addr, unsigned long frame, unsigned int grant_pte_flags, + struct vcpu *v) { - return replace_grant_va_mapping(addr, frame, l1e_empty(), v); + return replace_grant_va_mapping(addr, frame, grant_pte_flags, + l1e_empty(), v); } static int create_grant_p2m_mapping(uint64_t addr, unsigned long frame, @@ -4123,21 +4149,42 @@ int replace_grant_host_mapping( unsigned long gl1mfn; struct page_info *l1pg; int rc; + unsigned int grant_pte_flags; if ( paging_mode_external(current->domain) ) return replace_grant_p2m_mapping(addr, frame, new_addr, flags); + grant_pte_flags = + _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_GNTTAB; + if ( cpu_has_nx ) + grant_pte_flags |= _PAGE_NX_BIT; + + if ( flags & GNTMAP_application_map ) + grant_pte_flags |= _PAGE_USER; + if ( !(flags & GNTMAP_readonly) ) + grant_pte_flags |= _PAGE_RW; + /* + * On top of the explicit settings done by create_grant_host_mapping() + * also open-code relevant parts of adjust_guest_l1e(). Don't mirror + * available and cachability flags, though. + */ + if ( !is_pv_32bit_domain(curr->domain) ) + grant_pte_flags |= (grant_pte_flags & _PAGE_USER) + ? _PAGE_GLOBAL + : _PAGE_GUEST_KERNEL | _PAGE_USER; + if ( flags & GNTMAP_contains_pte ) { if ( !new_addr ) - return destroy_grant_pte_mapping(addr, frame, curr->domain); + return destroy_grant_pte_mapping(addr, frame, grant_pte_flags, + curr->domain); MEM_LOG("Unsupported grant table operation"); return GNTST_general_error; } if ( !new_addr ) - return destroy_grant_va_mapping(addr, frame, curr); + return destroy_grant_va_mapping(addr, frame, grant_pte_flags, curr); pl1e = guest_map_l1e(curr, new_addr, &gl1mfn); if ( !pl1e ) @@ -4185,7 +4232,7 @@ int replace_grant_host_mapping( put_page(l1pg); guest_unmap_l1e(curr, pl1e); - rc = replace_grant_va_mapping(addr, frame, ol1e, curr); + rc = replace_grant_va_mapping(addr, frame, grant_pte_flags, ol1e, curr); if ( rc && !paging_mode_refcounts(curr->domain) ) put_page_from_l1e(ol1e, curr->domain); debian/patches/xsa151.patch0000664000000000000000000000137712616222140012666 0ustar xenoprof: free domain's vcpu array This was overlooked in fb442e2171 ("x86_64: allow more vCPU-s per guest"). This is XSA-151. Signed-off-by: Jan Beulich Reviewed-by: Ian Campbell --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -239,6 +239,7 @@ static int alloc_xenoprof_struct( d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages), 0); if ( d->xenoprof->rawbuf == NULL ) { + xfree(d->xenoprof->vcpu); xfree(d->xenoprof); d->xenoprof = NULL; return -ENOMEM; @@ -286,6 +287,7 @@ void free_xenoprof_pages(struct domain * free_xenheap_pages(x->rawbuf, order); } + xfree(x->vcpu); xfree(x); d->xenoprof = NULL; } debian/patches/xsa224-4.5-0002-gnttab-never-create-host-mapping-unless-asked-to.patch0000664000000000000000000000254013126670733025032 0ustar From 52078b99abbc534a5bda6f7d8ab2b403711a9bcf Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Jun 2017 15:21:27 +0100 Subject: [PATCH 2/4] gnttab: never create host mapping unless asked to We shouldn't create a host mapping unless asked to even in the case of mapping a granted MMIO page. In particular the mapping wouldn't be torn down when processing the matching unmap request. This is part of XSA-224. Reported-by: Jan Beulich Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 2679073..c40073d 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -736,10 +736,13 @@ __gnttab_map_grant_ref( goto undo_out; } - rc = create_grant_host_mapping( - op->host_addr, frame, op->flags, cache_flags); - if ( rc != GNTST_okay ) - goto undo_out; + if ( op->flags & GNTMAP_host_map ) + { + rc = create_grant_host_mapping(op->host_addr, frame, op->flags, + cache_flags); + if ( rc != GNTST_okay ) + goto undo_out; + } } else if ( owner == rd || owner == dom_cow ) { -- 2.1.4 debian/patches/xsa148-4.4.patch0000664000000000000000000000304012616222077013175 0ustar x86: guard against undue super page PTE creation When optional super page support got added (commit bd1cd81d64 "x86: PV support for hugepages"), two adjustments were missed: mod_l2_entry() needs to consider the PSE and RW bits when deciding whether to use the fast path, and the PSE bit must not be removed from L2_DISALLOW_MASK unconditionally. This is XSA-148. Signed-off-by: Jan Beulich Reviewed-by: Tim Deegan --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -163,7 +163,10 @@ static void put_superpage(unsigned long static uint32_t base_disallow_mask; #define L1_DISALLOW_MASK (base_disallow_mask | _PAGE_GNTTAB) -#define L2_DISALLOW_MASK (base_disallow_mask & ~_PAGE_PSE) + +#define L2_DISALLOW_MASK (unlikely(opt_allow_superpage) \ + ? base_disallow_mask & ~_PAGE_PSE \ + : base_disallow_mask) #define l3_disallow_mask(d) (!is_pv_32on64_domain(d) ? \ base_disallow_mask : \ @@ -1786,7 +1789,10 @@ static int mod_l2_entry(l2_pgentry_t *pl } /* Fast path for identical mapping and presence. */ - if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT) ) + if ( !l2e_has_changed(ol2e, nl2e, + unlikely(opt_allow_superpage) + ? _PAGE_PSE | _PAGE_RW | _PAGE_PRESENT + : _PAGE_PRESENT) ) { adjust_guest_l2e(nl2e, d); if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) ) debian/patches/xsa217-4.5.patch0000664000000000000000000000251413126666252013204 0ustar From: Jan Beulich Subject: x86/mm: disallow page stealing from HVM domains The operation's success can't be controlled by the guest, as the device model may have an active mapping of the page. If we nevertheless permitted this operation, we'd have to add further TLB flushing to prevent scenarios like "Domains A (HVM), B (PV), C (PV); B->target==A Steps: 1. B maps page X from A as writable 2. B unmaps page X without a TLB flush 3. A sends page X to C via GNTTABOP_transfer 4. C maps page X as pagetable (potentially causing a TLB flush in C, but not in B) At this point, X would be mapped as a pagetable in C while being writable through a stale TLB entry in B." A similar scenario could be constructed for A using XENMEM_exchange and some arbitrary PV domain C then having this page allocated. This is XSA-217. Reported-by: Jann Horn Signed-off-by: Jan Beulich Acked-by: George Dunlap Reviewed-by: Konrad Rzeszutek Wilk --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4217,6 +4217,9 @@ int steal_page( unsigned long x, y; bool_t drop_dom_ref = 0; + if ( paging_mode_external(d) ) + return -1; + spin_lock(&d->page_alloc_lock); if ( is_xen_heap_page(page) || (page_get_owner(page) != d) ) debian/patches/xsa181-4.4.patch0000664000000000000000000000240512725552175013204 0ustar From 605a2711c411247920116a5026e772815b1168cd Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 2 Jun 2016 14:19:00 +0100 Subject: [PATCH] xen/arm: Don't free p2m->first_level in p2m_teardown() before it has been allocated If p2m_init() didn't complete successfully, (e.g. due to VMID exhaustion), p2m_teardown() is called and unconditionally tries to free p2m->first_level before it has been allocated. free_domheap_pages() doesn't tolerate NULL pointers. This is XSA-181 Reported-by: Aaron Cornelius Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Reviewed-by: Julien Grall --- xen/arch/arm/p2m.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index aff7a2c..9cf6f91 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -615,7 +615,8 @@ void p2m_teardown(struct domain *d) while ( (pg = page_list_remove_head(&p2m->pages)) ) free_domheap_page(pg); - free_domheap_pages(p2m->first_level, P2M_FIRST_ORDER); + if ( p2m->first_level ) + free_domheap_pages(p2m->first_level, P2M_FIRST_ORDER); p2m->first_level = NULL; -- 2.1.4 debian/patches/xsa192-4.5.patch0000664000000000000000000000440613035176455013210 0ustar From: Jan Beulich Subject: x86/HVM: don't load LDTR with VM86 mode attrs during task switch Just like TR, LDTR is purely a protected mode facility and hence needs to be loaded accordingly. Also move its loading to where it architecurally belongs. This is XSA-192. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Tested-by: Andrew Cooper --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3577,16 +3577,15 @@ static void hvm_unmap_entry(void *p) } static int hvm_load_segment_selector( - enum x86_segment seg, uint16_t sel) + enum x86_segment seg, uint16_t sel, unsigned int eflags) { struct segment_register desctab, cs, segr; struct desc_struct *pdesc, desc; u8 dpl, rpl, cpl; int fault_type = TRAP_invalid_tss; - struct cpu_user_regs *regs = guest_cpu_user_regs(); struct vcpu *v = current; - if ( regs->eflags & X86_EFLAGS_VM ) + if ( eflags & X86_EFLAGS_VM ) { segr.sel = sel; segr.base = (uint32_t)sel << 4; @@ -3829,6 +3828,8 @@ void hvm_task_switch( if ( rc != HVMCOPY_okay ) goto out; + if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt, 0) ) + goto out; if ( hvm_set_cr3(tss.cr3) ) goto out; @@ -3851,13 +3852,12 @@ void hvm_task_switch( } exn_raised = 0; - if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt) || - hvm_load_segment_selector(x86_seg_es, tss.es) || - hvm_load_segment_selector(x86_seg_cs, tss.cs) || - hvm_load_segment_selector(x86_seg_ss, tss.ss) || - hvm_load_segment_selector(x86_seg_ds, tss.ds) || - hvm_load_segment_selector(x86_seg_fs, tss.fs) || - hvm_load_segment_selector(x86_seg_gs, tss.gs) ) + if ( hvm_load_segment_selector(x86_seg_es, tss.es, tss.eflags) || + hvm_load_segment_selector(x86_seg_cs, tss.cs, tss.eflags) || + hvm_load_segment_selector(x86_seg_ss, tss.ss, tss.eflags) || + hvm_load_segment_selector(x86_seg_ds, tss.ds, tss.eflags) || + hvm_load_segment_selector(x86_seg_fs, tss.fs, tss.eflags) || + hvm_load_segment_selector(x86_seg_gs, tss.gs, tss.eflags) ) exn_raised = 1; rc = hvm_copy_to_guest_virt( debian/patches/xsa231-4.5.patch0000664000000000000000000000655513167425042013204 0ustar From: George Dunlap Subject: xen/mm: make sure node is less than MAX_NUMNODES The output of MEMF_get_node(memflags) can be as large as nodeid_t can hold (currently 255). This is then used as an index to arrays of size MAX_NUMNODE, which is 64 on x86 and 1 on ARM, can be passed in by an untrusted guest (via memory_exchange and increase_reservation) and is not currently bounds-checked. Check the value in page_alloc.c before using it, and also check the value in the hypercall call sites and return -EINVAL if appropriate. Don't permit domains other than the hardware or control domain to allocate node-constrained memory. This is XSA-231. Reported-by: Matthew Daley Signed-off-by: George Dunlap Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -383,6 +383,30 @@ static void decrease_reservation(struct a->nr_done = i; } +static bool_t propagate_node(unsigned int xmf, unsigned int *memflags) +{ + const struct domain *currd = current->domain; + + BUILD_BUG_ON(XENMEMF_get_node(0) != NUMA_NO_NODE); + + if ( XENMEMF_get_node(xmf) == NUMA_NO_NODE ) + return 1; + + if ( is_hardware_domain(currd) || is_control_domain(currd) ) + { + if ( XENMEMF_get_node(xmf) >= MAX_NUMNODES ) + return 0; + + *memflags |= MEMF_node(XENMEMF_get_node(xmf)); + if ( xmf & XENMEMF_exact_node_request ) + *memflags |= MEMF_exact_node; + } + else if ( xmf & XENMEMF_exact_node_request ) + return 0; + + return 1; +} + static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) { struct xen_memory_exchange exch; @@ -455,6 +479,12 @@ static long memory_exchange(XEN_GUEST_HA } } + if ( unlikely(!propagate_node(exch.out.mem_flags, &memflags)) ) + { + rc = -EINVAL; + goto fail_early; + } + d = rcu_lock_domain_by_any_id(exch.in.domid); if ( d == NULL ) { @@ -473,7 +503,6 @@ static long memory_exchange(XEN_GUEST_HA d, XENMEMF_get_address_bits(exch.out.mem_flags) ? : (BITS_PER_LONG+PAGE_SHIFT))); - memflags |= MEMF_node(XENMEMF_get_node(exch.out.mem_flags)); for ( i = (exch.nr_exchanged >> in_chunk_order); i < (exch.in.nr_extents >> in_chunk_order); @@ -814,9 +843,8 @@ long do_memory_op(unsigned long cmd, XEN args.memflags = MEMF_bits(address_bits); } - args.memflags |= MEMF_node(XENMEMF_get_node(reservation.mem_flags)); - if ( reservation.mem_flags & XENMEMF_exact_node_request ) - args.memflags |= MEMF_exact_node; + if ( unlikely(!propagate_node(reservation.mem_flags, &args.memflags)) ) + return -EINVAL; if ( op == XENMEM_populate_physmap && (reservation.mem_flags & XENMEMF_populate_on_demand) ) --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -610,9 +610,13 @@ static struct page_info *alloc_heap_page if ( node >= MAX_NUMNODES ) node = cpu_to_node(smp_processor_id()); } + else if ( unlikely(node >= MAX_NUMNODES) ) + { + ASSERT_UNREACHABLE(); + return NULL; + } first_node = node; - ASSERT(node >= 0); ASSERT(zone_lo <= zone_hi); ASSERT(zone_hi < NR_ZONES); debian/patches/xsa206-4.4-0025-oxenstored-track-commit-history.patch0000664000000000000000000000261013104300260022015 0ustar From dd5758b85234356ad03615160433c0b0347a4aec Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Mon, 27 Mar 2017 08:58:29 +0000 Subject: [PATCH 25/30] oxenstored: track commit history Since the list of historic activity cannot grow without bound, it is safe to use this to track commits. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Thomas Sanders --- tools/ocaml/xenstored/process.ml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index f95992d..706b8a0 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -290,12 +290,7 @@ let write_response_log ~ty ~tid ~con ~response = let record_commit ~con ~tid ~before ~after = let inc r = r := Int64.add 1L !r in let finish_count = inc Transaction.counter; !Transaction.counter in - (* This call would leak memory if historic activity is retained forever - so can only be uncommented if history is guaranteed not to grow - unboundedly. History.push {History.con=con; tid=tid; before=before; after=after; finish_count=finish_count} - *) - () (* Replay a stored transaction against a fresh store, check the responses are all equivalent: if so, commit the transaction. Otherwise send the abort to -- 2.1.4 debian/patches/xsa178-xen4.4-0009-libxl-Rename-READ_BACKEND-to-READ_LIBXLDEV.patch0000664000000000000000000000564612725542005023073 0ustar From c1f9a268b8ad4b1052843e10960b0d2bf3f702e2 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 16:07:02 +0100 Subject: [PATCH 09/16] libxl: Rename READ_BACKEND to READ_LIBXLDEV We are going to want to change all the functions that use READ_BACKEND to get untrustworthy information from the backend, to use trustworthy information from /libxl. This will involve replacing READ_BACKEND, which reads from be_path, with a similar macro READ_LIBXLDEV, which reads from libxl_path. The macro name change generates a lot of clutter in the diff. So we break it out into this separate patch. Here, we rename the macro, but the implementation does not really match the new name. So, another way to look at this, is that we have transformed the bug: * All of the backends use READ_BACKEND, which is unsafe into the new bug: * READ_LIBXLDEV actually reads be_path, which is unsafe. There is no functional change as yet. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 5a9a05e..ed7687b 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3039,7 +3039,7 @@ static int libxl__device_nic_from_xenstore(libxl__gc *gc, libxl_device_nic_init(nic); -#define READ_BACKEND(tgc, subpath) ({ \ +#define READ_LIBXLDEV(tgc, subpath) ({ \ rc = libxl__xs_read_checked(tgc, XBT_NULL, \ GCSPRINTF("%s/" subpath, be_path), \ &tmp); \ @@ -3047,7 +3047,7 @@ static int libxl__device_nic_from_xenstore(libxl__gc *gc, (char*)tmp; \ }); - tmp = READ_BACKEND(gc, "handle"); + tmp = READ_LIBXLDEV(gc, "handle"); if (tmp) nic->devid = atoi(tmp); else @@ -3055,7 +3055,7 @@ static int libxl__device_nic_from_xenstore(libxl__gc *gc, /* nic->mtu = */ - tmp = READ_BACKEND(gc, "mac"); + tmp = READ_LIBXLDEV(gc, "mac"); if (tmp) { rc = libxl__parse_mac(tmp, nic->mac); if (rc) goto out; @@ -3063,9 +3063,9 @@ static int libxl__device_nic_from_xenstore(libxl__gc *gc, memset(nic->mac, 0, sizeof(nic->mac)); } - nic->ip = READ_BACKEND(NOGC, "ip"); - nic->bridge = READ_BACKEND(NOGC, "bridge"); - nic->script = READ_BACKEND(NOGC, "script"); + nic->ip = READ_LIBXLDEV(NOGC, "ip"); + nic->bridge = READ_LIBXLDEV(NOGC, "bridge"); + nic->script = READ_LIBXLDEV(NOGC, "script"); /* vif_ioemu nics use the same xenstore entries as vif interfaces */ nic->nictype = LIBXL_NIC_TYPE_VIF; -- 1.9.1 debian/patches/xsa141.patch0000664000000000000000000000203412571017662012667 0ustar From: Julien Grall Date: Thu, 13 Aug 2015 12:03:43 +0100 Subject: [PATCH] xen/arm: mm: Do not dump the p2m when mapping a foreign gfn The physmap operation XENMAPSPACE_gfmn_foreign is dumping the p2m when an error occured by calling dump_p2m_lookup. But this function is not using ratelimited printk. Any domain able to map foreign gfmn would be able to flood the Xen console. The information wasn't not useful so drop it. This is XSA-141. Signed-off-by: Julien Grall Acked-by: Ian Campbell --- xen/arch/arm/mm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index ae0f34c..d00d526 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -1114,7 +1114,6 @@ int xenmem_add_to_physmap_one( page = get_page_from_gfn(od, idx, &p2mt, P2M_ALLOC); if ( !page ) { - dump_p2m_lookup(od, pfn_to_paddr(idx)); rcu_unlock_domain(od); return -EINVAL; } -- 2.1.4 debian/patches/xsa155-qemut-qdisk-double-access.patch0000664000000000000000000000344512631277620017653 0ustar From 27942b0cb2327e93deb12326bbe7b36c81f9fa7b Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 20 Nov 2015 10:56:00 -0500 Subject: [PATCH] blkif: Avoid double access to src->nr_segments src is stored in shared memory and src->nr_segments is dereferenced twice at the end of the function. If a compiler decides to compile this into two separate memory accesses then the size limitation could be bypassed. Fix it by removing the double access to src->nr_segments. This is part of XSA-155. Signed-off-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- qemu/hw/xen_blkif.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/qemu/hw/xen_blkif.h b/qemu/hw/xen_blkif.h index ca3a65b..eb29cb1 100644 --- a/qemu/hw/xen_blkif.h +++ b/qemu/hw/xen_blkif.h @@ -79,8 +79,10 @@ static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque dst->handle = src->handle; dst->id = src->id; dst->sector_number = src->sector_number; - if (n > src->nr_segments) - n = src->nr_segments; + /* prevent the compiler from optimizing the code and using src->nr_segments instead */ + xen_mb(); + if (n > dst->nr_segments) + n = dst->nr_segments; for (i = 0; i < n; i++) dst->seg[i] = src->seg[i]; } @@ -94,8 +96,10 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_reque dst->handle = src->handle; dst->id = src->id; dst->sector_number = src->sector_number; - if (n > src->nr_segments) - n = src->nr_segments; + /* prevent the compiler from optimizing the code and using src->nr_segments instead */ + xen_mb(); + if (n > dst->nr_segments) + n = dst->nr_segments; for (i = 0; i < n; i++) dst->seg[i] = src->seg[i]; } -- 2.4.3 debian/patches/xsa218-4.4-0004-gnttab-correct-maptrack-table-accesses.patch0000664000000000000000000000170713126666335023162 0ustar From 1b0cf99d046286c601a28af0ef7c1a17eb3eb2cb Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 15 Jun 2017 12:05:29 +0100 Subject: [PATCH 4/4] gnttab: correct maptrack table accesses In order to observe a consistent (limit,pointer-table) pair, the reader needs to either hold the maptrack lock (in line with documentation) or both sides need to order their accesses suitably. At the same time add read barriers to lockless readers. This is part of XSA-218. Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 5203929..ac98aef 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -908,7 +908,9 @@ __gnttab_unmap_common( return; } + smp_rmb(); map = &maptrack_entry(lgt, op->handle); + spin_lock(&lgt->lock); if ( unlikely(!map->flags) ) -- 2.1.4 debian/patches/xsa175-4.4-0001-libxl-Record-backend-frontend-paths-in-libxl-DOMID.patch0000664000000000000000000001661612725264607025007 0ustar From 9a5ccbd7b599c75b3a95c52bf128e362c0ae9e45 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 16 May 2016 16:44:31 +0100 Subject: [PATCH 01/10] libxl: Record backend/frontend paths in /libxl/$DOMID This gives us a record of all the backends we have set up for a domain, which is separate from the frontends in /local/domain/$DOMID/device. In particular: 1. A guest has write permission for the frontend path: /local/domain/$DOMID/device/$KIND/$DEVID which means that the guest can completely delete the frontend. (They can't recreate it because they don't have write permission on the containing directory.) 2. A guest has write permission for the backend path recorded in the frontend, ie, it can write to /local/domain/$DOMID/device/$KIND/$DEVID/backend which means that the guest can break the association between frontend and backend. So we can't rely on iterating over the frontends to find all the backends, or examining a frontend to discover how a device is configured. So, have libxl__device_generic_add record the frontend and backend paths in /libxl/$DOMID/device, and have libxl__device_destroy remove them again. Create the containing directory /libxl/GUEST/device in libxl__domain_make. The already existing xs_rm in devices_destroy_cb will take care of removing it. This is part of XSA-175. Backport note: Backported over 7472ced, which fixes a bug in driver domain teardown. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- v2: Correct actual path computation (!) v3: Correct actual path computation - really this time (!) --- docs/misc/xenstore-paths.markdown | 15 +++++++++++++++ tools/libxl/libxl_create.c | 2 ++ tools/libxl/libxl_device.c | 34 +++++++++++++++++++++++++++++++++- tools/libxl/libxl_internal.h | 1 + 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/misc/xenstore-paths.markdown b/docs/misc/xenstore-paths.markdown index 70ab7f4..e018b55 100644 --- a/docs/misc/xenstore-paths.markdown +++ b/docs/misc/xenstore-paths.markdown @@ -381,6 +381,21 @@ The guest's virtual time offset from UTC in seconds. ### libxl Specific Paths +#### /libxl/$DOMID/device/$KIND/$DEVID + +Created by libxl for every frontend/backend pair created for $DOMID. +Used by libxl for enumeration and management of the device. + +#### /libxl/$DOMID/device/$KIND/$DEVID/frontend + +Path in xenstore to the frontend, normally +/local/domain/$DOMID/device/$KIND/$DEVID + +#### /libxl/$DOMID/device/$KIND/$DEVID/backend + +Path in xenstore to the backend, normally +/local/domain/$BACKEND_DOMID/backend/$KIND/$DOMID/$DEVID + #### /libxl/$DOMID/dm-version ("qemu\_xen"|"qemu\_xen\_traditional") = [n,INTERNAL] The device model version for a domain. diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 5292c15..0e26666 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -528,6 +528,8 @@ retry_transaction: xs_rm(ctx->xsh, t, libxl_path); libxl__xs_mkdir(gc, t, libxl_path, noperm, ARRAY_SIZE(noperm)); + libxl__xs_mkdir(gc, t, GCSPRINTF("%s/device", libxl_path), + noperm, ARRAY_SIZE(noperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl__domain_rename(gc, *domid, 0, info->name, t); diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 29ed547..e9d2424 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -40,6 +40,15 @@ char *libxl__device_backend_path(libxl__gc *gc, libxl__device *device) device->domid, device->devid); } +char *libxl__device_libxl_path(libxl__gc *gc, libxl__device *device) +{ + char *libxl_dom_path = libxl__xs_libxl_path(gc, device->domid); + + return GCSPRINTF("%s/device/%s/%d", libxl_dom_path, + libxl__device_kind_to_string(device->kind), + device->devid); +} + int libxl__parse_backend_path(libxl__gc *gc, const char *path, libxl__device *dev) @@ -87,14 +96,16 @@ int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, libxl__device *device, char **bents, char **fents, char **ro_fents) { libxl_ctx *ctx = libxl__gc_owner(gc); - char *frontend_path, *backend_path; + char *frontend_path, *backend_path, *libxl_path; struct xs_permissions frontend_perms[2]; struct xs_permissions ro_frontend_perms[2]; struct xs_permissions backend_perms[2]; int create_transaction = t == XBT_NULL; + int rc; frontend_path = libxl__device_frontend_path(gc, device); backend_path = libxl__device_backend_path(gc, device); + libxl_path = libxl__device_libxl_path(gc, device); frontend_perms[0].id = device->domid; frontend_perms[0].perms = XS_PERM_NONE; @@ -109,8 +120,22 @@ int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, retry_transaction: if (create_transaction) t = xs_transaction_start(ctx->xsh); + /* FIXME: read frontend_path and check state before removing stuff */ + rc = libxl__xs_rm_checked(gc, t, libxl_path); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/frontend",libxl_path), + frontend_path); + if (rc) goto out; + + rc = libxl__xs_write_checked(gc, t, GCSPRINTF("%s/backend",libxl_path), + backend_path); + if (rc) goto out; + + /* xxx much of this function lacks error checks! */ + if (fents || ro_fents) { xs_rm(ctx->xsh, t, frontend_path); xs_mkdir(ctx->xsh, t, frontend_path); @@ -156,6 +181,11 @@ retry_transaction: } } return 0; + + out: + if (create_transaction && t) + libxl__xs_transaction_abort(gc, &t); + return rc; } typedef struct { @@ -552,6 +582,7 @@ int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) { const char *be_path = libxl__device_backend_path(gc, dev); const char *fe_path = libxl__device_frontend_path(gc, dev); + const char *libxl_path = libxl__device_libxl_path(gc, dev); const char *tapdisk_path = GCSPRINTF("%s/%s", be_path, "tapdisk-params"); const char *tapdisk_params; xs_transaction_t t = 0; @@ -576,6 +607,7 @@ int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) */ libxl__xs_path_cleanup(gc, t, fe_path); libxl__xs_path_cleanup(gc, t, be_path); + libxl__xs_path_cleanup(gc, t, libxl_path); } else if (dev->backend_domid == domid) { /* * The driver domain is in charge for removing what it can diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index f6d469b..801e95d 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -968,6 +968,7 @@ _hidden int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, libxl__device *device, char **bents, char **fents, char **ro_fents); _hidden char *libxl__device_backend_path(libxl__gc *gc, libxl__device *device); _hidden char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device); +_hidden char *libxl__device_libxl_path(libxl__gc *gc, libxl__device *device); _hidden int libxl__parse_backend_path(libxl__gc *gc, const char *path, libxl__device *dev); _hidden int libxl__device_destroy(libxl__gc *gc, libxl__device *dev); -- 2.1.4 debian/patches/xsa218-4.4-0002-gnttab-fix-unmap-pin-accounting-race.patch0000664000000000000000000000657313126666314022576 0ustar From abbbccaa119bf8b05f0828bd9138104f08c4f8df Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Jun 2017 12:22:42 +0100 Subject: [PATCH 2/4] gnttab: fix unmap pin accounting race Once all {writable} mappings of a grant entry have been unmapped, the hypervisor informs the guest that the grant entry has been released by clearing the _GTF_{reading,writing} usage flags in the guest's grant table as appropriate. Unfortunately, at the moment, the code that updates the accounting happens in a different critical section than the one which updates the usage flags; this means that under the right circumstances, there may be a window in time after the hypervisor reported the grant as being free during which the grant referee still had access to the page. Move the grant accounting code into the same critical section as the reporting code to make sure this kind of race can't happen. This is part of XSA-218. Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -905,15 +905,8 @@ PIN_FAIL(unmap_out, GNTST_general_error, "Bad frame number doesn't match gntref. (%lx != %lx)\n", op->frame, act->frame); - if ( op->flags & GNTMAP_device_map ) - { - ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask)); - op->map->flags &= ~GNTMAP_device_map; - if ( op->flags & GNTMAP_readonly ) - act->pin -= GNTPIN_devr_inc; - else - act->pin -= GNTPIN_devw_inc; - } + + op->map->flags &= ~GNTMAP_device_map; } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -923,12 +916,7 @@ op->flags)) < 0 ) goto unmap_out; - ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)); op->map->flags &= ~GNTMAP_host_map; - if ( op->flags & GNTMAP_readonly ) - act->pin -= GNTPIN_hstr_inc; - else - act->pin -= GNTPIN_hstw_inc; } if ( is_pv_domain(ld) && need_iommu(ld) ) @@ -1016,6 +1004,12 @@ else put_page_and_type(pg); } + + ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask)); + if ( op->flags & GNTMAP_readonly ) + act->pin -= GNTPIN_devr_inc; + else + act->pin -= GNTPIN_devw_inc; } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -1024,7 +1018,9 @@ { /* * Suggests that __gntab_unmap_common failed in - * replace_grant_host_mapping() so nothing further to do + * replace_grant_host_mapping() or IOMMU handling, so nothing + * further to do (short of re-establishing the mapping in the + * latter case). */ goto unmap_out; } @@ -1035,6 +1031,12 @@ put_page_type(pg); put_page(pg); } + + ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)); + if ( op->flags & GNTMAP_readonly ) + act->pin -= GNTPIN_hstr_inc; + else + act->pin -= GNTPIN_hstw_inc; } if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 ) debian/patches/xsa178-xen4.4-0010-libxl-Have-READ_LIBXLDEV-use-libxl_path-rather-than-.patch0000664000000000000000000000356412725542005025502 0ustar From 7e42cb64bcf6cdfe679c04fede8fb6f45cf75a84 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 15:40:18 +0100 Subject: [PATCH 10/16] libxl: Have READ_LIBXLDEV use libxl_path rather than be_path Fix the just-introduced bug in this macro: now it reads the trustworthy libxl_path. Change the variable name in the two functions (nic and channel) which use it. Shuffling the bump in the carpet along, we now introduce three new bugs: the three call sites pass a backend path where a frontend path is expected. No functional change. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index ed7687b..0bf1c5b 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3031,7 +3031,7 @@ out: } static int libxl__device_nic_from_xenstore(libxl__gc *gc, - const char *be_path, + const char *libxl_path, libxl_device_nic *nic) { const char *tmp; @@ -3041,7 +3041,7 @@ static int libxl__device_nic_from_xenstore(libxl__gc *gc, #define READ_LIBXLDEV(tgc, subpath) ({ \ rc = libxl__xs_read_checked(tgc, XBT_NULL, \ - GCSPRINTF("%s/" subpath, be_path), \ + GCSPRINTF("%s/" subpath, libxl_path), \ &tmp); \ if (rc) goto out; \ (char*)tmp; \ -- 1.9.1 debian/patches/xsa206-4.4-0016-oxenstored-log-request-and-response-during-transacti.patch0000664000000000000000000000705513104300260026053 0ustar From c89859c4735ce717d4115a4f056c9565363b05a1 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:54:28 +0000 Subject: [PATCH 16/30] oxenstored: log request and response during transaction replay During a transaction replay, the replayed requests and the new responses are logged in the same way as the original requests and the original responses. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/process.ml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 3ade42d..10b7357 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -275,6 +275,18 @@ let input_handle_error ~cons ~doms ~fct ~con ~t ~req = | (Failure "int_of_string") -> reply_error "EINVAL" | Define.Unknown_operation -> reply_error "ENOSYS" +let write_access_log ~ty ~tid ~con ~data = + Logging.xb_op ~ty ~tid ~con data + +let write_answer_log ~ty ~tid ~con ~data = + Logging.xb_answer ~ty ~tid ~con data + +let write_response_log ~ty ~tid ~con ~response = + match response with + | Packet.Ack _ -> write_answer_log ~ty ~tid ~con ~data:"" + | Packet.Reply x -> write_answer_log ~ty ~tid ~con ~data:x + | Packet.Error e -> write_answer_log ~ty:(Xenbus.Xb.Op.Error) ~tid ~con ~data:e + (* Replay a stored transaction against a fresh store, check the responses are all equivalent: if so, commit the transaction. Otherwise send the abort to the client. *) @@ -288,8 +300,10 @@ let transaction_replay c t doms cons = let new_t = Transaction.make tid cstore in let con = sprintf "r(%d):%s" id (Connection.get_domstr c) in let perform_exn (request, response) = + write_access_log ~ty:request.Packet.ty ~tid ~con ~data:request.Packet.data; let fct = function_of_type_simple_op request.Packet.ty in let response' = input_handle_error ~cons ~doms ~fct ~con:c ~t:new_t ~req:request in + write_response_log ~ty:request.Packet.ty ~tid ~con ~response:response'; if not(Packet.response_equal response response') then raise Transaction_again in finally (fun () -> @@ -444,12 +458,6 @@ let process_packet ~store ~cons ~doms ~con ~req = error "process packet: %s" (Printexc.to_string exn); Connection.send_error con tid rid "EIO" -let write_access_log ~ty ~tid ~con ~data = - Logging.xb_op ~ty ~tid ~con:(Connection.get_domstr con) data - -let write_answer_log ~ty ~tid ~con ~data = - Logging.xb_answer ~ty ~tid ~con:(Connection.get_domstr con) data - let do_input store cons doms con = let newpacket = try @@ -471,7 +479,7 @@ let do_input store cons doms con = (Connection.get_domstr con) tid (Xenbus.Xb.Op.to_string ty) (sanitize_data data); *) process_packet ~store ~cons ~doms ~con ~req; - write_access_log ~ty ~tid ~con ~data; + write_access_log ~ty ~tid ~con:(Connection.get_domstr con) ~data; Connection.incr_ops con; ) @@ -484,7 +492,7 @@ let do_output store cons doms con = info "[%s] <- %s \"%s\"" (Connection.get_domstr con) (Xenbus.Xb.Op.to_string ty) (sanitize_data data);*) - write_answer_log ~ty ~tid ~con ~data; + write_answer_log ~ty ~tid ~con:(Connection.get_domstr con) ~data; ); ignore (Connection.do_output con) ) -- 2.1.4 debian/patches/xsa178-xen4.4-0011-libxl-Do-not-trust-backend-in-nic-getinfo.patch0000664000000000000000000000250112725542005024106 0ustar From 35fe0d66632fa6e7e6e250c8be90ba558e081037 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 16:35:21 +0100 Subject: [PATCH 11/16] libxl: Do not trust backend in nic getinfo This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 0bf1c5b..d20924c 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3198,10 +3198,8 @@ int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid, nicinfo->rref_tx = val ? strtoul(val, NULL, 10) : -1; val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/rx-ring-ref", nicpath)); nicinfo->rref_rx = val ? strtoul(val, NULL, 10) : -1; - nicinfo->frontend = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/frontend", nicinfo->backend), NULL); - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend-id", nicinfo->backend)); - nicinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + nicinfo->frontend = libxl__strdup(NOGC, nicpath); + nicinfo->frontend_id = domid; rc = 0; out: -- 1.9.1 debian/patches/xsa195.patch0000664000000000000000000000330613035177005012675 0ustar From: Jan Beulich Subject: x86emul: fix huge bit offset handling We must never chop off the high 32 bits. This is XSA-195. Reported-by: George Dunlap Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2549,6 +2549,12 @@ x86_emulate( else { /* + * Instructions such as bt can reference an arbitrary offset from + * their memory operand, but the instruction doing the actual + * emulation needs the appropriate op_bytes read from memory. + * Adjust both the source register and memory operand to make an + * equivalent instruction. + * * EA += BitOffset DIV op_bytes*8 * BitOffset = BitOffset MOD op_bytes*8 * DIV truncates towards negative infinity. @@ -2560,14 +2566,15 @@ x86_emulate( src.val = (int32_t)src.val; if ( (long)src.val < 0 ) { - unsigned long byte_offset; - byte_offset = op_bytes + (((-src.val-1) >> 3) & ~(op_bytes-1)); + unsigned long byte_offset = + op_bytes + (((-src.val - 1) >> 3) & ~(op_bytes - 1L)); + ea.mem.off -= byte_offset; src.val = (byte_offset << 3) + src.val; } else { - ea.mem.off += (src.val >> 3) & ~(op_bytes - 1); + ea.mem.off += (src.val >> 3) & ~(op_bytes - 1L); src.val &= (op_bytes << 3) - 1; } } debian/patches/tools-xentrace-rpath.diff0000664000000000000000000000076512276137135015553 0ustar Index: xen-4.4.0~rc3+20140210/tools/xentrace/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xentrace/Makefile 2014-02-10 12:56:12.526722759 +0100 +++ xen-4.4.0~rc3+20140210/tools/xentrace/Makefile 2014-02-10 12:56:13.258726342 +0100 @@ -5,6 +5,7 @@ CFLAGS += -Werror CFLAGS += $(CFLAGS_libxenctrl) LDLIBS += $(LDLIBS_libxenctrl) +LDFLAGS += $(call LDFLAGS_RPATH,../lib) BIN = xentrace xentrace_setsize LIBBIN = xenctx debian/patches/tools-disable.diff0000664000000000000000000000325712276137140014224 0ustar Index: xen-4.4.0~rc3+20140210/tools/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Makefile 2014-02-10 12:53:55.702053860 +0100 +++ xen-4.4.0~rc3+20140210/tools/Makefile 2014-02-10 12:56:16.154740499 +0100 @@ -16,11 +16,6 @@ SUBDIRS-y += console SUBDIRS-y += xenmon SUBDIRS-y += xenstat SUBDIRS-$(CONFIG_Linux) += memshr -ifeq ($(CONFIG_X86)$(CONFIG_Linux),yy) -SUBDIRS-$(CONFIG_BLKTAP1) += blktap -endif -SUBDIRS-$(CONFIG_Linux) += blktap2 -SUBDIRS-$(CONFIG_NetBSD) += blktap2 SUBDIRS-$(CONFIG_NetBSD) += xenbackendd SUBDIRS-y += libfsimage SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen @@ -28,9 +23,12 @@ SUBDIRS-$(CONFIG_Linux) += libvchan # do not recurse in to a dir we are about to delete ifneq "$(MAKECMDGOALS)" "distclean" +CONFIG_QEMU = $(CURDIR)/../qemu +ifneq ($(wildcard $(CONFIG_QEMU)),) SUBDIRS-$(CONFIG_QEMU_TRAD) += qemu-xen-traditional-dir SUBDIRS-$(CONFIG_QEMU_XEN) += qemu-xen-dir endif +endif SUBDIRS-y += xenpmd SUBDIRS-y += libxl Index: xen-4.4.0~rc3+20140210/tools/Rules.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Rules.mk 2014-02-10 12:55:58.834655821 +0100 +++ xen-4.4.0~rc3+20140210/tools/Rules.mk 2014-02-10 12:56:16.154740499 +0100 @@ -41,11 +41,7 @@ CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN) LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -L$(XEN_LIBVCHAN) -lxenvchan SHLIB_libxenvchan = -Wl,-rpath-link=$(XEN_LIBVCHAN) -ifeq ($(CONFIG_Linux),y) -LIBXL_BLKTAP ?= y -else LIBXL_BLKTAP ?= n -endif ifeq ($(LIBXL_BLKTAP),y) CFLAGS_libblktapctl = -I$(XEN_BLKTAP2)/control -I$(XEN_BLKTAP2)/include $(CFLAGS_xeninclude) debian/patches/xsa244-4.4.patch0000664000000000000000000000267113167430317013203 0ustar diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 772f1aa..4c50eb0 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -682,6 +682,9 @@ static int cpu_smpboot_alloc(unsigned int cpu) if ( idt_tables[cpu] == NULL ) goto oom; memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES * sizeof(idt_entry_t)); + set_ist(&idt_tables[cpu][TRAP_double_fault], IST_NONE); + set_ist(&idt_tables[cpu][TRAP_nmi], IST_NONE); + set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE); if ( zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, cpu)) && zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) ) diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 2a4b365..ba8162f 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -417,6 +417,11 @@ void __devinit subarch_percpu_traps_init(void) /* NMI handler has its own per-CPU 4kB stack. */ this_cpu(init_tss).ist[IST_NMI-1] = (unsigned long)&stack[IST_NMI * PAGE_SIZE]; + /* Uniformly set the IST references after the TSS is in place. */ + set_ist(&idt_tables[cpu][TRAP_double_fault], IST_DF); + set_ist(&idt_tables[cpu][TRAP_nmi], IST_NMI); + set_ist(&idt_tables[cpu][TRAP_machine_check], IST_MCE); + /* Trampoline for SYSCALL entry from long mode. */ stack = &stack[IST_MAX * PAGE_SIZE]; /* Skip the IST stacks. */ wrmsrl(MSR_LSTAR, (unsigned long)stack); debian/patches/xsa175-4.4-0009-libxl-Do-not-trust-frontend-for-nic-in-libxl_devid_t.patch0000664000000000000000000000274112725264607025607 0ustar From a7fb7be6b7a14e8ca5ab0609c49b06545d6772bf Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 15:52:53 +0100 Subject: [PATCH 09/10] libxl: Do not trust frontend for nic in libxl_devid_to_device_nic Find the backend by reading the pointer in /libxl rather than in the guest's frontend area. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index a0aeb50..7a8faba 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3066,17 +3066,17 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_nic *nic) { GC_INIT(ctx); - char *dompath, *path; + char *libxl_dom_path, *path; int rc = ERROR_FAIL; libxl_device_nic_init(nic); - dompath = libxl__xs_get_dompath(gc, domid); - if (!dompath) + libxl_dom_path = libxl__xs_libxl_path(gc, domid); + if (!libxl_dom_path) goto out; path = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%s/device/vif/%d/backend", - dompath, devid)); + GCSPRINTF("%s/device/vif/%d/backend", libxl_dom_path, + devid)); if (!path) goto out; -- 2.1.4 debian/patches/xsa179-qemut-4.4-0002-vga-add-vbe_enabled-helper.patch0000664000000000000000000000461012725550141021714 0ustar From 34db09fb9967441408a1ff0579d553222cf17441 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 26 Apr 2016 14:11:34 +0200 Subject: [PATCH 2/5] vga: add vbe_enabled() helper Makes code a bit easier to read. Signed-off-by: Gerd Hoffmann [Backport to qemu-xen-tradition] Signed-off-by: Andrew Cooper --- hw/vga.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) Index: xen-4.4.2/qemu/hw/vga.c =================================================================== --- xen-4.4.2.orig/qemu/hw/vga.c 2016-06-07 15:41:47.152796179 +0200 +++ xen-4.4.2/qemu/hw/vga.c 2016-06-07 15:47:06.404791256 +0200 @@ -160,6 +160,11 @@ static uint32_t expand4[256]; static uint16_t expand2[256]; static uint8_t expand4to8[16]; +static inline bool vbe_enabled(VGAState *s) +{ + return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; +} + static void vga_bios_init(VGAState *s); static void vga_screen_dump(void *opaque, const char *filename); @@ -613,8 +618,7 @@ static void vbe_ioport_write_data(void * s->bank_offset = (val << 16); break; case VBE_DISPI_INDEX_ENABLE: - if ((val & VBE_DISPI_ENABLED) && - !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { + if ((val & VBE_DISPI_ENABLED) && !vbe_enabled(s)) { int h, shift_control; if (s->vram_gmfn != s->lfb_addr) { @@ -1129,7 +1133,7 @@ static void vga_get_offsets(VGAState *s, { uint32_t start_addr, line_offset, line_compare; #ifdef CONFIG_BOCHS_VBE - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { + if (vbe_enabled(s)) { line_offset = s->vbe_line_offset; start_addr = s->vbe_start_addr; line_compare = 65535; @@ -1515,7 +1519,7 @@ static int vga_get_bpp(VGAState *s) { int ret; #ifdef CONFIG_BOCHS_VBE - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { + if (vbe_enabled(s)) { ret = s->vbe_regs[VBE_DISPI_INDEX_BPP]; } else #endif @@ -1530,7 +1534,7 @@ static void vga_get_resolution(VGAState int width, height; #ifdef CONFIG_BOCHS_VBE - if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { + if (vbe_enabled(s)) { width = s->vbe_regs[VBE_DISPI_INDEX_XRES]; height = s->vbe_regs[VBE_DISPI_INDEX_YRES]; } else debian/patches/xsa152-4.5.patch0000664000000000000000000000264312616222146013176 0ustar x86: rate-limit logging in do_xen{oprof,pmu}_op() Some of the sub-ops are acessible to all guests, and hence should be rate-limited. In the xenoprof case, just like for XSA-146, include them only in debug builds. Since the vPMU code is rather new, allow them to be always present, but downgrade them to (rate limited) guest messages. This is XSA-152. Signed-off-by: Jan Beulich --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -676,15 +676,13 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_H if ( (op < 0) || (op > XENOPROF_last_op) ) { - printk("xenoprof: invalid operation %d for domain %d\n", - op, current->domain->domain_id); + gdprintk(XENLOG_DEBUG, "invalid operation %d\n", op); return -EINVAL; } if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) ) { - printk("xenoprof: dom %d denied privileged operation %d\n", - current->domain->domain_id, op); + gdprintk(XENLOG_DEBUG, "denied privileged operation %d\n", op); return -EPERM; } @@ -907,8 +905,7 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_H spin_unlock(&xenoprof_lock); if ( ret < 0 ) - printk("xenoprof: operation %d failed for dom %d (status : %d)\n", - op, current->domain->domain_id, ret); + gdprintk(XENLOG_DEBUG, "operation %d failed: %d\n", op, ret); return ret; } debian/patches/qemu-disable-blktap.diff0000664000000000000000000000700212276137152015301 0ustar qemu: Disable blktap build There is no upstream version of this (only Citrix has something which is not going to be upstream for XenServer). Index: xen-4.4.0~rc3+20140210/qemu/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/Makefile 2014-02-10 12:53:53.914045123 +0100 +++ xen-4.4.0~rc3+20140210/qemu/Makefile 2014-02-10 12:56:26.314790166 +0100 @@ -47,13 +47,9 @@ $(filter %-user,$(SUBDIR_RULES)): libqem recurse-all: $(SUBDIR_RULES) CPPFLAGS += -I$(XEN_ROOT)/tools/libxc -CPPFLAGS += -I$(XEN_ROOT)/tools/blktap/lib CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore CPPFLAGS += -I$(XEN_ROOT)/tools/include -tapdisk-ioemu: tapdisk-ioemu.c cutils.c block.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c hw/xen_blktap.c osdep.c - $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS) - ####################################################################### # BLOCK_OBJS is code used by both qemu system emulation and qemu-img Index: xen-4.4.0~rc3+20140210/qemu/configure =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/configure 2014-02-10 12:53:53.862044869 +0100 +++ xen-4.4.0~rc3+20140210/qemu/configure 2014-02-10 12:56:26.314790166 +0100 @@ -185,9 +185,10 @@ bluez="yes" kvm="yes" kerneldir="" aix="no" -blobs="yes" +blobs="no" fdt="yes" sdl_x11="no" +brlapi="no" # OS specific if check_define __linux__ ; then Index: xen-4.4.0~rc3+20140210/qemu/hw/xen_machine_pv.c =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/hw/xen_machine_pv.c 2014-02-10 12:53:53.894045021 +0100 +++ xen-4.4.0~rc3+20140210/qemu/hw/xen_machine_pv.c 2014-02-10 12:56:26.318790190 +0100 @@ -29,10 +29,6 @@ #include "xen_backend.h" #include "qemu-xen.h" -#if defined(CONFIG_BLKTAP1) && !defined(CONFIG_STUBDOM) -#include -#endif - uint32_t xen_domid; enum xen_mode xen_mode = XEN_EMULATE; @@ -47,11 +43,6 @@ static void xen_init_pv(ram_addr_t ram_s CPUState *env; uint32_t domid_target; -#if defined(CONFIG_BLKTAP1) && !defined(CONFIG_STUBDOM) && !defined(__NetBSD__) - /* Initialize tapdisk client */ - init_blktap(); -#endif - /* Initialize a dummy CPU */ if (cpu_model == NULL) { #ifdef TARGET_X86_64 Index: xen-4.4.0~rc3+20140210/qemu/xen-config-host.h =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/xen-config-host.h 2014-02-10 12:53:53.938045237 +0100 +++ xen-4.4.0~rc3+20140210/qemu/xen-config-host.h 2014-02-10 12:56:26.318790190 +0100 @@ -18,9 +18,6 @@ extern int domid, domid_backend; #include "xenctrl.h" #include "xenstore.h" -#if defined(CONFIG_BLKTAP1) && !defined(CONFIG_STUBDOM) && !defined(__NetBSD__) -#include "blktaplib.h" -#endif #define BIOS_SIZE ((256 + 64) * 1024) Index: xen-4.4.0~rc3+20140210/qemu/xen-hooks.mak =================================================================== --- xen-4.4.0~rc3+20140210.orig/qemu/xen-hooks.mak 2014-02-10 12:56:25.594786651 +0100 +++ xen-4.4.0~rc3+20140210/qemu/xen-hooks.mak 2014-02-10 12:56:26.318790190 +0100 @@ -47,11 +47,6 @@ CONFIG_AUDIO= OBJS += xenfbfront.o else ifndef CONFIG_NetBSD -ifneq ($(CONFIG_BLKTAP1),n) -CPPFLAGS+= -DCONFIG_BLKTAP1 -I$(XEN_ROOT)/tools/blktap/lib -LIBS += -L$(XEN_ROOT)/tools/blktap/lib -lblktap -OBJS += xen_blktap.o -endif OBJS += tpm_tis.o endif endif debian/patches/xsa206-4.4-0010-oxenstored-refactor-putting-response-on-wire.patch0000664000000000000000000001112213104300260024423 0ustar From 3d3b87010ff9ede82cfb79aee445a30d2c9f88b8 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Thu, 23 Mar 2017 17:40:00 +0000 Subject: [PATCH 10/30] oxenstored: refactor putting response on wire Previously, the functions reply_{ack,data,data_or_ack} and input_handle_error put the response on the wire by invoking Connection.send_{ack,reply,error}. Instead, these functions now return a value indicating what needs to be put on the wire, and that action is done by a send_response function called afterwards. This refactoring gives us a chance to store the value of the response, useful for replaying transactions. Reported-by: Juergen Gross Signed-off-by: Jonathan Davies Reviewed-by: Andrew Cooper Reviewed-by: Jon Ludlam Reviewed-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/Makefile | 1 + tools/ocaml/xenstored/packet.ml | 4 ++++ tools/ocaml/xenstored/process.ml | 34 ++++++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 tools/ocaml/xenstored/packet.ml diff --git a/tools/ocaml/xenstored/Makefile b/tools/ocaml/xenstored/Makefile index b18f190..7a4c317 100644 --- a/tools/ocaml/xenstored/Makefile +++ b/tools/ocaml/xenstored/Makefile @@ -17,6 +17,7 @@ OBJS = define \ stdext \ trie \ config \ + packet \ logging \ quota \ perms \ diff --git a/tools/ocaml/xenstored/packet.ml b/tools/ocaml/xenstored/packet.ml new file mode 100644 index 0000000..c8ecfe5 --- /dev/null +++ b/tools/ocaml/xenstored/packet.ml @@ -0,0 +1,4 @@ +type response = + | Ack of (unit -> unit) (* function is the action to execute after sending the ack *) + | Reply of string + | Error of string diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 89db56c..8be2ff1 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -126,8 +126,7 @@ let do_watch con t rid domains cons data = | _ -> raise Invalid_Cmd_Args in let watch = Connections.add_watch cons con node token in - Connection.send_ack con (Transaction.get_id t) rid Xenbus.Xb.Op.Watch; - Connection.fire_single_watch watch + Packet.Ack (fun () -> Connection.fire_single_watch watch) let do_unwatch con t domains cons data = let (node, token) = @@ -284,20 +283,32 @@ let do_set_target con t domains cons data = | _ -> raise Invalid_Cmd_Args (*------------- Generic handling of ty ------------------*) +let send_response ty con t rid response = + match response with + | Packet.Ack f -> + Connection.send_ack con (Transaction.get_id t) rid ty; + (* Now do any necessary follow-up actions *) + f () + | Packet.Reply ret -> + Connection.send_reply con (Transaction.get_id t) rid ty ret + | Packet.Error e -> + Connection.send_error con (Transaction.get_id t) rid e + let reply_ack fct ty con t rid doms cons data = fct con t doms cons data; - Connection.send_ack con (Transaction.get_id t) rid ty; - if Transaction.get_id t = Transaction.none then - process_watch (Transaction.get_ops t) cons + Packet.Ack (fun () -> + if Transaction.get_id t = Transaction.none then + process_watch (Transaction.get_ops t) cons + ) let reply_data fct ty con t rid doms cons data = let ret = fct con t doms cons data in - Connection.send_reply con (Transaction.get_id t) rid ty ret + Packet.Reply ret let reply_data_or_ack fct ty con t rid doms cons data = match fct con t doms cons data with - | Some ret -> Connection.send_reply con (Transaction.get_id t) rid ty ret - | None -> Connection.send_ack con (Transaction.get_id t) rid ty + | Some ret -> Packet.Reply ret + | None -> Packet.Ack (fun () -> ()) let reply_none fct ty con t rid doms cons data = (* let the function reply *) @@ -329,7 +340,7 @@ let function_of_type ty = let input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data = let reply_error e = - Connection.send_error con (Transaction.get_id t) rid e in + Packet.Error e in try fct ty con t rid doms cons data with @@ -362,7 +373,10 @@ let process_packet ~store ~cons ~doms ~con ~tid ~rid ~ty ~data = else Connection.get_transaction con tid in - input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data; + let response = input_handle_error ~cons ~doms ~fct ~ty ~con ~t ~rid ~data in + + (* Put the response on the wire *) + send_response ty con t rid response with exn -> error "process packet: %s" (Printexc.to_string exn); Connection.send_error con tid rid "EIO" -- 2.1.4 debian/patches/tools-libfsimage-abiname.diff0000664000000000000000000000347612276137113016320 0ustar Index: xen-4.4.0~rc3+20140210/tools/libfsimage/common/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libfsimage/common/Makefile 2014-02-10 12:53:58.282066470 +0100 +++ xen-4.4.0~rc3+20140210/tools/libfsimage/common/Makefile 2014-02-10 12:55:55.710640548 +0100 @@ -1,9 +1,6 @@ XEN_ROOT = $(CURDIR)/../../.. include $(XEN_ROOT)/tools/libfsimage/Rules.mk -MAJOR = 1.0 -MINOR = 0 - LDFLAGS-$(CONFIG_SunOS) = -Wl,-M -Wl,mapfile-SunOS LDFLAGS-$(CONFIG_Linux) = -Wl,mapfile-GNU LDFLAGS = $(LDFLAGS-y) @@ -15,7 +12,7 @@ LIB_SRCS-y = fsimage.c fsimage_plugin.c PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y)) -LIB = libfsimage.so libfsimage.so.$(MAJOR) libfsimage.so.$(MAJOR).$(MINOR) +LIB = libfsimage.so .PHONY: all all: $(LIB) @@ -24,9 +21,7 @@ all: $(LIB) install: all $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_PROG) libfsimage.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) - ln -sf libfsimage.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libfsimage.so.$(MAJOR) - ln -sf libfsimage.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libfsimage.so + $(INSTALL_PROG) libfsimage.so $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) fsimage.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) fsimage_plugin.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) fsimage_grub.h $(DESTDIR)$(INCLUDEDIR) @@ -34,13 +29,8 @@ install: all clean distclean:: rm -f $(LIB) -libfsimage.so: libfsimage.so.$(MAJOR) - ln -sf $< $@ -libfsimage.so.$(MAJOR): libfsimage.so.$(MAJOR).$(MINOR) - ln -sf $< $@ - -libfsimage.so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libfsimage.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(PTHREAD_LIBS) +libfsimage.so: $(PIC_OBJS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $^ $(PTHREAD_LIBS) -include $(DEPS) debian/patches/xsa218-4.4-0001-IOMMU-handle-IOMMU-mapping-and-unmapping-failures.patch0000664000000000000000000000435113126666276024567 0ustar From 4ca403ecff82d3efdd838e08b258cb4dd3062c60 Mon Sep 17 00:00:00 2001 From: Quan Xu Date: Fri, 2 Jun 2017 12:30:34 +0100 Subject: [PATCH 1/4] IOMMU: handle IOMMU mapping and unmapping failures Treat IOMMU mapping and unmapping failures as a fatal to the DomU If IOMMU mapping and unmapping failed, crash the DomU and propagate the error up to the call trees. No spamming of the log can occur. For DomU, we avoid logging any message for already dying domains. For Dom0, that'll still be more verbose than we'd really like, but it at least wouldn't outright flood the console. Signed-off-by: Quan Xu Reviewed-by: Kevin Tian Reviewed-by: Jan Beulich --- xen/drivers/passthrough/iommu.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -433,21 +433,47 @@ unsigned int flags) { struct hvm_iommu *hd = domain_hvm_iommu(d); + int rc; if ( !iommu_enabled || !hd->platform_ops ) return 0; - return hd->platform_ops->map_page(d, gfn, mfn, flags); + rc = hd->platform_ops->map_page(d, gfn, mfn, flags); + if ( unlikely(rc) ) + { + if ( !d->is_shutting_down && printk_ratelimit() ) + printk(XENLOG_ERR + "d%d: IOMMU mapping gfn %#lx to mfn %#lx failed: %d\n", + d->domain_id, gfn, mfn, rc); + + if ( !is_hardware_domain(d) ) + domain_crash(d); + } + + return rc; } int iommu_unmap_page(struct domain *d, unsigned long gfn) { struct hvm_iommu *hd = domain_hvm_iommu(d); + int rc; if ( !iommu_enabled || !hd->platform_ops ) return 0; - return hd->platform_ops->unmap_page(d, gfn); + rc = hd->platform_ops->unmap_page(d, gfn); + if ( unlikely(rc) ) + { + if ( !d->is_shutting_down && printk_ratelimit() ) + printk(XENLOG_ERR + "d%d: IOMMU unmapping gfn %#lx failed: %d\n", + d->domain_id, gfn, rc); + + if ( !is_hardware_domain(d) ) + domain_crash(d); + } + + return rc; } static void iommu_free_pagetables(unsigned long unused) debian/patches/ubuntu-qemu-disable-qemu-upstream.diff0000664000000000000000000000217012276137153020153 0ustar Description: qemu: Disable build of upstream qemu The Xen make environment would try to get the upstream qemu code as well when the qemu-dm directory is re-added. Right now I think this should be provided by the qemu package. And also it would currently break the build when trying to download code from a git repo. So disable that part. Forwarded: not-needed Origin: vendor, created on merge Author: Stefan Bader Index: xen-4.4.0~rc3+20140210/tools/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Makefile 2014-02-10 12:56:16.154740499 +0100 +++ xen-4.4.0~rc3+20140210/tools/Makefile 2014-02-10 12:56:26.946793259 +0100 @@ -24,9 +24,10 @@ SUBDIRS-$(CONFIG_Linux) += libvchan # do not recurse in to a dir we are about to delete ifneq "$(MAKECMDGOALS)" "distclean" CONFIG_QEMU = $(CURDIR)/../qemu +#QEMU_UPSTREAM_URL = $(CURDIR)/../qemu-xen ifneq ($(wildcard $(CONFIG_QEMU)),) SUBDIRS-$(CONFIG_QEMU_TRAD) += qemu-xen-traditional-dir -SUBDIRS-$(CONFIG_QEMU_XEN) += qemu-xen-dir +#SUBDIRS-$(CONFIG_QEMU_XEN) += qemu-xen-dir endif endif debian/patches/xsa156-4.4.patch0000664000000000000000000001133312616674676013220 0ustar x86/HVM: always intercept #AC and #DB Both being benign exceptions, and both being possible to get triggered by exception delivery, this is required to prevent a guest from locking up a CPU (resulting from no other VM exits occurring once getting into such a loop). The specific scenarios: 1) #AC may be raised during exception delivery if the handler is set to be a ring-3 one by a 32-bit guest, and the stack is misaligned. 2) #DB may be raised during exception delivery when a breakpoint got placed on a data structure involved in delivering the exception. This can result in an endless loop when a 64-bit guest uses a non-zero IST for the vector 1 IDT entry, but even without use of IST the time it takes until a contributory fault would get raised (results depending on the handler) may be quite long. This is XSA-156. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Tested-by: Andrew Cooper --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -941,10 +941,11 @@ static void noreturn svm_do_resume(struc unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) ) { uint32_t intercepts = vmcb_get_exception_intercepts(vmcb); - uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3); + v->arch.hvm_vcpu.debug_state_latch = debug_state; vmcb_set_exception_intercepts( - vmcb, debug_state ? (intercepts | mask) : (intercepts & ~mask)); + vmcb, debug_state ? (intercepts | (1U << TRAP_int3)) + : (intercepts & ~(1U << TRAP_int3))); } if ( v->arch.hvm_svm.launch_core != smp_processor_id() ) @@ -2225,8 +2226,9 @@ void svm_vmexit_handler(struct cpu_user_ case VMEXIT_EXCEPTION_DB: if ( !v->domain->debugger_attached ) - goto unexpected_exit_type; - domain_pause_for_debugger(); + hvm_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE); + else + domain_pause_for_debugger(); break; case VMEXIT_EXCEPTION_BP: @@ -2274,6 +2276,11 @@ void svm_vmexit_handler(struct cpu_user_ break; } + case VMEXIT_EXCEPTION_AC: + HVMTRACE_1D(TRAP, TRAP_alignment_check); + hvm_inject_hw_exception(TRAP_alignment_check, vmcb->exitinfo1); + break; + case VMEXIT_EXCEPTION_UD: svm_vmexit_ud_intercept(regs); break; --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1132,16 +1132,10 @@ static void vmx_update_host_cr3(struct v void vmx_update_debug_state(struct vcpu *v) { - unsigned long mask; - - mask = 1u << TRAP_int3; - if ( !cpu_has_monitor_trap_flag ) - mask |= 1u << TRAP_debug; - if ( v->arch.hvm_vcpu.debug_state_latch ) - v->arch.hvm_vmx.exception_bitmap |= mask; + v->arch.hvm_vmx.exception_bitmap |= 1U << TRAP_int3; else - v->arch.hvm_vmx.exception_bitmap &= ~mask; + v->arch.hvm_vmx.exception_bitmap &= ~(1U << TRAP_int3); vmx_vmcs_enter(v); vmx_update_exception_bitmap(v); @@ -2678,9 +2672,10 @@ void vmx_vmexit_handler(struct cpu_user_ __vmread(EXIT_QUALIFICATION, &exit_qualification); HVMTRACE_1D(TRAP_DEBUG, exit_qualification); write_debugreg(6, exit_qualification | 0xffff0ff0); - if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag ) - goto exit_and_crash; - domain_pause_for_debugger(); + if ( !v->domain->debugger_attached ) + hvm_inject_hw_exception(vector, HVM_DELIVER_NO_ERROR_CODE); + else + domain_pause_for_debugger(); break; case TRAP_int3: { @@ -2745,6 +2740,11 @@ void vmx_vmexit_handler(struct cpu_user_ hvm_inject_page_fault(regs->error_code, exit_qualification); break; + case TRAP_alignment_check: + HVMTRACE_1D(TRAP, vector); + __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode); + hvm_inject_hw_exception(vector, ecode); + break; case TRAP_nmi: if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) != (X86_EVENTTYPE_NMI << 8) ) --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -393,7 +393,10 @@ static inline int hvm_event_pending(stru }) /* These exceptions must always be intercepted. */ -#define HVM_TRAP_MASK ((1U << TRAP_machine_check) | (1U << TRAP_invalid_op)) +#define HVM_TRAP_MASK ((1U << TRAP_debug) | \ + (1U << TRAP_invalid_op) | \ + (1U << TRAP_alignment_check) | \ + (1U << TRAP_machine_check)) /* * x86 event types. This enumeration is valid for: debian/patches/xsa206-4.4-0019-oxenstored-handling-of-domain-conflict-credit.patch0000664000000000000000000002726113104300260024442 0ustar From 6118099bec07d77bfd73a032d8b411cab29a9f3e Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Tue, 14 Mar 2017 12:15:52 +0000 Subject: [PATCH 19/30] oxenstored: handling of domain conflict-credit This commit gives each domain a conflict-credit variable, which will later be used for limiting how often a domain can cause other domain's transaction-commits to fail. This commit also provides functions and data for manipulating domains and their conflict-credit, and checking whether they have credit. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies Reviewed-by: Christian Lindig --- tools/ocaml/xenstored/connection.ml | 5 ++ tools/ocaml/xenstored/define.ml | 3 + tools/ocaml/xenstored/domain.ml | 11 +++- tools/ocaml/xenstored/domains.ml | 103 +++++++++++++++++++++++++++++++++- tools/ocaml/xenstored/oxenstored.conf | 32 +++++++++++ tools/ocaml/xenstored/transaction.ml | 2 + tools/ocaml/xenstored/xenstored.ml | 2 + 7 files changed, 154 insertions(+), 4 deletions(-) diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml index 15ff2b3..b52e8af 100644 --- a/tools/ocaml/xenstored/connection.ml +++ b/tools/ocaml/xenstored/connection.ml @@ -258,3 +258,8 @@ let debug con = let domid = get_domstr con in let watches = List.map (fun (path, token) -> Printf.sprintf "watch %s: %s %s\n" domid path token) (list_watches con) in String.concat "" watches + +let decr_conflict_credit doms con = + match con.dom with + | None -> () (* It's a socket connection. We don't know which domain we're in, so treat it as if it's free to conflict *) + | Some dom -> Domains.decr_conflict_credit doms dom diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml index d60861c..df1e91c 100644 --- a/tools/ocaml/xenstored/define.ml +++ b/tools/ocaml/xenstored/define.ml @@ -29,6 +29,9 @@ let maxwatch = ref (50) let maxtransaction = ref (20) let maxrequests = ref (-1) (* maximum requests per transaction *) +let conflict_burst_limit = ref 5.0 +let conflict_rate_limit_is_aggregate = ref true + let domid_self = 0x7FF0 exception Not_a_directory of string diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml index ab34314..e677aa3 100644 --- a/tools/ocaml/xenstored/domain.ml +++ b/tools/ocaml/xenstored/domain.ml @@ -31,8 +31,12 @@ type t = mutable io_credit: int; (* the rounds of ring process left to do, default is 0, usually set to 1 when there is work detected, could also set to n to give "lazy" clients extra credit *) + mutable conflict_credit: float; (* Must be positive to perform writes; a commit + that later causes conflict with another + domain's transaction costs credit. *) } +let is_dom0 d = d.id = 0 let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id) let get_id domain = domain.id let get_interface d = d.interface @@ -48,6 +52,10 @@ let set_io_credit ?(n=1) domain = domain.io_credit <- max 0 n let incr_io_credit domain = domain.io_credit <- domain.io_credit + 1 let decr_io_credit domain = domain.io_credit <- max 0 (domain.io_credit - 1) +let is_paused_for_conflict dom = dom.conflict_credit <= 0.0 + +let is_free_to_conflict = is_dom0 + let string_of_port = function | None -> "None" | Some x -> string_of_int (Xeneventchn.to_int x) @@ -84,6 +92,5 @@ let make id mfn remote_port interface eventchn = { port = None; bad_client = false; io_credit = 0; + conflict_credit = !Define.conflict_burst_limit; } - -let is_dom0 d = d.id = 0 diff --git a/tools/ocaml/xenstored/domains.ml b/tools/ocaml/xenstored/domains.ml index 92e438f..041d222 100644 --- a/tools/ocaml/xenstored/domains.ml +++ b/tools/ocaml/xenstored/domains.ml @@ -15,20 +15,58 @@ *) let debug fmt = Logging.debug "domains" fmt +let error fmt = Logging.error "domains" fmt +let warn fmt = Logging.warn "domains" fmt type domains = { eventchn: Event.t; table: (Xenctrl.domid, Domain.t) Hashtbl.t; + + (* N.B. the Queue module is not thread-safe but oxenstored is single-threaded. *) + (* Domains queue up to regain conflict-credit; we have a queue for + domains that are carrying some penalty and so are below the + maximum credit, and another queue for domains that have run out of + credit and so have had their access paused. *) + doms_conflict_paused: (Domain.t option ref) Queue.t; + doms_with_conflict_penalty: (Domain.t option ref) Queue.t; + + (* A callback function to be called when we go from zero to one paused domain. + This will be to reset the countdown until the next unit of credit is issued. *) + on_first_conflict_pause: unit -> unit; + + (* If config is set to use individual instead of aggregate conflict-rate-limiting, + we use this instead of the queues. *) + mutable n_paused: int; } -let init eventchn = - { eventchn = eventchn; table = Hashtbl.create 10 } +let init eventchn = { + eventchn = eventchn; + table = Hashtbl.create 10; + doms_conflict_paused = Queue.create (); + doms_with_conflict_penalty = Queue.create (); + on_first_conflict_pause = (fun () -> ()); (* Dummy value for now, pending subsequent commit. *) + n_paused = 0; +} let del doms id = Hashtbl.remove doms.table id let exist doms id = Hashtbl.mem doms.table id let find doms id = Hashtbl.find doms.table id let number doms = Hashtbl.length doms.table let iter doms fct = Hashtbl.iter (fun _ b -> fct b) doms.table +(* Functions to handle queues of domains given that the domain might be deleted while in a queue. *) +let push dom queue = + Queue.push (ref (Some dom)) queue + +let rec pop queue = + match !(Queue.pop queue) with + | None -> pop queue + | Some x -> x + +let remove_from_queue dom queue = + Queue.iter (fun d -> match !d with + | None -> () + | Some x -> if x=dom then d := None) queue + let cleanup xc doms = let notify = ref false in let dead_dom = ref [] in @@ -52,6 +90,11 @@ let cleanup xc doms = let dom = Hashtbl.find doms.table id in Domain.close dom; Hashtbl.remove doms.table id; + if dom.Domain.conflict_credit <= !Define.conflict_burst_limit + then ( + remove_from_queue dom doms.doms_with_conflict_penalty; + if (dom.Domain.conflict_credit <= 0.) then remove_from_queue dom doms.doms_conflict_paused + ) ) !dead_dom; !notify, !dead_dom @@ -84,3 +127,59 @@ let create0 fake doms = Domain.bind_interdomain dom; Domain.notify dom; dom + +let decr_conflict_credit doms dom = + let before = dom.Domain.conflict_credit in + let after = max (-1.0) (before -. 1.0) in + dom.Domain.conflict_credit <- after; + if !Define.conflict_rate_limit_is_aggregate then ( + if before >= !Define.conflict_burst_limit + && after < !Define.conflict_burst_limit + && after > 0.0 + then ( + push dom doms.doms_with_conflict_penalty + ) else if before > 0.0 && after <= 0.0 + then ( + let first_pause = Queue.is_empty doms.doms_conflict_paused in + push dom doms.doms_conflict_paused; + if first_pause then doms.on_first_conflict_pause () + ) else ( + (* The queues are correct already: no further action needed. *) + ) + ) else if before > 0.0 && after <= 0.0 then ( + doms.n_paused <- doms.n_paused + 1; + if doms.n_paused = 1 then doms.on_first_conflict_pause () + ) + +(* Give one point of credit to one domain, and update the queues appropriately. *) +let incr_conflict_credit_from_queue doms = + let process_queue q requeue_test = + let d = pop q in + d.Domain.conflict_credit <- min (d.Domain.conflict_credit +. 1.0) !Define.conflict_burst_limit; + if requeue_test d.Domain.conflict_credit then ( + push d q (* Make it queue up again for its next point of credit. *) + ) + in + let paused_queue_test cred = cred <= 0.0 in + let penalty_queue_test cred = cred < !Define.conflict_burst_limit in + try process_queue doms.doms_conflict_paused paused_queue_test + with Queue.Empty -> ( + try process_queue doms.doms_with_conflict_penalty penalty_queue_test + with Queue.Empty -> () (* Both queues are empty: nothing to do here. *) + ) + +let incr_conflict_credit doms = + if !Define.conflict_rate_limit_is_aggregate + then incr_conflict_credit_from_queue doms + else ( + (* Give a point of credit to every domain, subject only to the cap. *) + let inc dom = + let before = dom.Domain.conflict_credit in + let after = min (before +. 1.0) !Define.conflict_burst_limit in + dom.Domain.conflict_credit <- after; + if before <= 0.0 && after > 0.0 + then doms.n_paused <- doms.n_paused - 1 + in + (* Scope for optimisation (probably tiny): avoid iteration if all domains are at max credit *) + iter doms inc + ) diff --git a/tools/ocaml/xenstored/oxenstored.conf b/tools/ocaml/xenstored/oxenstored.conf index ac60f49..a100936 100644 --- a/tools/ocaml/xenstored/oxenstored.conf +++ b/tools/ocaml/xenstored/oxenstored.conf @@ -9,6 +9,38 @@ test-eagain = false # Activate transaction merge support merge-activate = true +# Limits applied to domains whose writes cause other domains' transaction +# commits to fail. Must include decimal point. + +# The burst limit is the number of conflicts a domain can cause to +# fail in a short period; this value is used for both the initial and +# the maximum value of each domain's conflict-credit, which falls by +# one point for each conflict caused, and when it reaches zero the +# domain's requests are ignored. +conflict-burst-limit = 5.0 + +# The conflict-credit is replenished over time: +# one point is issued after each conflict-max-history-seconds, so this +# is the minimum pause-time during which a domain will be ignored. +# conflict-max-history-seconds = 0.05 + +# If the conflict-rate-limit-is-aggregate flag is true then after each +# tick one point of conflict-credit is given to just one domain: the +# one at the front of the queue. If false, then after each tick each +# domain gets a point of conflict-credit. +# +# In environments where it is known that every transaction will +# involve a set of nodes that is writable by at most one other domain, +# then it is safe to set this aggregate-limit flag to false for better +# performance. (This can be determined by considering the layout of +# the xenstore tree and permissions, together with the content of the +# transactions that require protection.) +# +# A transaction which involves a set of nodes which can be modified by +# multiple other domains can suffer conflicts caused by any of those +# domains, so the flag must be set to true. +conflict-rate-limit-is-aggregate = true + # Activate node permission system perms-activate = true diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index 51d5d6a..6f758ff 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -14,6 +14,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. *) +let error fmt = Logging.error "transaction" fmt + open Stdext let none = 0 diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 656a79b..ea511de 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -89,6 +89,8 @@ let parse_config filename = let pidfile = ref default_pidfile in let options = [ ("merge-activate", Config.Set_bool Transaction.do_coalesce); + ("conflict-burst-limit", Config.Set_float Define.conflict_burst_limit); + ("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate); ("perms-activate", Config.Set_bool Perms.activate); ("quota-activate", Config.Set_bool Quota.activate); ("quota-maxwatch", Config.Set_int Define.maxwatch); -- 2.1.4 debian/patches/xsa224-4.5-0001-gnttab-Fix-handling-of-dev_bus_addr-during-unmap.patch0000664000000000000000000000757613126670720025000 0ustar From 0aa6bc3bba0aeec067feed2a7378d285d7529684 Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Thu, 15 Jun 2017 16:24:02 +0100 Subject: [PATCH 1/4] gnttab: Fix handling of dev_bus_addr during unmap If a grant has been mapped with the GNTTAB_device_map flag, calling grant_unmap_ref() with dev_bus_addr set to zero should cause the GNTTAB_device_map part of the mapping to be left alone. Unfortunately, at the moment, op->dev_bus_addr is implicitly checked before clearing the map and adjusting the pin count, but only the bits above 12; and it is not checked at all before dropping page references. This means a guest can repeatedly make such a call to cause the reference count to drop to zero, causing the page to be freed and re-used, even though it's still mapped in its pagetables. To fix this, always check op->dev_bus_addr explicitly for being non-zero, as well as op->flag & GNTMAP_device_map, before doing operations on the device_map. While we're here, make the logic a bit cleaner: * Always initialize op->frame to zero and set it from act->frame, to reduce the chance of untrusted input being used * Explicitly check the full dev_bus_addr against act->frame << PAGE_SHIFT, rather than ignoring the lower 12 bits This is part of XSA-224. Reported-by: Jan Beulich Signed-off-by: George Dunlap Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index ac98aef..2679073 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -899,8 +899,6 @@ __gnttab_unmap_common( ld = current->domain; lgt = ld->grant_table; - op->frame = (unsigned long)(op->dev_bus_addr >> PAGE_SHIFT); - if ( unlikely(op->handle >= lgt->maptrack_limit) ) { gdprintk(XENLOG_INFO, "Bad handle (%d).\n", op->handle); @@ -957,16 +955,14 @@ __gnttab_unmap_common( op->ref = map->ref; act = &active_entry(rgt, map->ref); - if ( op->frame == 0 ) - { - op->frame = act->frame; - } - else + op->frame = act->frame; + + if ( op->dev_bus_addr ) { - if ( unlikely(op->frame != act->frame) ) + if ( unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) ) PIN_FAIL(unmap_out, GNTST_general_error, - "Bad frame number doesn't match gntref. (%lx != %lx)\n", - op->frame, act->frame); + "Bus address doesn't match gntref (%"PRIx64" != %"PRIpaddr")\n", + op->dev_bus_addr, pfn_to_paddr(act->frame)); map->flags &= ~GNTMAP_device_map; } @@ -1057,7 +1053,8 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op) else status = &status_entry(rgt, op->ref); - if ( unlikely(op->frame != act->frame) ) + if ( op->dev_bus_addr && + unlikely(op->dev_bus_addr != pfn_to_paddr(act->frame)) ) { /* * Suggests that __gntab_unmap_common failed early and so @@ -1068,7 +1065,7 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op) pg = mfn_to_page(op->frame); - if ( op->flags & GNTMAP_device_map ) + if ( op->dev_bus_addr && (op->flags & GNTMAP_device_map) ) { if ( !is_iomem_page(act->frame) ) { @@ -1136,6 +1133,7 @@ __gnttab_unmap_grant_ref( /* Intialise these in case common contains old state */ common->new_addr = 0; common->rd = NULL; + common->frame = 0; __gnttab_unmap_common(common); op->status = common->status; @@ -1200,6 +1198,7 @@ __gnttab_unmap_and_replace( /* Intialise these in case common contains old state */ common->dev_bus_addr = 0; common->rd = NULL; + common->frame = 0; __gnttab_unmap_common(common); op->status = common->status; -- 2.1.4 debian/patches/xsa142-4.5.patch0000664000000000000000000000467112616222030013170 0ustar From 07ca00703f76ad392eda5ee52cce1197cf49c30a Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Subject: [PATCH v2.1 for-4.5] libxl: handle read-only drives with qemu-xen The current libxl code doesn't deal with read-only drives at all. Upstream QEMU and qemu-xen only support read-only cdrom drives: make sure to specify "readonly=on" for cdrom drives and return error in case the user requested a non-cdrom read-only drive. This is XSA-142, discovered by Lin Liu (https://bugzilla.redhat.com/show_bug.cgi?id=1257893). Signed-off-by: Stefano Stabellini Backport to Xen 4.5 and earlier, apropos of report and review from Michael Young. Signed-off-by: Ian Jackson --- tools/libxl/libxl_dm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index b4ce523..d74fb14 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -797,13 +797,18 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc, if (disks[i].is_cdrom) { if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) drive = libxl__sprintf - (gc, "if=ide,index=%d,media=cdrom,cache=writeback,id=ide-%i", - disk, dev_number); + (gc, "if=ide,index=%d,readonly=%s,media=cdrom,cache=writeback,id=ide-%i", + disk, disks[i].readwrite ? "off" : "on", dev_number); else drive = libxl__sprintf - (gc, "file=%s,if=ide,index=%d,media=cdrom,format=%s,cache=writeback,id=ide-%i", - disks[i].pdev_path, disk, format, dev_number); + (gc, "file=%s,if=ide,index=%d,readonly=%s,media=cdrom,format=%s,cache=writeback,id=ide-%i", + disks[i].pdev_path, disk, disks[i].readwrite ? "off" : "on", format, dev_number); } else { + if (!disks[i].readwrite) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "qemu-xen doesn't support read-only disk drivers"); + return NULL; + } + if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) { LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "cannot support" " empty disk format for %s", disks[i].vdev); -- 1.7.10.4 debian/patches/tools-xenmon-prefix.diff0000664000000000000000000000170712276137127015423 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenmon/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenmon/Makefile 2014-02-10 12:53:56.746058967 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenmon/Makefile 2014-02-10 12:56:07.358697499 +0100 @@ -27,10 +27,10 @@ build: xentrace_setmask xenbaked .PHONY: install install: build - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) xenbaked $(DESTDIR)$(SBINDIR)/xenbaked - $(INSTALL_PROG) xentrace_setmask $(DESTDIR)$(SBINDIR)/xentrace_setmask - $(INSTALL_PROG) xenmon.py $(DESTDIR)$(SBINDIR)/xenmon.py + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) xenbaked $(DESTDIR)$(PRIVATE_BINDIR)/xenbaked + $(INSTALL_PROG) xentrace_setmask $(DESTDIR)$(PRIVATE_BINDIR)/xentrace_setmask + $(INSTALL_PROG) xenmon.py $(DESTDIR)$(PRIVATE_BINDIR)/xenmon.py $(INSTALL_DIR) $(DESTDIR)$(DOCDIR) $(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.xenmon debian/patches/ubuntu-arm64-enablement.patch0000664000000000000000000000230512430115113016210 0ustar From: Stefan Bader Date: Fri, 11 Apr 2014 16:31:44 +0200 Subject: Enable build of arm64 / aarch64 Some defines are duplicated between libc and xen code. This got resolved later (assume libc dropped them or renamed those). For Trusty keep the block disabled in Xen. Signed-off-by: Stefan Bader Index: xen-4.4.0/xen/include/public/arch-arm.h =================================================================== --- xen-4.4.0.orig/xen/include/public/arch-arm.h 2014-03-10 11:43:57.000000000 +0100 +++ xen-4.4.0/xen/include/public/arch-arm.h 2014-04-11 16:30:42.168872602 +0200 @@ -342,6 +342,7 @@ typedef uint64_t xen_callback_t; /* 64 bit modes */ #define PSR_MODE_BIT 0x10 /* Set iff AArch32 */ +#ifndef PSR_MODE_EL3h /* Already defined in .../asm/ptrace. */ #define PSR_MODE_EL3h 0x0d #define PSR_MODE_EL3t 0x0c #define PSR_MODE_EL2h 0x09 @@ -349,6 +350,7 @@ typedef uint64_t xen_callback_t; #define PSR_MODE_EL1h 0x05 #define PSR_MODE_EL1t 0x04 #define PSR_MODE_EL0t 0x00 +#endif #define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC) #define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h) debian/patches/xsa188.patch0000664000000000000000000000150112775454762012714 0ustar evtchn-fifo: prevent use after free evtchn_fifo_init_control() calls evtchn_fifo_destroy() on an error path, leading to cleanup_event_array() which frees d->evtchn_fifo without also clearing the pointer. Otoh the bulk of evtchn_fifo_init_control() is dependent on d->evtchn_fifo being NULL. This is XSA-188. Reported-by: Mikhail V Gorobets Suggested-by: Mikhail V Gorobets Signed-off-by: Jan Beulich --- a/xen/common/event_fifo.c +++ b/xen/common/event_fifo.c @@ -482,6 +482,7 @@ static void cleanup_event_array(struct d for ( i = 0; i < EVTCHN_FIFO_MAX_EVENT_ARRAY_PAGES; i++ ) unmap_guest_page(d->evtchn_fifo->event_array[i]); xfree(d->evtchn_fifo); + d->evtchn_fifo = NULL; } static void setup_ports(struct domain *d) debian/patches/xsa193-4.5.patch0000664000000000000000000000550613035176512013205 0ustar From: Jan Beulich Subject: x86/PV: writes of %fs and %gs base MSRs require canonical addresses Commit c42494acb2 ("x86: fix FS/GS base handling when using the fsgsbase feature") replaced the use of wrmsr_safe() on these paths without recognizing that wr{f,g}sbase() use just wrmsrl() and that the WR{F,G}SBASE instructions also raise #GP for non-canonical input. Similarly arch_set_info_guest() needs to prevent non-canonical addresses from getting stored into state later to be loaded by context switch code. For consistency also check stack pointers and LDT base. DR0..3, otoh, already get properly checked in set_debugreg() (albeit we discard the error there). The SHADOW_GS_BASE check isn't strictly necessary, but I think we better avoid trying the WRMSR if we know it's going to fail. This is XSA-193. Reported-by: Andrew Cooper Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -741,7 +741,13 @@ int arch_set_info_guest( { if ( !compat ) { - if ( !is_canonical_address(c.nat->user_regs.eip) || + if ( !is_canonical_address(c.nat->user_regs.rip) || + !is_canonical_address(c.nat->user_regs.rsp) || + !is_canonical_address(c.nat->kernel_sp) || + (c.nat->ldt_ents && !is_canonical_address(c.nat->ldt_base)) || + !is_canonical_address(c.nat->fs_base) || + !is_canonical_address(c.nat->gs_base_kernel) || + !is_canonical_address(c.nat->gs_base_user) || !is_canonical_address(c.nat->event_callback_eip) || !is_canonical_address(c.nat->syscall_callback_eip) || !is_canonical_address(c.nat->failsafe_callback_eip) ) --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2439,19 +2439,19 @@ static int emulate_privileged_op(struct switch ( (u32)regs->ecx ) { case MSR_FS_BASE: - if ( is_pv_32on64_vcpu(v) ) + if ( is_pv_32on64_vcpu(v) || !is_canonical_address(msr_content) ) goto fail; wrfsbase(msr_content); v->arch.pv_vcpu.fs_base = msr_content; break; case MSR_GS_BASE: - if ( is_pv_32on64_vcpu(v) ) + if ( is_pv_32on64_vcpu(v) || !is_canonical_address(msr_content) ) goto fail; wrgsbase(msr_content); v->arch.pv_vcpu.gs_base_kernel = msr_content; break; case MSR_SHADOW_GS_BASE: - if ( is_pv_32on64_vcpu(v) ) + if ( is_pv_32on64_vcpu(v) || !is_canonical_address(msr_content) ) goto fail; if ( wrmsr_safe(MSR_SHADOW_GS_BASE, msr_content) ) goto fail; debian/patches/xsa206-4.4-0006-oxenstored-use-hash-table-to-store-socket-connection.patch0000664000000000000000000000736413104300257025743 0ustar From efa34c63e8a62dab87918c7854e51291bd8fabeb Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Fri, 24 Mar 2017 17:02:08 +0000 Subject: [PATCH 06/30] oxenstored: use hash table to store socket connections Currently we use list to store socket connections. This is fine for smaller number of connections. But when we scale up, traveling through a list of hundreds or thousands of connections just to find a single one of them is very low efficient. This patch replaces the list with a (Unix.file_descr -> Connection.t) hash table. Reported-by: Juergen Gross Signed-off-by: Zheng Li Reviewed-by: David Scott --- tools/ocaml/xenstored/connections.ml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml index f4550f9..3e6a48b 100644 --- a/tools/ocaml/xenstored/connections.ml +++ b/tools/ocaml/xenstored/connections.ml @@ -18,17 +18,17 @@ let debug fmt = Logging.debug "connections" fmt type t = { - mutable anonymous: Connection.t list; + anonymous: (Unix.file_descr, Connection.t) Hashtbl.t; domains: (int, Connection.t) Hashtbl.t; mutable watches: (string, Connection.watch list) Trie.t; } -let create () = { anonymous = []; domains = Hashtbl.create 8; watches = Trie.create () } +let create () = { anonymous = Hashtbl.create 37; domains = Hashtbl.create 37; watches = Trie.create () } let add_anonymous cons fd can_write = let xbcon = Xenbus.Xb.open_fd fd in let con = Connection.create xbcon None in - cons.anonymous <- con :: cons.anonymous + Hashtbl.add cons.anonymous (Xenbus.Xb.get_fd xbcon) con let add_domain cons dom = let xbcon = Xenbus.Xb.open_mmap (Domain.get_interface dom) (fun () -> Domain.notify dom) in @@ -36,14 +36,14 @@ let add_domain cons dom = Hashtbl.add cons.domains (Domain.get_id dom) con let select cons = - let inset = List.map (fun c -> Connection.get_fd c) cons.anonymous - and outset = List.fold_left (fun l c -> if Connection.has_output c - then Connection.get_fd c :: l - else l) [] cons.anonymous in - inset, outset + Hashtbl.fold + (fun _ con (ins, outs) -> + let fd = Connection.get_fd con in + (fd :: ins, if Connection.has_output con then fd :: outs else outs)) + cons.anonymous ([], []) -let find cons fd = - List.find (fun c -> Connection.get_fd c = fd) cons.anonymous +let find cons = + Hashtbl.find cons.anonymous let find_domain cons id = Hashtbl.find cons.domains id @@ -55,7 +55,7 @@ let del_watches_of_con con watches = let del_anonymous cons con = try - cons.anonymous <- Utils.list_remove con cons.anonymous; + Hashtbl.remove cons.anonymous (Connection.get_fd con); cons.watches <- Trie.map (del_watches_of_con con) cons.watches; Connection.close con with exn -> @@ -74,7 +74,7 @@ let iter_domains cons fct = Hashtbl.iter (fun k c -> fct c) cons.domains let iter_anonymous cons fct = - List.iter (fun c -> fct c) (List.rev cons.anonymous) + Hashtbl.iter (fun _ c -> fct c) cons.anonymous let iter cons fct = iter_domains cons fct; iter_anonymous cons fct @@ -163,10 +163,10 @@ let stats cons = nb_ops_dom := !nb_ops_dom + con_ops; nb_watchs_dom := !nb_watchs_dom + con_watchs; ); - (List.length cons.anonymous, !nb_ops_anon, !nb_watchs_anon, + (Hashtbl.length cons.anonymous, !nb_ops_anon, !nb_watchs_anon, Hashtbl.length cons.domains, !nb_ops_dom, !nb_watchs_dom) let debug cons = - let anonymous = List.map Connection.debug cons.anonymous in + let anonymous = Hashtbl.fold (fun _ con accu -> Connection.debug con :: accu) cons.anonymous [] in let domains = Hashtbl.fold (fun _ con accu -> Connection.debug con :: accu) cons.domains [] in String.concat "" (domains @ anonymous) -- 2.1.4 debian/patches/tools-xenpaging-prefix.diff0000664000000000000000000000167512276137131016076 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenpaging/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenpaging/Makefile 2014-02-10 12:53:56.534057933 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenpaging/Makefile 2014-02-10 12:56:08.838704731 +0100 @@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS) -LDFLAGS += $(PTHREAD_LDFLAGS) +LDFLAGS += $(PTHREAD_LDFLAGS) $(call LDFLAGS_RPATH,../lib) POLICY = default @@ -25,8 +25,8 @@ xenpaging: $(OBJS) install: all $(INSTALL_DIR) $(DESTDIR)$(XEN_PAGING_DIR) - $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC) - $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC) + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(PRIVATE_BINDIR) clean: rm -f *.o *~ $(DEPS) xen TAGS $(IBINS) $(LIB) debian/patches/tools-xenstore-compatibility.diff0000664000000000000000000000355512276137147017347 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstore/xenstore_client.c =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstore/xenstore_client.c 2014-02-10 12:53:54.286046943 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstore/xenstore_client.c 2014-02-10 12:56:23.166774780 +0100 @@ -632,7 +632,7 @@ main(int argc, char **argv) max_width = ws.ws_col - 2; } - xsh = xs_open(socket ? XS_OPEN_SOCKETONLY : 0); + xsh = xs_open(socket ? XS_OPEN_SOCKETONLY : XS_OPEN_DOMAINONLY); if (xsh == NULL) err(1, "xs_open"); again: Index: xen-4.4.0~rc3+20140210/tools/xenstore/xs.c =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstore/xs.c 2014-02-10 12:53:54.334047173 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstore/xs.c 2014-02-10 12:56:23.166774780 +0100 @@ -282,17 +282,19 @@ struct xs_handle *xs_daemon_open_readonl struct xs_handle *xs_domain_open(void) { - return xs_open(0); + return xs_open(XS_OPEN_DOMAINONLY); } struct xs_handle *xs_open(unsigned long flags) { struct xs_handle *xsh = NULL; + if (!(flags & XS_OPEN_DOMAINONLY)) { if (flags & XS_OPEN_READONLY) xsh = get_handle(xs_daemon_socket_ro()); else xsh = get_handle(xs_daemon_socket()); + } if (!xsh && !(flags & XS_OPEN_SOCKETONLY)) xsh = get_handle(xs_domain_dev()); Index: xen-4.4.0~rc3+20140210/tools/xenstore/xenstore.h =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstore/xenstore.h 2014-02-10 12:53:54.306047033 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstore/xenstore.h 2014-02-10 12:56:23.166774780 +0100 @@ -26,6 +26,7 @@ #define XS_OPEN_READONLY 1UL<<0 #define XS_OPEN_SOCKETONLY 1UL<<1 +#define XS_OPEN_DOMAINONLY 1UL<<2 /* * Setting XS_UNWATCH_FILTER arranges that after xs_unwatch, no debian/patches/xsa145.patch0000664000000000000000000000315312616222046012670 0ustar xen/arm: Support hypercall_create_continuation for multicall Multicall for ARM has been supported since commit f0dbdc6 "xen: arm: fully implement multicall interface.". Although, if an hypercall in multicall requires preemption, it will crash the host: (XEN) Xen BUG at domain.c:347 (XEN) ----[ Xen-4.7-unstable arm64 debug=y Tainted: C ]---- [...] (XEN) Xen call trace: (XEN) [<00000000002420cc>] hypercall_create_continuation+0x64/0x380 (PC) (XEN) [<0000000000217274>] do_memory_op+0x1b00/0x2334 (LR) (XEN) [<0000000000250d2c>] do_multicall_call+0x114/0x124 (XEN) [<0000000000217ff0>] do_multicall+0x17c/0x23c (XEN) [<000000000024f97c>] do_trap_hypercall+0x90/0x12c (XEN) [<0000000000251ca8>] do_trap_hypervisor+0xd2c/0x1ba4 (XEN) [<00000000002582cc>] guest_sync+0x88/0xb8 (XEN) (XEN) (XEN) **************************************** (XEN) Panic on CPU 5: (XEN) Xen BUG at domain.c:347 (XEN) **************************************** (XEN) (XEN) Manual reset required ('noreboot' specified) Looking to the code, the support of multicall looks valid to me, as we only need to fill call.args[...]. So drop the BUG(); This is XSA-145. Acked-by: Ian Campbell diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 575745c..5c5ac9e 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -344,8 +344,6 @@ unsigned long hypercall_create_continuation( if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) { - BUG(); /* XXX multicalls not implemented yet. */ - __set_bit(_MCSF_call_preempted, &mcs->flags); for ( i = 0; *p != '\0'; i++ ) debian/patches/xsa206-4.4-0009-oxenstored-add-a-safe-net-mechanism-for-existing-ill.patch0000664000000000000000000002364213104300257025546 0ustar From af37817fe5c03f17855b27f7b768783797318987 Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Fri, 24 Mar 2017 17:04:23 +0000 Subject: [PATCH 09/30] oxenstored: add a safe net mechanism for existing ill-behaved clients In previous commit, we moved from exhaustively scanning all domain connections to only processing those have correctly notified us by events. The benefits are not only efficiency but also correctness, because it could potentially block an ill-behaved client and have it waiting on its own mistake. If someone makes a mistake on this when developing a piece of code, he/she would immediately notice the problem (as the process being blocked), so that he/she could fix it rightaway before anything else. Note that the chances of making such mistakes are rare in reality, because most client code would use the libxenstore library (which has all the notification logic built in correctly) instead of having to implement raw accessing from scratch. On the other hand, we did notice that there were some legacy code that didn't do the notification correctly. As some code might be still running in wild, it would be bad if they break by this change (e.g. after an upgrade). This patch introduces a safe net mechanism to ensure ill-behaved clients continue to work, but still retain most of the performance benefits here. * We add a checker to still scan all the rings periodically, so that we can still pick up these messages at an acceptable frequency. * Internally, we introduce an io_credit concept for domain connections. It represents the rounds of ring scan we are going to perform on a domain connection. For well-behaved connections, this value is changing between 0 and 1; but for connections detected as ill-behaved, we'll bump its credit to a high value so that we'll unconditionally scan its ring for the next $n$ rounds. This way, the client won't hiccupped by the interval between checker's running (especially during periods when it continously interacts with oxenstored); and oxenstored doesn't have to keep scanning these rings indefinitely (with the credit running out), as they are usually quite most of the time. * We log an message when a domain connection is suspected as ill-behaved. Enable [info] level logging if you want/need to see it in action. Note that this information won't be accurate, as false positives are possible due to time window (e.g. we detect a client has written to the ring and we get no notificiation from it for the time being, but still the notification could potentially arrive at some time later). It's no harm to give a domain connection extra credit though. Reported-by: Juergen Gross Signed-off-by: Zheng Li Reviewed-by: David Scott --- tools/ocaml/xenstored/domain.ml | 11 ++++- tools/ocaml/xenstored/oxenstored.conf | 3 ++ tools/ocaml/xenstored/xenstored.ml | 76 ++++++++++++++++++++++++++--------- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml index 06d5749..ab34314 100644 --- a/tools/ocaml/xenstored/domain.ml +++ b/tools/ocaml/xenstored/domain.ml @@ -28,6 +28,9 @@ type t = eventchn: Event.t; mutable port: Xeneventchn.t option; mutable bad_client: bool; + mutable io_credit: int; (* the rounds of ring process left to do, default is 0, + usually set to 1 when there is work detected, could + also set to n to give "lazy" clients extra credit *) } let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id) @@ -40,6 +43,11 @@ let get_port d = d.port let is_bad_domain domain = domain.bad_client let mark_as_bad domain = domain.bad_client <- true +let get_io_credit domain = domain.io_credit +let set_io_credit ?(n=1) domain = domain.io_credit <- max 0 n +let incr_io_credit domain = domain.io_credit <- domain.io_credit + 1 +let decr_io_credit domain = domain.io_credit <- max 0 (domain.io_credit - 1) + let string_of_port = function | None -> "None" | Some x -> string_of_int (Xeneventchn.to_int x) @@ -74,7 +82,8 @@ let make id mfn remote_port interface eventchn = { interface = interface; eventchn = eventchn; port = None; - bad_client = false + bad_client = false; + io_credit = 0; } let is_dom0 d = d.id = 0 diff --git a/tools/ocaml/xenstored/oxenstored.conf b/tools/ocaml/xenstored/oxenstored.conf index 13ee770..dd20eda 100644 --- a/tools/ocaml/xenstored/oxenstored.conf +++ b/tools/ocaml/xenstored/oxenstored.conf @@ -33,3 +33,6 @@ persistent = false # acesss-log-nb-chars = 180 # access-log-special-ops = false +# Perodically scanning all the rings as a safenet for lazy clients. +# Define the interval in seconds, set to negative to disable. +# ring-scan-interval = 20 diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 4a1d027..58a1ffc 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -54,13 +54,14 @@ let process_connection_fds store cons domains rset wset = let process_domains store cons domains = let do_io_domain domain = if not (Domain.is_bad_domain domain) then - let con = Connections.find_domain cons (Domain.get_id domain) in + let io_credit = Domain.get_io_credit domain in + if io_credit > 0 then ( + let con = Connections.find_domain cons (Domain.get_id domain) in Process.do_input store cons domains con; - Process.do_output store cons domains con in - List.iter - (fun c -> - match Connection.get_domain c with - | Some d -> do_io_domain d | _ -> ()) + Process.do_output store cons domains con; + Domain.decr_io_credit domain; + ) in + Domains.iter domains do_io_domain let sigusr1_handler store = try @@ -82,6 +83,8 @@ let config_filename cf = let default_pidfile = "/var/run/xenstored.pid" +let ring_scan_interval = ref 20 + let parse_config filename = let pidfile = ref default_pidfile in let options = [ @@ -108,6 +111,7 @@ let parse_config filename = ("access-log-transactions-ops", Config.Set_bool Logging.access_log_transaction_ops); ("access-log-special-ops", Config.Set_bool Logging.access_log_special_ops); ("allow-debug", Config.Set_bool Process.allow_debug); + ("ring-scan-interval", Config.Set_int ring_scan_interval); ("pid-file", Config.Set_string pidfile); ] in begin try Config.read filename options (fun _ _ -> raise Not_found) with @@ -316,7 +320,8 @@ let _ = ) else let c = Connections.find_domain_by_port cons port in - process_domains store cons domains [c] + match Connection.get_domain c with + | Some dom -> Domain.incr_io_credit dom | None -> () ) (fun () -> Event.unmask eventchn port) and do_if_set fd set fct = if List.mem fd set then @@ -325,11 +330,30 @@ let _ = maybe (fun fd -> do_if_set fd rset (accept_connection true)) rw_sock; maybe (fun fd -> do_if_set fd rset (accept_connection false)) ro_sock; do_if_set (Event.fd eventchn) rset (handle_eventchn) - in + in + + let ring_scan_checker dom = + (* no need to scan domains already marked as for processing *) + if not (Domain.get_io_credit dom > 0) then + let con = Connections.find_domain cons (Domain.get_id dom) in + if not (Connection.has_more_work con) then ( + Process.do_output store cons domains con; + Process.do_input store cons domains con; + if Connection.has_more_work con then + (* Previously thought as no work, but detect some after scan (as + processing a new message involves multiple steps.) It's very + likely to be a "lazy" client, bump its credit. It could be false + positive though (due to time window), but it's no harm to give a + domain extra credit. *) + let n = 32 + 2 * (Domains.number domains) in + info "found lazy domain %d, credit %d" (Domain.get_id dom) n; + Domain.set_io_credit ~n dom + ) in let last_stat_time = ref 0. in - let periodic_ops_counter = ref 0 in - let periodic_ops () = + let last_scan_time = ref 0. in + + let periodic_ops now = (* we garbage collect the string->int dictionary after a sizeable amount of operations, * there's no need to be really fast even if we got loose * objects since names are often reuse. @@ -342,10 +366,13 @@ let _ = Symbol.garbage () end; + (* scan all the xs rings as a safenet for ill-behaved clients *) + if !ring_scan_interval >= 0 && now > (!last_scan_time +. float !ring_scan_interval) then + (last_scan_time := now; Domains.iter domains ring_scan_checker); + (* make sure we don't print general stats faster than 2 min *) - let ntime = Unix.gettimeofday () in - if ntime > (!last_stat_time +. 120.) then ( - last_stat_time := ntime; + if now > (!last_stat_time +. 120.) then ( + last_stat_time := now; let gc = Gc.stat () in let (lanon, lanon_ops, lanon_watchs, @@ -366,16 +393,20 @@ let _ = ) in + let period_ops_interval = 15. in + let period_start = ref 0. in + let main_loop () = - incr periodic_ops_counter; - if !periodic_ops_counter > 20 then ( - periodic_ops_counter := 0; - periodic_ops (); - ); let mw = Connections.has_more_work cons in + List.iter + (fun c -> + match Connection.get_domain c with + | None -> () | Some d -> Domain.incr_io_credit d) + mw; + let timeout = + if List.length mw > 0 then 0. else period_ops_interval in let inset, outset = Connections.select cons in - let timeout = if List.length mw > 0 then 0. else -1. in let rset, wset, _ = try Unix.select (spec_fds @ inset) outset [] timeout @@ -387,7 +418,12 @@ let _ = process_special_fds sfds; if List.length cfds > 0 || List.length wset > 0 then process_connection_fds store cons domains cfds wset; - process_domains store cons domains mw + if timeout <> 0. then ( + let now = Unix.gettimeofday () in + if now > !period_start +. period_ops_interval then + (period_start := now; periodic_ops now) + ); + process_domains store cons domains in while not !quit -- 2.1.4 debian/patches/tools-hotplug-udevrules.diff0000664000000000000000000000240412276137144016314 0ustar Index: xen-4.4.0~rc3+20140210/tools/hotplug/Linux/xen-backend.rules =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/hotplug/Linux/xen-backend.rules 2014-02-10 12:53:54.934050101 +0100 +++ xen-4.4.0~rc3+20140210/tools/hotplug/Linux/xen-backend.rules 2014-02-10 12:56:20.746762945 +0100 @@ -5,11 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif-* SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ENV{UDEV_CALL}="1", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif" SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}" SUBSYSTEM=="xen-backend", ACTION=="remove", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/xen-hotplug-cleanup" -KERNEL=="evtchn", NAME="xen/%k" -SUBSYSTEM=="xen", KERNEL=="blktap[0-9]*", NAME="xen/%k", MODE="0600" -SUBSYSTEM=="blktap2", KERNEL=="blktap[0-9]*", NAME="xen/blktap-2/%k", MODE="0600" -KERNEL=="blktap-control", NAME="xen/blktap-2/control", MODE="0600" -KERNEL=="gntdev", NAME="xen/%k", MODE="0600" -KERNEL=="pci_iomul", NAME="xen/%k", MODE="0600" -KERNEL=="tapdev[a-z]*", NAME="xen/blktap-2/tapdev%m", MODE="0600" SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap" debian/patches/xsa131-qemut-5.patch0000664000000000000000000000142512571017504014157 0ustar xen/pt: mark all PCIe capability bits read-only xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read- only to avoid unintended write-back (just a precaution, the field ought to be read-only in hardware). This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -577,7 +577,7 @@ static struct pt_reg_info_tbl pt_emu_reg .offset = PCI_EXP_DEVCAP, .size = 4, .init_val = 0x00000000, - .ro_mask = 0x1FFCFFFF, + .ro_mask = 0xFFFFFFFF, .emu_mask = 0x10000000, .init = pt_common_reg_init, .u.dw.read = pt_long_reg_read, debian/patches/xsa136.patch0000664000000000000000000000121212571017622012664 0ustar From: Andrew Cooper Subject: x86/traps: loop in the correct direction in compat_iret() This is XSA-136. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- a/xen/arch/x86/x86_64/compat/traps.c +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -119,7 +119,7 @@ unsigned int compat_iret(void) } else if ( ksp > regs->_esp ) { - for (i = 9; i > 0; ++i) + for ( i = 9; i > 0; --i ) { rc |= __get_user(x, (u32 *)regs->rsp + i); rc |= __put_user(x, (u32 *)(unsigned long)ksp + i); debian/patches/xsa131-qemut-3.patch0000664000000000000000000000144512571017454014163 0ustar xen/pt: correctly handle PM status bit xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS). This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -3786,7 +3786,8 @@ static int pt_pmcsr_reg_write(struct pt_ /* create value for writing to I/O device register */ throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS, + throughable_mask); if (!ptdev->power_mgmt) return 0; debian/patches/xsa209-qemut.patch0000664000000000000000000000364513104310130014011 0ustar From: Gerd Hoffmann Subject: [PATCH 3/3] cirrus: add blit_is_unsafe call to cirrus_bitblt_cputovideo CIRRUS_BLTMODE_MEMSYSSRC blits do NOT check blit destination and blit width, at all. Oops. Fix it. Security impact: high. The missing blit destination check allows to write to host memory. Basically same as CVE-2014-8106 for the other blit variants. The missing blit width check allows to overflow cirrus_bltbuf, with the attractive target cirrus_srcptr (current cirrus_bltbuf write position) being located right after cirrus_bltbuf in CirrusVGAState. Due to cirrus emulation writing cirrus_bltbuf bytewise the attacker hasn't full control over cirrus_srcptr though, only one byte can be changed. Once the first byte has been modified further writes land elsewhere. [ This is CVE-2017-2620 / XSA-209 - Ian Jackson ] Fixed compilation by removing extra parameter to blit_is_unsafe. -iwj Reported-by: Gerd Hoffmann Signed-off-by: Gerd Hoffmann Signed-off-by: Ian Jackson --- diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index e6c3893..45facb6 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -900,6 +900,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) { int w; + if (blit_is_unsafe(s)) { + return 0; + } + s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; s->cirrus_srcptr = &s->cirrus_bltbuf[0]; s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; @@ -925,6 +929,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) } s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; } + + /* the blit_is_unsafe call above should catch this */ + assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE); + s->cirrus_srcptr = s->cirrus_bltbuf; s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; cirrus_update_memory_access(s); debian/patches/xsa237-4.5-0004-x86-IRQ-conditionally-preserve-irq-pirq-mapping-on-error.patch0000664000000000000000000000741413167427362026304 0ustar From: Jan Beulich Subject: x86/IRQ: conditionally preserve irq <-> pirq mapping on map error paths Mappings that had been set up before should not be torn down when handling unrelated errors. This is part of XSA-237. Signed-off-by: Jan Beulich Reviewed-by: George Dunlap --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1249,7 +1249,8 @@ static int prepare_domain_irq_pirq(struc return -ENOMEM; } *pinfo = info; - return 0; + + return !!err; } static void set_domain_irq_pirq(struct domain *d, int irq, struct pirq *pirq) @@ -1292,7 +1293,10 @@ int init_domain_irq_mapping(struct domai continue; err = prepare_domain_irq_pirq(d, i, i, &info); if ( err ) + { + ASSERT(err < 0); break; + } set_domain_irq_pirq(d, i, info); } @@ -1900,6 +1904,7 @@ int map_domain_pirq( struct pirq *info; struct irq_desc *desc; unsigned long flags; + DECLARE_BITMAP(prepared, MAX_MSI_IRQS) = {}; ASSERT(spin_is_locked(&d->event_lock)); @@ -1943,8 +1948,10 @@ int map_domain_pirq( } ret = prepare_domain_irq_pirq(d, irq, pirq, &info); - if ( ret ) + if ( ret < 0 ) goto revoke; + if ( !ret ) + __set_bit(0, prepared); desc = irq_to_desc(irq); @@ -2016,8 +2023,10 @@ int map_domain_pirq( irq = create_irq(NUMA_NO_NODE); ret = irq >= 0 ? prepare_domain_irq_pirq(d, irq, pirq + nr, &info) : irq; - if ( ret ) + if ( ret < 0 ) break; + if ( !ret ) + __set_bit(nr, prepared); msi_desc[nr].irq = irq; if ( irq_permit_access(d, irq) != 0 ) @@ -2050,15 +2059,15 @@ int map_domain_pirq( desc->msi_desc = NULL; spin_unlock_irqrestore(&desc->lock, flags); } - while ( nr-- ) + while ( nr ) { if ( irq >= 0 && irq_deny_access(d, irq) ) printk(XENLOG_G_ERR "dom%d: could not revoke access to IRQ%d (pirq %d)\n", d->domain_id, irq, pirq); - if ( info ) + if ( info && test_bit(nr, prepared) ) cleanup_domain_irq_pirq(d, irq, info); - info = pirq_info(d, pirq + nr); + info = pirq_info(d, pirq + --nr); irq = info->arch.irq; } msi_desc->irq = -1; @@ -2074,12 +2083,14 @@ int map_domain_pirq( spin_lock_irqsave(&desc->lock, flags); set_domain_irq_pirq(d, irq, info); spin_unlock_irqrestore(&desc->lock, flags); + ret = 0; } done: if ( ret ) { - cleanup_domain_irq_pirq(d, irq, info); + if ( test_bit(0, prepared) ) + cleanup_domain_irq_pirq(d, irq, info); revoke: if ( irq_deny_access(d, irq) ) printk(XENLOG_G_ERR --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -185,7 +185,7 @@ int physdev_map_pirq(domid_t domid, int } else if ( type == MAP_PIRQ_TYPE_MULTI_MSI ) { - if ( msi->entry_nr <= 0 || msi->entry_nr > 32 ) + if ( msi->entry_nr <= 0 || msi->entry_nr > MAX_MSI_IRQS ) ret = -EDOM; else if ( msi->entry_nr != 1 && !iommu_intremap ) ret = -EOPNOTSUPP; --- a/xen/include/asm-x86/msi.h +++ b/xen/include/asm-x86/msi.h @@ -55,6 +55,8 @@ /* MAX fixed pages reserved for mapping MSIX tables. */ #define FIX_MSIX_MAX_PAGES 512 +#define MAX_MSI_IRQS 32 /* limited by MSI capability struct properties */ + struct msi_info { u16 seg; u8 bus; debian/patches/xsa182-4.5.patch0000664000000000000000000001025112775454463013212 0ustar From 798c1498f764bfaa7b0b955bab40b01b0610d372 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Mon, 11 Jul 2016 14:32:03 +0100 Subject: [PATCH] x86/pv: Remove unsafe bits from the mod_l?_entry() fastpath All changes in writeability and cacheability must go through full re-validation. Rework the logic as a whitelist, to make it clearer to follow. This is XSA-182 Reported-by: Jérémie Boutoille Signed-off-by: Andrew Cooper Reviewed-by: Tim Deegan --- xen/arch/x86/mm.c | 28 ++++++++++++++++------------ xen/include/asm-x86/page.h | 1 + 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index b4c4fa4..a68a1ab 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1695,6 +1695,14 @@ static inline int update_intpte(intpte_t *p, _t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \ (_m), (_v), (_ad)) +/* + * PTE flags that a guest may change without re-validating the PTE. + * All other bits affect translation, caching, or Xen's safety. + */ +#define FASTPATH_FLAG_WHITELIST \ + (_PAGE_NX_BIT | _PAGE_AVAIL_HIGH | _PAGE_AVAIL | _PAGE_GLOBAL | \ + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_USER) + /* Update the L1 entry at pl1e to new value nl1e. */ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, unsigned long gl1mfn, int preserve_ad, @@ -1735,9 +1743,8 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, return -EINVAL; } - /* Fast path for identical mapping, r/w, presence, and cachability. */ - if ( !l1e_has_changed(ol1e, nl1e, - PAGE_CACHE_ATTRS | _PAGE_RW | _PAGE_PRESENT) ) + /* Fast path for sufficiently-similar mappings. */ + if ( !l1e_has_changed(ol1e, nl1e, ~FASTPATH_FLAG_WHITELIST) ) { adjust_guest_l1e(nl1e, pt_dom); if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, @@ -1819,11 +1826,8 @@ static int mod_l2_entry(l2_pgentry_t *pl2e, return -EINVAL; } - /* Fast path for identical mapping and presence. */ - if ( !l2e_has_changed(ol2e, nl2e, - unlikely(opt_allow_superpage) - ? _PAGE_PSE | _PAGE_RW | _PAGE_PRESENT - : _PAGE_PRESENT) ) + /* Fast path for sufficiently-similar mappings. */ + if ( !l2e_has_changed(ol2e, nl2e, ~FASTPATH_FLAG_WHITELIST) ) { adjust_guest_l2e(nl2e, d); if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) ) @@ -1888,8 +1892,8 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, return -EINVAL; } - /* Fast path for identical mapping and presence. */ - if ( !l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT) ) + /* Fast path for sufficiently-similar mappings. */ + if ( !l3e_has_changed(ol3e, nl3e, ~FASTPATH_FLAG_WHITELIST) ) { adjust_guest_l3e(nl3e, d); rc = UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, vcpu, preserve_ad); @@ -1952,8 +1956,8 @@ static int mod_l4_entry(l4_pgentry_t *pl4e, return -EINVAL; } - /* Fast path for identical mapping and presence. */ - if ( !l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT) ) + /* Fast path for sufficiently-similar mappings. */ + if ( !l4e_has_changed(ol4e, nl4e, ~FASTPATH_FLAG_WHITELIST) ) { adjust_guest_l4e(nl4e, d); rc = UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, vcpu, preserve_ad); diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index 6dc9646..03c024c 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -308,6 +308,7 @@ void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t); #define _PAGE_AVAIL2 _AC(0x800,U) #define _PAGE_AVAIL _AC(0xE00,U) #define _PAGE_PSE_PAT _AC(0x1000,U) +#define _PAGE_AVAIL_HIGH (_AC(0x7ff, U) << 12) /* non-architectural flags */ #define _PAGE_PAGED 0x2000U #define _PAGE_SHARED 0x4000U -- 2.1.4 debian/patches/xsa237-4.5-0003-x86-MSI-disallow-redundant-enabling.patch0000664000000000000000000000454413167425767022230 0ustar From: Jan Beulich Subject: x86/MSI: disallow redundant enabling At the moment, Xen attempts to allow redundant enabling of MSI by having pci_enable_msi() return 0, and point to the existing MSI descriptor, when the msi already exists. Unfortunately, if subsequent errors are encountered, the cleanup paths assume pci_enable_msi() had done full initialization, and hence undo everything that was assumed to be done by that function without also undoing other setup that would normally occur only after that function was called (in map_domain_pirq() itself). Rather than try to make the redundant enabling case work properly, just forbid it entirely by having pci_enable_msi() return -EEXIST when MSI is already set up. This is part of XSA-237. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Reviewed-by: George Dunlap --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -886,12 +886,10 @@ static int __pci_enable_msi(struct msi_i old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI); if ( old_desc ) { - dprintk(XENLOG_WARNING, "irq %d has already mapped to MSI on " - "device %04x:%02x:%02x.%01x\n", - msi->irq, msi->seg, msi->bus, - PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); - *desc = old_desc; - return 0; + printk(XENLOG_ERR "irq %d already mapped to MSI on %04x:%02x:%02x.%u\n", + msi->irq, msi->seg, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); + return -EEXIST; } old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX); @@ -956,12 +954,10 @@ static int __pci_enable_msix(struct msi_ old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX); if ( old_desc ) { - dprintk(XENLOG_WARNING, "irq %d has already mapped to MSIX on " - "device %04x:%02x:%02x.%01x\n", - msi->irq, msi->seg, msi->bus, - PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); - *desc = old_desc; - return 0; + printk(XENLOG_ERR "irq %d already mapped to MSI-X on %04x:%02x:%02x.%u\n", + msi->irq, msi->seg, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); + return -EEXIST; } old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSI); debian/patches/xsa200-4.6.patch0000664000000000000000000000361713035177713013200 0ustar From: Jan Beulich Subject: x86emul: CMPXCHG8B ignores operand size prefix Otherwise besides mis-handling the instruction, the comparison failure case would result in uninitialized stack data being handed back to the guest in rDX:rAX (32 bits leaked for 32-bit guests, 96 bits for 64-bit ones). This is XSA-200. Signed-off-by: Jan Beulich --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -429,6 +429,24 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing cmpxchg8b (%edi) [opsize]..."); + instr[0] = 0x66; instr[1] = 0x0f; instr[2] = 0xc7; instr[3] = 0x0f; + res[0] = 0x12345678; + res[1] = 0x87654321; + regs.eflags = 0x200; + regs.eip = (unsigned long)&instr[0]; + regs.edi = (unsigned long)res; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || + (res[0] != 0x12345678) || + (res[1] != 0x87654321) || + (regs.eax != 0x12345678) || + (regs.edx != 0x87654321) || + ((regs.eflags&0x240) != 0x200) || + (regs.eip != (unsigned long)&instr[4]) ) + goto fail; + printf("okay\n"); + printf("%-40s", "Testing movsxbd (%%eax),%%ecx..."); instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08; regs.eflags = 0x200; --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -4739,8 +4739,12 @@ x86_emulate( generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1); generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); if ( op_bytes == 8 ) + { vcpu_must_have_cx16(); - op_bytes *= 2; + op_bytes = 16; + } + else + op_bytes = 8; /* Get actual old value. */ if ( (rc = ops->read(ea.mem.seg, ea.mem.off, old, op_bytes, debian/patches/xsa131-qemut-1.patch0000664000000000000000000000433412571017434014157 0ustar xen/MSI: don't open-code pass-through of enable bit modifications Without this the actual XSA-131 fix would cause the enable bit to not get set anymore (due to the write back getting suppressed there based on the OR of emu_mask, ro_mask, and res_mask). Note that the fiddling with the enable bit shouldn't really be done by qemu, but making this work right (via libxc and the hypervisor) will require more extensive changes, which can be postponed until after the security issue got addressed. This is a preparatory patch for XSA-131. Signed-off-by: Jan Beulich Acked-by: Stefano Stabellini --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -648,7 +648,7 @@ static struct pt_reg_info_tbl pt_emu_reg .size = 2, .init_val = 0x0000, .ro_mask = 0xFF8E, - .emu_mask = 0x017F, + .emu_mask = 0x017E, .init = pt_msgctrl_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_msgctrl_reg_write, @@ -3901,6 +3901,9 @@ static int pt_msgctrl_reg_write(struct p /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + /* also emulate MSI_ENABLE bit for MSI-INTx translation */ + if (ptdev->msi_trans_en) + writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->flags |= cfg_entry->data & @@ -3909,6 +3912,9 @@ static int pt_msgctrl_reg_write(struct p /* create value for writing to I/O device register */ val = *value; throughable_mask = ~reg->emu_mask & valid_mask; + /* don't pass through MSI_ENABLE bit for MSI-INTx translation */ + if (ptdev->msi_trans_en) + throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ @@ -3952,12 +3958,6 @@ static int pt_msgctrl_reg_write(struct p } } - /* pass through MSI_ENABLE bit when no MSI-INTx translation */ - if (!ptdev->msi_trans_en) { - *value &= ~PCI_MSI_FLAGS_ENABLE; - *value |= val & PCI_MSI_FLAGS_ENABLE; - } - return 0; } debian/patches/xsa226-4.5-0002-gnttab-fix-transitive-grant-handling.patch0000664000000000000000000002610613147037572022710 0ustar From: Jan Beulich Subject: gnttab: fix transitive grant handling Processing of transitive grants must not use the fast path, or else reference counting breaks due to the skipped recursive call to __acquire_grant_for_copy() (its __release_grant_for_copy() counterpart occurs independent of original pin count). Furthermore after re-acquiring temporarily dropped locks we need to verify no grant properties changed if the original pin count was non-zero; checking just the pin counts is sufficient only for well-behaved guests. As a result, __release_grant_for_copy() needs to mirror that new behavior. Furthermore a __release_grant_for_copy() invocation was missing on the retry path of __acquire_grant_for_copy(), and gnttab_set_version() also needs to bail out upon encountering a transitive grant. This is part of CVE-2017-12135 / XSA-226. Reported-by: Andrew Cooper Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1808,13 +1808,8 @@ __release_grant_for_copy( unsigned long r_frame; uint16_t *status; grant_ref_t trans_gref; - int released_read; - int released_write; struct domain *td; - released_read = 0; - released_write = 0; - spin_lock(&rgt->lock); act = &active_entry(rgt, gref); @@ -1844,30 +1839,21 @@ __release_grant_for_copy( act->pin -= GNTPIN_hstw_inc; if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) ) - { - released_write = 1; gnttab_clear_flag(_GTF_writing, status); - } } if ( !act->pin ) - { gnttab_clear_flag(_GTF_reading, status); - released_read = 1; - } spin_unlock(&rgt->lock); if ( td != rd ) { /* - * Recursive calls, but they're bounded (acquire permits only a single + * Recursive call, but it is bounded (acquire permits only a single * level of transitivity), so it's okay. */ - if ( released_write ) - __release_grant_for_copy(td, trans_gref, 0); - else if ( released_read ) - __release_grant_for_copy(td, trans_gref, 1); + __release_grant_for_copy(td, trans_gref, readonly); rcu_unlock_domain(td); } @@ -1948,79 +1934,113 @@ __acquire_grant_for_copy( act->domid, ldom, act->pin); old_pin = act->pin; - if ( !act->pin || - (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) ) + if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive ) { - if ( (rc = _set_status(rgt->gt_version, ldom, - readonly, 0, shah, act, - status) ) != GNTST_okay ) - goto unlock_out; + if ( (!old_pin || (!readonly && + !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)))) && + (rc = _set_status_v2(ldom, readonly, 0, shah, act, + status)) != GNTST_okay ) + goto unlock_out; + + if ( !allow_transitive ) + PIN_FAIL(unlock_out_clear, GNTST_general_error, + "transitive grant when transitivity not allowed\n"); + + trans_domid = sha2->transitive.trans_domid; + trans_gref = sha2->transitive.gref; + barrier(); /* Stop the compiler from re-loading + trans_domid from shared memory */ + if ( trans_domid == rd->domain_id ) + PIN_FAIL(unlock_out_clear, GNTST_general_error, + "transitive grants cannot be self-referential\n"); - td = rd; - trans_gref = gref; - if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive ) + /* + * We allow the trans_domid == ldom case, which corresponds to a + * grant being issued by one domain, sent to another one, and then + * transitively granted back to the original domain. Allowing it + * is easy, and means that you don't need to go out of your way to + * avoid it in the guest. + */ + + /* We need to leave the rrd locked during the grant copy. */ + td = rcu_lock_domain_by_id(trans_domid); + if ( td == NULL ) + PIN_FAIL(unlock_out_clear, GNTST_general_error, + "transitive grant referenced bad domain %d\n", + trans_domid); + + /* + * __acquire_grant_for_copy() could take the lock on the + * remote table (if rd == td), so we have to drop the lock + * here and reacquire. + */ + spin_unlock(&rgt->lock); + + rc = __acquire_grant_for_copy(td, trans_gref, rd->domain_id, + readonly, &grant_frame, page, + &trans_page_off, &trans_length, 0); + + spin_lock(&rgt->lock); + + if ( rc != GNTST_okay ) { - if ( !allow_transitive ) - PIN_FAIL(unlock_out_clear, GNTST_general_error, - "transitive grant when transitivity not allowed\n"); - - trans_domid = sha2->transitive.trans_domid; - trans_gref = sha2->transitive.gref; - barrier(); /* Stop the compiler from re-loading - trans_domid from shared memory */ - if ( trans_domid == rd->domain_id ) - PIN_FAIL(unlock_out_clear, GNTST_general_error, - "transitive grants cannot be self-referential\n"); - - /* We allow the trans_domid == ldom case, which - corresponds to a grant being issued by one domain, sent - to another one, and then transitively granted back to - the original domain. Allowing it is easy, and means - that you don't need to go out of your way to avoid it - in the guest. */ - - /* We need to leave the rrd locked during the grant copy */ - td = rcu_lock_domain_by_id(trans_domid); - if ( td == NULL ) - PIN_FAIL(unlock_out_clear, GNTST_general_error, - "transitive grant referenced bad domain %d\n", - trans_domid); + __fixup_status_for_copy_pin(act, status); + rcu_unlock_domain(td); spin_unlock(&rgt->lock); + return rc; + } - rc = __acquire_grant_for_copy(td, trans_gref, rd->domain_id, - readonly, &grant_frame, page, - &trans_page_off, &trans_length, 0); - - spin_lock(&rgt->lock); - if ( rc != GNTST_okay ) { - __fixup_status_for_copy_pin(act, status); - rcu_unlock_domain(td); - spin_unlock(&rgt->lock); - return rc; - } + /* + * We dropped the lock, so we have to check that the grant didn't + * change, and that nobody else tried to pin/unpin it. If anything + * changed, just give up and tell the caller to retry. + */ + if ( rgt->gt_version != 2 || + act->pin != old_pin || + (old_pin && (act->domid != ldom || act->frame != grant_frame || + act->start != trans_page_off || + act->length != trans_length || + act->trans_domain != td || + act->trans_gref != trans_gref || + !act->is_sub_page)) ) + { + __release_grant_for_copy(td, trans_gref, readonly); + __fixup_status_for_copy_pin(act, status); + rcu_unlock_domain(td); + spin_unlock(&rgt->lock); + put_page(*page); + *page = NULL; + return ERESTART; + } + if ( !old_pin ) + { + act->domid = ldom; + act->start = trans_page_off; + act->length = trans_length; + act->trans_domain = td; + act->trans_gref = trans_gref; + act->frame = grant_frame; + act->gfn = -1ul; /* - * We dropped the lock, so we have to check that nobody else tried - * to pin (or, for that matter, unpin) the reference in *this* - * domain. If they did, just give up and tell the caller to retry. + * The actual remote remote grant may or may not be a sub-page, + * but we always treat it as one because that blocks mappings of + * transitive grants. */ - if ( act->pin != old_pin ) - { - __fixup_status_for_copy_pin(act, status); - rcu_unlock_domain(td); - spin_unlock(&rgt->lock); - put_page(*page); - *page = NULL; - return ERESTART; - } - - /* The actual remote remote grant may or may not be a - sub-page, but we always treat it as one because that - blocks mappings of transitive grants. */ - is_sub_page = 1; - act->gfn = -1ul; + act->is_sub_page = 1; } - else if ( sha1 ) + } + else if ( !old_pin || + (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) ) + { + if ( (rc = _set_status(rgt->gt_version, ldom, + readonly, 0, shah, act, + status) ) != GNTST_okay ) + goto unlock_out; + + td = rd; + trans_gref = gref; + if ( sha1 ) { rc = __get_paged_frame(sha1->frame, &grant_frame, page, readonly, rd); if ( rc != GNTST_okay ) @@ -2295,14 +2315,35 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARA } } - /* XXX: If we're going to version 2, we could maybe shrink the - active grant table here. */ - - if ( op.version == 2 && gt->gt_version < 2 ) + switch ( gt->gt_version ) { - res = gnttab_populate_status_frames(d, gt, nr_grant_frames(gt)); - if ( res < 0) - goto out_unlock; + case 0: + if ( op.version == 2 ) + { + case 1: + /* XXX: We could maybe shrink the active grant table here. */ + res = gnttab_populate_status_frames(d, gt, nr_grant_frames(gt)); + if ( res < 0) + goto out_unlock; + } + break; + case 2: + for ( i = 0; i < GNTTAB_NR_RESERVED_ENTRIES; i++ ) + { + switch ( shared_entry_v2(gt, i).hdr.flags & GTF_type_mask ) + { + case GTF_permit_access: + if ( !(shared_entry_v2(gt, i).full_page.frame >> 32) ) + break; + /* fall through */ + case GTF_transitive: + gdprintk(XENLOG_WARNING, + "tried to change grant table version to 1 with non-representable entries\n"); + res = -ERANGE; + goto out_unlock; + } + } + break; } /* Preserve the first 8 entries (toolstack reserved grants) */ debian/patches/xsa175-4.4-0012-libxl-Document-serial-correctly.patch0000664000000000000000000000255212725543022021726 0ustar From aea2669313d95739253745078e37d97a2f5d1fb9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 15:17:45 +0100 Subject: [PATCH 16/16] libxl: Document ~/serial/ correctly xenstore-paths.markdown talked about ~/device/serial/, but that's not used. (It is very wrong for this value, which contains a driver domain filesystem path, to be in the guest's area of xenstore. However, it is only ever created by libxl and ready by xenconsoled. When it is created, it inherits the read-only permissions of /local/domain/DOMID. So there is no security bug.) This is a followup to XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- docs/misc/xenstore-paths.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/misc/xenstore-paths.markdown b/docs/misc/xenstore-paths.markdown index c2e2842..70d6fad 100644 --- a/docs/misc/xenstore-paths.markdown +++ b/docs/misc/xenstore-paths.markdown @@ -232,7 +232,7 @@ The primary PV console device. Described in [console.txt](console.txt) A secondary PV console device. Described in [console.txt](console.txt) -#### ~/device/serial/$DEVID/* [HVM] +#### ~/serial/$DEVID/* [HVM] An emulated serial device. Described in [console.txt](console.txt) -- 1.9.1 debian/patches/xsa133-qemut.patch0000664000000000000000000000532712524660674014036 0ustar From ac7ddbe342d7aa2303c39ca731cc6229dbbd739b Mon Sep 17 00:00:00 2001 From: Petr Matousek Date: Wed, 6 May 2015 09:48:59 +0200 Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated buffer During processing of certain commands such as FD_CMD_READ_ID and FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could get out of bounds leading to memory corruption with values coming from the guest. Fix this by making sure that the index is always bounded by the allocated memory. This is CVE-2015-3456. Signed-off-by: Petr Matousek Reviewed-by: John Snow --- hw/fdc.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/qemu/hw/fdc.c b/qemu/hw/fdc.c index b00a4ec..aba02e4 100644 --- a/qemu/hw/fdc.c +++ b/qemu/hw/fdc.c @@ -1318,7 +1318,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) { fdrive_t *cur_drv; uint32_t retval = 0; - int pos; + uint32_t pos; cur_drv = get_cur_drv(fdctrl); fdctrl->dsr &= ~FD_DSR_PWRDOWN; @@ -1327,8 +1327,8 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) return 0; } pos = fdctrl->data_pos; + pos %= FD_SECTOR_LEN; if (fdctrl->msr & FD_MSR_NONDMA) { - pos %= FD_SECTOR_LEN; if (pos == 0) { if (fdctrl->data_pos != 0) if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { @@ -1673,10 +1673,13 @@ static void fdctrl_handle_option (fdctrl_t *fdctrl, int direction) static void fdctrl_handle_drive_specification_command (fdctrl_t *fdctrl, int direction) { fdrive_t *cur_drv = get_cur_drv(fdctrl); + uint32_t pos; - if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) { + pos = fdctrl->data_pos - 1; + pos %= FD_SECTOR_LEN; + if (fdctrl->fifo[pos] & 0x80) { /* Command parameters done */ - if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) { + if (fdctrl->fifo[pos] & 0x40) { fdctrl->fifo[0] = fdctrl->fifo[1]; fdctrl->fifo[2] = 0; fdctrl->fifo[3] = 0; @@ -1771,7 +1774,7 @@ static uint8_t command_to_handler[256]; static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) { fdrive_t *cur_drv; - int pos; + uint32_t pos; /* Reset mode */ if (!(fdctrl->dor & FD_DOR_nRESET)) { @@ -1817,7 +1820,9 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) } FLOPPY_DPRINTF("%s: %02x\n", __func__, value); - fdctrl->fifo[fdctrl->data_pos++] = value; + pos = fdctrl->data_pos++; + pos %= FD_SECTOR_LEN; + fdctrl->fifo[pos] = value; if (fdctrl->data_pos == fdctrl->data_len) { /* We now have all parameters * and will be able to treat the command debian/patches/tools-libfsimage-rpath.diff0000664000000000000000000000114212276137121016025 0ustar Index: xen-4.4.0~rc3+20140210/tools/libfsimage/Rules.mk =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/libfsimage/Rules.mk 2014-02-10 12:56:00.898665912 +0100 +++ xen-4.4.0~rc3+20140210/tools/libfsimage/Rules.mk 2014-02-10 12:56:01.642669551 +0100 @@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Wno-unknown-pragmas -I$(XEN_ROOT)/tools/libfsimage/common/ -DFSIMAGE_FSDIR=\"$(FSDIR)\" CFLAGS += -Werror -D_GNU_SOURCE LDFLAGS += -L../common/ +LDFLAGS += $(call LDFLAGS_RPATH,../..) PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y)) debian/patches/tools-xenmon-rpath.diff0000664000000000000000000000076412276137130015240 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenmon/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenmon/Makefile 2014-02-10 12:56:07.358697499 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenmon/Makefile 2014-02-10 12:56:08.110701169 +0100 @@ -16,6 +16,7 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror CFLAGS += $(CFLAGS_libxenctrl) LDLIBS += $(LDLIBS_libxenctrl) +LDFLAGS += $(call LDFLAGS_RPATH,../lib) SCRIPTS = xenmon.py debian/patches/xsa201-3-4.4.patch0000664000000000000000000000512413035726545013335 0ustar From: Wei Chen Subject: arm: crash the guest when it traps on external abort If we spot a data or prefetch abort bearing the ESR_EL2.EA bit set, we know that this is an external abort, and that should crash the guest. This is CVE-2016-9817, part of XSA-201. Signed-off-by: Wei Chen Reviewed-by: Stefano Stabellini Reviewed-by: Steve Capper Reviewed-by: Julien Grall Index: xen-4.4.2/xen/arch/arm/traps.c =================================================================== --- xen-4.4.2.orig/xen/arch/arm/traps.c +++ xen-4.4.2/xen/arch/arm/traps.c @@ -1751,6 +1751,16 @@ static void do_trap_instr_abort_guest(st union hsr hsr) { register_t addr = READ_SYSREG(FAR_EL2); + + /* + * If this bit has been set, it means that this instruction abort is caused + * by a guest external abort. Currently we crash the guest to protect the + * hypervisor. In future one can better handle this by injecting a virtual + * abort to the guest. + */ + if ( hsr.iabt.eat ) + domain_crash_synchronous(); + inject_iabt_exception(regs, addr, hsr.len); } @@ -1767,6 +1777,15 @@ static void do_trap_data_abort_guest(str return; } + /* + * If this bit has been set, it means that this data abort is caused + * by a guest external abort. Currently we crash the guest to protect the + * hypervisor. In future one can better handle this by injecting a virtual + * abort to the guest. + */ + if ( dabt.eat ) + domain_crash_synchronous(); + info.dabt = dabt; #ifdef CONFIG_ARM_32 info.gva = READ_CP32(HDFAR); Index: xen-4.4.2/xen/include/asm-arm/processor.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-arm/processor.h +++ xen-4.4.2/xen/include/asm-arm/processor.h @@ -310,6 +310,17 @@ union hsr { } sysreg; /* HSR_EC_SYSREG */ #endif + struct hsr_iabt { + unsigned long ifsc:6; /* Instruction fault status code */ + unsigned long res0:1; + unsigned long s1ptw:1; /* Stage 2 fault during stage 1 translation */ + unsigned long res1:1; + unsigned long eat:1; /* External abort type */ + unsigned long res2:15; + unsigned long len:1; /* Instruction length */ + unsigned long ec:6; /* Exception Class */ + } iabt; /* HSR_EC_INSTR_ABORT_* */ + struct hsr_dabt { unsigned long dfsc:6; /* Data Fault Status Code */ unsigned long write:1; /* Write / not Read */ debian/patches/xsa233.patch0000664000000000000000000000336013167425544012700 0ustar From: Juergen Gross Subject: tools/xenstore: dont unlink connection object twice A connection object of a domain with associated stubdom has two parents: the domain and the stubdom. When cleaning up the list of active domains in domain_cleanup() make sure not to unlink the connection twice from the same domain. This could happen when the domain and its stubdom are being destroyed at the same time leading to the domain loop being entered twice. Additionally don't use talloc_free() in this case as it will remove a random parent link, leading eventually to a memory leak. Use talloc_unlink() instead specifying the context from which the connection object should be removed. This is XSA-233. Reported-by: Eric Chanudet Signed-off-by: Juergen Gross Reviewed-by: Ian Jackson --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -221,10 +221,11 @@ static int destroy_domain(void *_domain) static void domain_cleanup(void) { xc_dominfo_t dominfo; - struct domain *domain, *tmp; + struct domain *domain; int notify = 0; - list_for_each_entry_safe(domain, tmp, &domains, list) { + again: + list_for_each_entry(domain, &domains, list) { if (xc_domain_getinfo(*xc_handle, domain->domid, 1, &dominfo) == 1 && dominfo.domid == domain->domid) { @@ -236,8 +237,12 @@ static void domain_cleanup(void) if (!dominfo.dying) continue; } - talloc_free(domain->conn); - notify = 0; /* destroy_domain() fires the watch */ + if (domain->conn) { + talloc_unlink(talloc_autofree_context(), domain->conn); + domain->conn = NULL; + notify = 0; /* destroy_domain() fires the watch */ + goto again; + } } if (notify) debian/patches/xsa212.patch0000664000000000000000000000650013104310572012655 0ustar memory: properly check guest memory ranges in XENMEM_exchange handling The use of guest_handle_okay() here (as introduced by the XSA-29 fix) is insufficient here, guest_handle_subrange_okay() needs to be used instead. Note that the uses are okay in - XENMEM_add_to_physmap_batch handling due to the size field being only 16 bits wide, - livepatch_list() due to the limit of 1024 enforced on the number-of-entries input (leaving aside the fact that this can be called by a privileged domain only anyway), - compat mode handling due to counts there being limited to 32 bits, - everywhere else due to guest arrays being accessed sequentially from index zero. This is XSA-212. Reported-by: Jann Horn Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -436,8 +436,8 @@ static long memory_exchange(XEN_GUEST_HA goto fail_early; } - if ( !guest_handle_okay(exch.in.extent_start, exch.in.nr_extents) || - !guest_handle_okay(exch.out.extent_start, exch.out.nr_extents) ) + if ( !guest_handle_subrange_okay(exch.in.extent_start, exch.nr_exchanged, + exch.in.nr_extents - 1) ) { rc = -EFAULT; goto fail_early; @@ -447,11 +447,27 @@ static long memory_exchange(XEN_GUEST_HA { in_chunk_order = exch.out.extent_order - exch.in.extent_order; out_chunk_order = 0; + + if ( !guest_handle_subrange_okay(exch.out.extent_start, + exch.nr_exchanged >> in_chunk_order, + exch.out.nr_extents - 1) ) + { + rc = -EFAULT; + goto fail_early; + } } else { in_chunk_order = 0; out_chunk_order = exch.in.extent_order - exch.out.extent_order; + + if ( !guest_handle_subrange_okay(exch.out.extent_start, + exch.nr_exchanged << out_chunk_order, + exch.out.nr_extents - 1) ) + { + rc = -EFAULT; + goto fail_early; + } } d = rcu_lock_domain_by_any_id(exch.in.domid); --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -29,8 +29,9 @@ extern void *xlat_malloc(unsigned long * /* * Valid if in +ve half of 48-bit address space, or above Xen-reserved area. * This is also valid for range checks (addr, addr+size). As long as the - * start address is outside the Xen-reserved area then we will access a - * non-canonical address (and thus fault) before ever reaching VIRT_START. + * start address is outside the Xen-reserved area, sequential accesses + * (starting at addr) will hit a non-canonical address (and thus fault) + * before ever reaching VIRT_START. */ #define __addr_ok(addr) \ (((unsigned long)(addr) < (1UL<<47)) || \ @@ -40,7 +41,8 @@ extern void *xlat_malloc(unsigned long * (__addr_ok(addr) || is_compat_arg_xlat_range(addr, size)) #define array_access_ok(addr, count, size) \ - (access_ok(addr, (count)*(size))) + (likely(((count) ?: 0UL) < (~0UL / (size))) && \ + access_ok(addr, (count) * (size))) #define __compat_addr_ok(d, addr) \ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(d)) debian/patches/xsa178-xen4.4-0005-libxl-Do-not-trust-backend-for-disk-fix-driver-domai.patch0000664000000000000000000002261112725542005026171 0ustar From 5f0749272567c4f7403b9d3f45ab94f91da84a20 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 18:29:45 +0100 Subject: [PATCH 05/16] libxl: Do not trust backend for disk; fix driver domain disks list Rework libxl__device_disk_from_xs_be (which takes a backend path) into to libxl__device_disk_from_xenstore (which takes a libxl path). libxl__device_disk_from_xenstore now finds the backend path itself, although it doesn't use it any more for most of its functions. We rename the variable from be_path to backend_path to make sure we didn't miss any cases. All the data collection is now done by reading from the copy in /libxl. libxl_device_disk_list and its helper libxl__append_disk_list (which used to be libxl__append_disk_list_of_type) need extensive rework, because they now need to specify the /libxl path rather than the backend path. To do that they enumerate disks by looking in the appropriate area in /libxl. Previously they scanned various of the backend directories in dom0 (which was broken for driver domains). It is no longer necessary to enumerate the various disk backends, because they all use the same paths in /devices. libxl__device_disk_from_xenstore will parse the type out of the backend path, for itself. (Indeed, it did so before - the now-gone type parameter to libxl__append_disk_list_of_type wasn't used other than to construct the directory to list.) Finally, remove a redundant store to pdisk->backend_domid in libxl__append_disk_list[_of_type]. Even before this commit, that store was not needed because libxl_device_disk_init (called by libxl__device_disk_from_xenstore) would zero it. Now it overwrites the correct backend domid with zero; so remove it. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- v2: Also fix up COLO reads, following rebase Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 84 +++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index df62bcc..cab98e0 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2270,8 +2270,8 @@ void libxl__device_disk_add(libxl__egc *egc, uint32_t domid, device_disk_add(egc, domid, disk, aodev, NULL, NULL); } -static int libxl__device_disk_from_xs_be(libxl__gc *gc, - const char *be_path, +static int libxl__device_disk_from_xenstore(libxl__gc *gc, + const char *libxl_path, libxl_device_disk *disk) { libxl_ctx *ctx = libxl__gc_owner(gc); @@ -2281,15 +2281,27 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, libxl_device_disk_init(disk); - rc = sscanf(be_path, "/local/domain/%d/", &disk->backend_domid); + const char *backend_path; + rc = libxl__xs_read_checked(gc, XBT_NULL, + GCSPRINTF("%s/backend", libxl_path), + &backend_path); + if (rc) goto out; + + if (!backend_path) { + LOG(ERROR, "disk %s does not exist (no backend path", libxl_path); + rc = ERROR_FAIL; + goto out; + } + + rc = sscanf(backend_path, "/local/domain/%d/", &disk->backend_domid); if (rc != 1) { - LOG(ERROR, "Unable to fetch device backend domid from %s", be_path); + LOG(ERROR, "Unable to fetch device backend domid from %s", backend_path); goto cleanup; } /* "params" may not be present; but everything else must be. */ tmp = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/params", be_path), &len); + libxl__sprintf(gc, "%s/params", libxl_path), &len); if (tmp && strchr(tmp, ':')) { disk->pdev_path = strdup(strchr(tmp, ':') + 1); free(tmp); @@ -2299,31 +2311,31 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, tmp = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%s/type", be_path)); + libxl__sprintf(gc, "%s/type", libxl_path)); if (!tmp) { - LOG(ERROR, "Missing xenstore node %s/type", be_path); + LOG(ERROR, "Missing xenstore node %s/type", libxl_path); goto cleanup; } libxl_string_to_backend(ctx, tmp, &(disk->backend)); disk->vdev = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/dev", be_path), &len); + libxl__sprintf(gc, "%s/dev", libxl_path), &len); if (!disk->vdev) { - LOG(ERROR, "Missing xenstore node %s/dev", be_path); + LOG(ERROR, "Missing xenstore node %s/dev", libxl_path); goto cleanup; } tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf - (gc, "%s/removable", be_path)); + (gc, "%s/removable", libxl_path)); if (!tmp) { - LOG(ERROR, "Missing xenstore node %s/removable", be_path); + LOG(ERROR, "Missing xenstore node %s/removable", libxl_path); goto cleanup; } disk->removable = atoi(tmp); - tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/mode", be_path)); + tmp = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/mode", libxl_path)); if (!tmp) { - LOG(ERROR, "Missing xenstore node %s/mode", be_path); + LOG(ERROR, "Missing xenstore node %s/mode", libxl_path); goto cleanup; } if (!strcmp(tmp, "w")) @@ -2332,9 +2344,9 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, disk->readwrite = 0; tmp = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%s/device-type", be_path)); + libxl__sprintf(gc, "%s/device-type", libxl_path)); if (!tmp) { - LOG(ERROR, "Missing xenstore node %s/device-type", be_path); + LOG(ERROR, "Missing xenstore node %s/device-type", libxl_path); goto cleanup; } disk->is_cdrom = !strcmp(tmp, "cdrom"); @@ -2343,15 +2355,17 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, return 0; cleanup: + rc = ERROR_FAIL; + out: libxl_device_disk_dispose(disk); - return ERROR_FAIL; + return rc; } int libxl_vdev_to_device_disk(libxl_ctx *ctx, uint32_t domid, const char *vdev, libxl_device_disk *disk) { GC_INIT(ctx); - char *dompath, *path; + char *dom_xl_path, *libxl_path; int devid = libxl__device_disk_dev_number(vdev, NULL, NULL); int rc = ERROR_FAIL; @@ -2360,39 +2374,34 @@ int libxl_vdev_to_device_disk(libxl_ctx *ctx, uint32_t domid, libxl_device_disk_init(disk); - dompath = libxl__xs_get_dompath(gc, domid); - if (!dompath) { + dom_xl_path = libxl__xs_libxl_path(gc, domid); + if (!dom_xl_path) { goto out; } - path = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%s/device/vbd/%d/backend", - dompath, devid)); - if (!path) - goto out; + libxl_path = GCSPRINTF("%s/device/vbd/%d", dom_xl_path, devid); - rc = libxl__device_disk_from_xs_be(gc, path, disk); + rc = libxl__device_disk_from_xenstore(gc, libxl_path, disk); out: GC_FREE; return rc; } -static int libxl__append_disk_list_of_type(libxl__gc *gc, +static int libxl__append_disk_list(libxl__gc *gc, uint32_t domid, - const char *type, libxl_device_disk **disks, int *ndisks) { - char *be_path = NULL; + char *libxl_dir_path = NULL; char **dir = NULL; unsigned int n = 0; libxl_device_disk *pdisk = NULL, *pdisk_end = NULL; int rc=0; int initial_disks = *ndisks; - be_path = libxl__sprintf(gc, "%s/backend/%s/%d", - libxl__xs_get_dompath(gc, 0), type, domid); - dir = libxl__xs_directory(gc, XBT_NULL, be_path, &n); + libxl_dir_path = GCSPRINTF("%s/device/vbd", + libxl__xs_libxl_path(gc, domid)); + dir = libxl__xs_directory(gc, XBT_NULL, libxl_dir_path, &n); if (dir && n) { libxl_device_disk *tmp; tmp = realloc(*disks, sizeof (libxl_device_disk) * (*ndisks + n)); @@ -2403,10 +2412,9 @@ static int libxl__append_disk_list_of_type(libxl__gc *gc, pdisk_end = *disks + initial_disks + n; for (; pdisk < pdisk_end; pdisk++, dir++) { const char *p; - p = libxl__sprintf(gc, "%s/%s", be_path, *dir); - if ((rc=libxl__device_disk_from_xs_be(gc, p, pdisk))) + p = libxl__sprintf(gc, "%s/%s", libxl_dir_path, *dir); + if ((rc=libxl__device_disk_from_xenstore(gc, p, pdisk))) goto out; - pdisk->backend_domid = 0; *ndisks += 1; } } @@ -2422,13 +2430,7 @@ libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *n *num = 0; - rc = libxl__append_disk_list_of_type(gc, domid, "vbd", &disks, num); - if (rc) goto out_err; - - rc = libxl__append_disk_list_of_type(gc, domid, "tap", &disks, num); - if (rc) goto out_err; - - rc = libxl__append_disk_list_of_type(gc, domid, "qdisk", &disks, num); + rc = libxl__append_disk_list(gc, domid, &disks, num); if (rc) goto out_err; GC_FREE; -- 1.9.1 debian/patches/tools-firmware-etherboot-packaged.diff0000664000000000000000000000260412276137142020160 0ustar Index: xen-4.4.0~rc3+20140210/tools/firmware/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/firmware/Makefile 2014-02-10 12:53:55.378052281 +0100 +++ xen-4.4.0~rc3+20140210/tools/firmware/Makefile 2014-02-10 12:56:18.042749731 +0100 @@ -14,7 +14,6 @@ SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir endif SUBDIRS-$(CONFIG_ROMBIOS) += rombios SUBDIRS-$(CONFIG_ROMBIOS) += vgabios -SUBDIRS-$(CONFIG_ROMBIOS) += etherboot SUBDIRS-y += hvmloader ovmf-dir: @@ -50,9 +49,6 @@ clean: subdirs-clean .PHONY: distclean distclean: subdirs-distclean -subdir-distclean-etherboot: .phony - $(MAKE) -C etherboot distclean - subdir-distclean-ovmf: .phony rm -rf ovmf-dir ovmf-dir-remote Index: xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/firmware/hvmloader/Makefile 2014-02-10 12:53:55.402052398 +0100 +++ xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile 2014-02-10 12:56:18.042749731 +0100 @@ -48,7 +48,7 @@ CIRRUSVGA_ROM := ../vgabios/VGABIOS-lgpl 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/lib/ipxe/, $(addsuffix .rom, $(ETHERBOOT_NICS))) endif ROMS := debian/patches/xsa201-4.patch0000664000000000000000000001145713035200720013017 0ustar From: Wei Chen Subject: arm32: handle async aborts delivered while at HYP If guest generates an asynchronous abort and then traps into HYP (by HVC or IRQ) before the abort has been delivered, the hypervisor could not catch it, because the PSTATE.A bit is masked all the time in hypervisor. So this asynchronous abort may be slipped to next running guest with PSTATE.A bit unmasked. In order to avoid this, it is necessary to take the abort at HYP, by clearing the PSTATE.A bit. In this patch, we unmask the PSTATE.A bit to open a window to catch guest-generated asynchronous abort in all Guest -> HYP switch paths. If we caught such asynchronous abort in checking window, the HYP data abort exception will be triggered and the abort source guest will be crashed. This is CVE-2016-9818, part of XSA-201. Signed-off-by: Wei Chen Reviewed-by: Julien Grall Index: xen-4.4.2/xen/arch/arm/arm32/entry.S =================================================================== --- xen-4.4.2.orig/xen/arch/arm/arm32/entry.S +++ xen-4.4.2/xen/arch/arm/arm32/entry.S @@ -42,6 +42,61 @@ save_guest_regs: SAVE_BANKED(fiq) SAVE_ONE_BANKED(R8_fiq); SAVE_ONE_BANKED(R9_fiq); SAVE_ONE_BANKED(R10_fiq) SAVE_ONE_BANKED(R11_fiq); SAVE_ONE_BANKED(R12_fiq); + /* + * Start to check pending virtual abort in the gap of Guest -> HYP + * world switch. + * + * Save ELR_hyp to check whether the pending virtual abort exception + * takes place while we are doing this trap exception. + */ + mrs r1, ELR_hyp + + /* + * Force loads and stores to complete before unmasking asynchronous + * aborts and forcing the delivery of the exception. + */ + dsb sy + + /* + * Unmask asynchronous abort bit. If there is a pending asynchronous + * abort, the data_abort exception will happen after A bit is cleared. + */ + cpsie a + + /* + * This is our single instruction exception window. A pending + * asynchronous abort is guaranteed to occur at the earliest when we + * unmask it, and at the latest just after the ISB. + * + * If a pending abort occurs, the program will jump to data_abort + * exception handler, and the ELR_hyp will be set to + * abort_guest_exit_start or abort_guest_exit_end. + */ + .global abort_guest_exit_start +abort_guest_exit_start: + + isb + + .global abort_guest_exit_end +abort_guest_exit_end: + /* Mask CPSR asynchronous abort bit, close the checking window. */ + cpsid a + + /* + * Compare ELR_hyp and the saved value to check whether we are + * returning from a valid exception caused by pending virtual + * abort. + */ + mrs r2, ELR_hyp + cmp r1, r2 + + /* + * Not equal, the pending virtual abort exception took place, the + * initial exception does not have any significance to be handled. + * Exit ASAP. + */ + bne return_from_trap + mov pc, lr #define DEFINE_TRAP_ENTRY(trap) \ Index: xen-4.4.2/xen/arch/arm/arm32/traps.c =================================================================== --- xen-4.4.2.orig/xen/arch/arm/arm32/traps.c +++ xen-4.4.2/xen/arch/arm/arm32/traps.c @@ -40,7 +40,10 @@ asmlinkage void do_trap_prefetch_abort(s asmlinkage void do_trap_data_abort(struct cpu_user_regs *regs) { - do_unexpected_trap("Data Abort", regs); + if ( VABORT_GEN_BY_GUEST(regs) ) + do_trap_guest_error(regs); + else + do_unexpected_trap("Data Abort", regs); } /* Index: xen-4.4.2/xen/include/asm-arm/arm32/processor.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-arm/arm32/processor.h +++ xen-4.4.2/xen/include/asm-arm/arm32/processor.h @@ -55,6 +55,17 @@ struct cpu_user_regs uint32_t pad1; /* Doubleword-align the user half of the frame */ }; + +/* Functions for pending virtual abort checking window. */ +void abort_guest_exit_start(void); +void abort_guest_exit_end(void); + +#define VABORT_GEN_BY_GUEST(r) \ +( \ + ( (unsigned long)abort_guest_exit_start == (r)->pc ) || \ + ( (unsigned long)abort_guest_exit_end == (r)->pc ) \ +) + #endif /* Layout as used in assembly, with src/dest registers mixed in */ Index: xen-4.4.2/xen/include/asm-arm/processor.h =================================================================== --- xen-4.4.2.orig/xen/include/asm-arm/processor.h +++ xen-4.4.2/xen/include/asm-arm/processor.h @@ -480,6 +480,8 @@ struct cpuinfo_x86 { uint32_t pfr32[2]; }; +void do_trap_guest_error(struct cpu_user_regs *regs); + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARM_PROCESSOR_H */ /* debian/patches/xsa240-4.4-0001-x86-limit-linear-page-table-use-to-a-single-level.patch0000664000000000000000000004711013167430177024600 0ustar diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index d8cc29a..5ffb4af 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -975,6 +975,7 @@ int arch_set_info_guest( case -EINTR: rc = -EAGAIN; case -EAGAIN: + v->arch.old_guest_ptpg = NULL; v->arch.old_guest_table = pagetable_get_page(v->arch.guest_table); v->arch.guest_table = pagetable_null(); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 5274c7d..182fa65 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -674,6 +674,61 @@ static void put_data_page( put_page(page); } +static bool_t inc_linear_entries(struct page_info *pg) +{ + typeof(pg->linear_pt_count) nc = read_atomic(&pg->linear_pt_count), oc; + + do { + /* + * The check below checks for the "linear use" count being non-zero + * as well as overflow. Signed integer overflow is undefined behavior + * according to the C spec. However, as long as linear_pt_count is + * smaller in size than 'int', the arithmetic operation of the + * increment below won't overflow; rather the result will be truncated + * when stored. Ensure that this is always true. + */ + BUILD_BUG_ON(sizeof(nc) >= sizeof(int)); + oc = nc++; + if ( nc <= 0 ) + return 0; + nc = cmpxchg(&pg->linear_pt_count, oc, nc); + } while ( oc != nc ); + + return 1; +} + +static void dec_linear_entries(struct page_info *pg) +{ + typeof(pg->linear_pt_count) oc; + + oc = arch_fetch_and_add(&pg->linear_pt_count, -1); + ASSERT(oc > 0); +} + +static bool_t inc_linear_uses(struct page_info *pg) +{ + typeof(pg->linear_pt_count) nc = read_atomic(&pg->linear_pt_count), oc; + + do { + /* See the respective comment in inc_linear_entries(). */ + BUILD_BUG_ON(sizeof(nc) >= sizeof(int)); + oc = nc--; + if ( nc >= 0 ) + return 0; + nc = cmpxchg(&pg->linear_pt_count, oc, nc); + } while ( oc != nc ); + + return 1; +} + +static void dec_linear_uses(struct page_info *pg) +{ + typeof(pg->linear_pt_count) oc; + + oc = arch_fetch_and_add(&pg->linear_pt_count, 1); + ASSERT(oc < 0); +} + /* * We allow root tables to map each other (a.k.a. linear page tables). It * needs some special care with reference counts and access permissions: @@ -703,15 +758,35 @@ get_##level##_linear_pagetable( \ \ if ( (pfn = level##e_get_pfn(pde)) != pde_pfn ) \ { \ + struct page_info *ptpg = mfn_to_page(pde_pfn); \ + \ + /* Make sure the page table belongs to the correct domain. */ \ + if ( unlikely(page_get_owner(ptpg) != d) ) \ + return 0; \ + \ /* Make sure the mapped frame belongs to the correct domain. */ \ if ( unlikely(!get_page_from_pagenr(pfn, d)) ) \ return 0; \ \ /* \ - * Ensure that the mapped frame is an already-validated page table. \ + * Ensure that the mapped frame is an already-validated page table \ + * and is not itself having linear entries, as well as that the \ + * containing page table is not iself in use as a linear page table \ + * elsewhere. \ * If so, atomically increment the count (checking for overflow). \ */ \ page = mfn_to_page(pfn); \ + if ( !inc_linear_entries(ptpg) ) \ + { \ + put_page(page); \ + return 0; \ + } \ + if ( !inc_linear_uses(page) ) \ + { \ + dec_linear_entries(ptpg); \ + put_page(page); \ + return 0; \ + } \ y = page->u.inuse.type_info; \ do { \ x = y; \ @@ -719,6 +794,8 @@ get_##level##_linear_pagetable( \ unlikely((x & (PGT_type_mask|PGT_validated)) != \ (PGT_##level##_page_table|PGT_validated)) ) \ { \ + dec_linear_uses(page); \ + dec_linear_entries(ptpg); \ put_page(page); \ return 0; \ } \ @@ -1096,6 +1173,9 @@ get_page_from_l4e( l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \ } while ( 0 ) +static int _put_page_type(struct page_info *page, bool_t preemptible, + struct page_info *ptpg); + void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner) { unsigned long pfn = l1e_get_pfn(l1e); @@ -1165,17 +1245,22 @@ static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn) if ( l2e_get_flags(l2e) & _PAGE_PSE ) put_superpage(l2e_get_pfn(l2e)); else - put_page_and_type(l2e_get_page(l2e)); + { + struct page_info *pg = l2e_get_page(l2e); + int rc = _put_page_type(pg, 0, mfn_to_page(pfn)); + + ASSERT(!rc); + put_page(pg); + } return 0; } -static int __put_page_type(struct page_info *, int preemptible); - static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn, int partial, bool_t defer) { struct page_info *pg; + int rc; if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) || (l3e_get_pfn(l3e) == pfn) ) return 1; @@ -1198,21 +1283,28 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn, if ( unlikely(partial > 0) ) { ASSERT(!defer); - return __put_page_type(pg, 1); + return _put_page_type(pg, 1, mfn_to_page(pfn)); } if ( defer ) { + current->arch.old_guest_ptpg = mfn_to_page(pfn); current->arch.old_guest_table = pg; return 0; } - return put_page_and_type_preemptible(pg); + rc = _put_page_type(pg, 1, mfn_to_page(pfn)); + if ( likely(!rc) ) + put_page(pg); + + return rc; } static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn, int partial, bool_t defer) { + int rc = 1; + if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && (l4e_get_pfn(l4e) != pfn) ) { @@ -1221,18 +1313,22 @@ static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn, if ( unlikely(partial > 0) ) { ASSERT(!defer); - return __put_page_type(pg, 1); + return _put_page_type(pg, 1, mfn_to_page(pfn)); } if ( defer ) { + current->arch.old_guest_ptpg = mfn_to_page(pfn); current->arch.old_guest_table = pg; return 0; } - return put_page_and_type_preemptible(pg); + rc = _put_page_type(pg, 1, mfn_to_page(pfn)); + if ( likely(!rc) ) + put_page(pg); } - return 1; + + return rc; } static int alloc_l1_table(struct page_info *page) @@ -1430,6 +1526,7 @@ static int alloc_l3_table(struct page_info *page) { page->nr_validated_ptes = i; page->partial_pte = 0; + current->arch.old_guest_ptpg = NULL; current->arch.old_guest_table = page; } while ( i-- > 0 ) @@ -1495,6 +1592,7 @@ static int alloc_l4_table(struct page_info *page) { if ( current->arch.old_guest_table ) page->nr_validated_ptes++; + current->arch.old_guest_ptpg = NULL; current->arch.old_guest_table = page; } } @@ -2227,8 +2325,8 @@ int free_page_type(struct page_info *page, unsigned long type, } -static int __put_final_page_type( - struct page_info *page, unsigned long type, int preemptible) +static int _put_final_page_type(struct page_info *page, unsigned long type, + bool_t preemptible, struct page_info *ptpg) { int rc = free_page_type(page, type, preemptible); @@ -2245,6 +2343,12 @@ static int __put_final_page_type( if ( !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) page->tlbflush_timestamp = tlbflush_current_time(); + if ( ptpg && PGT_type_equal(type, ptpg->u.inuse.type_info) ) + { + dec_linear_uses(page); + dec_linear_entries(ptpg); + } + ASSERT(!page->linear_pt_count || page_get_owner(page)->is_dying); wmb(); page->u.inuse.type_info--; } @@ -2270,8 +2374,8 @@ static int __put_final_page_type( } -static int __put_page_type(struct page_info *page, - int preemptible) +static int _put_page_type(struct page_info *page, bool_t preemptible, + struct page_info *ptpg) { unsigned long nx, x, y = page->u.inuse.type_info; int rc = 0; @@ -2298,12 +2402,28 @@ static int __put_page_type(struct page_info *page, x, nx)) != x) ) continue; /* We cleared the 'valid bit' so we do the clean up. */ - rc = __put_final_page_type(page, x, preemptible); + rc = _put_final_page_type(page, x, preemptible, ptpg); + ptpg = NULL; if ( x & PGT_partial ) put_page(page); break; } + if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) ) + { + /* + * page_set_tlbflush_timestamp() accesses the same union + * linear_pt_count lives in. Unvalidated page table pages, + * however, should occur during domain destruction only + * anyway. Updating of linear_pt_count luckily is not + * necessary anymore for a dying domain. + */ + ASSERT(page_get_owner(page)->is_dying); + ASSERT(page->linear_pt_count < 0); + ASSERT(ptpg->linear_pt_count > 0); + ptpg = NULL; + } + /* * Record TLB information for flush later. We do not stamp page * tables when running in shadow mode: @@ -2323,6 +2443,13 @@ static int __put_page_type(struct page_info *page, return -EINTR; } + if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) ) + { + ASSERT(!rc); + dec_linear_uses(page); + dec_linear_entries(ptpg); + } + return rc; } @@ -2457,6 +2584,7 @@ static int __get_page_type(struct page_info *page, unsigned long type, page->nr_validated_ptes = 0; page->partial_pte = 0; } + page->linear_pt_count = 0; rc = alloc_page_type(page, type, preemptible); } @@ -2468,7 +2596,7 @@ static int __get_page_type(struct page_info *page, unsigned long type, void put_page_type(struct page_info *page) { - int rc = __put_page_type(page, 0); + int rc = _put_page_type(page, 0, NULL); ASSERT(rc == 0); (void)rc; } @@ -2484,7 +2612,7 @@ int get_page_type(struct page_info *page, unsigned long type) int put_page_type_preemptible(struct page_info *page) { - return __put_page_type(page, 1); + return _put_page_type(page, 1, NULL); } int get_page_type_preemptible(struct page_info *page, unsigned long type) @@ -2690,11 +2818,14 @@ int put_old_guest_table(struct vcpu *v) if ( !v->arch.old_guest_table ) return 0; - switch ( rc = put_page_and_type_preemptible(v->arch.old_guest_table) ) + switch ( rc = _put_page_type(v->arch.old_guest_table, 1, + v->arch.old_guest_ptpg) ) { case -EINTR: case -EAGAIN: return -EAGAIN; + case 0: + put_page(v->arch.old_guest_table); } v->arch.old_guest_table = NULL; @@ -2848,6 +2979,7 @@ int new_guest_cr3(unsigned long mfn) case -EINTR: rc = -EAGAIN; case -EAGAIN: + curr->arch.old_guest_ptpg = NULL; curr->arch.old_guest_table = page; break; default: @@ -3093,7 +3225,10 @@ long do_mmuext_op( if ( type == PGT_l1_page_table ) put_page_and_type(page); else + { + curr->arch.old_guest_ptpg = NULL; curr->arch.old_guest_table = page; + } } } @@ -3126,6 +3261,7 @@ long do_mmuext_op( { case -EINTR: case -EAGAIN: + curr->arch.old_guest_ptpg = NULL; curr->arch.old_guest_table = page; rc = 0; break; @@ -3203,6 +3339,7 @@ long do_mmuext_op( case -EINTR: rc = -EAGAIN; case -EAGAIN: + curr->arch.old_guest_ptpg = NULL; curr->arch.old_guest_table = page; okay = 0; break; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index a03fc2e..92fa583 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -426,6 +426,8 @@ struct arch_vcpu pagetable_t guest_table_user; /* (MFN) x86/64 user-space pagetable */ pagetable_t guest_table; /* (MFN) guest notion of cr3 */ struct page_info *old_guest_table; /* partially destructed pagetable */ + struct page_info *old_guest_ptpg; /* containing page table of the */ + /* former, if any */ /* 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 */ diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index c835f76..93c3315 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -119,11 +119,11 @@ struct page_info u32 tlbflush_timestamp; /* - * When PGT_partial is true then this field is valid and indicates - * that PTEs in the range [0, @nr_validated_ptes) have been validated. - * An extra page reference must be acquired (or not dropped) whenever - * PGT_partial gets set, and it must be dropped when the flag gets - * cleared. This is so that a get() leaving a page in partially + * When PGT_partial is true then the first two fields are valid and + * indicate that PTEs in the range [0, @nr_validated_ptes) have been + * validated. An extra page reference must be acquired (or not dropped) + * whenever PGT_partial gets set, and it must be dropped when the flag + * gets cleared. This is so that a get() leaving a page in partially * validated state (where the caller would drop the reference acquired * due to the getting of the type [apparently] failing [-EAGAIN]) * would not accidentally result in a page left with zero general @@ -147,10 +147,18 @@ struct page_info * put_page_from_lNe() (due to the apparent failure), and hence it * must be dropped when the put operation is resumed (and completes), * but it must not be acquired if picking up the page for validation. + * + * The 3rd field, @linear_pt_count, indicates + * - by a positive value, how many same-level page table entries a page + * table has, + * - by a negative value, in how many same-level page tables a page is + * in use. */ struct { - u16 nr_validated_ptes; - s8 partial_pte; + u16 nr_validated_ptes:PAGETABLE_ORDER + 1; + u16 :16 - PAGETABLE_ORDER - 1 - 2; + s16 partial_pte:2; + s16 linear_pt_count; }; /* @@ -201,6 +209,9 @@ struct page_info #define PGT_count_width PG_shift(9) #define PGT_count_mask ((1UL< Date: Wed, 27 Apr 2016 16:08:49 +0100 Subject: [PATCH 05/10] libxl: Do not trust frontend for disk eject event Use the /libxl path for interpreting disk eject watch events: do not read the backend path out of the frontend. Instead, use the version in /libxl. That avoids us relying on the guest-modifiable $frontend/backend pointer. To implement this we store the path /libxl/$guest/device/vbd/$devid/backend in the evgen structure. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 28 ++++++++++++++++++++++------ tools/libxl/libxl_internal.h | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index b52e63e..f101334 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1141,9 +1141,10 @@ static void disk_eject_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *w, const char *wpath, const char *epath) { EGC_GC; libxl_evgen_disk_eject *evg = (void*)w; - char *backend; + const char *backend; char *value; char backend_type[BACKEND_STRING_SIZE+1]; + int rc; value = libxl__xs_read(gc, XBT_NULL, wpath); @@ -1159,9 +1160,16 @@ static void disk_eject_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *w, libxl_event *ev = NEW_EVENT(egc, DISK_EJECT, evg->domid, evg->user); libxl_device_disk *disk = &ev->u.disk_eject.disk; - backend = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%.*s/backend", - (int)strlen(wpath)-6, wpath)); + rc = libxl__xs_read_checked(gc, XBT_NULL, evg->be_ptr_path, &backend); + if (rc) { + LIBXL__EVENT_DISASTER(egc, "xs_read failed reading be_ptr_path", + errno, LIBXL_EVENT_TYPE_DISK_EJECT); + return; + } + if (!backend) { + /* device has been removed, not simply ejected */ + return; + } sscanf(backend, "/local/domain/%d/backend/%" TOSTRING(BACKEND_STRING_SIZE) @@ -1210,11 +1218,18 @@ int libxl_evenable_disk_eject(libxl_ctx *ctx, uint32_t guest_domid, if (!domid) domid = guest_domid; - path = libxl__sprintf(gc, "%s/device/vbd/%d/eject", + int devid = libxl__device_disk_dev_number(vdev, NULL, NULL); + + path = GCSPRINTF("%s/device/vbd/%d/eject", libxl__xs_get_dompath(gc, domid), - libxl__device_disk_dev_number(vdev, NULL, NULL)); + devid); if (!path) { rc = ERROR_NOMEM; goto out; } + const char *libxl_path = GCSPRINTF("%s/device/vbd/%d", + libxl__xs_libxl_path(gc, domid), + devid); + evg->be_ptr_path = libxl__sprintf(NOGC, "%s/backend", libxl_path); + rc = libxl__ev_xswatch_register(gc, &evg->watch, disk_eject_xswatch_callback, path); if (rc) goto out; @@ -1241,6 +1256,7 @@ void libxl__evdisable_disk_eject(libxl__gc *gc, libxl_evgen_disk_eject *evg) { libxl__ev_xswatch_deregister(gc, &evg->watch); free(evg->vdev); + free(evg->be_ptr_path); free(evg); CTX_UNLOCK; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 3fc9997..8128e76 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -257,7 +257,7 @@ struct libxl__evgen_disk_eject { uint32_t domid; LIBXL_LIST_ENTRY(libxl_evgen_disk_eject) entry; libxl_ev_user user; - char *vdev; + char *vdev, *be_ptr_path; }; _hidden void libxl__evdisable_disk_eject(libxl__gc*, libxl_evgen_disk_eject*); -- 2.1.4 debian/patches/xsa149.patch0000664000000000000000000000077612616222107012702 0ustar xen: free domain's vcpu array This was overlooked in fb442e2171 ("x86_64: allow more vCPU-s per guest"). This is XSA-149. Signed-off-by: Jan Beulich Reviewed-by: Ian Campbell --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -841,6 +841,7 @@ static void complete_domain_destroy(stru xsm_free_security_domain(d); free_cpumask_var(d->domain_dirty_cpumask); + xfree(d->vcpu); free_domain_struct(d); send_global_virq(VIRQ_DOM_EXC); debian/patches/xsa167-4.4.patch0000664000000000000000000000423212661613522013201 0ustar x86/mm: PV superpage handling lacks sanity checks MMUEXT_{,UN}MARK_SUPER fail to check the input MFN for validity before dereferencing pointers into the superpage frame table. get_superpage() has a similar issue. This is XSA-167. Reported-by: Qinghao Tang Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2566,6 +2566,9 @@ int get_superpage(unsigned long mfn, str ASSERT(opt_allow_superpage); + if ( !mfn_valid(mfn | (L1_PAGETABLE_ENTRIES - 1)) ) + return -EINVAL; + spage = mfn_to_spage(mfn); y = spage->type_info; do { @@ -3320,14 +3323,6 @@ long do_mmuext_op( unsigned long mfn; struct spage_info *spage; - mfn = op.arg1.mfn; - if ( mfn & (L1_PAGETABLE_ENTRIES-1) ) - { - MEM_LOG("Unaligned superpage reference mfn %lx", mfn); - okay = 0; - break; - } - if ( !opt_allow_superpage ) { MEM_LOG("Superpages disallowed"); @@ -3336,16 +3331,6 @@ long do_mmuext_op( break; } - spage = mfn_to_spage(mfn); - okay = (mark_superpage(spage, d) >= 0); - break; - } - - case MMUEXT_UNMARK_SUPER: - { - unsigned long mfn; - struct spage_info *spage; - mfn = op.arg1.mfn; if ( mfn & (L1_PAGETABLE_ENTRIES-1) ) { @@ -3354,16 +3339,16 @@ long do_mmuext_op( break; } - if ( !opt_allow_superpage ) + if ( !mfn_valid(mfn | (L1_PAGETABLE_ENTRIES - 1)) ) { - MEM_LOG("Superpages disallowed"); okay = 0; - rc = -ENOSYS; break; } spage = mfn_to_spage(mfn); - okay = (unmark_superpage(spage) >= 0); + okay = ((op.cmd == MMUEXT_MARK_SUPER + ? mark_superpage(spage, d) + : unmark_superpage(spage)) >= 0); break; } debian/patches/xsa180-qemut.patch0000664000000000000000000000456112725551660014034 0ustar From 7490dab5c1a01b1623e9d87bdc653cb4f963dd8a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 19 May 2016 19:38:35 +0100 Subject: [PATCH] main loop: Big hammer to fix logfile disk DoS in Xen setups Each time round the main loop, we now fstat stderr. If it is too big, we dup2 /dev/null onto it. This is not a very pretty patch but it is very simple, easy to see that it's correct, and has a low risk of collateral damage. The limit is 1Mby by default but can be adjusted by setting a new environment variable. This fixes CVE-2014-3672. Signed-off-by: Ian Jackson Tested-by: Ian Jackson --- vl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/qemu/vl.c b/qemu/vl.c index c864e7d..d7ef742 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -3752,6 +3752,50 @@ static void host_main_loop_wait(int *timeout) } #endif +static void check_cve_2014_3672_xen(void) +{ + static unsigned long limit = ~0UL; + const int fd = 2; + struct stat stab; + + if (limit == ~0UL) { + const char *s = getenv("XEN_QEMU_CONSOLE_LIMIT"); + /* XEN_QEMU_CONSOLE_LIMIT=0 means no limit */ + limit = s ? strtoul(s,0,0) : 1*1024*1024; + } + if (limit == 0) + return; + + int r = fstat(fd, &stab); + if (r) { + perror("fstat stderr (for CVE-2014-3672 check)"); + exit(-1); + } + if (!S_ISREG(stab.st_mode)) + return; + if (stab.st_size <= limit) + return; + + /* oh dear */ + fprintf(stderr,"\r\n" + "Closing stderr due to CVE-2014-3672 limit. " + " Set XEN_QEMU_CONSOLE_LIMIT to number of bytes to override," + " or 0 for no limit.\n"); + fflush(stderr); + + int nfd = open("/dev/null", O_WRONLY); + if (nfd < 0) { + perror("open /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + r = dup2(nfd, fd); + if (r != fd) { + perror("dup2 /dev/null (for CVE-2014-3672 check)"); + exit(-1); + } + close(nfd); +} + void main_loop_wait(int timeout) { IOHandlerRecord *ioh; @@ -3763,6 +3807,8 @@ void main_loop_wait(int timeout) host_main_loop_wait(&timeout); + check_cve_2014_3672_xen(); + /* poll any events */ /* XXX: separate device handlers from system ones */ nfds = -1; -- 1.7.10.4 debian/patches/xsa159.patch0000664000000000000000000000311512631300033012661 0ustar memory: fix XENMEM_exchange error handling assign_pages() can fail due to the domain getting killed in parallel, which should not result in a hypervisor crash. Also delete a redundant put_gfn() - all relevant paths leading to the "fail" label already do this (and there are also paths where it was plain wrong). All of the put_gfn()-s got introduced by 51032ca058 ("Modify naming of queries into the p2m"), including the otherwise unneeded initializer for k (with even a kind of misleading comment - the compiler warning could actually have served as a hint that the use is wrong). This is XSA-159. Signed-off-by: Jan Beulich Acked-by: Ian Campbell --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -334,7 +334,7 @@ static long memory_exchange(XEN_GUEST_HA PAGE_LIST_HEAD(out_chunk_list); unsigned long in_chunk_order, out_chunk_order; xen_pfn_t gpfn, gmfn, mfn; - unsigned long i, j, k = 0; /* gcc ... */ + unsigned long i, j, k; unsigned int memflags = 0; long rc = 0; struct domain *d; @@ -572,11 +572,12 @@ static long memory_exchange(XEN_GUEST_HA fail: /* Reassign any input pages we managed to steal. */ while ( (page = page_list_remove_head(&in_chunk_list)) ) - { - put_gfn(d, gmfn + k--); if ( assign_pages(d, page, 0, MEMF_no_refcount) ) - BUG(); - } + { + BUG_ON(!d->is_dying); + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) + put_page(page); + } dying: rcu_unlock_domain(d); debian/patches/xsa168.patch0000664000000000000000000000175512661613535012712 0ustar x86/VMX: prevent INVVPID failure due to non-canonical guest address While INVLPG (and on SVM INVLPGA) don't fault on non-canonical addresses, INVVPID fails (in the "individual address" case) when passed such an address. Since such intercepted INVLPG are effectively no-ops anyway, don't fix this in vmx_invlpg_intercept(), but instead have paging_invlpg() never return true in such a case. This is XSA-168. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Ian Campbell --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -245,7 +245,7 @@ paging_fault(unsigned long va, struct cp * or 0 if it's safe not to do so. */ static inline int paging_invlpg(struct vcpu *v, unsigned long va) { - return paging_get_hostmode(v)->invlpg(v, va); + return is_canonical_address(va) && paging_get_hostmode(v)->invlpg(v, va); } /* Translate a guest virtual address to the frame number that the debian/patches/xsa153-libxl.patch0000664000000000000000000000710212616222214013772 0ustar From 27593ec62bdad8621df910931349d964a6dbaa8c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 21 Oct 2015 16:18:30 +0100 Subject: [PATCH XSA-153 v3] libxl: adjust PoD target by memory fudge, too PoD guests need to balloon at least as far as required by PoD, or risk crashing. Currently they don't necessarily know what the right value is, because our memory accounting is (at the very least) confusing. Apply the memory limit fudge factor to the in-hypervisor PoD memory target, too. This will increase the size of the guest's PoD cache by the fudge factor LIBXL_MAXMEM_CONSTANT (currently 1Mby). This ensures that even with a slightly-off balloon driver, the guest will be stable even under memory pressure. There are two call sites of xc_domain_set_pod_target that need fixing: The one in libxl_set_memory_target is straightforward. The one in xc_hvm_build_x86.c:setup_guest is more awkward. Simply setting the PoD target differently does not work because the various amounts of memory during domain construction no longer match up. Instead, we adjust the guest memory target in xenstore (but only for PoD guests). This introduces a 1Mby discrepancy between the balloon target of a PoD guest at boot, and the target set by an apparently-equivalent `xl mem-set' (or similar) later. This approach is low-risk for a security fix but we need to fix this up properly in xen.git#staging and probably also in stable trees. This is XSA-153. Signed-off-by: Ian Jackson --- tools/libxl/libxl.c | 2 +- tools/libxl/libxl_dom.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) Index: xen-4.4.2/tools/libxl/libxl.c =================================================================== --- xen-4.4.2.orig/tools/libxl/libxl.c 2015-11-03 15:17:41.012558005 -0600 +++ xen-4.4.2/tools/libxl/libxl.c 2015-11-03 15:17:41.008558005 -0600 @@ -4126,7 +4126,7 @@ retry_transaction: new_target_memkb -= videoram; rc = xc_domain_set_pod_target(ctx->xch, domid, - new_target_memkb / 4, NULL, NULL, NULL); + (new_target_memkb + LIBXL_MAXMEM_CONSTANT) / 4, NULL, NULL, NULL); if (rc != 0) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_domain_set_pod_target domid=%d, memkb=%d " Index: xen-4.4.2/tools/libxl/libxl_dom.c =================================================================== --- xen-4.4.2.orig/tools/libxl/libxl_dom.c 2015-11-03 15:17:41.012558005 -0600 +++ xen-4.4.2/tools/libxl/libxl_dom.c 2015-11-03 15:17:41.008558005 -0600 @@ -270,6 +270,7 @@ int libxl__build_post(libxl__gc *gc, uin xs_transaction_t t; char **ents, **hvm_ents; int i, rc; + int64_t mem_target_fudge; rc = libxl_domain_sched_params_set(CTX, domid, &info->sched_params); if (rc) @@ -286,11 +287,17 @@ int libxl__build_post(libxl__gc *gc, uin if (info->cpuid != NULL) libxl_cpuid_set(ctx, domid, info->cpuid); + mem_target_fudge = + (info->type == LIBXL_DOMAIN_TYPE_HVM && + info->max_memkb > info->target_memkb) + ? LIBXL_MAXMEM_CONSTANT : 0; + ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; ents[1] = GCSPRINTF("%"PRId64, info->max_memkb); ents[2] = "memory/target"; - ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb); + ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb + - mem_target_fudge); ents[4] = "memory/videoram"; ents[5] = GCSPRINTF("%"PRId64, info->video_memkb); ents[6] = "domid"; debian/patches/xsa214.patch0000664000000000000000000000336613104311516012665 0ustar From: Jan Beulich Subject: x86: discard type information when stealing pages While a page having just a single general reference left necessarily has a zero type reference count too, its type may still be valid (and in validated state; at present this is only possible and relevant for PGT_seg_desc_page, as page tables have their type forcibly zapped when their type reference count drops to zero, and PGT_{writable,shared}_page pages don't require any validation). In such a case when the page is being re-used with the same type again, validation is being skipped. As validation criteria differ between 32- and 64-bit guests, pages to be transferred between guests need to have their validation indicator zapped (and with it we zap all other type information at once). This is XSA-214. Reported-by: Jann Horn Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4466,6 +4466,17 @@ int steal_page( y = cmpxchg(&page->count_info, x, x & ~PGC_count_mask); } while ( y != x ); + /* + * With the sole reference dropped temporarily, no-one can update type + * information. Type count also needs to be zero in this case, but e.g. + * PGT_seg_desc_page may still have PGT_validated set, which we need to + * clear before transferring ownership (as validation criteria vary + * depending on domain type). + */ + BUG_ON(page->u.inuse.type_info & (PGT_count_mask | PGT_locked | + PGT_pinned)); + page->u.inuse.type_info = 0; + /* Swizzle the owner then reinstate the PGC_allocated reference. */ page_set_owner(page, NULL); y = page->count_info; debian/patches/xsa178-xen4.4-0008-libxl-Rename-libxl__device_nic_from_xs_be-to-_from_x.patch0000664000000000000000000000402112725542005026503 0ustar From 0eb5ef298605a6cbf3de1bf15eb1b9bc856066a9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 16:18:36 +0100 Subject: [PATCH 08/16] libxl: Rename libxl__device_nic_from_xs_be to _from_xenstore We are going to change these functions to expect, and be passed, a /libxl path. So it is wrong that they are called _from_xs_be. Neither function reads anything which isn't found in both places, so we can and will change the call sites later. The only remaining function in libxl called *_from_xs_be relates to PCI devices, for which the backend domain is hardcoded to 0 throughout the libxl_pci.c. No functional change. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 362fb22..5a9a05e 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3030,7 +3030,7 @@ out: return; } -static int libxl__device_nic_from_xs_be(libxl__gc *gc, +static int libxl__device_nic_from_xenstore(libxl__gc *gc, const char *be_path, libxl_device_nic *nic) { @@ -3095,7 +3095,7 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, if (!path) goto out; - rc = libxl__device_nic_from_xs_be(gc, path, nic); + rc = libxl__device_nic_from_xenstore(gc, path, nic); if (rc) goto out; rc = 0; @@ -3130,7 +3130,7 @@ static int libxl__append_nic_list_of_type(libxl__gc *gc, for (; pnic < pnic_end; pnic++, dir++) { const char *p; p = libxl__sprintf(gc, "%s/%s", be_path, *dir); - rc = libxl__device_nic_from_xs_be(gc, p, pnic); + rc = libxl__device_nic_from_xenstore(gc, p, pnic); if (rc) goto out; pnic->backend_domid = 0; } -- 1.9.1 debian/patches/xsa155-xen-0003-libvchan-Read-prod-cons-only-once.patch0000664000000000000000000000315112631310307022272 0ustar From c1fce65e2b720684ea6ba76ae59921542bd154bb Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 20 Nov 2015 12:22:14 -0500 Subject: [PATCH 3/3] libvchan: Read prod/cons only once. We must ensure that the prod/cons are only read once and that the compiler won't try to optimize the reads. That is split the read of these in multiple instructions influencing later branch code. As such insert barriers when fetching the cons and prod index. This is part of XSA155. Signed-off-by: Konrad Rzeszutek Wilk --- tools/libvchan/io.c | 2 ++ 1 file changed, 2 insertions(+) Index: xen-4.4.2/tools/libvchan/io.c =================================================================== --- xen-4.4.2.orig/tools/libvchan/io.c 2015-12-07 14:56:46.164042495 +0100 +++ xen-4.4.2/tools/libvchan/io.c 2015-12-07 14:59:32.156039935 +0100 @@ -118,6 +118,7 @@ static inline int send_notify(struct lib static inline int raw_get_data_ready(struct libxenvchan *ctrl) { uint32_t ready = rd_prod(ctrl) - rd_cons(ctrl); + xen_mb(); /* Ensure 'ready' is read only once. */ if (ready >= rd_ring_size(ctrl)) /* We have no way to return errors. Locking up the ring is * better than the alternatives. */ @@ -159,6 +160,7 @@ int libxenvchan_data_ready(struct libxen static inline int raw_get_buffer_space(struct libxenvchan *ctrl) { uint32_t ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl)); + xen_mb(); /* Ensure 'ready' is read only once. */ if (ready > wr_ring_size(ctrl)) /* We have no way to return errors. Locking up the ring is * better than the alternatives. */ debian/patches/xsa206-4.4-0028-oxenstored-do-not-commit-read-only-transactions.patch0000664000000000000000000000464313104300260025023 0ustar From f44d628a0101d4c5318b3b14d7c19ace10a18a61 Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Fri, 24 Mar 2017 16:16:10 +0000 Subject: [PATCH 28/30] oxenstored: do not commit read-only transactions The packet telling us to end the transaction has always carried an argument telling us whether to commit. If the transaction made no modifications to the tree, now we ignore that argument and do not commit: it is just a waste of effort. This makes read-only transactions immune to conflicts, and means that we do not need to store any of their details in the history that is used for assigning blame for conflicts. We count a transaction as a read-only transaction only if it contains no operations that modified the tree. This means that (for example) a transaction that creates a new node then deletes it would NOT count as read-only, even though it makes no change overall. A more sophisticated algorithm could judge the transaction based on comparison of its initial and final states, but this would add complexity and computational cost. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies --- tools/ocaml/xenstored/process.ml | 1 + tools/ocaml/xenstored/transaction.ml | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index ff2ca65..a983b49 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -387,6 +387,7 @@ let do_transaction_end con t domains cons data = | x :: _ -> raise (Invalid_argument x) | _ -> raise Invalid_Cmd_Args in + let commit = commit && not (Transaction.is_read_only t) in let success = let commit = if commit then Some (fun con trans -> transaction_replay con trans domains cons) else None in History.end_transaction t con (Transaction.get_id t) commit in diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index edd1178..8f95301 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -128,6 +128,7 @@ let make ?(internal=false) id store = let get_store t = t.store let get_paths t = t.paths +let is_read_only t = t.paths = [] let add_wop t ty path = t.paths <- (ty, path) :: t.paths let add_operation ~perm t request response = if !Define.maxrequests >= 0 -- 2.1.4 debian/patches/tools-firmware-seabios-packaged.diff0000664000000000000000000000323512276137142017613 0ustar Index: xen-4.4.0~rc3+20140210/tools/firmware/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/firmware/Makefile 2014-02-10 12:56:18.042749731 +0100 +++ xen-4.4.0~rc3+20140210/tools/firmware/Makefile 2014-02-10 12:56:18.614752527 +0100 @@ -9,9 +9,6 @@ SUBDIRS-y := ifeq ($(OVMF_PATH),) SUBDIRS-$(CONFIG_OVMF) += ovmf-dir endif -ifeq ($(SEABIOS_PATH),) -SUBDIRS-$(CONFIG_SEABIOS) += seabios-dir -endif SUBDIRS-$(CONFIG_ROMBIOS) += rombios SUBDIRS-$(CONFIG_ROMBIOS) += vgabios SUBDIRS-y += hvmloader @@ -52,9 +49,6 @@ distclean: subdirs-distclean subdir-distclean-ovmf: .phony rm -rf ovmf-dir ovmf-dir-remote -subdir-distclean-seabios-dir: .phony - rm -rf seabios-dir seabios-dir-remote - .PHONY: ovmf-dir-force-update ovmf-dir-force-update: set -ex; \ Index: xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/firmware/hvmloader/Makefile 2014-02-10 12:56:18.042749731 +0100 +++ xen-4.4.0~rc3+20140210/tools/firmware/hvmloader/Makefile 2014-02-10 12:56:18.614752527 +0100 @@ -39,7 +39,7 @@ CIRRUSVGA_DEBUG ?= n OVMF_DIR := ../ovmf-dir ROMBIOS_DIR := ../rombios -SEABIOS_DIR := ../seabios-dir +SEABIOS_DIR := /usr/share/seabios ifeq ($(CONFIG_ROMBIOS),y) STDVGA_ROM := ../vgabios/VGABIOS-lgpl-latest.bin @@ -74,11 +74,7 @@ endif ifeq ($(CONFIG_SEABIOS),y) OBJS += seabios.o CFLAGS += -DENABLE_SEABIOS -ifeq ($(SEABIOS_PATH),) - SEABIOS_ROM := $(SEABIOS_DIR)/out/bios.bin -else - SEABIOS_ROM := $(SEABIOS_PATH) -endif +SEABIOS_ROM := $(SEABIOS_DIR)/bios.bin ROMS += $(SEABIOS_ROM) endif debian/patches/xsa206-4.4-0029-oxenstored-don-t-wake-to-issue-no-conflict-credit.patch0000664000000000000000000001300613104300260025126 0ustar From b0c7a48af6d0b0dedf638bef6cf166c245057229 Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Fri, 24 Mar 2017 19:55:03 +0000 Subject: [PATCH 29/30] oxenstored: don't wake to issue no conflict-credit In the main loop, when choosing the timeout for the select function call, we were setting it so as to wake up to issue conflict-credit to any domains that could accept it. When xenstore is idle, this would mean waking up every 50ms (by default) to do no work. With this commit, we check whether any domain is below its cap, and if not then we set the timeout for longer (the same timeout as before the conflict-protection feature was added). Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies --- tools/ocaml/xenstored/domains.ml | 51 ++++++++++++++++++++++++++++++-------- tools/ocaml/xenstored/xenstored.ml | 5 +++- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/tools/ocaml/xenstored/domains.ml b/tools/ocaml/xenstored/domains.ml index 63c6ad5..25fd592 100644 --- a/tools/ocaml/xenstored/domains.ml +++ b/tools/ocaml/xenstored/domains.ml @@ -35,8 +35,9 @@ type domains = { on_first_conflict_pause: unit -> unit; (* If config is set to use individual instead of aggregate conflict-rate-limiting, - we use this instead of the queues. *) - mutable n_paused: int; + we use these counts instead of the queues. The second one includes the first. *) + mutable n_paused: int; (* Number of domains with zero or negative credit *) + mutable n_penalised: int; (* Number of domains with less than maximum credit *) } let init eventchn on_first_conflict_pause = { @@ -46,6 +47,7 @@ let init eventchn on_first_conflict_pause = { doms_with_conflict_penalty = Queue.create (); on_first_conflict_pause = on_first_conflict_pause; n_paused = 0; + n_penalised = 0; } let del doms id = Hashtbl.remove doms.table id let exist doms id = Hashtbl.mem doms.table id @@ -53,6 +55,23 @@ let find doms id = Hashtbl.find doms.table id let number doms = Hashtbl.length doms.table let iter doms fct = Hashtbl.iter (fun _ b -> fct b) doms.table +let rec is_empty_queue q = + Queue.is_empty q || + if !(Queue.peek q) = None + then ( + ignore (Queue.pop q); + is_empty_queue q + ) else false + +let all_at_max_credit doms = + if !Define.conflict_rate_limit_is_aggregate + then + (* Check both becuase if burst limit is 1.0 then a domain can go straight + * from max-credit to paused without getting into the penalty queue. *) + is_empty_queue doms.doms_with_conflict_penalty + && is_empty_queue doms.doms_conflict_paused + else doms.n_penalised = 0 + (* Functions to handle queues of domains given that the domain might be deleted while in a queue. *) let push dom queue = Queue.push (ref (Some dom)) queue @@ -132,13 +151,16 @@ let decr_conflict_credit doms dom = let before = dom.Domain.conflict_credit in let after = max (-1.0) (before -. 1.0) in dom.Domain.conflict_credit <- after; + let newly_penalised = + before >= !Define.conflict_burst_limit + && after < !Define.conflict_burst_limit in + let newly_paused = before > 0.0 && after <= 0.0 in if !Define.conflict_rate_limit_is_aggregate then ( - if before >= !Define.conflict_burst_limit - && after < !Define.conflict_burst_limit + if newly_penalised && after > 0.0 then ( push dom doms.doms_with_conflict_penalty - ) else if before > 0.0 && after <= 0.0 + ) else if newly_paused then ( let first_pause = Queue.is_empty doms.doms_conflict_paused in push dom doms.doms_conflict_paused; @@ -146,9 +168,12 @@ let decr_conflict_credit doms dom = ) else ( (* The queues are correct already: no further action needed. *) ) - ) else if before > 0.0 && after <= 0.0 then ( - doms.n_paused <- doms.n_paused + 1; - if doms.n_paused = 1 then doms.on_first_conflict_pause () + ) else ( + if newly_penalised then doms.n_penalised <- doms.n_penalised + 1; + if newly_paused then ( + doms.n_paused <- doms.n_paused + 1; + if doms.n_paused = 1 then doms.on_first_conflict_pause () + ) ) (* Give one point of credit to one domain, and update the queues appropriately. *) @@ -177,9 +202,13 @@ let incr_conflict_credit doms = let before = dom.Domain.conflict_credit in let after = min (before +. 1.0) !Define.conflict_burst_limit in dom.Domain.conflict_credit <- after; + if before <= 0.0 && after > 0.0 - then doms.n_paused <- doms.n_paused - 1 + then doms.n_paused <- doms.n_paused - 1; + + if before < !Define.conflict_burst_limit + && after >= !Define.conflict_burst_limit + then doms.n_penalised <- doms.n_penalised - 1 in - (* Scope for optimisation (probably tiny): avoid iteration if all domains are at max credit *) - iter doms inc + if doms.n_penalised > 0 then iter doms inc ) diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index c009701..8c82fe9 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -436,7 +436,10 @@ let _ = peaceful_mw; let start_time = Unix.gettimeofday () in let timeout = - let until_next_activity = min (max 0. (!next_frequent_ops -. start_time)) period_ops_interval in + let until_next_activity = + if Domains.all_at_max_credit domains + then period_ops_interval + else min (max 0. (!next_frequent_ops -. start_time)) period_ops_interval in if peaceful_mw <> [] then 0. else until_next_activity in let inset, outset = Connections.select ~only_if:is_peaceful cons in -- 2.1.4 debian/patches/ubuntu-tools-armhf-without-ocaml.patch0000664000000000000000000000216112276137154020215 0ustar From: Stefan Bader Date: Fri, 02 Aug 2013 16:47:22 +0100 Subject: tools: Disable ocaml build on armhf Problem right now is that the ocaml library seems to have hard dependencies on some cpuid related functions which only exist on x86. Until that is sorted out upstream (apparently when they build for Arm they have had no ocaml package installed), prevent the build. This also needs some modifications in debian/rules.real but those won't show up in the patch. Signed-off-by: Stefan Bader Index: xen-4.4.0~rc3+20140210/tools/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/Makefile 2014-02-10 12:56:26.946793259 +0100 +++ xen-4.4.0~rc3+20140210/tools/Makefile 2014-02-10 12:56:28.546801076 +0100 @@ -43,8 +43,10 @@ SUBDIRS-$(CONFIG_TESTS) += tests ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) SUBDIRS-y += python SUBDIRS-y += pygrub +ifeq ($(filter arm32 arm64,$(XEN_COMPILE_ARCH)),) SUBDIRS-$(OCAML_TOOLS) += ocaml endif +endif # For the sake of linking, set the sys-root ifneq ($(CROSS_COMPILE),) debian/patches/xsa206-4.4-0001-xenstored-apply-a-write-transaction-rate-limit.patch0000664000000000000000000003265013104302015024631 0ustar From 7df6157ccf3dd8f9d6fae690be3f6216b0c2dd2b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 18 Mar 2017 17:12:39 +0000 Subject: [PATCH 01/30] xenstored: apply a write transaction rate limit This avoids a rogue client being about to stall another client (eg the toolstack) indefinitely. This is XSA-206. Reported-by: Juergen Gross Signed-off-by: Ian Jackson --- tools/xenstore/Makefile | 3 +- tools/xenstore/xenstored_core.c | 9 ++ tools/xenstore/xenstored_core.h | 6 + tools/xenstore/xenstored_domain.c | 215 +++++++++++++++++++++++++++++++++ tools/xenstore/xenstored_domain.h | 25 ++++ tools/xenstore/xenstored_transaction.c | 5 + 6 files changed, 262 insertions(+), 1 deletion(-) Index: xen-4.4.2/tools/xenstore/Makefile =================================================================== --- xen-4.4.2.orig/tools/xenstore/Makefile +++ xen-4.4.2/tools/xenstore/Makefile @@ -21,6 +21,7 @@ XENSTORED_OBJS_$(CONFIG_NetBSD) = xensto XENSTORED_OBJS_$(CONFIG_MiniOS) = xenstored_minios.o XENSTORED_OBJS += $(XENSTORED_OBJS_y) +LDLIBS_xenstored += -lrt ifneq ($(XENSTORE_STATIC_CLIENTS),y) LIBXENSTORE := libxenstore.so @@ -63,7 +64,7 @@ init-xenstore-domain: init-xenstore-doma $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(call LDFLAGS_RPATH,../lib) -o $@ $(APPEND_LDFLAGS) xenstored: $(XENSTORED_OBJS) - $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) $(call LDFLAGS_RPATH,../lib) -o $@ $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_xenstored) $(SOCKET_LIBS) $(call LDFLAGS_RPATH,../lib) -o $@ $(APPEND_LDFLAGS) xenstored.a: $(XENSTORED_OBJS) $(AR) cr $@ $^ Index: xen-4.4.2/tools/xenstore/xenstored_core.c =================================================================== --- xen-4.4.2.orig/tools/xenstore/xenstored_core.c +++ xen-4.4.2/tools/xenstore/xenstored_core.c @@ -342,6 +342,7 @@ static void initialize_fds(int sock, int int *ptimeout) { struct connection *conn; + struct wrl_timestampt now; if (fds) memset(fds, 0, sizeof(struct pollfd) * current_array_size); @@ -361,8 +362,11 @@ static void initialize_fds(int sock, int xce_pollfd_idx = set_fd(xc_evtchn_fd(xce_handle), POLLIN|POLLPRI); + wrl_gettime_now(&now); + list_for_each_entry(conn, &connections, list) { if (conn->domain) { + wrl_check_timeout(conn->domain, now, ptimeout); if (domain_can_read(conn) || (domain_can_write(conn) && !list_empty(&conn->out_list))) @@ -795,6 +799,7 @@ static void delete_node_single(struct co corrupt(conn, "Could not delete '%s'", node->name); return; } + domain_entry_dec(conn, node); } @@ -934,6 +939,7 @@ static void do_write(struct connection * } add_change_node(conn->transaction, name, false); + wrl_apply_debit_direct(conn); fire_watches(conn, name, false); send_ack(conn, XS_WRITE); } @@ -958,6 +964,7 @@ static void do_mkdir(struct connection * return; } add_change_node(conn->transaction, name, false); + wrl_apply_debit_direct(conn); fire_watches(conn, name, false); } send_ack(conn, XS_MKDIR); @@ -1083,6 +1090,7 @@ static void do_rm(struct connection *con if (_rm(conn, node, name)) { add_change_node(conn->transaction, name, true); + wrl_apply_debit_direct(conn); fire_watches(conn, name, true); send_ack(conn, XS_RM); } @@ -1158,6 +1166,7 @@ static void do_set_perms(struct connecti } add_change_node(conn->transaction, name, false); + wrl_apply_debit_direct(conn); fire_watches(conn, name, false); send_ack(conn, XS_SET_PERMS); } Index: xen-4.4.2/tools/xenstore/xenstored_core.h =================================================================== --- xen-4.4.2.orig/tools/xenstore/xenstored_core.h +++ xen-4.4.2/tools/xenstore/xenstored_core.h @@ -31,6 +31,12 @@ #include "list.h" #include "tdb.h" +#define MIN(a, b) (((a) < (b))? (a) : (b)) + +typedef int32_t wrl_creditt; +#define WRL_CREDIT_MAX (1000*1000*1000) +/* ^ satisfies non-overflow condition for wrl_xfer_credit */ + struct buffered_data { struct list_head list; Index: xen-4.4.2/tools/xenstore/xenstored_domain.c =================================================================== --- xen-4.4.2.orig/tools/xenstore/xenstored_domain.c +++ xen-4.4.2/tools/xenstore/xenstored_domain.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "utils.h" #include "talloc.h" @@ -75,6 +76,10 @@ struct domain /* number of watch for this domain */ int nbwatch; + + /* write rate limit */ + wrl_creditt wrl_credit; /* [ -wrl_config_writecost, +_dburst ] */ + struct wrl_timestampt wrl_timestamp; }; static LIST_HEAD(domains); @@ -207,6 +212,8 @@ static int destroy_domain(void *_domain) fire_watches(NULL, "@releaseDomain", false); + wrl_domain_destroy(domain); + return 0; } @@ -254,6 +261,9 @@ void handle_event(void) bool domain_can_read(struct connection *conn) { struct xenstore_domain_interface *intf = conn->domain->interface; + + if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0) + return false; return (intf->req_cons != intf->req_prod); } @@ -285,6 +295,8 @@ static struct domain *new_domain(void *c domain->domid = domid; domain->path = talloc_domain_path(domain, domid); + wrl_domain_new(domain); + list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); @@ -748,6 +760,209 @@ int domain_watch(struct connection *conn : 0; } +static wrl_creditt wrl_config_writecost = WRL_FACTOR; +static wrl_creditt wrl_config_rate = WRL_RATE * WRL_FACTOR; +static wrl_creditt wrl_config_dburst = WRL_DBURST * WRL_FACTOR; +static wrl_creditt wrl_config_gburst = WRL_GBURST * WRL_FACTOR; +static wrl_creditt wrl_config_newdoms_dburst = + WRL_DBURST * WRL_NEWDOMS * WRL_FACTOR; + +long wrl_ntransactions; + +static long wrl_ndomains; +static wrl_creditt wrl_reserve; /* [-wrl_config_newdoms_dburst, +_gburst ] */ + +void wrl_gettime_now(struct wrl_timestampt *now_wt) +{ + struct timespec now_ts; + int r; + + r = clock_gettime(CLOCK_MONOTONIC, &now_ts); + if (r) + barf_perror("Could not find time (clock_gettime failed)"); + + now_wt->sec = now_ts.tv_sec; + now_wt->msec = now_ts.tv_nsec / 1000000; +} + +static void wrl_xfer_credit(wrl_creditt *debit, wrl_creditt debit_floor, + wrl_creditt *credit, wrl_creditt credit_ceil) + /* + * Transfers zero or more credit from "debit" to "credit". + * Transfers as much as possible while maintaining + * debit >= debit_floor and credit <= credit_ceil. + * (If that's violated already, does nothing.) + * + * Sufficient conditions to avoid overflow, either of: + * |every argument| <= 0x3fffffff + * |every argument| <= 1E9 + * |every argument| <= WRL_CREDIT_MAX + * (And this condition is preserved.) + */ +{ + wrl_creditt xfer = MIN( *debit - debit_floor, + credit_ceil - *credit ); + if (xfer > 0) { + *debit -= xfer; + *credit += xfer; + } +} + +void wrl_domain_new(struct domain *domain) +{ + domain->wrl_credit = 0; + wrl_gettime_now(&domain->wrl_timestamp); + wrl_ndomains++; + /* Steal up to DBURST from the reserve */ + wrl_xfer_credit(&wrl_reserve, -wrl_config_newdoms_dburst, + &domain->wrl_credit, wrl_config_dburst); +} + +void wrl_domain_destroy(struct domain *domain) +{ + wrl_ndomains--; + /* + * Don't bother recalculating domain's credit - this just + * means we don't give the reserve the ending domain's credit + * for time elapsed since last update. + */ + wrl_xfer_credit(&domain->wrl_credit, 0, + &wrl_reserve, wrl_config_dburst); +} + +void wrl_credit_update(struct domain *domain, struct wrl_timestampt now) +{ + /* + * We want to calculate + * credit += (now - timestamp) * RATE / ndoms; + * But we want it to saturate, and to avoid floating point. + * To avoid rounding errors from constantly adding small + * amounts of credit, we only add credit for whole milliseconds. + */ + long seconds = now.sec - domain->wrl_timestamp.sec; + long milliseconds = now.msec - domain->wrl_timestamp.msec; + long msec; + int64_t denom, num; + wrl_creditt surplus; + + seconds = MIN(seconds, 1000*1000); /* arbitrary, prevents overflow */ + msec = seconds * 1000 + milliseconds; + + if (msec < 0) + /* shouldn't happen with CLOCK_MONOTONIC */ + msec = 0; + + /* 32x32 -> 64 cannot overflow */ + denom = (int64_t)msec * wrl_config_rate; + num = (int64_t)wrl_ndomains * 1000; + /* denom / num <= 1E6 * wrl_config_rate, so with + reasonable wrl_config_rate, denom / num << 2^64 */ + + /* at last! */ + domain->wrl_credit = MIN( (int64_t)domain->wrl_credit + denom / num, + WRL_CREDIT_MAX ); + /* (maybe briefly violating the DBURST cap on wrl_credit) */ + + /* maybe take from the reserve to make us nonnegative */ + wrl_xfer_credit(&wrl_reserve, 0, + &domain->wrl_credit, 0); + + /* return any surplus (over DBURST) to the reserve */ + surplus = 0; + wrl_xfer_credit(&domain->wrl_credit, wrl_config_dburst, + &surplus, WRL_CREDIT_MAX); + wrl_xfer_credit(&surplus, 0, + &wrl_reserve, wrl_config_gburst); + /* surplus is now implicitly discarded */ + + domain->wrl_timestamp = now; + + trace("wrl: dom %4d %6ld msec %9ld credit %9ld reserve" + " %9ld discard\n", + domain->domid, + msec, + (long)domain->wrl_credit, (long)wrl_reserve, + (long)surplus); +} + +void wrl_check_timeout(struct domain *domain, + struct wrl_timestampt now, + int *ptimeout) +{ + uint64_t num, denom; + int wakeup; + + wrl_credit_update(domain, now); + + if (domain->wrl_credit >= 0) + /* not blocked */ + return; + + if (!*ptimeout) + /* already decided on immediate wakeup, + so no need to calculate our timeout */ + return; + + /* calculate wakeup = now + -credit / (RATE / ndoms); */ + + /* credit cannot go more -ve than one transaction, + * so the first multiplication cannot overflow even 32-bit */ + num = (uint64_t)(-domain->wrl_credit * 1000) * wrl_ndomains; + denom = wrl_config_rate; + + wakeup = MIN( num / denom /* uint64_t */, INT_MAX ); + if (*ptimeout==-1 || wakeup < *ptimeout) + *ptimeout = wakeup; + + trace("wrl: domain %u credit=%ld (reserve=%ld) SLEEPING for %d\n", + domain->domid, + (long)domain->wrl_credit, (long)wrl_reserve, + wakeup); +} + +void wrl_apply_debit_actual(struct domain *domain) +{ + struct wrl_timestampt now; + + if (!domain) + /* sockets escape the write rate limit */ + return; + + wrl_gettime_now(&now); + wrl_credit_update(domain, now); + + domain->wrl_credit -= wrl_config_writecost; + trace("wrl: domain %u credit=%ld (reserve=%ld)\n", + domain->domid, + (long)domain->wrl_credit, (long)wrl_reserve); +} + +void wrl_apply_debit_direct(struct connection *conn) +{ + if (!conn) + /* some writes are generated internally */ + return; + + if (conn->transaction) + /* these are accounted for when the transaction ends */ + return; + + if (!wrl_ntransactions) + /* we don't conflict with anyone */ + return; + + wrl_apply_debit_actual(conn->domain); +} + +void wrl_apply_debit_trans_commit(struct connection *conn) +{ + if (wrl_ntransactions <= 1) + /* our own transaction appears in the counter */ + return; + + wrl_apply_debit_actual(conn->domain); +} + /* * Local variables: * c-file-style: "linux" Index: xen-4.4.2/tools/xenstore/xenstored_domain.h =================================================================== --- xen-4.4.2.orig/tools/xenstore/xenstored_domain.h +++ xen-4.4.2/tools/xenstore/xenstored_domain.h @@ -66,4 +66,29 @@ void domain_watch_inc(struct connection void domain_watch_dec(struct connection *conn); int domain_watch(struct connection *conn); +/* Write rate limiting */ + +#define WRL_FACTOR 1000 /* for fixed-point arithmetic */ +#define WRL_RATE 200 +#define WRL_DBURST 10 +#define WRL_GBURST 1000 +#define WRL_NEWDOMS 5 + +struct wrl_timestampt { + time_t sec; + int msec; +}; + +extern long wrl_ntransactions; + +void wrl_gettime_now(struct wrl_timestampt *now_ts); +void wrl_domain_new(struct domain *domain); +void wrl_domain_destroy(struct domain *domain); +void wrl_credit_update(struct domain *domain, struct wrl_timestampt now); +void wrl_check_timeout(struct domain *domain, + struct wrl_timestampt now, + int *ptimeout); +void wrl_apply_debit_direct(struct connection *conn); +void wrl_apply_debit_trans_commit(struct connection *conn); + #endif /* _XENSTORED_DOMAIN_H */ Index: xen-4.4.2/tools/xenstore/xenstored_transaction.c =================================================================== --- xen-4.4.2.orig/tools/xenstore/xenstored_transaction.c +++ xen-4.4.2/tools/xenstore/xenstored_transaction.c @@ -117,6 +117,7 @@ static int destroy_transaction(void *_tr { struct transaction *trans = _transaction; + wrl_ntransactions--; trace_destroy(trans, "transaction"); if (trans->tdb) tdb_close(trans->tdb); @@ -180,6 +181,7 @@ void do_transaction_start(struct connect talloc_steal(conn, trans); talloc_set_destructor(trans, destroy_transaction); conn->transaction_started++; + wrl_ntransactions++; snprintf(id_str, sizeof(id_str), "%u", trans->id); send_reply(conn, XS_TRANSACTION_START, id_str, strlen(id_str)+1); @@ -214,6 +216,9 @@ void do_transaction_end(struct connectio send_error(conn, EAGAIN); return; } + + wrl_apply_debit_trans_commit(conn); + if (!replace_tdb(trans->tdb_name, trans->tdb)) { send_error(conn, errno); return; debian/patches/xsa175-4.4-0006-libxl-Do-not-trust-frontend-for-disk-in-getinfo.patch0000664000000000000000000000646212725264607024614 0ustar From 3d1d7473c756d79e464600cee370c8759bd20f89 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 29 Apr 2016 19:21:51 +0100 Subject: [PATCH 06/10] libxl: Do not trust frontend for disk in getinfo * Rename the frontend variable to `fe_path' to check we caught them all * Read the backend path from /libxl, rather than from the frontend * Parse the backend domid from the backend path, rather than reading it from the frontend (and add the appropriate error path and initialisation) This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index f101334..18f9f0a 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2449,27 +2449,34 @@ int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, libxl_diskinfo *diskinfo) { GC_INIT(ctx); - char *dompath, *diskpath; + char *dompath, *fe_path, *libxl_path; char *val; + int rc; + + diskinfo->backend = NULL; dompath = libxl__xs_get_dompath(gc, domid); diskinfo->devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL); /* tap devices entries in xenstore are written as vbd devices. */ - diskpath = libxl__sprintf(gc, "%s/device/vbd/%d", dompath, diskinfo->devid); + fe_path = GCSPRINTF("%s/device/vbd/%d", dompath, diskinfo->devid); + libxl_path = GCSPRINTF("%s/device/vbd/%d", + libxl__xs_libxl_path(gc, domid), diskinfo->devid); diskinfo->backend = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/backend", diskpath), NULL); + GCSPRINTF("%s/backend", libxl_path), NULL); if (!diskinfo->backend) { GC_FREE; return ERROR_FAIL; } - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/backend-id", diskpath)); - diskinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/state", diskpath)); + rc = libxl__backendpath_parse_domid(gc, diskinfo->backend, + &diskinfo->backend_id); + if (rc) goto out; + + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", fe_path)); diskinfo->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/event-channel", diskpath)); + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/event-channel", fe_path)); diskinfo->evtch = val ? strtoul(val, NULL, 10) : -1; - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/ring-ref", diskpath)); + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/ring-ref", fe_path)); diskinfo->rref = val ? strtoul(val, NULL, 10) : -1; diskinfo->frontend = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(gc, "%s/frontend", diskinfo->backend), NULL); @@ -2478,6 +2485,10 @@ int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, GC_FREE; return 0; + + out: + free(diskinfo->backend); + return rc; } int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, -- 2.1.4 debian/patches/xsa206-4.4-0007-oxenstored-enable-domain-connection-indexing-based-o.patch0000664000000000000000000000654413104300257025707 0ustar From 3595258f4a60dd49a75b6229e623ec478eaf239b Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Fri, 24 Mar 2017 17:02:55 +0000 Subject: [PATCH 07/30] oxenstored: enable domain connection indexing based on eventchn port Currently in xenstore connection database, we use a hash table of (domid -> connection) to store domain connections. This allows fast indexing based on dom ids. This patch adds another dimention of fast indexing that is based on eventchn port number. This is useful when doing selective connection processing based on the port numbers of incoming events. Reported-by: Juergen Gross Signed-off-by: Zheng Li Reviewed-by: David Scott --- tools/ocaml/xenstored/connections.ml | 26 ++++++++++++++++++++++---- tools/ocaml/xenstored/domain.ml | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml index 3e6a48b..1c8d911 100644 --- a/tools/ocaml/xenstored/connections.ml +++ b/tools/ocaml/xenstored/connections.ml @@ -20,10 +20,16 @@ let debug fmt = Logging.debug "connections" fmt type t = { anonymous: (Unix.file_descr, Connection.t) Hashtbl.t; domains: (int, Connection.t) Hashtbl.t; + ports: (Xeneventchn.t, Connection.t) Hashtbl.t; mutable watches: (string, Connection.watch list) Trie.t; } -let create () = { anonymous = Hashtbl.create 37; domains = Hashtbl.create 37; watches = Trie.create () } +let create () = { + anonymous = Hashtbl.create 37; + domains = Hashtbl.create 37; + ports = Hashtbl.create 37; + watches = Trie.create () +} let add_anonymous cons fd can_write = let xbcon = Xenbus.Xb.open_fd fd in @@ -33,7 +39,10 @@ let add_anonymous cons fd can_write = let add_domain cons dom = let xbcon = Xenbus.Xb.open_mmap (Domain.get_interface dom) (fun () -> Domain.notify dom) in let con = Connection.create xbcon (Some dom) in - Hashtbl.add cons.domains (Domain.get_id dom) con + Hashtbl.add cons.domains (Domain.get_id dom) con; + match Domain.get_port dom with + | Some p -> Hashtbl.add cons.ports p con; + | None -> () let select cons = Hashtbl.fold @@ -45,8 +54,11 @@ let select cons = let find cons = Hashtbl.find cons.anonymous -let find_domain cons id = - Hashtbl.find cons.domains id +let find_domain cons = + Hashtbl.find cons.domains + +let find_domain_by_port cons port = + Hashtbl.find cons.ports port let del_watches_of_con con watches = match List.filter (fun w -> Connection.get_con w != con) watches with @@ -65,6 +77,12 @@ let del_domain cons id = try let con = find_domain cons id in Hashtbl.remove cons.domains id; + (match Connection.get_domain con with + | Some d -> + (match Domain.get_port d with + | Some p -> Hashtbl.remove cons.ports p + | None -> ()) + | None -> ()); cons.watches <- Trie.map (del_watches_of_con con) cons.watches; Connection.close con with exn -> diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml index 444069d..06d5749 100644 --- a/tools/ocaml/xenstored/domain.ml +++ b/tools/ocaml/xenstored/domain.ml @@ -35,6 +35,7 @@ let get_id domain = domain.id let get_interface d = d.interface let get_mfn d = d.mfn let get_remote_port d = d.remote_port +let get_port d = d.port let is_bad_domain domain = domain.bad_client let mark_as_bad domain = domain.bad_client <- true -- 2.1.4 debian/patches/xsa237-4.4-0004-x86-MSI-fix-error-handling.patch0000664000000000000000000001035213167427007020331 0ustar From 5a7c04221c47c3196326e669f55beb4524d0de56 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 21 Apr 2015 09:13:51 +0200 Subject: [PATCH] x86/MSI: fix error handling __setup_msi_irq() needs to undo what it did before calling write_msi_msg() in case that returned an error. map_domain_pirq() needs to get rid of the MSI descriptor it (implicitly) allocated. The case of a setup_msi_irq() failure on a non-initial multi-vector-MSI interrupt needs special handling: While the initial IRQ will get freed by the caller (who also passed it to us), we need to undo the effect setup_msi_irq() had on it. (As a benefit from the added call to msi_free_irq() we no longer need to explicitly call destroy_irq() on the non-initial slots.) Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper master commit: 29c1b7886c36d4e6aa03a779b2251b829d9689c3 master date: 2015-03-26 11:19:57 +0100 Signed-off-by: Stefan Bader --- xen/arch/x86/irq.c | 27 ++++++++++++++++++--------- xen/arch/x86/msi.c | 14 ++++++++++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index f214072..84738e5 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1973,6 +1973,8 @@ int map_domain_pirq( dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n", d->domain_id, irq); pci_disable_msi(msi_desc); + msi_desc->irq = -1; + msi_free_irq(msi_desc); ret = -EBUSY; goto done; } @@ -2027,22 +2029,29 @@ int map_domain_pirq( if ( ret ) { spin_unlock_irqrestore(&desc->lock, flags); + pci_disable_msi(msi_desc); + if ( nr ) + { + ASSERT(msi_desc->irq >= 0); + desc = irq_to_desc(msi_desc->irq); + spin_lock_irqsave(&desc->lock, flags); + desc->handler = &no_irq_type; + desc->msi_desc = NULL; + spin_unlock_irqrestore(&desc->lock, flags); + } while ( nr-- ) { - if ( irq >= 0 ) - { - if ( irq_deny_access(d, irq) ) - printk(XENLOG_G_ERR - "dom%d: could not revoke access to IRQ%d (pirq %d)\n", - d->domain_id, irq, pirq); - destroy_irq(irq); - } + if ( irq >= 0 && irq_deny_access(d, irq) ) + printk(XENLOG_G_ERR + "dom%d: could not revoke access to IRQ%d (pirq %d)\n", + d->domain_id, irq, pirq); if ( info ) cleanup_domain_irq_pirq(d, irq, info); info = pirq_info(d, pirq + nr); irq = info->arch.irq; } - pci_disable_msi(msi_desc); + msi_desc->irq = -1; + msi_free_irq(msi_desc); goto done; } diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index 14d37ec..7410d03 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -470,6 +470,7 @@ static struct msi_desc *alloc_msi_entry(unsigned int nr) while ( nr-- ) { entry[nr].dev = NULL; + entry[nr].irq = -1; entry[nr].remap_index = -1; } @@ -487,11 +488,19 @@ int __setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc, hw_irq_controller *handler) { struct msi_msg msg; + int ret; desc->msi_desc = msidesc; desc->handler = handler; msi_compose_msg(desc->arch.vector, desc->arch.cpu_mask, &msg); - return write_msi_msg(msidesc, &msg); + ret = write_msi_msg(msidesc, &msg); + if ( unlikely(ret) ) + { + desc->handler = &no_irq_type; + desc->msi_desc = NULL; + } + + return ret; } int msi_free_irq(struct msi_desc *entry) @@ -501,7 +510,8 @@ int msi_free_irq(struct msi_desc *entry) while ( nr-- ) { - destroy_irq(entry[nr].irq); + if ( entry[nr].irq >= 0 ) + destroy_irq(entry[nr].irq); /* Free the unused IRTE if intr remap enabled */ if ( iommu_intremap ) -- 2.7.4 debian/patches/tools-flags.diff0000664000000000000000000000131612276137136013714 0ustar Description: Export flags from configure Author: Bastian Blank Origin: vendor Forwarded: not-needed Index: xen-4.4.0~rc3+20140210/config/Tools.mk.in =================================================================== --- xen-4.4.0~rc3+20140210.orig/config/Tools.mk.in 2014-02-10 12:53:55.942055036 +0100 +++ xen-4.4.0~rc3+20140210/config/Tools.mk.in 2014-02-10 12:56:14.038730150 +0100 @@ -26,6 +26,9 @@ FETCHER := @FETCHER@ SEABIOS_PATH := @seabios_path@ OVMF_PATH := @ovmf_path@ +CFLAGS += @CFLAGS@ +CPPFLAGS += @CPPFLAGS@ + # Extra folder for libs/includes PREPEND_INCLUDES := @PREPEND_INCLUDES@ PREPEND_LIB := @PREPEND_LIB@ debian/patches/xsa224-4.5-0003-gnttab-correct-logic-to-get-page-references-during-m.patch0000664000000000000000000001374713126670744025552 0ustar From 5fd4726857a913e90de95623dc385f8856465839 Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Fri, 2 Jun 2017 15:21:27 +0100 Subject: [PATCH 3/4] gnttab: correct logic to get page references during map requests The rules for reference counting are somewhat complicated: * Each of GNTTAB_host_map and GNTTAB_device_map need their own reference count * If the mapping is writeable: - GNTTAB_host_map needs a type count under only some conditions - GNTTAB_device_map always needs a type count If the mapping succeeds, we need to keep all of these; if the mapping fails, we need to release whatever references we have acquired so far. Additionally, the code that does a lot of this calculation "inherits" a reference as part of the process of finding out who the owner is. Finally, if the grant is mapped as writeable (without the GNTMAP_readonly flag), but the hypervisor cannot grab a PGT_writeable_page type, the entire operation should fail. Unfortunately, the current code has several logic holes: * If a grant is mapped only GNTTAB_device_map, and with a writeable mapping, but in conditions where a *host* type count is not necessary, the code will fail to grab the necessary type count. * If a grant is mapped both GNTTAB_device_map and GNTTAB_host_map, with a writeable mapping, in conditions where the host type count is not necessary, *and* where the page cannot be changed to type PGT_writeable, the condition will not be detected. In both cases, this means that on success, the type count will be erroneously reduced when the grant is unmapped. In the second case, the type count will be erroneously reduced on the failure path as well. (In the first case the failure path logic has the same hole as the reference grabbing logic.) Additionally, the return value of get_page() is not checked; but this may fail even if the first get_page() succeeded due to a reference counting overflow. First of all, simplify the restoration logic by explicitly counting the reference and type references acquired. Consider each mapping type separately, explicitly marking the 'incoming' reference as used so we know when we need to grab a second one. Finally, always check the return value of get_page[_type]() and go to the failure path if appropriate. This is part of XSA-224. Reported-by: Jan Beulich Signed-off-by: George Dunlap Signed-off-by: Jan Beulich --- xen/common/grant_table.c | 58 +++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index c40073d..9f4fc37 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -572,12 +572,12 @@ __gnttab_map_grant_ref( struct grant_table *lgt, *rgt; struct vcpu *led; int handle; - unsigned long frame = 0, nr_gets = 0; + unsigned long frame = 0; struct page_info *pg = NULL; int rc = GNTST_okay; u32 old_pin; u32 act_pin; - unsigned int cache_flags; + unsigned int cache_flags, refcnt = 0, typecnt = 0; struct active_grant_entry *act = NULL; struct grant_mapping *mt; grant_entry_v1_t *sha1; @@ -714,11 +714,17 @@ __gnttab_map_grant_ref( else owner = page_get_owner(pg); + if ( owner ) + refcnt++; + if ( !pg || (owner == dom_io) ) { /* Only needed the reference to confirm dom_io ownership. */ if ( pg ) + { put_page(pg); + refcnt--; + } if ( paging_mode_external(ld) ) { @@ -746,27 +752,38 @@ __gnttab_map_grant_ref( } else if ( owner == rd || owner == dom_cow ) { - if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) + if ( (op->flags & GNTMAP_device_map) && !(op->flags & GNTMAP_readonly) ) { if ( (owner == dom_cow) || !get_page_type(pg, PGT_writable_page) ) goto could_not_pin; + typecnt++; } - nr_gets++; if ( op->flags & GNTMAP_host_map ) { - rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0); - if ( rc != GNTST_okay ) - goto undo_out; - + /* + * Only need to grab another reference if device_map claimed + * the other one. + */ if ( op->flags & GNTMAP_device_map ) { - nr_gets++; - (void)get_page(pg, rd); - if ( !(op->flags & GNTMAP_readonly) ) - get_page_type(pg, PGT_writable_page); + if ( !get_page(pg, rd) ) + goto could_not_pin; + refcnt++; + } + + if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) + { + if ( (owner == dom_cow) || + !get_page_type(pg, PGT_writable_page) ) + goto could_not_pin; + typecnt++; } + + rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0); + if ( rc != GNTST_okay ) + goto undo_out; } } else @@ -775,8 +792,6 @@ __gnttab_map_grant_ref( if ( !rd->is_dying ) gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame); - if ( owner != NULL ) - put_page(pg); rc = GNTST_general_error; goto undo_out; } @@ -827,18 +842,11 @@ __gnttab_map_grant_ref( return; undo_out: - if ( nr_gets > 1 ) - { - if ( !(op->flags & GNTMAP_readonly) ) - put_page_type(pg); - put_page(pg); - } - if ( nr_gets > 0 ) - { - if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) - put_page_type(pg); + while ( typecnt-- ) + put_page_type(pg); + + while ( refcnt-- ) put_page(pg); - } spin_lock(&rgt->lock); -- 2.1.4 debian/patches/xsa173-4.4.patch0000664000000000000000000002201312725264515013200 0ustar commit 5893f9ea852f428e7120a4f3184a20deeb145d91 Author: Tim Deegan Date: Wed Mar 16 17:05:25 2016 +0000 x86: limit GFNs to 32 bits for shadowed superpages. Superpage shadows store the shadowed GFN in the backpointer field, which for non-BIGMEM builds is 32 bits wide. Shadowing a superpage mapping of a guest-physical address above 2^44 would lead to the GFN being truncated there, and a crash when we come to remove the shadow from the hash table. Track the valid width of a GFN for each guest, including reporting it through CPUID, and enforce it in the shadow pagetables. Set the maximum witth to 32 for guests where this truncation could occur. This is XSA-173. Signed-off-by: Tim Deegan Signed-off-by: Jan Beulich Reported-by: Ling Liu diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 4221826..f436f91 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -37,6 +37,7 @@ integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx); struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; unsigned int paddr_bits __read_mostly = 36; +unsigned int hap_paddr_bits __read_mostly = 36; /* * Default host IA32_CR_PAT value to cover all memory types. @@ -195,7 +196,7 @@ static void __init early_cpu_detect(void) static void __cpuinit generic_identify(struct cpuinfo_x86 *c) { - u32 tfms, xlvl, capability, excap, ebx; + u32 tfms, xlvl, capability, excap, eax, ebx; /* Get vendor name */ cpuid(0x00000000, &c->cpuid_level, @@ -230,8 +231,11 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) } if ( xlvl >= 0x80000004 ) get_model_name(c); /* Default name */ - if ( xlvl >= 0x80000008 ) - paddr_bits = cpuid_eax(0x80000008) & 0xff; + if ( xlvl >= 0x80000008 ) { + eax = cpuid_eax(0x80000008); + paddr_bits = eax & 0xff; + hap_paddr_bits = ((eax >> 16) & 0xff) ?: paddr_bits; + } } /* Might lift BIOS max_leaf=3 limit. */ diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index f3f6c61..a4bfb90 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2966,8 +2966,7 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx, break; case 0x80000008: - count = cpuid_eax(0x80000008); - count = (count >> 16) & 0xff ?: count & 0xff; + count = d->arch.paging.gfn_bits + PAGE_SHIFT; if ( (*eax & 0xff) > count ) *eax = (*eax & ~0xff) | count; diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c index 70460b6..09511f0 100644 --- a/xen/arch/x86/mm/guest_walk.c +++ b/xen/arch/x86/mm/guest_walk.c @@ -94,6 +94,12 @@ void *map_domain_gfn(struct p2m_domain *p2m, gfn_t gfn, mfn_t *mfn, struct page_info *page; void *map; + if ( gfn_x(gfn) >> p2m->domain->arch.paging.gfn_bits ) + { + *rc = _PAGE_INVALID_BIT; + return NULL; + } + /* Translate the gfn, unsharing if shared */ page = get_page_from_gfn_p2m(p2m->domain, p2m, gfn_x(gfn), p2mt, NULL, q); @@ -294,20 +300,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m, flags &= ~_PAGE_PAT; if ( gfn_x(start) & GUEST_L2_GFN_MASK & ~0x1 ) - { -#if GUEST_PAGING_LEVELS == 2 - /* - * Note that _PAGE_INVALID_BITS is zero in this case, yielding a - * no-op here. - * - * Architecturally, the walk should fail if bit 21 is set (others - * aren't being checked at least in PSE36 mode), but we'll ignore - * this here in order to avoid specifying a non-natural, non-zero - * _PAGE_INVALID_BITS value just for that case. - */ -#endif rc |= _PAGE_INVALID_BITS; - } + /* Increment the pfn by the right number of 4k pages. * Mask out PAT and invalid bits. */ start = _gfn((gfn_x(start) & ~GUEST_L2_GFN_MASK) + @@ -390,5 +384,11 @@ set_ad: put_page(mfn_to_page(mfn_x(gw->l1mfn))); } + /* If this guest has a restricted physical address space then the + * target GFN must fit within it. */ + if ( !(rc & _PAGE_PRESENT) + && gfn_x(guest_l1e_get_gfn(gw->l1e)) >> d->arch.paging.gfn_bits ) + rc |= _PAGE_INVALID_BITS; + return rc; } diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c index c06369b..ccc4174 100644 --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -428,6 +428,7 @@ static void hap_destroy_monitor_table(struct vcpu* v, mfn_t mmfn) void hap_domain_init(struct domain *d) { INIT_PAGE_LIST_HEAD(&d->arch.paging.hap.freelist); + d->arch.paging.gfn_bits = hap_paddr_bits - PAGE_SHIFT; } /* return 0 for success, -errno for failure */ diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 90ba4d6..06a04ad 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -48,6 +48,16 @@ void shadow_domain_init(struct domain *d, unsigned int domcr_flags) INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.freelist); INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows); + d->arch.paging.gfn_bits = paddr_bits - PAGE_SHIFT; +#ifndef CONFIG_BIGMEM + /* + * Shadowed superpages store GFNs in 32-bit page_info fields. + * Note that we cannot use guest_supports_superpages() here. + */ + if ( !is_pv_domain(d) || opt_allow_superpage ) + d->arch.paging.gfn_bits = 32; +#endif + /* Use shadow pagetables for log-dirty support */ paging_log_dirty_init(d, shadow_enable_log_dirty, shadow_disable_log_dirty, shadow_clean_dirty_bitmap); diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 0f499bf..6c88d4e 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -527,7 +527,8 @@ _sh_propagate(struct vcpu *v, ASSERT(GUEST_PAGING_LEVELS > 3 || level != 3); /* Check there's something for the shadows to map to */ - if ( !p2m_is_valid(p2mt) && !p2m_is_grant(p2mt) ) + if ( (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt)) + || gfn_x(target_gfn) >> d->arch.paging.gfn_bits ) { *sp = shadow_l1e_empty(); goto done; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 7dfbbcb..a03fc2e 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -187,6 +187,9 @@ struct paging_domain { /* log dirty support */ struct log_dirty_domain log_dirty; + /* Number of valid bits in a gfn. */ + unsigned int gfn_bits; + /* preemption handling */ struct { const struct domain *dom; diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h index d2a8250..d95f835 100644 --- a/xen/include/asm-x86/guest_pt.h +++ b/xen/include/asm-x86/guest_pt.h @@ -220,15 +220,17 @@ guest_supports_nx(struct vcpu *v) } -/* Some bits are invalid in any pagetable entry. */ -#if GUEST_PAGING_LEVELS == 2 -#define _PAGE_INVALID_BITS (0) -#elif GUEST_PAGING_LEVELS == 3 -#define _PAGE_INVALID_BITS \ - get_pte_flags(((1ull<<63) - 1) & ~((1ull< --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -538,6 +538,16 @@ static struct pt_reg_info_tbl pt_emu_reg .u.b.restore = NULL, }, { + .offset = PCI_VPD_ADDR, + .size = 2, + .ro_mask = 0x0003, + .emu_mask = 0x0003, + .init = pt_common_reg_init, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_word_reg_write, + .u.w.restore = pt_word_reg_restore, + }, + { .size = 0, }, }; @@ -599,6 +609,17 @@ static struct pt_reg_info_tbl pt_emu_reg .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, + /* Device Status reg */ + { + .offset = PCI_EXP_DEVSTA, + .size = 2, + .res_mask = 0xFFC0, + .ro_mask = 0x0030, + .init = pt_common_reg_init, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_word_reg_write, + .u.w.restore = pt_word_reg_restore, + }, /* Link Control reg */ { .offset = PCI_EXP_LNKCTL, @@ -611,6 +632,16 @@ static struct pt_reg_info_tbl pt_emu_reg .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, + /* Link Status reg */ + { + .offset = PCI_EXP_LNKSTA, + .size = 2, + .ro_mask = 0x3FFF, + .init = pt_common_reg_init, + .u.w.read = pt_word_reg_read, + .u.w.write = pt_word_reg_write, + .u.w.restore = pt_word_reg_restore, + }, /* Device Control 2 reg */ { .offset = 0x28, --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -105,6 +105,14 @@ #define PCI_EXP_TYPE_ROOT_EC 0xa #endif +#ifndef PCI_VPD_ADDR +/* Vital Product Data */ +#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */ +#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ +#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ +#define PCI_VPD_DATA 4 /* 32-bits of data returned here */ +#endif + #ifndef PCI_ERR_UNCOR_MASK /* Uncorrectable Error Mask */ #define PCI_ERR_UNCOR_MASK 8 debian/patches/tools-xenstat-prefix.diff0000664000000000000000000000246712276137131015604 0ustar Index: xen-4.4.0~rc3+20140210/tools/xenstat/xentop/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstat/xentop/Makefile 2014-02-10 12:53:56.430057415 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstat/xentop/Makefile 2014-02-10 12:56:09.582708372 +0100 @@ -30,8 +30,8 @@ all: xentop .PHONY: install install: xentop xentop.1 - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) xentop $(DESTDIR)$(SBINDIR)/xentop + $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) + $(INSTALL_PROG) xentop $(DESTDIR)$(PRIVATE_BINDIR)/xentop $(INSTALL_DIR) $(DESTDIR)$(MAN1DIR) $(INSTALL_DATA) xentop.1 $(DESTDIR)$(MAN1DIR)/xentop.1 Index: xen-4.4.0~rc3+20140210/tools/xenstat/libxenstat/Makefile =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/xenstat/libxenstat/Makefile 2014-02-10 12:56:02.394673225 +0100 +++ xen-4.4.0~rc3+20140210/tools/xenstat/libxenstat/Makefile 2014-02-10 12:56:09.582708372 +0100 @@ -51,6 +51,7 @@ $(SHLIB): $(OBJECTS-y) .PHONY: install install: all + $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(PRIVATE_LIBDIR) $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) $(LIB) $(DESTDIR)$(LIBDIR)/libxenstat.a $(INSTALL_PROG) src/libxenstat.so $(DESTDIR)$(PRIVATE_LIBDIR) debian/patches/xsa230.patch0000664000000000000000000000252013147037627012671 0ustar From: Jan Beulich Subject: gnttab: correct pin status fixup for copy Regardless of copy operations only setting GNTPIN_hst*, GNTPIN_dev* also need to be taken into account when deciding whether to clear _GTF_{read,writ}ing. At least for consistency with code elsewhere the read part better doesn't use any mask at all. This is XSA-230. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index ae34547..9c9d33c 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -2107,10 +2107,10 @@ __release_grant_for_copy( static void __fixup_status_for_copy_pin(const struct active_grant_entry *act, uint16_t *status) { - if ( !(act->pin & GNTPIN_hstw_mask) ) + if ( !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) gnttab_clear_flag(_GTF_writing, status); - if ( !(act->pin & GNTPIN_hstr_mask) ) + if ( !act->pin ) gnttab_clear_flag(_GTF_reading, status); } @@ -2318,7 +2318,7 @@ __acquire_grant_for_copy( unlock_out_clear: if ( !(readonly) && - !(act->pin & GNTPIN_hstw_mask) ) + !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) gnttab_clear_flag(_GTF_writing, status); if ( !act->pin ) debian/patches/xsa172.patch0000664000000000000000000000317112725264471012701 0ustar x86: fix information leak on AMD CPUs The fix for XSA-52 was wrong, and so was the change synchronizing that new behavior to the FXRSTOR logic: AMD's manuals explictly state that writes to the ES bit are ignored, and it instead gets calculated from the exception and mask bits (it gets set whenever there is an unmasked exception, and cleared otherwise). Hence we need to follow that model in our workaround. This is XSA-172. The first hunk (xen/arch/x86/i387.c:fpu_fxrstor) is CVE-2016-3159. The second hunk (xen/arch/x86/xstate.c:xrstor) is CVE-2016-3158. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -49,7 +49,7 @@ static inline void fpu_fxrstor(struct vc * 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 ( !(fpu_ctxt->fsw & 0x0080) && + if ( !(fpu_ctxt->fsw & ~fpu_ctxt->fcw & 0x003f) && boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) { asm volatile ( "fnclex\n\t" --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -344,7 +344,7 @@ void xrstor(struct vcpu *v, uint64_t mas * 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) && + !(ptr->fpu_sse.fsw & ~ptr->fpu_sse.fcw & 0x003f) && boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) asm volatile ( "fnclex\n\t" /* clear exceptions */ "ffree %%st(7)\n\t" /* clear stack tag */ debian/patches/xsa170-4.5.patch0000664000000000000000000000611512661613567013207 0ustar x86/VMX: sanitize rIP before re-entering guest ... to prevent guest user mode arranging for a guest crash (due to failed VM entry). (On the AMD system I checked, hardware is doing exactly the canonicalization being added here.) Note that fixing this in an architecturally correct way would be quite a bit more involved: Making the x86 instruction emulator check all branch targets for validity, plus dealing with invalid rIP resulting from update_guest_eip() or incoming directly during a VM exit. The only way to get the latter right would be by not having hardware do the injection. Note further that there are a two early returns from vmx_vmexit_handler(): One (through vmx_failed_vmentry()) leads to domain_crash() anyway, and the other covers real mode only and can neither occur with a non-canonical rIP nor result in an altered rIP, so we don't need to force those paths through the checking logic. This is XSA-170. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Tested-by: Andrew Cooper --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2675,7 +2675,7 @@ void vmx_handle_EOI_induced_exit(struct void vmx_vmexit_handler(struct cpu_user_regs *regs) { unsigned long exit_qualification, exit_reason, idtv_info, intr_info = 0; - unsigned int vector = 0; + unsigned int vector = 0, mode; struct vcpu *v = current; __vmread(GUEST_RIP, ®s->rip); @@ -3219,6 +3219,41 @@ void vmx_vmexit_handler(struct cpu_user_ out: if ( nestedhvm_vcpu_in_guestmode(v) ) nvmx_idtv_handling(); + + /* + * VM entry will fail (causing the guest to get crashed) if rIP (and + * rFLAGS, but we don't have an issue there) doesn't meet certain + * criteria. As we must not allow less than fully privileged mode to have + * such an effect on the domain, we correct rIP in that case (accepting + * this not being architecturally correct behavior, as the injected #GP + * fault will then not see the correct [invalid] return address). + * And since we know the guest will crash, we crash it right away if it + * already is in most privileged mode. + */ + mode = vmx_guest_x86_mode(v); + if ( mode == 8 ? !is_canonical_address(regs->rip) + : regs->rip != regs->_eip ) + { + struct segment_register ss; + + gdprintk(XENLOG_WARNING, "Bad rIP %lx for mode %u\n", regs->rip, mode); + + vmx_get_segment_register(v, x86_seg_ss, &ss); + if ( ss.attr.fields.dpl ) + { + __vmread(VM_ENTRY_INTR_INFO, &intr_info); + if ( !(intr_info & INTR_INFO_VALID_MASK) ) + hvm_inject_hw_exception(TRAP_gp_fault, 0); + /* Need to fix rIP nevertheless. */ + if ( mode == 8 ) + regs->rip = (long)(regs->rip << (64 - VADDR_BITS)) >> + (64 - VADDR_BITS); + else + regs->rip = regs->_eip; + } + else + domain_crash(v->domain); + } } void vmx_vmenter_helper(const struct cpu_user_regs *regs) debian/patches/xsa179-qemut-4.4-0004-vga-update-vga-register-setup-on-vbe-changes.patch0000664000000000000000000000204512725551531025300 0ustar From 5e840e6292825fcae90f6750a8f57bc989e28c5f Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 26 Apr 2016 15:39:22 +0200 Subject: [PATCH 4/5] vga: update vga register setup on vbe changes Call the new vbe_update_vgaregs() function on vbe configuration changes, to make sure vga registers are up-to-date. Signed-off-by: Gerd Hoffmann [Backport to qemu-xen-tradition] Signed-off-by: Andrew Cooper --- hw/vga.c | 1 + 1 file changed, 1 insertion(+) Index: xen-4.4.2/qemu/hw/vga.c =================================================================== --- xen-4.4.2.orig/qemu/hw/vga.c 2016-06-07 15:58:24.560780801 +0200 +++ xen-4.4.2/qemu/hw/vga.c 2016-06-07 15:59:48.748779503 +0200 @@ -640,6 +640,7 @@ static void vbe_ioport_write_data(void * case VBE_DISPI_INDEX_YRES: if (val <= VBE_DISPI_MAX_YRES) { s->vbe_regs[s->vbe_index] = val; + vbe_update_vgaregs(s); } break; case VBE_DISPI_INDEX_BPP: debian/patches/xsa206-4.4-0031-oxenstored-trim-history-in-the-frequent_ops-function.patch0000664000000000000000000000574713104300260026126 0ustar From 26b15d4eb7ac71fcab28a7fca664afa0549c135c Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Tue, 28 Mar 2017 18:57:52 +0100 Subject: [PATCH 31/30] oxenstored: trim history in the frequent_ops function We were trimming the history of commits only at the end of each transaction (regardless of how it ended). Therefore if non-transactional writes were being made but no transactions were being ended, the history would grow indefinitely. Now we trim the history at regular intervals. Signed-off-by: Thomas Sanders --- tools/ocaml/xenstored/history.ml | 6 +++--- tools/ocaml/xenstored/transaction.ml | 8 ++++++-- tools/ocaml/xenstored/xenstored.ml | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml index 4079588..f39565b 100644 --- a/tools/ocaml/xenstored/history.ml +++ b/tools/ocaml/xenstored/history.ml @@ -39,7 +39,8 @@ let mark_symbols () = (* Keep only enough commit-history to protect the running transactions that we are still tracking *) (* There is scope for optimisation here, replacing List.filter with something more efficient, * probably on a different list-like structure. *) -let trim () = +let trim ?txn () = + Transaction.trim_short_running_transactions txn; history := match Transaction.oldest_short_running_transaction () with | None -> [] (* We have no open transaction, so no history is needed *) | Some (_, txn) -> ( @@ -49,8 +50,7 @@ let trim () = let end_transaction txn con tid commit = let success = Connection.end_transaction con tid commit in - Transaction.end_transaction txn; - trim (); + trim ~txn (); success let push (x: history_record) = diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index da4a3e3..23e7ccf 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -106,10 +106,14 @@ let oldest_short_running_transaction () = | x :: xs -> last xs in last !short_running_txns -let end_transaction txn = +let trim_short_running_transactions txn = let cutoff = Unix.gettimeofday () -. !Define.conflict_max_history_seconds in + let keep = match txn with + | None -> (function (start_time, _) -> start_time >= cutoff) + | Some t -> (function (start_time, tx) -> start_time >= cutoff && tx != t) + in short_running_txns := List.filter - (function (start_time, tx) -> start_time >= cutoff && tx != txn) + keep !short_running_txns let make ?(internal=false) id store = diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 92ea99e..c45146d 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -280,6 +280,7 @@ let _ = * than the periodic_ops function *) let frequent_ops () = if Unix.gettimeofday () > !next_frequent_ops then ( + History.trim (); Domains.incr_conflict_credit domains; advance_next_frequent_ops () ) in -- 1.7.9.5 debian/patches/tools-misc-xend-startup.diff0000664000000000000000000000243312276137137016211 0ustar Index: xen-4.4.0~rc3+20140210/tools/python/xen/xend/xend =================================================================== --- xen-4.4.0~rc3+20140210.orig/tools/python/xen/xend/xend 2014-02-10 12:56:03.094676653 +0100 +++ xen-4.4.0~rc3+20140210/tools/python/xen/xend/xend 2014-02-10 12:56:15.482737211 +0100 @@ -71,13 +71,6 @@ def check_user(): 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() @@ -89,18 +82,14 @@ def main(): 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': return daemon.status() debian/patches/xsa184-qemut-master.patch0000664000000000000000000000275012775454555015341 0ustar From 17d8c4e47dfb41cb6778520ff2eab7a11fe12dfd Mon Sep 17 00:00:00 2001 From: P J P Date: Tue, 26 Jul 2016 15:31:59 +0100 Subject: [PATCH] virtio: error out if guest exceeds virtqueue size A broken or malicious guest can submit more requests than the virtqueue size permits. The guest can submit requests without bothering to wait for completion and is therefore not bound by virtqueue size. This requires reusing vring descriptors in more than one request, which is incorrect but possible. Processing a request allocates a VirtQueueElement and therefore causes unbounded memory allocation controlled by the guest. Exit with an error if the guest provides more requests than the virtqueue size permits. This bounds memory allocation and makes the buggy guest visible to the user. Reported-by: Zhenhao Hong Signed-off-by: Stefan Hajnoczi --- hw/virtio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c index c26feff..42897bf 100644 --- a/qemu/hw/virtio.c +++ b/qemu/hw/virtio.c @@ -421,6 +421,11 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) /* When we start there are none of either input nor output. */ elem->out_num = elem->in_num = 0; + if (vq->inuse >= vq->vring.num) { + fprintf(stderr, "Virtqueue size exceeded"); + exit(1); + } + i = head = virtqueue_get_head(vq, vq->last_avail_idx++); do { struct iovec *sg; -- 2.1.4 debian/patches/xsa129-qemut.patch0000664000000000000000000001145512571016626014034 0ustar xen: don't allow guest to control MSI mask register It's being used by the hypervisor. For now simply mimic a device not capable of masking, and fully emulate any accesses a guest may issue nevertheless as simple reads/writes without side effects. This is XSA-129. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -147,6 +147,10 @@ static uint32_t pt_msgaddr64_reg_init(st struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_mask_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); +static uint32_t pt_pending_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset); static uint32_t pt_header_type_reg_init(struct pt_dev *ptdev, @@ -644,7 +648,7 @@ static struct pt_reg_info_tbl pt_emu_reg .size = 2, .init_val = 0x0000, .ro_mask = 0xFF8E, - .emu_mask = 0x007F, + .emu_mask = 0x017F, .init = pt_msgctrl_reg_init, .u.w.read = pt_word_reg_read, .u.w.write = pt_msgctrl_reg_write, @@ -698,6 +702,50 @@ static struct pt_reg_info_tbl pt_emu_reg .u.w.write = pt_msgdata_reg_write, .u.w.restore = NULL, }, + /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */ + { + .offset = PCI_MSI_MASK_32, + .size = 4, + .init_val = 0x00000000, + .ro_mask = 0xFFFFFFFF, + .emu_mask = 0xFFFFFFFF, + .init = pt_mask_reg_init, + .u.dw.read = pt_long_reg_read, + .u.dw.write = pt_long_reg_write, + }, + /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */ + { + .offset = PCI_MSI_MASK_64, + .size = 4, + .init_val = 0x00000000, + .ro_mask = 0xFFFFFFFF, + .emu_mask = 0xFFFFFFFF, + .init = pt_mask_reg_init, + .u.dw.read = pt_long_reg_read, + .u.dw.write = pt_long_reg_write, + }, + /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */ + { + .offset = PCI_MSI_MASK_32 + 4, + .size = 4, + .init_val = 0x00000000, + .ro_mask = 0xFFFFFFFF, + .emu_mask = 0x00000000, + .init = pt_pending_reg_init, + .u.dw.read = pt_long_reg_read, + .u.dw.write = pt_long_reg_write, + }, + /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */ + { + .offset = PCI_MSI_MASK_64 + 4, + .size = 4, + .init_val = 0x00000000, + .ro_mask = 0xFFFFFFFF, + .emu_mask = 0x00000000, + .init = pt_pending_reg_init, + .u.dw.read = pt_long_reg_read, + .u.dw.write = pt_long_reg_write, + }, { .size = 0, }, @@ -3023,6 +3071,42 @@ static uint32_t pt_msgdata_reg_init(stru return PT_INVALID_REG; } +/* this function will be called twice (for 32 bit and 64 bit type) */ +/* initialize Mask register */ +static uint32_t pt_mask_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + uint32_t flags = ptdev->msi->flags; + uint32_t offset = reg->offset; + + if (!(flags & PCI_MSI_FLAGS_MASK_BIT)) + return PT_INVALID_REG; + + if (offset == (flags & PCI_MSI_FLAGS_64BIT ? + PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) + return reg->init_val; + + return PT_INVALID_REG; +} + +/* this function will be called twice (for 32 bit and 64 bit type) */ +/* initialize Pending register */ +static uint32_t pt_pending_reg_init(struct pt_dev *ptdev, + struct pt_reg_info_tbl *reg, uint32_t real_offset) +{ + uint32_t flags = ptdev->msi->flags; + uint32_t offset = reg->offset; + + if (!(flags & PCI_MSI_FLAGS_MASK_BIT)) + return PT_INVALID_REG; + + if (offset == (flags & PCI_MSI_FLAGS_64BIT ? + PCI_MSI_MASK_64 + 4 : PCI_MSI_MASK_32 + 4)) + return reg->init_val; + + return PT_INVALID_REG; +} + /* initialize Message Control register for MSI-X */ static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev, struct pt_reg_info_tbl *reg, uint32_t real_offset) --- a/qemu/hw/pass-through.h +++ b/qemu/hw/pass-through.h @@ -84,6 +84,12 @@ #define PCI_MSI_FLAGS_MASK_BIT 0x0100 #endif +#ifndef PCI_MSI_MASK_32 +/* interrupt masking register */ +#define PCI_MSI_MASK_32 12 +#define PCI_MSI_MASK_64 16 +#endif + #ifndef PCI_EXP_TYPE_PCIE_BRIDGE /* PCI/PCI-X to PCIE Bridge */ #define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 debian/patches/xsa191-4.6.patch0000664000000000000000000001204313035175374013203 0ustar From: Andrew Cooper Subject: x86/hvm: Fix the handling of non-present segments In 32bit, the data segments may be NULL to indicate that the segment is ineligible for use. In both 32bit and 64bit, the LDT selector may be NULL to indicate that the entire LDT is ineligible for use. However, nothing in Xen actually checks for this condition when performing other segmentation checks. (Note however that limit and writeability checks are correctly performed). Neither Intel nor AMD specify the exact behaviour of loading a NULL segment. Experimentally, AMD zeroes all attributes but leaves the base and limit unmodified. Intel zeroes the base, sets the limit to 0xfffffff and resets the attributes to just .G and .D/B. The use of the segment information in the VMCB/VMCS is equivalent to a native pipeline interacting with the segment cache. The present bit can therefore have a subtly different meaning, and it is now cooked to uniformly indicate whether the segment is usable or not. GDTR and IDTR don't have access rights like the other segments, but for consistency, they are treated as being present so no special casing is needed elsewhere in the segmentation logic. AMD hardware does not consider the present bit for %cs and %tr, and will function as if they were present. They are therefore unconditionally set to present when reading information from the VMCB, to maintain the new meaning of usability. Intel hardware has a separate unusable bit in the VMCS segment attributes. This bit is inverted and stored in the present field, so the hvm code can work with architecturally-common state. This is XSA-191. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3666,6 +3666,10 @@ int hvm_virtual_to_linear_addr( * COMPATIBILITY MODE: Apply segment checks and add base. */ + /* Segment not valid for use (cooked meaning of .p)? */ + if ( !reg->attr.fields.p ) + return 0; + switch ( access_type ) { case hvm_access_read: @@ -3871,6 +3875,10 @@ static int hvm_load_segment_selector( hvm_get_segment_register( v, (sel & 4) ? x86_seg_ldtr : x86_seg_gdtr, &desctab); + /* Segment not valid for use (cooked meaning of .p)? */ + if ( !desctab.attr.fields.p ) + goto fail; + /* Check against descriptor table limit. */ if ( ((sel & 0xfff8) + 7) > desctab.limit ) goto fail; --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -620,6 +620,7 @@ static void svm_get_segment_register(str { case x86_seg_cs: memcpy(reg, &vmcb->cs, sizeof(*reg)); + reg->attr.fields.p = 1; reg->attr.fields.g = reg->limit > 0xFFFFF; break; case x86_seg_ds: @@ -653,13 +654,16 @@ static void svm_get_segment_register(str case x86_seg_tr: svm_sync_vmcb(v); memcpy(reg, &vmcb->tr, sizeof(*reg)); + reg->attr.fields.p = 1; reg->attr.fields.type |= 0x2; break; case x86_seg_gdtr: memcpy(reg, &vmcb->gdtr, sizeof(*reg)); + reg->attr.bytes = 0x80; break; case x86_seg_idtr: memcpy(reg, &vmcb->idtr, sizeof(*reg)); + reg->attr.bytes = 0x80; break; case x86_seg_ldtr: svm_sync_vmcb(v); --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -867,10 +867,12 @@ void vmx_get_segment_register(struct vcp reg->sel = sel; reg->limit = limit; - reg->attr.bytes = (attr & 0xff) | ((attr >> 4) & 0xf00); - /* Unusable flag is folded into Present flag. */ - if ( attr & (1u<<16) ) - reg->attr.fields.p = 0; + /* + * Fold VT-x representation into Xen's representation. The Present bit is + * unconditionally set to the inverse of unusable. + */ + reg->attr.bytes = + (!(attr & (1u << 16)) << 7) | (attr & 0x7f) | ((attr >> 4) & 0xf00); /* Adjust for virtual 8086 mode */ if ( v->arch.hvm_vmx.vmx_realmode && seg <= x86_seg_tr @@ -950,11 +952,11 @@ static void vmx_set_segment_register(str } } - attr = ((attr & 0xf00) << 4) | (attr & 0xff); - - /* Not-present must mean unusable. */ - if ( !reg->attr.fields.p ) - attr |= (1u << 16); + /* + * Unfold Xen representation into VT-x representation. The unusable bit + * is unconditionally set to the inverse of present. + */ + attr = (!(attr & (1u << 7)) << 16) | ((attr & 0xf00) << 4) | (attr & 0xff); /* VMX has strict consistency requirement for flag G. */ attr |= !!(limit >> 20) << 15; --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1209,6 +1209,10 @@ protmode_load_seg( &desctab, ctxt)) ) return rc; + /* Segment not valid for use (cooked meaning of .p)? */ + if ( !desctab.attr.fields.p ) + goto raise_exn; + /* Check against descriptor table limit. */ if ( ((sel & 0xfff8) + 7) > desctab.limit ) goto raise_exn; debian/patches/xsa206-4.4-0027-oxenstored-allow-self-conflicts.patch0000664000000000000000000000506213104300260021761 0ustar From 0c7841d03e182585fcb9444b4799f432e2a444cb Mon Sep 17 00:00:00 2001 From: Thomas Sanders Date: Thu, 23 Mar 2017 19:06:54 +0000 Subject: [PATCH 27/30] oxenstored: allow self-conflicts We already avoid inter-domain conflicts but now allow intra-domain conflicts. Although there are no known practical examples of a domain that might perform operations that conflict with its own transactions, this is conceivable, so here we avoid changing those semantics unnecessarily. When a transaction commit fails with a conflict and we look through the history of commits to see which connection(s) to blame, ignore historical commits that were made by the same connection as the failing commit. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Reviewed-by: Jonathan Davies --- tools/ocaml/xenstored/history.ml | 3 ++- tools/ocaml/xenstored/process.ml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml index e941e2b..4079588 100644 --- a/tools/ocaml/xenstored/history.ml +++ b/tools/ocaml/xenstored/history.ml @@ -60,11 +60,12 @@ let push (x: history_record) = | Some d -> if not (Domain.is_free_to_conflict d) then history := x :: !history (* Find the connections from records since commit-count [since] for which [f record] returns [true] *) -let filter_connections ~since ~f = +let filter_connections ~ignore ~since ~f = (* The "mem" call is an optimisation, to avoid calling f if we have picked con already. *) (* Using a hash table rather than a list is to optimise the "mem" call. *) List.fold_left (fun acc hist_rec -> if hist_rec.finish_count > since + && not (hist_rec.con == ignore) && not (Hashtbl.mem acc hist_rec.con) && f hist_rec then Hashtbl.replace acc hist_rec.con (); diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index 698a456..ff2ca65 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -344,7 +344,7 @@ let transaction_replay c t doms cons = then (punish hist_rec.History.con; true) else false ) in - let guilty_cons = History.filter_connections ~since:t.Transaction.start_count ~f:judge_and_sentence in + let guilty_cons = History.filter_connections ~ignore:c ~since:t.Transaction.start_count ~f:judge_and_sentence in if Hashtbl.length guilty_cons = 0 then debug "Found no culprit for conflict in %s: must be self or not in history." con; false ) -- 2.1.4 debian/patches/xsa175-4.4-0010-libxl-Do-not-trust-frontend-for-nic-in-getinfo.patch0000664000000000000000000000537412725264607024427 0ustar From e4c0f9b55819194a501e3ecae6b12188a2db1d01 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 16:31:07 +0100 Subject: [PATCH 10/10] libxl: Do not trust frontend for nic in getinfo libxl_device_nic_getinfo needs to examine devices without trusting frontend-controlled data. So: * Use /libxl to find the backend path. * Parse the backend path to find the backend domid, rather than reading it from the frontend. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 7a8faba..c794d3a 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3155,22 +3155,27 @@ int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic, libxl_nicinfo *nicinfo) { GC_INIT(ctx); - char *dompath, *nicpath; + char *dompath, *nicpath, *libxl_path; char *val; + int rc; dompath = libxl__xs_get_dompath(gc, domid); nicinfo->devid = nic->devid; - nicpath = libxl__sprintf(gc, "%s/device/vif/%d", dompath, nicinfo->devid); + nicpath = GCSPRINTF("%s/device/vif/%d", dompath, nicinfo->devid); + libxl_path = GCSPRINTF("%s/device/vif/%d", + libxl__xs_libxl_path(gc, domid), nicinfo->devid); nicinfo->backend = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/backend", nicpath), NULL); + GCSPRINTF("%s/backend", libxl_path), NULL); if (!nicinfo->backend) { GC_FREE; return ERROR_FAIL; } - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/backend-id", nicpath)); - nicinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; - val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/state", nicpath)); + rc = libxl__backendpath_parse_domid(gc, nicinfo->backend, + &nicinfo->backend_id); + if (rc) goto out; + + val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", nicpath)); nicinfo->state = val ? strtoul(val, NULL, 10) : -1; val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/event-channel", nicpath)); nicinfo->evtch = val ? strtoul(val, NULL, 10) : -1; @@ -3183,8 +3188,10 @@ int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid, val = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/frontend-id", nicinfo->backend)); nicinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + rc = 0; + out: GC_FREE; - return 0; + return rc; } const char *libxl__device_nic_devname(libxl__gc *gc, -- 2.1.4 debian/patches/xsa175-4.4-0007-libxl-Do-not-trust-frontend-for-vtpm-list.patch0000664000000000000000000000452312725264607023561 0ustar From 44aadb912061fc75e41fceb00c67b8d222a2c7c4 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 15:58:32 +0100 Subject: [PATCH 07/10] libxl: Do not trust frontend for vtpm list libxl_device_vtpm_list needs to enumerate and identify devices without trusting frontend-controlled data. So * Use the /libxl path to enumerate vtpms. * Use the /libxl path to find the corresponding backends. * Parse the backend path to find the backend domid. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 18f9f0a..0886d92 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1879,14 +1879,15 @@ libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *n GC_INIT(ctx); libxl_device_vtpm* vtpms = NULL; - char* fe_path = NULL; + char *libxl_path; char** dir = NULL; unsigned int ndirs = 0; + int rc; *num = 0; - fe_path = libxl__sprintf(gc, "%s/device/vtpm", libxl__xs_get_dompath(gc, domid)); - dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); + libxl_path = GCSPRINTF("%s/device/vtpm", libxl__xs_libxl_path(gc, domid)); + dir = libxl__xs_directory(gc, XBT_NULL, libxl_path, &ndirs); if (dir && ndirs) { vtpms = malloc(sizeof(*vtpms) * ndirs); libxl_device_vtpm* vtpm; @@ -1895,16 +1896,15 @@ libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *n char* tmp; const char* be_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s/backend", - fe_path, *dir)); + libxl_path, *dir)); libxl_device_vtpm_init(vtpm); vtpm->devid = atoi(*dir); - tmp = libxl__xs_read(gc, XBT_NULL, - GCSPRINTF("%s/%s/backend-id", - fe_path, *dir)); - vtpm->backend_domid = atoi(tmp); + rc = libxl__backendpath_parse_domid(gc, be_path, + &vtpm->backend_domid); + if (rc) return NULL; tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/uuid", be_path)); if (tmp) { -- 2.1.4 debian/patches/xsa175-4.4-0004-libxl-Do-not-trust-frontend-in-libxl__device_nextid.patch0000664000000000000000000000256312725264607025604 0ustar From 90f14dc5c68f52baeef9722090695a166c7e083d Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 15:30:32 +0100 Subject: [PATCH 04/10] libxl: Do not trust frontend in libxl__device_nextid When selecting the devid for a new device, we should look in /libxl/device for existing devices, not in the frontend area. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index e2a5be3..b52e63e 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1743,15 +1743,16 @@ out: /* common function to get next device id */ static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device) { - char *dompath, **l; + char *libxl_dom_path, **l; unsigned int nb; int nextid = -1; - if (!(dompath = libxl__xs_get_dompath(gc, domid))) + if (!(libxl_dom_path = libxl__xs_libxl_path(gc, domid))) return nextid; l = libxl__xs_directory(gc, XBT_NULL, - GCSPRINTF("%s/device/%s", dompath, device), &nb); + GCSPRINTF("%s/device/%s", libxl_dom_path, device), + &nb); if (l == NULL || nb == 0) nextid = 0; else -- 2.1.4 debian/patches/xsa178-xen4.4-0012-libxl-Do-not-trust-backend-for-nic-in-devid_to_devic.patch0000664000000000000000000000314612725542005026215 0ustar From 9b2061daa55fe42470435cdfd0529203a0ad1e40 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 4 May 2016 16:20:05 +0100 Subject: [PATCH 12/16] libxl: Do not trust backend for nic in devid_to_device libxl_devid_to_device_nic should read the information it needs from the /libxl/device path, not the backend. This is part of XSA-178. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu Signed-off-by: Stefan Bader --- tools/libxl/libxl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index d20924c..ec141b5 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3081,7 +3081,7 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, int devid, libxl_device_nic *nic) { GC_INIT(ctx); - char *libxl_dom_path, *path; + char *libxl_dom_path, *libxl_path; int rc = ERROR_FAIL; libxl_device_nic_init(nic); @@ -3089,13 +3089,9 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, if (!libxl_dom_path) goto out; - path = libxl__xs_read(gc, XBT_NULL, - GCSPRINTF("%s/device/vif/%d/backend", libxl_dom_path, - devid)); - if (!path) - goto out; + libxl_path = GCSPRINTF("%s/device/vif/%d", libxl_dom_path, devid); - rc = libxl__device_nic_from_xenstore(gc, path, nic); + rc = libxl__device_nic_from_xenstore(gc, libxl_path, nic); if (rc) goto out; rc = 0; -- 1.9.1 debian/patches/tools-libxl-abiname.diff0000664000000000000000000000654612305377517015340 0ustar Index: xen-4.4.0/tools/libxl/Makefile =================================================================== --- xen-4.4.0.orig/tools/libxl/Makefile 2014-03-04 17:27:46.140995048 +0100 +++ xen-4.4.0/tools/libxl/Makefile 2014-03-04 17:28:59.685354588 +0100 @@ -5,12 +5,6 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 4.4 -MINOR = 0 - -XLUMAJOR = 4.3 -XLUMINOR = 0 - CFLAGS += -Werror -Wno-format-zero-length -Wmissing-declarations \ -Wno-declaration-after-statement -Wformat-nonliteral CFLAGS += -I. -fPIC @@ -185,29 +179,23 @@ _libxl_type%.h _libxl_type%_json.h _libx $(call move-if-changed,__libxl_type$*_json.h,_libxl_type$*_json.h) $(call move-if-changed,__libxl_type$*.c,_libxl_type$*.c) -libxenlight.so: libxenlight.so.$(MAJOR) - ln -sf $< $@ - -libxenlight.so.$(MAJOR): libxenlight.so.$(MAJOR).$(MINOR) +libxenlight.so: libxenlight-$(XEN_VERSION).so ln -sf $< $@ -libxenlight.so.$(MAJOR).$(MINOR): $(LIBXL_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) +libxenlight-$(XEN_VERSION).so: $(LIBXL_OBJS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) libxenlight_test.so: $(LIBXL_OBJS) $(LIBXL_TEST_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight-$(XEN_VERSION).so $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) libxenlight.a: $(LIBXL_OBJS) $(AR) rcs libxenlight.a $^ -libxlutil.so: libxlutil.so.$(XLUMAJOR) - ln -sf $< $@ - -libxlutil.so.$(XLUMAJOR): libxlutil.so.$(XLUMAJOR).$(XLUMINOR) +libxlutil.so: libxlutil-$(XEN_VERSION).so ln -sf $< $@ -libxlutil.so.$(XLUMAJOR).$(XLUMINOR): $(LIBXLU_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxlutil.so.$(XLUMAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXLU_LIBS) $(APPEND_LDFLAGS) +libxlutil-$(XEN_VERSION).so: $(LIBXLU_OBJS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXLU_LIBS) $(APPEND_LDFLAGS) libxlutil.a: $(LIBXLU_OBJS) $(AR) rcs libxlutil.a $^ @@ -234,13 +222,11 @@ install: all $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_PROG) xl $(DESTDIR)$(SBINDIR) $(INSTALL_PROG) libxl-save-helper $(DESTDIR)$(PRIVATE_BINDIR) - $(INSTALL_PROG) libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) - ln -sf libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenlight.so.$(MAJOR) - ln -sf libxenlight.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenlight.so + $(INSTALL_PROG) libxenlight-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR) + ln -sf libxenlight-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR)/libxenlight.so $(INSTALL_DATA) libxenlight.a $(DESTDIR)$(LIBDIR) - $(INSTALL_PROG) libxlutil.so.$(XLUMAJOR).$(XLUMINOR) $(DESTDIR)$(LIBDIR) - ln -sf libxlutil.so.$(XLUMAJOR).$(XLUMINOR) $(DESTDIR)$(LIBDIR)/libxlutil.so.$(XLUMAJOR) - ln -sf libxlutil.so.$(XLUMAJOR) $(DESTDIR)$(LIBDIR)/libxlutil.so + $(INSTALL_PROG) libxlutil-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR) + ln -sf libxlutil-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR)/libxlutil.so $(INSTALL_DATA) libxlutil.a $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) libxl.h libxl_event.h libxl_json.h _libxl_types.h _libxl_types_json.h _libxl_list.h libxl_utils.h libxl_uuid.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) bash-completion $(DESTDIR)$(BASH_COMPLETION_DIR)/xl.sh debian/patches/xsa208-qemut.patch0000664000000000000000000000362313104305546014023 0ustar From 8f63265efeb6f92e63f7e749cb26131b68b20df7 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Mon, 13 Feb 2017 15:22:15 +0000 Subject: [PATCH] cirrus: fix oob access issue (CVE-2017-2615) When doing bitblt copy in backward mode, we should minus the blt width first just like the adding in the forward mode. This can avoid the oob access of the front of vga's vram. This is XSA-208. upstream-commit-id: 62d4c6bd5263bb8413a06c80144fc678df6dfb64 Signed-off-by: Li Qiang { kraxel: with backward blits (negative pitch) addr is the topmost address, so check it as-is against vram size ] [ This is CVE-2017-2615 / XSA-208 - Ian Jackson ] Cc: qemu-stable@nongnu.org Cc: P J P Cc: Laszlo Ersek Cc: Paolo Bonzini Cc: Wolfgang Bumiller Fixes: d3532a0db02296e687711b8cdc7791924efccea0 (CVE-2014-8106) Signed-off-by: Gerd Hoffmann Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com Reviewed-by: Laszlo Ersek Signed-off-by: Stefano Stabellini Signed-off-by: Ian Jackson --- hw/cirrus_vga.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index e6c3893..364e22d 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -308,10 +308,9 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s, { if (pitch < 0) { int64_t min = addr - + ((int64_t)s->cirrus_blt_height-1) * pitch; - int32_t max = addr - + s->cirrus_blt_width; - if (min < 0 || max >= s->vram_size) { + + ((int64_t)s->cirrus_blt_height - 1) * pitch + - s->cirrus_blt_width; + if (min < -1 || addr >= s->vram_size) { return true; } } else { -- 2.1.4 debian/patches/xsa175-4.4-0003-libxl-Do-not-trust-frontend-in-libxl__devices_destro.patch0000664000000000000000000000600012725264607025761 0ustar From ef216637a72ce30661d28a47ccc7464869baa398 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 May 2016 18:39:36 +0100 Subject: [PATCH 03/10] libxl: Do not trust frontend in libxl__devices_destroy We need to enumerate the devices we have provided to a domain, without trusting the guest-writeable (or, at least, guest-deletable) frontend paths. Instead, enumerate via, and read the backend path from, /libxl. The console /libxl path is regular, so the special case for console 0 is not relevant any more: /libxl/GUEST/device/console/0 will be found, and then libxl__device_destroy will DTRT to the right frontend path. This is part of XSA-175. Signed-off-by: Ian Jackson Reviewed-by: Wei Liu --- tools/libxl/libxl_device.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index b500264..e7650d0 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -665,7 +665,7 @@ void libxl__devices_destroy(libxl__egc *egc, libxl__devices_remove_state *drs) libxl__multidev_begin(ao, multidev); multidev->callback = devices_remove_callback; - path = GCSPRINTF("/local/domain/%d/device", domid); + path = GCSPRINTF("/libxl/%d/device", domid); kinds = libxl__xs_directory(gc, XBT_NULL, path, &num_kinds); if (!kinds) { if (errno != ENOENT) { @@ -678,12 +678,12 @@ void libxl__devices_destroy(libxl__egc *egc, libxl__devices_remove_state *drs) if (libxl__device_kind_from_string(kinds[i], &kind)) continue; - path = GCSPRINTF("/local/domain/%d/device/%s", domid, kinds[i]); + path = GCSPRINTF("/libxl/%d/device/%s", domid, kinds[i]); devs = libxl__xs_directory(gc, XBT_NULL, path, &num_dev_xsentries); if (!devs) continue; for (j = 0; j < num_dev_xsentries; j++) { - path = GCSPRINTF("/local/domain/%d/device/%s/%s/backend", + path = GCSPRINTF("/libxl/%d/device/%s/%s/backend", domid, kinds[i], devs[j]); path = libxl__xs_read(gc, XBT_NULL, path); GCNEW(dev); @@ -708,22 +708,6 @@ void libxl__devices_destroy(libxl__egc *egc, libxl__devices_remove_state *drs) } } - /* console 0 frontend directory is not under /local/domain//device */ - path = GCSPRINTF("/local/domain/%d/console/backend", domid); - path = libxl__xs_read(gc, XBT_NULL, path); - GCNEW(dev); - if (path && strcmp(path, "") && - libxl__parse_backend_path(gc, path, dev) == 0) { - dev->domid = domid; - dev->kind = LIBXL__DEVICE_KIND_CONSOLE; - dev->devid = 0; - - /* Currently console devices can be destroyed synchronously by just - * removing xenstore entries, this is what libxl__device_destroy does. - */ - libxl__device_destroy(gc, dev); - } - out: libxl__multidev_prepared(egc, multidev, rc); } -- 2.1.4 debian/patches/xsa206-4.4-0004-oxenstored-perform-a-3-way-merge-of-the-quota-after-.patch0000664000000000000000000001042513104300257025340 0ustar From a0cdc0e823117ff32560822e16f44260983b5142 Mon Sep 17 00:00:00 2001 From: Jerome Maloberti Date: Fri, 24 Mar 2017 16:57:40 +0000 Subject: [PATCH 04/30] oxenstored: perform a 3-way merge of the quota after a transaction At a beginning of a transaction, the quotas from the global store are duplicated and modified by the transaction. If during the transaction, an action associated to no transaction is concurrently executed, the quotas of the global store are updated, and then the updates are lost when the transaction merges. We fix this problem by keeping another copy of the quota at the beginning of the transaction, and performing a 3-way merge between the quotas from the transaction and the "original" copy of the quota onto the quota of the global store. Reported-by: Juergen Gross Signed-off-by: Jerome Maloberti Signed-off-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/quota.ml | 5 +++++ tools/ocaml/xenstored/store.ml | 13 +++++-------- tools/ocaml/xenstored/transaction.ml | 4 +++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/ocaml/xenstored/quota.ml b/tools/ocaml/xenstored/quota.ml index c668302..e6953c6 100644 --- a/tools/ocaml/xenstored/quota.ml +++ b/tools/ocaml/xenstored/quota.ml @@ -81,3 +81,8 @@ let add_entry quota id = let add quota diff = Hashtbl.iter (fun id nb -> set_entry quota id (get_entry quota id + nb)) diff.cur + +let merge orig_quota mod_quota dest_quota = + Hashtbl.iter (fun id nb -> let diff = nb - (get_entry orig_quota id) in + if diff <> 0 then + set_entry dest_quota id ((get_entry dest_quota id) + diff)) mod_quota.cur diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml index 3efe515..223ee21 100644 --- a/tools/ocaml/xenstored/store.ml +++ b/tools/ocaml/xenstored/store.ml @@ -188,20 +188,17 @@ let rec get_deepest_existing_node node = function with Not_found -> node, false let set_node rnode path nnode = - let quota = Quota.create () in - if !Quota.activate then Node.recurse (fun node -> Quota.add_entry quota (Node.get_owner node)) nnode; if path = [] then - nnode, quota + nnode else let set_node node name = try let ent = Node.find node name in - if !Quota.activate then Node.recurse (fun node -> Quota.del_entry quota (Node.get_owner node)) ent; Node.replace_child node ent nnode with Not_found -> Node.add_child node nnode in - apply_modify rnode path set_node, quota + apply_modify rnode path set_node (* read | ls | getperms use this *) let rec lookup node path fct = @@ -375,10 +372,10 @@ let dump_buffer store = dump_store_buf store.root (* modifying functions with quota udpate *) -let set_node store path node = - let root, quota_diff = Path.set_node store.root path node in +let set_node store path node orig_quota mod_quota = + let root = Path.set_node store.root path node in store.root <- root; - Quota.add store.quota quota_diff + Quota.merge orig_quota mod_quota store.quota let write store perm path value = let node, existing = get_deepest_existing_node store path in diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml index e59d681..77de4e8 100644 --- a/tools/ocaml/xenstored/transaction.ml +++ b/tools/ocaml/xenstored/transaction.ml @@ -74,6 +74,7 @@ type ty = No | Full of (int * Store.Node.t * Store.t) type t = { ty: ty; store: Store.t; + quota: Quota.t; mutable ops: (Xenbus.Xb.Op.operation * Store.Path.t) list; mutable read_lowpath: Store.Path.t option; mutable write_lowpath: Store.Path.t option; @@ -84,6 +85,7 @@ let make id store = { ty = ty; store = if id = none then store else Store.copy store; + quota = Quota.copy store.Store.quota; ops = []; read_lowpath = None; write_lowpath = None; @@ -155,7 +157,7 @@ let commit ~con t = (* it has to be in the store, otherwise it means bugs in the lowpath registration. we don't need to handle none. *) - maybe (fun n -> Store.set_node cstore p n) n; + maybe (fun n -> Store.set_node cstore p n t.quota store.Store.quota) n; Logging.write_coalesce ~tid:(get_id t) ~con (Store.Path.to_string p); ) t.write_lowpath; maybe (fun p -> -- 2.1.4 debian/patches/xsa237-4.5-0002-x86-enforce-proper-privilege-when-mapping-pIRQ-s.patch0000664000000000000000000000411613167425756024570 0ustar From: Jan Beulich Subject: x86: enforce proper privilege when (un)mapping pIRQ-s (Un)mapping of IRQs, just like other RESOURCE__ADD* / RESOURCE__REMOVE* actions (in FLASK terms) should be XSM_DM_PRIV rather than XSM_TARGET. This in turn requires bypassing the XSM check in physdev_unmap_pirq() for the HVM emuirq case just like is being done in physdev_map_pirq(). The primary goal security wise, however, is to no longer allow HVM guests, by specifying their own domain ID instead of DOMID_SELF, to enter code paths intended for PV guest and the control domains of HVM guests only. This is part of XSA-237. Signed-off-by: Jan Beulich Reviewed-by: George Dunlap --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -110,7 +110,7 @@ int physdev_map_pirq(domid_t domid, int if ( d == NULL ) return -ESRCH; - ret = xsm_map_domain_pirq(XSM_TARGET, d); + ret = xsm_map_domain_pirq(XSM_DM_PRIV, d); if ( ret ) goto free_domain; @@ -255,13 +255,14 @@ int physdev_map_pirq(domid_t domid, int int physdev_unmap_pirq(domid_t domid, int pirq) { struct domain *d; - int ret; + int ret = 0; d = rcu_lock_domain_by_any_id(domid); if ( d == NULL ) return -ESRCH; - ret = xsm_unmap_domain_pirq(XSM_TARGET, d); + if ( domid != DOMID_SELF || !is_hvm_domain(d) ) + ret = xsm_unmap_domain_pirq(XSM_DM_PRIV, d); if ( ret ) goto free_domain; --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -429,7 +429,7 @@ static XSM_INLINE char *xsm_show_irq_sid static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d) { - XSM_ASSERT_ACTION(XSM_TARGET); + XSM_ASSERT_ACTION(XSM_DM_PRIV); return xsm_default_action(action, current->domain, d); } @@ -441,7 +441,7 @@ static XSM_INLINE int xsm_map_domain_irq static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d) { - XSM_ASSERT_ACTION(XSM_TARGET); + XSM_ASSERT_ACTION(XSM_DM_PRIV); return xsm_default_action(action, current->domain, d); } debian/patches/xsa206-4.4-0003-oxenstored-exempt-dom0-from-domU-node-quotas.patch0000664000000000000000000000443613104300257024175 0ustar From 59bb62aa888cd4b94510e4d16003077ab1d77e9b Mon Sep 17 00:00:00 2001 From: Vincent Bernardoff Date: Fri, 24 Mar 2017 16:57:02 +0000 Subject: [PATCH 03/30] oxenstored: exempt dom0 from domU node quotas If a domU has exhausted its quota we still want the toolstack in dom0 to be able to create new nodes in places like /local/domain/%d/control/shutdown Without this patch, a domU which has exhausted its quota can only be powered off, which is not as good as being able to request a clean shutdown. Reported-by: Juergen Gross Signed-off-by: Thomas Sanders Signed-off-by: Euan Harris Acked-by: David Scott --- tools/ocaml/xenstored/store.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml index cac0b44..3efe515 100644 --- a/tools/ocaml/xenstored/store.ml +++ b/tools/ocaml/xenstored/store.ml @@ -383,7 +383,7 @@ let set_node store path node = let write store perm path value = let node, existing = get_deepest_existing_node store path in let owner = Node.get_owner node in - if existing then + if existing || (Perms.Connection.is_dom0 perm) then (* Only check the string length limit *) Quota.check store.quota (-1) (String.length value) else @@ -398,7 +398,7 @@ let mkdir store perm path = let node, existing = get_deepest_existing_node store path in let owner = Node.get_owner node in (* It's upt to the mkdir logic to decide what to do with existing path *) - if not existing then Quota.check store.quota owner 0; + if not (existing || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota owner 0; store.root <- path_mkdir store perm path; Quota.add_entry store.quota owner @@ -416,7 +416,7 @@ let setperms store perm path nperms = | Some node -> let old_owner = Node.get_owner node in let new_owner = Perms.Node.get_owner nperms in - if old_owner <> new_owner then Quota.check store.quota new_owner 0; + if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0; store.root <- path_setperms store perm path nperms; Quota.del_entry store.quota old_owner; Quota.add_entry store.quota new_owner -- 2.1.4 debian/patches/xsa237-4.4-0005-x86-FLASK-fix-unmap-domain-IRQ-XSM-hook.patch0000664000000000000000000000230413167427476022260 0ustar diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index be7c753..a02a45f 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -2132,7 +2132,8 @@ int unmap_domain_pirq(struct domain *d, int pirq) nr = msi_desc->msi.nvec; } - ret = xsm_unmap_domain_irq(XSM_HOOK, d, irq, msi_desc); + ret = xsm_unmap_domain_irq(XSM_HOOK, d, irq, + msi_desc ? msi_desc->dev : NULL); if ( ret ) goto done; diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index d94ab77..f6c78dd 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -873,11 +873,11 @@ static int flask_unmap_domain_irq (struct domain *d, int irq, void *data) { u32 sid; int rc = -EPERM; - struct msi_info *msi = data; + const struct pci_dev *pdev = data; struct avc_audit_data ad; - if ( irq >= nr_static_irqs && msi ) { - u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn; + if ( irq >= nr_static_irqs && pdev ) { + u32 machine_bdf = (pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn; AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = machine_bdf; rc = security_device_sid(machine_bdf, &sid); debian/patches/xsa126-qemut.patch0000664000000000000000000001252612510722513014021 0ustar xen: limit guest control of PCI command register Otherwise the guest can abuse that control to cause e.g. PCIe Unsupported Request responses (by disabling memory and/or I/O decoding and subsequently causing [CPU side] accesses to the respective address ranges), which (depending on system configuration) may be fatal to the host. This is CVE-2015-2756 / XSA-126. Signed-off-by: Jan Beulich Reviewed-by: Stefano Stabellini Acked-by: Ian Campbell --- a/qemu/hw/pass-through.c +++ b/qemu/hw/pass-through.c @@ -172,9 +172,6 @@ static int pt_word_reg_read(struct pt_de static int pt_long_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint32_t *value, uint32_t valid_mask); -static int pt_cmd_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t valid_mask); static int pt_bar_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint32_t *value, uint32_t valid_mask); @@ -286,9 +283,9 @@ static struct pt_reg_info_tbl pt_emu_reg .size = 2, .init_val = 0x0000, .ro_mask = 0xF880, - .emu_mask = 0x0740, + .emu_mask = 0x0743, .init = pt_common_reg_init, - .u.w.read = pt_cmd_reg_read, + .u.w.read = pt_word_reg_read, .u.w.write = pt_cmd_reg_write, .u.w.restore = pt_cmd_reg_restore, }, @@ -1905,7 +1902,7 @@ static int pt_dev_is_virtfn(struct pci_d return rc; } -static int pt_register_regions(struct pt_dev *assigned_device) +static int pt_register_regions(struct pt_dev *assigned_device, uint16_t *cmd) { int i = 0; uint32_t bar_data = 0; @@ -1925,17 +1922,26 @@ static int pt_register_regions(struct pt /* Register current region */ if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_IO ) + { pci_register_io_region((PCIDevice *)assigned_device, i, (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO, pt_ioport_map); + *cmd |= PCI_COMMAND_IO; + } else if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_MEM_PREFETCH ) + { pci_register_io_region((PCIDevice *)assigned_device, i, (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH, pt_iomem_map); + *cmd |= PCI_COMMAND_MEMORY; + } else + { pci_register_io_region((PCIDevice *)assigned_device, i, (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM, pt_iomem_map); + *cmd |= PCI_COMMAND_MEMORY; + } PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n", (uint32_t)(pci_dev->size[i]), @@ -3263,27 +3269,6 @@ static int pt_long_reg_read(struct pt_de return 0; } -/* read Command register */ -static int pt_cmd_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t valid_emu_mask = 0; - uint16_t emu_mask = reg->emu_mask; - - if ( ptdev->is_virtfn ) - emu_mask |= PCI_COMMAND_MEMORY; - if ( pt_is_iomul(ptdev) ) - emu_mask |= PCI_COMMAND_IO; - - /* emulate word register */ - valid_emu_mask = emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); - - return 0; -} - /* read BAR */ static int pt_bar_reg_read(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -3418,19 +3403,13 @@ static int pt_cmd_reg_write(struct pt_de uint16_t writable_mask = 0; uint16_t throughable_mask = 0; uint16_t wr_value = *value; - uint16_t emu_mask = reg->emu_mask; - - if ( ptdev->is_virtfn ) - emu_mask |= PCI_COMMAND_MEMORY; - if ( pt_is_iomul(ptdev) ) - emu_mask |= PCI_COMMAND_IO; /* modify emulate register */ writable_mask = ~reg->ro_mask & valid_mask; cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* create value for writing to I/O device register */ - throughable_mask = ~emu_mask & valid_mask; + throughable_mask = ~reg->emu_mask & valid_mask; if (*value & PCI_COMMAND_DISABLE_INTx) { @@ -4211,6 +4190,7 @@ static struct pt_dev * register_real_dev struct pt_dev *assigned_device = NULL; struct pci_dev *pci_dev; uint8_t e_device, e_intx; + uint16_t cmd = 0; char *key, *val; int msi_translate, power_mgmt; @@ -4300,7 +4280,7 @@ static struct pt_dev * register_real_dev assigned_device->dev.config[i] = pci_read_byte(pci_dev, i); /* Handle real device's MMIO/PIO BARs */ - pt_register_regions(assigned_device); + pt_register_regions(assigned_device, &cmd); /* Setup VGA bios for passthroughed gfx */ if ( setup_vga_pt(assigned_device) < 0 ) @@ -4378,6 +4358,10 @@ static struct pt_dev * register_real_dev } out: + if (cmd) + pci_write_word(pci_dev, PCI_COMMAND, + *(uint16_t *)(&assigned_device->dev.config[PCI_COMMAND]) | cmd); + PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n" "IRQ type = %s\n", r_bus, r_dev, r_func, assigned_device->msi_trans_en? "MSI-INTx":"INTx"); debian/patches/xsa135-qemut-2.patch0000664000000000000000000000304312571017610014154 0ustar From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001 From: Petr Matousek Date: Sun, 24 May 2015 10:53:44 +0200 Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx 4096 is the maximum length per TMD and it is also currently the size of the relay buffer pcnet driver uses for sending the packet data to QEMU for further processing. With packet spanning multiple TMDs it can happen that the overall packet size will be bigger than sizeof(buffer), which results in memory corruption. Fix this by only allowing to queue maximum sizeof(buffer) bytes. This is CVE-2015-3209. Signed-off-by: Petr Matousek Reported-by: Matt Tait Reviewed-by: Peter Maydell Reviewed-by: Stefan Hajnoczi --- hw/pcnet.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/pcnet.c b/hw/pcnet.c index bdfd38f..6d32e4c 100644 --- a/qemu/hw/pcnet.c +++ b/qemu/hw/pcnet.c @@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s) } bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); + + /* if multi-tmd packet outsizes s->buffer then skip it silently. + Note: this is not what real hw does */ + if (s->xmit_pos + bcnt > sizeof(s->buffer)) { + s->xmit_pos = -1; + goto txdone; + } + s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); s->xmit_pos += bcnt; -- 2.1.0 debian/patches/xsa127-4.x.patch0000664000000000000000000000340012510722526013273 0ustar domctl: don't allow a toolstack domain to call domain_pause() on itself These DOMCTL subops were accidentally declared safe for disaggregation in the wake of XSA-77. This is XSA-127. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Acked-by: Ian Campbell Index: xen-4.4.1/xen/arch/x86/domctl.c =================================================================== --- xen-4.4.1.orig/xen/arch/x86/domctl.c 2015-04-07 11:37:20.544537268 +0200 +++ xen-4.4.1/xen/arch/x86/domctl.c 2015-04-07 11:37:20.532537268 +0200 @@ -955,6 +955,10 @@ long arch_do_domctl( { xen_guest_tsc_info_t info; + ret = -EINVAL; + if ( d == current->domain ) /* no domain_pause() */ + break; + domain_pause(d); tsc_get_info(d, &info.tsc_mode, &info.elapsed_nsec, @@ -970,6 +974,10 @@ long arch_do_domctl( case XEN_DOMCTL_settscinfo: { + ret = -EINVAL; + if ( d == current->domain ) /* no domain_pause() */ + break; + domain_pause(d); tsc_set_info(d, domctl->u.tsc_info.info.tsc_mode, domctl->u.tsc_info.info.elapsed_nsec, Index: xen-4.4.1/xen/common/domctl.c =================================================================== --- xen-4.4.1.orig/xen/common/domctl.c 2015-04-07 11:37:20.544537268 +0200 +++ xen-4.4.1/xen/common/domctl.c 2015-04-07 11:37:20.540537268 +0200 @@ -395,8 +395,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_resumedomain: { - domain_resume(d); - ret = 0; + if ( d == current->domain ) /* no domain_pause() */ + ret = -EINVAL; + else + domain_resume(d); } break; debian/patches/tools-libxl-prefix.diff0000664000000000000000000000617412305372154015226 0ustar Index: xen-4.4.0/tools/libxl/Makefile =================================================================== --- xen-4.4.0.orig/tools/libxl/Makefile 2014-03-04 16:36:45.830033949 +0100 +++ xen-4.4.0/tools/libxl/Makefile 2014-03-04 16:42:31.191722330 +0100 @@ -12,6 +12,8 @@ CFLAGS += -I. -fPIC ifeq ($(CONFIG_Linux),y) LIBUUID_LIBS += -luuid endif +LDFLAGS_XL = $(call LDFLAGS_RPATH,../lib) +LDFLAGS_LIBXL = $(call LDFLAGS_RPATH) LIBXL_LIBS = LIBXL_LIBS = $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS) @@ -183,10 +185,10 @@ libxenlight.so: libxenlight-$(XEN_VERSIO ln -sf $< $@ libxenlight-$(XEN_VERSION).so: $(LIBXL_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG),$@ $(LDFLAGS_LIBXL) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) libxenlight_test.so: $(LIBXL_OBJS) $(LIBXL_TEST_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight-$(XEN_VERSION).so $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight-$(XEN_VERSION).so $(LDFLAGS_LIBXL) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXL_LIBS) $(APPEND_LDFLAGS) libxenlight.a: $(LIBXL_OBJS) $(AR) rcs libxenlight.a $^ @@ -201,7 +203,7 @@ libxlutil.a: $(LIBXLU_OBJS) $(AR) rcs libxlutil.a $^ xl: $(XL_OBJS) libxlutil.so libxenlight.so - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxenctrl) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $(LDFLAGS_XL) -o $@ $(XL_OBJS) libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxenctrl) -lyajl $(APPEND_LDFLAGS) test_%: test_%.o test_common.o libxlutil.so libxenlight_test.so $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxenctrl) -lyajl $(APPEND_LDFLAGS) @@ -214,13 +216,12 @@ testidl: testidl.o libxlutil.so libxenli .PHONY: install install: all - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DIR) $(DESTDIR)$(BASH_COMPLETION_DIR) $(INSTALL_DIR) $(DESTDIR)$(XEN_RUN_DIR) $(INSTALL_DIR) $(DESTDIR)$(PRIVATE_BINDIR) - $(INSTALL_PROG) xl $(DESTDIR)$(SBINDIR) + $(INSTALL_PROG) xl $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_PROG) libxl-save-helper $(DESTDIR)$(PRIVATE_BINDIR) $(INSTALL_PROG) libxenlight-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR) ln -sf libxenlight-$(XEN_VERSION).so $(DESTDIR)$(LIBDIR)/libxenlight.so Index: xen-4.4.0/tools/xenstat/libxenstat/Makefile =================================================================== --- xen-4.4.0.orig/tools/xenstat/libxenstat/Makefile 2014-03-04 16:37:02.198113965 +0100 +++ xen-4.4.0/tools/xenstat/libxenstat/Makefile 2014-03-04 16:37:08.482144687 +0100 @@ -53,7 +53,7 @@ $(SHLIB): $(OBJECTS-y) install: all $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) $(LIB) $(DESTDIR)$(LIBDIR)/libxenstat.a - $(INSTALL_PROG) src/libxenstat.so $(DESTDIR)$(LIBDIR) + $(INSTALL_PROG) src/libxenstat.so $(DESTDIR)$(PRIVATE_LIBDIR) PYLIB=bindings/swig/python/_xenstat.so PYMOD=bindings/swig/python/xenstat.py debian/xen-utils-common.postrm0000664000000000000000000000053211756646550013673 0ustar #!/bin/sh set -e case "$1" in purge) rmdir --ignore-fail-on-non-empty /var/log/xen ;; remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit ;; esac dpkg-maintscript-helper mv_conffile /etc/init.d/xend /etc/init.d/xen 4.1.2-4~ -- "$@" #DEBHELPER# exit 0 debian/bin/0000775000000000000000000000000012212071061007730 5ustar debian/bin/gencontrol.py0000775000000000000000000001202012012256702012457 0ustar #!/usr/bin/env python import os, sys sys.path.append(os.path.join(sys.path[0], "../lib/python")) from debian_xen.debian import VersionXen from debian_linux.config import ConfigCoreHierarchy from debian_linux.debian import Changelog, PackageArchitecture from debian_linux.gencontrol import Gencontrol as Base from debian_linux.utils import Templates class Gencontrol(Base): config_schema = { 'description': { } } def __init__(self): super(Gencontrol, self).__init__(ConfigCoreHierarchy(self.config_schema, ["debian/arch"]), Templates(["debian/templates"])) self.process_changelog() def do_main_setup(self, vars, makeflags, extra): makeflags.update({ 'VERSION': self.version.xen_version, }) def do_arch_setup(self, vars, makeflags, arch, extra): config_entry = self.config.merge('base', arch) config_entry_description = self.config.merge('description', arch) for i in ( ('xen-arch', 'XEN_ARCH'), ): makeflags[i[1]] = config_entry[i[0]] def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): packages_main = self.process_packages(self.templates["control.main"], vars) packages_utils = self.process_packages(self.templates["control.utils"], vars) for package in packages_main + packages_utils: name = package['Package'] if name in packages: package = packages.get(name) else: packages.append(package) arches = package.setdefault('Architecture', PackageArchitecture()) if 'all' not in arches: arches.add(arch) package_utils_name = packages_utils[0]['Package'] for i in ('postinst', 'prerm', 'lintian-overrides'): j = self.substitute(self.templates["xen-utils.%s" % i], vars) file("debian/%s.%s" % (package_utils_name, i), 'w').write(j) cmds_binary_arch = ["$(MAKE) -f debian/rules.real binary-arch-arch %s" % makeflags] cmds_build = ["$(MAKE) -f debian/rules.real build-arch-arch %s" % makeflags] cmds_setup = ["$(MAKE) -f debian/rules.real setup-arch %s" % makeflags] makefile.add('binary-arch_%s_real' % arch, cmds = cmds_binary_arch) makefile.add('build-arch_%s_real' % arch, cmds = cmds_build) makefile.add('setup_%s_real' % arch, cmds = cmds_setup) def do_flavour_setup(self, vars, makeflags, arch, featureset, flavour, extra): config_entry = self.config.merge('base', arch, featureset, flavour) config_description = self.config.merge('description', arch, featureset, flavour) vars['class'] = config_description['hardware'] vars['longclass'] = config_description.get('hardware-long') or vars['class'] for i in ( ('xen-arch', 'XEN_ARCH'), ): if config_entry.has_key(i[0]): makeflags[i[1]] = config_entry[i[0]] def do_flavour_packages(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra): hypervisor = self.templates["control.hypervisor"] system_latest = self.templates["control.system.latest"] if not vars.has_key('desc'): vars['desc'] = '' packages_own = [] packages_own.extend(self.process_packages(hypervisor, vars)) packages_dummy = self.process_packages(system_latest, vars) for package in packages_own + packages_dummy: name = package['Package'] package.setdefault('Architecture', PackageArchitecture()).add(arch) if name in packages: package = packages.get(name) else: packages.append(package) arches = package.setdefault('Architecture', PackageArchitecture()) if 'all' not in arches: arches.add(arch) package_name = packages_own[0]['Package'] for i in ('postinst', 'postrm'): j = self.substitute(self.templates["xen-hypervisor.%s" % i], vars) file("debian/%s.%s" % (package_name, i), 'w').write(j) cmds_binary_arch = ["$(MAKE) -f debian/rules.real binary-arch-flavour %s" % makeflags] cmds_build = ["$(MAKE) -f debian/rules.real build-arch-flavour %s" % makeflags] cmds_setup = ["$(MAKE) -f debian/rules.real setup-flavour %s" % makeflags] cmds_binary_arch += ["$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='%s' %s" % (u' '.join([u"-p%s" % i['Package'] for i in packages_dummy]), makeflags)] makefile.add("binary-arch_%s_%s_%s" % (arch, featureset, flavour), cmds = cmds_binary_arch) makefile.add("build-arch_%s_%s_%s" % (arch, featureset, flavour), cmds = cmds_build) makefile.add("setup_%s_%s_%s" % (arch, featureset, flavour), cmds = cmds_setup) def process_changelog(self): changelog = Changelog(version = VersionXen) self.version = changelog[0].version self.vars = { 'version': self.version.xen_version, } if __name__ == '__main__': Gencontrol()() debian/bin/genorig.py0000775000000000000000000000601211556215027011752 0ustar #!/usr/bin/env python import sys sys.path.append(sys.path[0] + '/../lib/python') import itertools import os, os.path import shutil import subprocess from debian_xen.debian import VersionXen from debian_linux.debian import Changelog class RepoHg(object): def __init__(self, repo, options): self.repo = repo self.tag = options.tag or 'tip' def do_archive(self, info): orig_dir = os.path.join(info.temp_dir, info.orig_dir) args = ('hg', 'archive', '-r', self.tag, os.path.realpath(orig_dir)) subprocess.check_call(args, cwd=self.repo) class RepoGit(object): def __init__(self, repo, options): self.repo = repo self.tag = options.tag or 'HEAD' def do_archive(self, info): temp_tar = os.path.join(info.temp_dir, 'orig.tar') args = ('git', 'archive', '--prefix', '%s/' % info.orig_dir, '-o', os.path.realpath(temp_tar), self.tag) subprocess.check_call(args, cwd=self.repo) subprocess.check_call(('tar', '-C', info.temp_dir, '-xf', temp_tar)) class Main(object): log = sys.stdout.write def __init__(self, options, repo): self.options = options self.changelog_entry = Changelog(version=VersionXen)[0] self.source = self.changelog_entry.source if options.version: self.version = options.version else: raise NotImplementedError if os.path.exists(os.path.join(repo, '.hg')): self.repo = RepoHg(repo, options) elif os.path.exists(os.path.join(repo, '.git')): self.repo = RepoGit(repo, options) else: raise NotImplementedError if options.component: self.orig_dir = options.component self.orig_tar = '%s_%s.orig-%s.tar.gz' % (self.source, self.version, options.component) else: self.orig_dir = '%s-%s' % (self.source, self.version) self.orig_tar = '%s_%s.orig.tar.gz' % (self.source, self.version) def __call__(self): import tempfile self.temp_dir = tempfile.mkdtemp(prefix='genorig', dir='debian') try: self.do_archive() self.do_tar() finally: shutil.rmtree(self.temp_dir) def do_archive(self): self.log("Create archive.\n") self.repo.do_archive(self) def do_tar(self): out = "../orig/%s" % self.orig_tar self.log("Generate tarball %s\n" % out) try: os.stat(out) raise RuntimeError("Destination already exists") except OSError: pass subprocess.check_call(('tar', '-C', self.temp_dir, '-czf', out, self.orig_dir)) if __name__ == '__main__': from optparse import OptionParser p = OptionParser(prog=sys.argv[0], usage='%prog [OPTION]... DIR') p.add_option('-c', '--component', dest='component') p.add_option('-t', '--tag', dest='tag') p.add_option('-v', '--version', dest='version') options, args = p.parse_args() if len(args) != 1: raise RuntimeError Main(options, *args)() debian/bin/check-patches.sh0000775000000000000000000000062011207041024012766 0ustar #!/bin/sh -e TMPDIR=$(mktemp -d) trap "rm -rf $TMPDIR" EXIT grep -v "^#" debian/patches/series | awk '{if (NF == 1) print "debian/patches/" $1}' | sort -u > $TMPDIR/used find debian/patches -type f -name "*.diff" -printf "%p\n" | sort > $TMPDIR/avail echo "Used patches" echo "==============" cat $TMPDIR/used echo echo "Unused patches" echo "==============" fgrep -v -f $TMPDIR/used $TMPDIR/avail debian/xen-sxp2xm0000775000000000000000000002311212317541001011140 0ustar #! /usr/bin/python # -*- mode: python; -*- #============================================================================== # Copyright (C) 2013 Canonical Inc., Stefan Bader #============================================================================== """Conversion tool for domain configurations in sxp format. Provides a way to convert xend managed domains into xm style config file which the xl command can handle. Run: xen-sxp2xm [] Reads the config.sxp and either writes the xm configuration to stdout or creates a .cfg in the given directory if that file does not yet exist. WARNING: The conversion is not perfect. Manual inspection of the result is highly recommended. """ import sys, os.path import types import tempfile sys.path.insert(1, sys.path[0] + '/../lib/python') from xen.xend import XendDomain from xen.xend import XendConfig # # Pop a key off the directory (if it exists) and if that is not the # default setting, emit the data using newkey as the new key name. # def show_cfg_nondefault(cfg, key, newkey, out=sys.stdout): value = None if cfg.has_key(key): defaults = cfg._defaults() if defaults.has_key(key): if defaults[key] != cfg[key]: value = cfg[key] else: value = cfg[key] cfg.pop(key) if value: if not isinstance(value, (types.IntType, types.FloatType)): value = "'%s'" % value out.write("%s=%s\n" % (newkey, value)) def get_vif_string(devcfg): vifstr = "" sep = "" for key in devcfg.iterkeys(): if key == "uuid": continue elif key == "backend": val = devcfg[key] if val != "0": diskstr += "%sbackend=%s" % (sep, val) else: vifstr += "%s%s=%s" % (sep, key, devcfg[key]) sep = "," return vifstr def get_disk_string(devcfg): diskstr = "" sep = "" target="" for key in devcfg.iterkeys(): if key == "uuid": continue elif key == "bootable": continue elif key == "driver": continue elif key == "VDI": continue elif key == "protocol": continue elif key == "backend": val = devcfg[key] if val != "0": diskstr += "%sbackend=%s" % (sep, val) elif key == "dev": val = devcfg[key].split(":", 1) diskstr += "%svdev=%s" % (sep, val[0]) if len(val) > 1 and val[1] == "cdrom": diskstr += ",devtype=cdrom" elif key == "mode": val = devcfg[key] if val == "w": val = "rw" elif val == "r": val = "ro" diskstr += "%saccess=%s" % (sep, val) elif key == "uname": val = devcfg[key] target = "target=%s" % val.split(":")[1] else: diskstr += "%s%s=%s" % (sep, key, devcfg[key]) sep = "," if target != "": diskstr += "%s%s" % (sep, target) return diskstr def get_vfb_string(devcfg): vfbstr = "" sep = "" for key in devcfg.iterkeys(): if key == "uuid": continue if key == "other_config": # other = devcfg[key] continue if key == "keymap": vfbstr += "%s%s=\"%s\"" % (sep, key, devcfg[key]) else: vfbstr += "%s%s=%s" % (sep, key, devcfg[key]) sep = "," return vfbstr def show_dev_list(name, devlist, out=sys.stdout): if len(devlist) > 0: s = "%s=[" % name sep = "" for devstr in devlist: s = s + "%s '%s'" % (sep, devstr) sep = "," s = s + " ]\n" out.write(s) def show_cfg_devices(devices, out=sys.stdout): vifs = [] vfbs = [] disks = [] vtpms = [] for uuid in devices.iterkeys(): (devclass, devcfg) = devices[uuid] if devclass == "vif": vifs.append(get_vif_string(devcfg)) elif devclass == "vbd": disks.append(get_disk_string(devcfg)) elif devclass == "vfb": vfbs.append(get_vfb_string(devcfg)) else: out.write("# WARNING: Unhandled device: %s\n" \ % devclass) for key in devcfg.iterkeys(): out.write("# - %s=%s\n" % (key, devcfg[key])) show_dev_list("vfb", vfbs, out) show_dev_list("vif", vifs, out) show_dev_list("disk", disks, out) show_dev_list("vtpm", vtpms, out) def show_cfg_xm(cfg, out=sys.stdout): hvm = False if cfg['platform'].has_key('loader') and \ "hvmloader" in cfg['platform']['loader']: hvm = True if hvm: out.write("#\n# Autogenerated HVM configuration\n") else: out.write("#\n# Autogenerated PV configuration\n") val = cfg.pop("description") if val != "": out.write("#\n#\n", val) val = cfg.pop("Description") if val != "": out.write("#\n#\n", val) out.write("#\n") if hvm: out.write("builder='hvm'\n") show_cfg_nondefault(cfg, "name_label", "name", out) show_cfg_nondefault(cfg, "uuid", "uuid", out) # # CPU options. Looks like the vcpu_avail bitmap maps best to # vpcus and VCPUs_max # if cfg.has_key('vcpu_avail'): val = int(cfg.pop('vcpu_avail')) n = 0 while val: if val & 1: n += 1 val /= 2 out.write("vcpus=%i\n" % n) out.write("maxvcpus=%i\n" % cfg.pop('VCPUs_max')) else: val = int(cfg.pop('VCPUs_max', 1)) out.write("vcpus=%i\n" % val) out.write("maxvcpus=%i\n" % val) # # Optionally show the weight and cap VCPU option # val = cfg.pop('vcpus_params') n = val.pop('weight', 256) if n != 256: out.write("cpu_weight=%i\n" % n) n = val.pop('cap', 0) if n > 0: out.write("cap=%i\n" % n) show_cfg_nondefault(cfg, "pool_name", "pool", out) # Ignored cfg.pop("VCPUs_live") cfg.pop("VCPUs_at_startup") # # Memory allocation. There seem to be memory_static_(min|max) and # memory_dynamic_(min|max). It looks a bit like static min might be # always 0... # val = cfg.pop('memory_static_min', 0) if val: out.write("WARNING: memory_static_min != 0 was not expected!\n") minmem = cfg.pop('memory_dynamic_min', 0) val = cfg.pop('memory_static_max', 0) val1 = cfg.pop('memory_dynamic_max', 0) if val != val1: out.write("# WARNING: dynamic/static max memory mismatch " \ "(%i/%i)\n" % (val1, val)) maxmem = max(val, val1) if minmem != maxmem: out.write("memory=%i\n" % (minmem / 1024 / 1024)) out.write("maxmem=%i\n" % (maxmem / 1024 / 1024)) else: out.write("memory=%i\n" % (minmem / 1024 / 1024)) val = cfg.pop("shadow_memory") if hvm and val > 0: out.write("shadow_memory=%i\n" % (val)) show_cfg_nondefault(cfg, "actions_after_shutdown", "on_poweroff", out) show_cfg_nondefault(cfg, "actions_after_reboot", "on_reboot", out) show_cfg_nondefault(cfg, "actions_after_crash", "on_crash", out) # Ignored cfg.pop("actions_after_suspend") cfg.pop("on_xend_start") cfg.pop("on_xend_stop") # # Devices # devices = cfg.pop("devices") if devices: show_cfg_devices(devices, out) # # Platform # val = cfg.pop("platform") if val.pop("nomigrate", "0") != "0": out.write("nomigrate=1\n") if cfg.pop("is_control_domain", False): out.write("driver_domain=1\n") # # PV guest specific # val = cfg.pop("PV_kernel") if not hvm: out.write("kernel='%s'\n" % val) val = cfg.pop("PV_ramdisk") if not hvm and val != "": out.write("ramdisk='%s'\n" % val) val = cfg.pop("PV_bootloader") if not hvm and val != "": out.write("bootloader='%s'\n" % val) val = cfg.pop("PV_bootloader_args") if not hvm and val != "": out.write("bootloader_args='%s'\n" % val) val = cfg.pop("PV_args") if not hvm and val != "": out.write("extra='%s'\n" % val) # # HVM guest specific # val = cfg.pop("HVM_boot_params") val = val.pop("order", "c") if hvm: out.write("boot=%s\n" % val) # Ignore cfg.pop("HVM_boot_policy") # # Things just ignored without complaint # cfg.pop("vbd_refs") cfg.pop("vif_refs") cfg.pop("console_refs") cfg.pop("auto_power_on") cfg.pop("status") cfg.pop("use_tmp_kernel") cfg.pop("use_tmp_ramdisk") out.write("#\n# The following options were not converted:\n#\n") for k in cfg.iterkeys(): out.write("# %s=%s\n" % (k, cfg[k])) # # Check for one argument (the filename) # if len(sys.argv) < 2: print "Usage: %s " % os.path.basename(sys.argv[0]) sys.exit(1) cfgname = sys.argv[1] # # If a second argument is given, make sure this is pointing to a directory. # outdir = None if len(sys.argv) == 3: outdir = sys.argv[2] if not os.path.isdir(outdir): print "Error: %s is not a directory!" % outdir sys.exit(1) # # Special pre-processing as it turned out that the sanity check of # XendConfig object does not like the device_model or loader path # to be wrong. # For device_model just filter out the line to make the resulting # config go for the default. # For the loader, strip the pathname # (tmpfd, tmpname) = tempfile.mkstemp() try: cfgfile = open(cfgname) except: print "Failed to open %s" % cfgname tmpfd.close() unlink(tmpname) sys.exit(1) for line in cfgfile: if "(device_model" in line: continue if "(loader" in line: idx = line.index("(loader") val = os.path.basename(line[idx+8:-1]) line = "%s%s" % (line[:idx+8], val) os.write(tmpfd, line) cfgfile.close() os.close(tmpfd) # # Let XenConfig parse the pre-processed sxp file. Note to self: the raise # is there because otherwise its pretty much impossible to find out what # went wrong if things go wrong. # try: cfg = XendConfig.XendConfig(filename = tmpname) except Exception: print('Unable to open of parse sxp file: %s' % cfgfile) os.unlink(tmpname) raise os.unlink(tmpname) if cfg.pop("is_a_template", False): print "Skipping %s (template)" % cfgname sys.exit(2) # # If this should go into an output directory, check whether that file # actually is there already. # outfile = sys.stdout if outdir: if not cfg.has_key("name_label"): print "Skipping %s without name defined." % cfgname sys.exit(2) outname = os.path.join(outdir, cfg["name_label"] + ".cfg") if os.path.exists(outname): print "Config %s already exists." % outname sys.exit(3) try: outfile = open(outname, "w") except: print "Failed to create %s!" % outname sys.exit(1) if outdir: print "Creating %s" % outname show_cfg_xm(cfg, outfile) sys.exit(0) debian/rules.defs0000664000000000000000000000015512212071014011154 0ustar KERNELVERSION := 3.10-2 BUILD_DIR = debian/build STAMPS_DIR = debian/stamps TEMPLATES_DIR = debian/templates debian/xen-utils-common.xend.default0000664000000000000000000000004211711764012014705 0ustar XENCONSOLED_ARGS= XENSTORED_ARGS= debian/copyright0000664000000000000000000003221111556260647011136 0ustar This work was downloaded from http://xenbits.xensource.com/ Copyright: Copyright (C) 1998-2005 Hewlett-Packard Co 1999-2006 Silicon Graphics, Inc 2001-2006 IBM Corporation 2005-2006 XenSource Inc 2006-2010 Citrix Systems Inc. and many others License: This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This package 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". The bundled qemu is: Copyright (C) 2007 Alexander Graf 2005,2007 Alex Beregszaszi 2005-2008 Andrzej Zaborowski 2005-2007 Anthony Liguori 2004 Antony T Curtis 2007 Arastra, Inc. 2007 Armin Kuster or 1999 AT&T Laboratories Cambridge 2006,2007 Aurelien Jarno 2007-2008 AXIS Communications AB 2007-2008 Bull S.A.S. 2006 Christian Limpach 2008 Citrix Systems, Inc. 2005-2008 CodeSourcery 2007 Dan Aloni 1995,1996 Danny Gasparovski 2000-2003 David McCullough 2008 Dmitry Baryshkov 2007-2009 Edgar E. Iglesias, Axis Communications AB. 1996-1999 Eduardo Horvath 1998,2003-2008 Fabrice Bellard 2005 Filip Navara 2006 Frederick Reeve 2009 Freescale Semiconductor 1986-2007 Free Software Foundation, Inc. 2004 Gianni Tedesco 2008 Gleb Natapov 2002 Greg Ungerer 2007-2009 Hervé Poussineau 2005,2007,2008 IBM Corporation 2008 IBM Corporation 2006 Igor Kovalenko 2006 InnoTek Systemberatung GmbH 1999-2008 Intel Corporation 2009 Isaku Yamahata 2003-2004 James Yonan 2008 Jan Kiszka 2006 Joachim Henke 2003-2007 Jocelyn Mayer 2004,2005 Johannes E. Schindelin 2005 Julian Chesterfield and Andrew Warfield. 2008 Kamala Narasimhan 1998 Kenneth Albanowski 2008 Kevin Wolf 2009 Kevin Wolf 2009 Laurent Vivier 2007-2008 Lauro Ramos Venancio 2000,2001 Lineo, by David McCullough 1991,1992,1996 Linus Torvalds 2006 Lonnie Mendez 2008 Lubomir Rintel 2004,2007 Magnus Damm 2004 Makoto Suzuki (suzu) 2002-2006 Marcel Holtmann 2006 Marius Groeger (FPU operations) 2007 Marko Kohtala 2002-2003 Maxim Krasnyansky 2008 Max Krasnyansky 2005,2008 Mike Kronenberg 2007 MontaVista Software, Inc 2007 Neocleus Corporation. 2007-2008 Nokia Corporation 2001 OKTET Ltd., St.-Petersburg, Russia 2006-2008 Openedhand Ltd. 2007-2008 OpenMoko, Inc. 1996 Paul Mackerras. 2008 Paul Mundt 2006 Pierre d'Herbemont 2000-2001 Qualcomm Incorporated 2006-2008 Qumranet Technologies 1997-1999,2001,2009 Red Hat, Inc. 1988,1989,1990,1991,1992 Richard Outerbridge 2007 Robert Reif 1998-2004 Samuel Rydh (samuel@ibrium.se) 2005 Samuel Tardieu 2007,2008 Samuel Thibault 2008 Semihalf 2008 Shin-ichiro KAWASAKI 2002 SnapGear, by Paul Dale 2006-2007 Stefan Weil 2008 Takashi YOSHII 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development 1993 Theodore Ts'o 2006,2007 Thiemo Seufer 2003 Thomas M. Ogrisegg 2006 Thomas Sailer 1998-2001,2003 Thomas Sailer (t.sailer@alumni.ethz.ch) 2006,2007 Thorsten Zitterell 2000-2007 Tibor "TS" Schütz 2008 TJ 2002-2005 Vassili Karpov (malc) 2005 Vassili Karpov (malc) 2007 Vladimir Ananiev 2006 XenSource The Debian packaging is: Copyright (C) 2008-2010 Bastian Blank you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The following parts are subject of a different license: * tools/firmware/vgabios * tools/libaio * tools/libxen * tools/xenstat/libxenstat * tools/xenstore This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This package 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 General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU Lesser General Public License can be found in "/usr/share/common-licenses/LGPL-2". Files in xen/include/public are subject to the following license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Files in extra/mini-os are subject to the following license: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files in tools/vtpm_manager are subject to the following license: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. File tools/python/test.py is subject to the following license: This software is Copyright (c) Zope Corporation (tm) and Contributors. All rights reserved. This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name Zope Corporation (tm) must not be used to endorse or promote products derived from this software without prior written permission from Zope Corporation. 4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of Zope Corporation. Use of them is covered in a separate agreement (see http://www.zope.com/Marks). 5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. Disclaimer THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of contributions made by Zope Corporation and many individuals on behalf of Zope Corporation. Specific attributions are listed in the accompanying credits file. debian/xen-hypervisor-4.4-amd64.postinst0000664000000000000000000000051412212071167015212 0ustar #!/bin/bash set -e case "$1" in configure) if command -v update-grub > /dev/null && [ -d /boot/grub ]; then update-grub || : fi ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/xen-utils-common.preinst0000664000000000000000000000046511743751336014033 0ustar #!/bin/sh set -e case "$1" in install|upgrade) ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac dpkg-maintscript-helper mv_conffile /etc/init.d/xend /etc/init.d/xen 4.1.2-4~ -- "$@" update-rc.d -f xend remove >/dev/null #DEBHELPER# exit 0 debian/xen-utils.README.Debian0000664000000000000000000000430711402217463013164 0ustar Xen for Debian ============== Config behaviour ---------------- The Debian packages changes the behaviour of some config options. The options "kernel", "initrd" and "loader" searches in the Xen private boot directory (/usr/lib/xen-$version/boot) first. "bootloader" and "device_model" also searches the Xen private bin directory (/usr/lib/xen-$version/bin). This means that the following entries will properly find anything: loader = 'hvmloader' bootloader = 'pygrub' Network setup ------------- The Debian package of Xen don't change the network setup in any way. This differs from the upstream version, which overwrites the main network card (eth0) with a bridge setup and may break the network at this point.. To setup a bridge please follow the instructions in the manpage for bridge-utils-interfaces(5). You can also change the /etc/xen/xend-config.sxp file and re-enable the Xen included network setup by adding (network-script network-bridge) to the file. But please note that this may or may not work. Loop devices ------------ If you plan hosting virtual domains with file backed block devices (ie. the ones xen-tools creates by default) be careful about two issues: 1. Maximum number of loop devices By default the loop driver supports a maximum of 8 loop devices. Of course since every Xen domain uses at least two (one for the data and one for the swap) this number is absolutely insufficient. You should increase it by adding a file named local-loop in /etc/modprobe.d containing the string "options loop max_loop=128", if the loop driver is compiled as a module, or by appending the string max_loop=128 to your kernel parameters if the driver is in-kernel. Of course you can increase or decrease the number 128 as you see fit. 2. Driver loading (only if loop is compiled as a module) Normally the loop driver gets loaded when the first loop device is accessed. When using udev, though, the loop devices get created only after the driver gets loaded. This means that Xen will fail if the loop driver is not already loaded when it tries to start a file-backed virtual domain. To fix this just add "loop" in your /etc/modules file, thus forcing it to be loaded at boot time. debian/arch/0000775000000000000000000000000012212071061010075 5ustar debian/arch/i386/0000775000000000000000000000000012221302632010567 5ustar debian/arch/i386/defines0000664000000000000000000000004212221321177012130 0ustar [base] flavours: xen-arch: x86_32 debian/arch/amd64/0000775000000000000000000000000012212071061011010 5ustar debian/arch/amd64/defines0000664000000000000000000000022111341232036012346 0ustar [base] flavours: amd64 xen-arch: x86_64 [amd64_description] hardware: AMD64 hardware-long: all 64bit single- and multiprocessor AMD and Intel debian/arch/defines0000664000000000000000000000004311201572564011445 0ustar [abi] [base] arches: amd64 i386 debian/rules.gen0000664000000000000000000002005312322026612011011 0ustar .NOTPARALLEL: binary-arch: binary-arch_amd64 binary-arch_i386 binary-arch_armhf binary-arch_arm64 binary-arch_amd64: binary-arch_amd64_none binary-arch_amd64_real binary-arch_amd64_none: binary-arch_amd64_none_amd64 binary-arch_amd64_none_real binary-arch_amd64_none_amd64:: binary-arch_amd64_none_amd64_real binary-arch_amd64_none_amd64:: $(MAKE) -f debian/rules.real binary-arch-flavour ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-system-amd64' ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-hypervisor-4.1-amd64' ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.1' XEN_ARCH='x86_64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-hypervisor-4.3-amd64' ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.3' XEN_ARCH='x86_64' binary-arch_amd64_none_amd64_real: binary-arch_amd64_none_real: binary-arch_amd64_real:: $(MAKE) -f debian/rules.real binary-arch-arch ARCH='amd64' VERSION='4.4' XEN_ARCH='x86_64' binary-arch_i386: binary-arch_i386_none binary-arch_i386_real binary-arch_i386_none: binary-arch_i386_none_amd64 binary-arch_i386_none_i386 binary-arch_i386_none_real binary-arch_i386_none_amd64:: binary-arch_i386_none_amd64_real binary-arch_i386_none_amd64:: $(MAKE) -f debian/rules.real binary-arch-flavour ARCH='i386' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-system-amd64' ARCH='i386' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-hypervisor-4.1-amd64' ARCH='i386' FEATURESET='none' FLAVOUR='amd64' VERSION='4.1' XEN_ARCH='x86_64' binary-arch_i386_none_amd64_real: binary-arch_i386_none_i386:: binary-arch_i386_none_i386_real binary-arch_i386_none_i386:: binary-arch_i386_none_i386_real: binary-arch_i386_none_real: binary-arch_i386_real:: $(MAKE) -f debian/rules.real binary-arch-arch ARCH='i386' VERSION='4.4' XEN_ARCH='x86_32' binary-indep:: $(MAKE) -f debian/rules.real binary-indep VERSION='4.4' build-arch: build-arch_amd64 build-arch_i386 build-arch_armhf build-arch_arm64 build-arch_amd64: build-arch_amd64_none build-arch_amd64_real build-arch_amd64_none: build-arch_amd64_none_amd64 build-arch_amd64_none_real build-arch_amd64_none_amd64:: build-arch_amd64_none_amd64_real build-arch_amd64_none_amd64:: $(MAKE) -f debian/rules.real build-arch-flavour ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' build-arch_amd64_none_amd64_real: build-arch_amd64_none_real: build-arch_amd64_real:: $(MAKE) -f debian/rules.real build-arch-arch ARCH='amd64' VERSION='4.4' XEN_ARCH='x86_64' build-arch_i386: build-arch_i386_none build-arch_i386_real build-arch_i386_none: build-arch_i386_none_amd64 build-arch_i386_none_i386 build-arch_i386_none_real build-arch_i386_none_amd64:: build-arch_i386_none_amd64_real build-arch_i386_none_amd64:: $(MAKE) -f debian/rules.real build-arch-flavour ARCH='i386' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' build-arch_i386_none_amd64_real: build-arch_i386_none_i386:: build-arch_i386_none_i386_real build-arch_i386_none_i386:: build-arch_i386_none_i386_real: build-arch_i386_none_real: build-arch_i386_real:: $(MAKE) -f debian/rules.real build-arch-arch ARCH='i386' VERSION='4.4' XEN_ARCH='x86_32' build-indep:: $(MAKE) -f debian/rules.real build-indep VERSION='4.4' setup: setup_amd64 setup_i386 setup_armhf setup_arm64 setup_amd64: setup_amd64_none setup_amd64_real setup_amd64_none: setup_amd64_none_amd64 setup_amd64_none_real setup_amd64_none_amd64:: setup_amd64_none_amd64_real setup_amd64_none_amd64:: $(MAKE) -f debian/rules.real setup-flavour ARCH='amd64' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' setup_amd64_none_amd64_real: setup_amd64_none_real: setup_amd64_real:: $(MAKE) -f debian/rules.real setup-arch ARCH='amd64' VERSION='4.4' XEN_ARCH='x86_64' setup_i386: setup_i386_none setup_i386_real setup_i386_none: setup_i386_none_amd64 setup_i386_none_i386 setup_i386_none_real setup_i386_none_amd64:: setup_i386_none_amd64_real setup_i386_none_amd64:: $(MAKE) -f debian/rules.real setup-flavour ARCH='i386' FEATURESET='none' FLAVOUR='amd64' VERSION='4.4' XEN_ARCH='x86_64' setup_i386_none_amd64_real: setup_i386_none_i386:: setup_i386_none_i386_real setup_i386_none_i386:: setup_i386_none_i386_real: setup_i386_none_real: setup_i386_real:: $(MAKE) -f debian/rules.real setup-arch ARCH='i386' VERSION='4.4' XEN_ARCH='x86_32' binary-arch_armhf: binary-arch_armhf_none binary-arch_armhf_real binary-arch_armhf_none: binary-arch_armhf_none_armhf binary-arch_armhf_none_real binary-arch_armhf_none_armhf:: binary-arch_armhf_none_armhf_real binary-arch_armhf_none_armhf:: $(MAKE) -f debian/rules.real binary-arch-flavour ARCH='armhf' FEATURESET='none' FLAVOUR='armhf' VERSION='4.4' XEN_ARCH='arm32' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-system-armhf' ARCH='armhf' FEATURESET='none' FLAVOUR='armhf' VERSION='4.4' XEN_ARCH='arm32' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-hypervisor-4.3-armhf' ARCH='armhf' FEATURESET='none' FLAVOUR='armhf' VERSION='4.3' XEN_ARCH='arm32' binary-arch_armhf_none_armhf_real: binary-arch_armhf_none_real: binary-arch_armhf_real:: $(MAKE) -f debian/rules.real binary-arch-arch ARCH='armhf' VERSION='4.4' XEN_ARCH='arm32' build-arch_armhf: build-arch_armhf_none build-arch_armhf_real build-arch_armhf_none: build-arch_armhf_none_armhf build-arch_armhf_none_real build-arch_armhf_none_armhf:: build-arch_armhf_none_armhf_real build-arch_armhf_none_armhf:: $(MAKE) -f debian/rules.real build-arch-flavour ARCH='armhf' FEATURESET='none' FLAVOUR='armhf' VERSION='4.4' XEN_ARCH='arm32' build-arch_armhf_none_armhf_real: build-arch_armhf_none_real: build-arch_armhf_real:: $(MAKE) -f debian/rules.real build-arch-arch ARCH='armhf' VERSION='4.4' XEN_ARCH='arm32' setup_armhf: setup_armhf_none setup_armhf_real setup_armhf_none: setup_armhf_none_armhf setup_armhf_none_real setup_armhf_none_armhf:: setup_armhf_none_armhf_real setup_armhf_none_armhf:: $(MAKE) -f debian/rules.real setup-flavour ARCH='armhf' FEATURESET='none' FLAVOUR='armhf' VERSION='4.4' XEN_ARCH='arm32' setup_armhf_none_armhf_real: setup_armhf_none_real: setup_armhf_real:: $(MAKE) -f debian/rules.real setup-arch ARCH='armhf' VERSION='4.4' XEN_ARCH='arm32' binary-arch_arm64: binary-arch_arm64_none binary-arch_arm64_real binary-arch_arm64_none: binary-arch_arm64_none_arm64 binary-arch_arm64_none_real binary-arch_arm64_none_arm64:: binary-arch_arm64_none_arm64_real binary-arch_arm64_none_arm64:: $(MAKE) -f debian/rules.real binary-arch-flavour ARCH='arm64' FEATURESET='none' FLAVOUR='arm64' VERSION='4.4' XEN_ARCH='arm64' $(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-pxen-system-arm64' ARCH='arm64' FEATURESET='none' FLAVOUR='arm64' VERSION='4.4' XEN_ARCH='arm64' binary-arch_arm64_none_arm64_real: binary-arch_arm64_none_real: binary-arch_arm64_real:: $(MAKE) -f debian/rules.real binary-arch-arch ARCH='arm64' VERSION='4.4' XEN_ARCH='arm32' build-arch_arm64: build-arch_arm64_none build-arch_arm64_real build-arch_arm64_none: build-arch_arm64_none_arm64 build-arch_arm64_none_real build-arch_arm64_none_arm64:: build-arch_arm64_none_arm64_real build-arch_arm64_none_arm64:: $(MAKE) -f debian/rules.real build-arch-flavour ARCH='arm64' FEATURESET='none' FLAVOUR='arm64' VERSION='4.4' XEN_ARCH='arm64' build-arch_arm64_none_arm64_real: build-arch_arm64_none_real: build-arch_arm64_real:: $(MAKE) -f debian/rules.real build-arch-arch ARCH='arm64' VERSION='4.4' XEN_ARCH='arm64' setup_arm64: setup_arm64_none setup_arm64_real setup_arm64_none: setup_arm64_none_arm64 setup_arm64_none_real setup_arm64_none_arm64:: setup_arm64_none_arm64_real setup_arm64_none_arm64:: $(MAKE) -f debian/rules.real setup-flavour ARCH='arm64' FEATURESET='none' FLAVOUR='arm64' VERSION='4.4' XEN_ARCH='arm64' setup_arm64_none_arm64_real: setup_arm64_none_real: setup_arm64_real:: $(MAKE) -f debian/rules.real setup-arch ARCH='arm64' VERSION='4.4' XEN_ARCH='arm64' debian/xen-hypervisor-4.4.xen.cfg0000664000000000000000000000336512316303457013762 0ustar # # Uncomment the following variable and set to 0 or 1 to avoid warning. # #XEN_OVERRIDE_GRUB_DEFAULT=0 echo "Including Xen overrides from /etc/default/grub.d/xen.cfg" # # When running update-grub with the Xen hypervisor installed, there are # some additional variables that can be used to pass options to the # hypervisor or the dom0 kernel. # The following two are used to generate arguments for the hypervisor: # #GRUB_CMDLINE_XEN_DEFAULT="" #GRUB_CMDLINE_XEN="" # # For example: # # dom0_mem=[M]:max=[M] # Sets the amount of memory dom0 uses (max prevents balloning for more) # com[12]=, # Initialize a serial console from in the hypervisor (eg. 115200,8n1) # Note that com1 would be ttyS0 in Linux. # console=[, ...] # Redirects Xen hypervisor console (eg. com1,vga) # # The next two lines are used for creating kernel arguments for the dom0 # kernel. This allows to have different options for the same kernel used # natively or as dom0 kernel. # #GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT" #GRUB_CMDLINE_LINUX_XEN_REPLACE="$GRUB_CMDLINE_LINUX" # # For example: # # earlyprintk=xenboot # Allows to send early printk messages to the Xen hypervisor console # console=hvc0 # Redirects the Linux console to the hypervisor console # # Make booting into Xen the default if not changed above. Finding the # current string for it always has been a problem. # if [ "$XEN_OVERRIDE_GRUB_DEFAULT" = "" ]; then echo "WARNING: GRUB_DEFAULT changed to boot into Xen by default!" echo " Edit /etc/default/grub.d/xen.cfg to avoid this warning." XEN_OVERRIDE_GRUB_DEFAULT=1 fi if [ "$XEN_OVERRIDE_GRUB_DEFAULT" = "1" ]; then GRUB_DEFAULT="Ubuntu GNU/Linux, with Xen hypervisor" fi debian/rules.real0000664000000000000000000002400412322026766011175 0ustar include /usr/share/dpkg/default.mk include /usr/share/ocaml/ocamlvars.mk export DH_OPTIONS setup_env := env -u ARCH -u FLAVOUR -u VERSION -u MAKEFLAGS MAKE_CLEAN = $(setup_env) $(MAKE) V=1 MAKE_SELF = $(MAKE) -f debian/rules.real include debian/rules.defs stamp = [ -d $(dir $@) ] || mkdir $(dir $@); touch $@ binary-arch-arch: install-libxen_$(ARCH) binary-arch-arch: install-libxen-dev_$(ARCH) binary-arch-arch: install-libxenstore_$(ARCH) binary-arch-arch: install-utils_$(ARCH) binary-arch-arch: install-xenstore-utils_$(ARCH) ifeq (,$(findstring $(ARCH),armhf arm64)) binary-arch-arch: install-lib-ocaml-dev_$(ARCH) binary-arch-arch: install-lib-ocaml_$(ARCH) endif binary-arch-flavour: install-hypervisor_$(ARCH)_$(FLAVOUR) binary-indep: install-utils-common build-arch-arch: $(STAMPS_DIR)/build-utils_$(ARCH) build-arch-flavour: $(STAMPS_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR) build-indep: $(STAMPS_DIR)/build-docs setup-arch: $(STAMPS_DIR)/setup-utils_$(ARCH) setup-flavour: $(STAMPS_DIR)/setup-hypervisor_$(ARCH)_$(FLAVOUR) $(STAMPS_DIR)/setup-docs: SOURCE_FILES = $(filter-out debian, $(wildcard *)) $(STAMPS_DIR)/setup-docs: DIR=$(BUILD_DIR)/build-docs $(STAMPS_DIR)/setup-docs: @rm -rf $(DIR) mkdir -p $(DIR) cp -al $(SOURCE_FILES) $(DIR) cd $(DIR)/docs; ./configure --enable-xend --prefix=/usr cd $(DIR)/tools; \ WGET=/bin/false \ ./configure --enable-xend --prefix=/usr @$(stamp) $(STAMPS_DIR)/setup-hypervisor_$(ARCH)_$(FLAVOUR): SOURCE_FILES = $(filter-out debian, $(wildcard *)) $(STAMPS_DIR)/setup-hypervisor_$(ARCH)_$(FLAVOUR): DIR=$(BUILD_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR) $(STAMPS_DIR)/setup-hypervisor_$(ARCH)_$(FLAVOUR): @rm -rf $(DIR) mkdir -p $(DIR) cp -al $(SOURCE_FILES) $(DIR) echo "XEN_VENDORVERSION := $(EXTRAVERSION)" > $(DIR)/xen/xen-version @$(stamp) $(STAMPS_DIR)/setup-utils_$(ARCH): SOURCE_FILES = $(filter-out debian, $(wildcard *)) $(STAMPS_DIR)/setup-utils_$(ARCH): DIR=$(BUILD_DIR)/build-utils_$(ARCH) $(STAMPS_DIR)/setup-utils_$(ARCH): @rm -rf $(DIR) mkdir -p $(DIR) cp -al $(SOURCE_FILES) $(DIR) cd $(DIR)/tools; \ CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ WGET=/bin/false \ ./configure \ --enable-xend \ --prefix=/usr \ --includedir=$${prefix}/include \ --mandir=$${prefix}/share/man \ --infodir=$${prefix}/share/info \ --sysconfdir=/etc \ --localstatedir=/var @$(stamp) $(STAMPS_DIR)/build-docs: DIR=$(BUILD_DIR)/build-docs $(STAMPS_DIR)/build-docs: $(STAMPS_DIR)/setup-docs +$(MAKE_CLEAN) -C $(DIR)/docs touch $@ $(STAMPS_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR): DIR=$(BUILD_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR) $(STAMPS_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR): $(STAMPS_DIR)/setup-hypervisor_$(ARCH)_$(FLAVOUR) +$(MAKE_CLEAN) -C $(DIR)/xen \ XEN_COMPILE_ARCH=$(XEN_ARCH) \ XEN_TARGET_ARCH=$(XEN_ARCH) touch $@ $(STAMPS_DIR)/build-utils_$(ARCH) \ $(STAMPS_DIR)/install-utils_$(ARCH): CONFIG = \ debug=n \ XEN_COMPILE_ARCH=$(XEN_ARCH) \ XEN_TARGET_ARCH=$(XEN_ARCH) \ XEN_VERSION=$(VERSION) \ OCAMLDESTDIR=$(CURDIR)/$(BUILD_DIR)/install-utils_$(ARCH)/$(OCAML_STDLIB_DIR) \ PYTHON=$(shell pyversions -r) $(STAMPS_DIR)/build-utils_$(ARCH): DIR=$(BUILD_DIR)/build-utils_$(ARCH) $(STAMPS_DIR)/build-utils_$(ARCH): $(STAMPS_DIR)/setup-utils_$(ARCH) +$(MAKE_CLEAN) -C $(DIR)/tools $(CONFIG) touch $@ $(STAMPS_DIR)/install-utils_$(ARCH): DIR = $(BUILD_DIR)/build-utils_$(ARCH) $(STAMPS_DIR)/install-utils_$(ARCH): INSTALL_DIR = $(BUILD_DIR)/install-utils_$(ARCH) $(STAMPS_DIR)/install-utils_$(ARCH): $(STAMPS_DIR)/build-utils_$(ARCH) @rm -rf $(INSTALL_DIR) mkdir -p $(INSTALL_DIR)/$(OCAML_DLL_DIR) +$(MAKE_CLEAN) -C $(DIR)/tools install DESTDIR=$(CURDIR)/$(INSTALL_DIR) $(CONFIG) ifeq (,$(findstring $(ARCH),armhf arm64)) # hvmloader strip --remove-section=.comment --remove-section=.note $(INSTALL_DIR)/usr/lib/xen*/boot/* endif touch $@ $(STAMPS_DIR)/install-utils-common: DIR = $(BUILD_DIR)/build-docs $(STAMPS_DIR)/install-utils-common: INSTALL_DIR = $(BUILD_DIR)/install-utils-common $(STAMPS_DIR)/install-utils-common: export DESTDIR = $(CURDIR)/$(INSTALL_DIR) $(STAMPS_DIR)/install-utils-common: $(STAMPS_DIR)/build-docs @rm -rf $(INSTALL_DIR) +$(MAKE_CLEAN) -C $(SOURCE_DIR)/tools/examples install-configs +$(MAKE_CLEAN) -C $(SOURCE_DIR)/tools/hotplug/common install-scripts +$(MAKE_CLEAN) -C $(SOURCE_DIR)/tools/hotplug/Linux install-udev install-scripts UDEV_RULES_DIR=/lib/udev +$(MAKE_CLEAN) -C debian/scripts install touch $@ install-base: dh_installchangelogs -XChangelog dh_installdirs dh_installdocs dh_installexamples dh_compress dh_fixperms dh_installdeb dh_gencontrol -- $(GENCONTROL_ARGS) dh_md5sums dh_builddeb install-dummy: dh_testdir dh_testroot dh_prep +$(MAKE_SELF) install-base install-hypervisor_$(ARCH)_$(FLAVOUR): DIR=$(BUILD_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR) install-hypervisor_$(ARCH)_$(FLAVOUR): PACKAGE_NAME = xen-hypervisor-$(VERSION)-$(FLAVOUR) install-hypervisor_$(ARCH)_$(FLAVOUR): DH_OPTIONS = -p$(PACKAGE_NAME) install-hypervisor_$(ARCH)_$(FLAVOUR): $(STAMPS_DIR)/build-hypervisor_$(ARCH)_$(FLAVOUR) dh_testdir dh_testroot dh_prep dh_installdirs boot dh_installdirs etc/default/grub.d install -D -m644 debian/xen-hypervisor-$(VERSION).xen.cfg \ debian/$(PACKAGE_NAME)/etc/default/grub.d/xen.cfg ifeq (,$(findstring $(ARCH),armhf arm64)) cp $(DIR)/xen/xen.gz debian/$(PACKAGE_NAME)/boot/xen-$(VERSION)-$(FLAVOUR).gz else cp $(DIR)/xen/xen debian/$(PACKAGE_NAME)/boot/xen-$(VERSION)-$(FLAVOUR) endif +$(MAKE_SELF) install-base install-libxen_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-libxen_$(ARCH): DH_OPTIONS = -plibxen-$(VERSION) install-libxen_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) install-libxenstore_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) usr/lib/lib*-$(VERSION).so dh_strip dh_makeshlibs -V dh_shlibdeps +$(MAKE_SELF) install-base install-libxen-dev_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-libxen-dev_$(ARCH): PACKAGE_NAME = libxen-dev install-libxen-dev_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-libxen-dev_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) dh_strip dh_shlibdeps +$(MAKE_SELF) install-base install-lib-ocaml_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-lib-ocaml_$(ARCH): PACKAGE_NAME = libxen-ocaml install-lib-ocaml_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-lib-ocaml_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/META dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/*.cma dh_install --sourcedir=$(DIR) -X.so.owner ./$(OCAML_DLL_DIR)/* dh_strip dh_shlibdeps dh_ocaml +$(MAKE_SELF) install-base install-lib-ocaml-dev_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-lib-ocaml-dev_$(ARCH): PACKAGE_NAME = libxen-ocaml-dev install-lib-ocaml-dev_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-lib-ocaml-dev_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/*.cmx dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/*.cmxa dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/*.cmi dh_install --sourcedir=$(DIR) ./$(OCAML_STDLIB_DIR)/*/*.a dh_strip dh_shlibdeps dh_ocaml +$(MAKE_SELF) install-base install-libxenstore_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-libxenstore_$(ARCH): PACKAGE_NAME = libxenstore3.0 install-libxenstore_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-libxenstore_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) dh_strip dh_makeshlibs -V dh_shlibdeps +$(MAKE_SELF) install-base install-utils_$(ARCH): SOURCE_DIR = $(BUILD_DIR)/build-utils_$(ARCH) install-utils_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-utils_$(ARCH): PACKAGE_NAME = xen-utils-$(VERSION) install-utils_$(ARCH): PACKAGE_DIR = debian/$(PACKAGE_NAME) install-utils_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-utils_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) install-libxenstore_$(ARCH) dh_testdir dh_testroot dh_prep install -D -m644 debian/xen-utils.NEWS $(PACKAGE_DIR)/usr/share/doc/$(PACKAGE_NAME)/NEWS install -D -m644 debian/xen-utils.README.Debian $(PACKAGE_DIR)/usr/share/doc/$(PACKAGE_NAME)/README.Debian install -D -m644 debian/xen-utils-$(VERSION).lintian-overrides $(PACKAGE_DIR)/usr/share/lintian/overrides/$(PACKAGE_NAME) dh_install --sourcedir=$(DIR) usr/lib/xen-$(VERSION) # Hack around usr/sbin dh_install --sourcedir=$(DIR) usr/sbin/* /usr/lib/xen-$(VERSION)/bin/ install -m 755 debian/xen-sxp2xm \ $(PACKAGE_DIR)/usr/lib/xen-$(VERSION)/bin install -m 755 debian/xen-migrate-xend-managed-domains \ $(PACKAGE_DIR)/usr/lib/xen-$(VERSION)/bin ( echo -n "misc:Built-Using="; dpkg-query -f='$${source:Package} (= $${source:Version}), ' -W ipxe-qemu seabios; echo ) >> debian/$(PACKAGE_NAME).substvars dh_python2 -V$(shell pyversions -rv) /usr/lib/xen-$(VERSION) dh_strip dh_makeshlibs -V dh_shlibdeps +$(MAKE_SELF) install-base install-utils-common: SOURCE_DIR = $(BUILD_DIR)/build-docs install-utils-common: DIR = $(BUILD_DIR)/install-utils-common install-utils-common: PACKAGE_NAME = xen-utils-common install-utils-common: DH_OPTIONS = -p$(PACKAGE_NAME) install-utils-common: $(STAMPS_DIR)/install-utils-common dh_testdir dh_testroot dh_prep dh_install -X .svn --sourcedir=$(DIR) dh_installinit --name xen -- defaults 20 21 dh_installinit --name xend dh_installinit --name xendomains --no-start -- defaults 21 20 dh_installman $(SOURCE_DIR)/docs/man1/* $(SOURCE_DIR)/docs/man5/* dh_link dh_ucf +$(MAKE_SELF) install-base install-xenstore-utils_$(ARCH): DIR = $(BUILD_DIR)/install-utils_$(ARCH) install-xenstore-utils_$(ARCH): PACKAGE_NAME = xenstore-utils install-xenstore-utils_$(ARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-xenstore-utils_$(ARCH): $(STAMPS_DIR)/install-utils_$(ARCH) install-libxenstore_$(ARCH) dh_testdir dh_testroot dh_prep dh_install --sourcedir=$(DIR) dh_strip dh_shlibdeps +$(MAKE_SELF) install-base # vim: filetype=make debian/xen-utils-common.ucf0000664000000000000000000000007111755460744013120 0ustar /usr/share/xen-utils-common/default.xen /etc/default/xen debian/xen-migrate-xend-managed-domains0000775000000000000000000000270712321454755015332 0ustar #!/bin/sh SRCDIR="/var/lib/xend/domains" TGTDIR="/etc/xen" if [ ! -d "$SRCDIR" ]; then exit 0 fi if [ -f /var/lib/xend/migration-done ]; then exit 0 fi XENPROC="/proc/xen/capabilities" if [ ! -f $XENPROC ] || [ "$(cat $XENPROC)" != "control_d" ]; then if [ "$(find $SRCDIR -name config.sxp 2>/dev/null)" != "" ]; then echo "---" echo "--- INFO: Cannot migrate xend domains when not" echo "--- running under Xen hypervisor!" echo "---" echo "Boot into the Xen hypervisor and run" echo "$0 inside dom0." fi >&2 exit 0 fi PATH="$(/usr/lib/xen-common/bin/xen-dir)/bin:$PATH" export PATH N=0 LOG="" for DOMUUID in $(ls -1 "$SRCDIR"); do CFGFILE="$SRCDIR/$DOMUUID/config.sxp" if [ -f "$CFGFILE" ]; then LOG="$LOG\n$(xen-sxp2xm $CFGFILE $TGTDIR)" if [ $? -eq 0 ]; then N=$(($N + 1)) fi fi done if [ $N -gt 0 ]; then echo "---" echo "--- INFO" echo "---" echo "The xm toolstack is deprecated and the default was changed to" echo "xl. However the xl toolstack does not support the managed" echo "domains of xend. $N domain(s) were converted into the xen-xm" echo "format and can be found under /etc/xen/.cfg." echo "The conversion might be incomplete. Please make sure to review" echo "the result." echo "Note that those might only be meaningful if using the xl/xen" echo "commands directly. Access through libvirt will get (or has" echo "been) migrated separately." echo "$LOG" touch /var/lib/xend/migration-done fi >&2 debian/tree/0000775000000000000000000000000012212071061010117 5ustar debian/tree/xen-utils-common/0000775000000000000000000000000012212071061013335 5ustar debian/tree/xen-utils-common/usr/0000775000000000000000000000000012212071061014146 5ustar debian/tree/xen-utils-common/usr/share/0000775000000000000000000000000012212071061015250 5ustar debian/tree/xen-utils-common/usr/share/xen-utils-common/0000775000000000000000000000000012316237263020503 5ustar debian/tree/xen-utils-common/usr/share/xen-utils-common/default.xen0000664000000000000000000000045412307374333022646 0ustar # Configuration for Xen system # ---------------------------- # There exists several tool stacks to configure a Xen system. # xm: This is the old, deprecated toolstack (xend) # xl: This is the new toolstack using libxenlight/libxl # # Attention: You need to reboot after changing this! TOOLSTACK=xl debian/xen-utils.NEWS0000664000000000000000000000045711230344377011630 0ustar xen-3.0 (3.4.0-1) UNRELEASED; urgency=low This version does not longer ship the ioemu part, aka the patched qemu. So it does not support * full virtualized domains and * virtual console support for paravirtualized domains. -- Bastian Blank Sat, 18 Jul 2009 15:05:31 +0200 debian/lib/0000775000000000000000000000000012212071061007726 5ustar debian/lib/python/0000775000000000000000000000000012212071061011247 5ustar debian/lib/python/debian_xen/0000775000000000000000000000000012221321226013344 5ustar debian/lib/python/debian_xen/debian.py0000664000000000000000000000116111766343634015163 0ustar import re from debian_linux.debian import Version class VersionXen(Version): _version_xen_rules = ur""" ^ (?P \d+\.\d+ ) (?: \.\d+ (?: ~rc\d+ )? (?: \+hg-\d+.[a-z0-9]+ )? | ~hg-\d+.[a-z0-9]+ ) - (?:[^-]+) $ """ _version_xen_re = re.compile(_version_xen_rules, re.X) def __init__(self, version): super(VersionXen, self).__init__(version) match = self._version_xen_re.match(version) if match is None: raise ValueError("Invalid debian xen version") d = match.groupdict() self.xen_version = d['version'] debian/lib/python/debian_xen/__init__.py0000664000000000000000000000115710720110172015457 0ustar def _setup(): import os.path, sys version = None rules = os.path.join(__path__[0], "../../../rules.defs") f = file(rules) for l in f: l = l.strip().split() if l[0] == 'KERNELVERSION': version = l[-1] f.close() if version is None: raise RuntimeError("Can't find KERNELVERSION setting") global support support = '/usr/src/linux-support-%s' % version if not os.path.exists(support): raise RuntimeError("Can't find %s, please install the linux-support-%s package" % (support, version)) sys.path.append('%s/lib/python' % support) _setup() debian/rules0000775000000000000000000000552612173475050010264 0ustar #!/usr/bin/make -f # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 include /usr/share/dpkg/default.mk SOURCE := $(shell dpkg-parsechangelog | sed -ne 's,^Source: *\(.*\)$$,\1,p') VERSION_BINNMU := $(shell echo "$(DEB_VERSION)" | sed -ne 's,.*\+b\(.*\)$$,\1,p') include debian/rules.defs setup: debian/control dh_testdir $(MAKE) -f debian/rules.gen setup_$(DEB_HOST_ARCH) build: build-arch build-indep build-arch: setup dh_testdir $(MAKE) -f debian/rules.gen build-arch_$(DEB_HOST_ARCH) build-indep: setup dh_testdir $(MAKE) -f debian/rules.gen build-indep maintainerclean: rm -f debian/control* debian/rules.gen debian/xen-hypervisor-* debian/xen-utils-[0-9]* rm -rf $(filter-out .svn debian, $(wildcard * .[^.]*)) clean: debian/control dh_testdir rm -rf $(BUILD_DIR) $(STAMPS_DIR) debian/lib/python/debian_xen/*.pyc dh_clean binary-indep: dh_testdir $(MAKE) -f debian/rules.gen binary-indep binary-arch: dh_testdir $(MAKE) -f debian/rules.gen binary-arch_$(DEB_HOST_ARCH) binary: binary-indep binary-arch DIR_ORIG = ../orig/$(SOURCE)-$(DEB_VERSION_EPOCH_UPSTREAM) TAR_ORIG_MAIN_NAME = $(SOURCE)_$(DEB_VERSION_EPOCH_UPSTREAM).orig.tar.gz TAR_ORIG_MAIN = $(firstword $(wildcard ../$(TAR_ORIG_MAIN_NAME)) $(wildcard ../orig/$(TAR_ORIG_MAIN_NAME))) TAR_ORIG_QEMU_NAME = $(SOURCE)_$(DEB_VERSION_EPOCH_UPSTREAM).orig-qemu.tar.gz TAR_ORIG_QEMU = $(firstword $(wildcard ../$(TAR_ORIG_QEMU_NAME)) $(wildcard ../orig/$(TAR_ORIG_QEMU_NAME))) orig: $(DIR_ORIG) rsync --delete --exclude debian --exclude .svk --exclude .svn -a $(DIR_ORIG)/ . $(DIR_ORIG): ifeq ($(TAR_ORIG_MAIN),) $(error Cannot find main orig tarball $(TAR_ORIG_MAIN_NAME)) else mkdir -p ../orig tar -C ../orig -xzf $(TAR_ORIG_MAIN) endif ifeq ($(TAR_ORIG_QEMU),) $(warning Cannot find qemu orig tarball $(TAR_ORIG_QEMU_NAME)) else tar -C $@ -xzf $(TAR_ORIG_QEMU) endif CONTROL_FILES += debian/changelog debian/bin/gencontrol.py $(wildcard debian/templates/*.in) CONTROL_FILES += $(wildcard debian/arch/defines) $(wildcard debian/arch/*/defines) GENCONTROL = $(__MODULES_DIR)gencontrol.py debian/control debian/rules.gen: $(CONTROL_FILES) ifeq ($(wildcard debian/control.md5sum),) $(MAKE) -f debian/rules debian/control-real else ifeq ($(VERSION_BINNMU),) md5sum --check debian/control.md5sum --status || \ $(MAKE) -f debian/rules debian/control-real else grep -v debian/changelog debian/control.md5sum | md5sum --check - --status || \ $(MAKE) -f debian/rules debian/control-real endif debian/control-real: $(CONTROL_FILES) debian/bin/gencontrol.py md5sum $^ > debian/control.md5sum @echo @echo This target is made to fail intentionally, to make sure @echo that it is NEVER run during the automated build. Please @echo ignore the following error, the debian/control file has @echo been generated SUCCESSFULLY. @echo exit 1 .PHONY: clean build binary-indep binary-arch binary debian/xen-utils-4.4.postinst0000664000000000000000000000055312321467057013242 0ustar #!/bin/sh set -e case "$1" in configure) if [ -x "/etc/init.d/xen" ]; then invoke-rc.d xen start || exit $? fi /usr/lib/xen-4.4/bin/xen-migrate-xend-managed-domains ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/libxen-dev.install0000664000000000000000000000067312175760301012625 0ustar usr/lib/libxenctrl.a usr/lib/libxenctrl.so usr/lib/libxenguest.a usr/lib/libxenguest.so usr/lib/libxenlight.a usr/lib/libxenlight.so usr/lib/libxenstore.a usr/lib/libxenstore.so usr/lib/libxlutil.a usr/lib/libxlutil.so usr/include/_libxl*.h usr/include/libxl*.h usr/include/xenctrl.h usr/include/xenguest.h usr/include/xenstore*.h usr/include/xenstore-compat/xs* usr/include usr/include/xentoollog.h usr/include/xenctrlosdep.h usr/include/xen