parent
70a9b2bdb2
commit
60e940e1aa
@ -1,2 +1,3 @@
|
||||
DIST glance-2013.1.4.tar.gz 724110 SHA256 dfb8070a12bbf5761db1c55d21db4772fe81ed903d57cf991618e5224cbdcd67 SHA512 31c6c4ba0e777fcd345fe24d32eab548f8e9756764051d8b3c50d4d54404c902473760a0dc1158e8b6b42a0b81e14ae6a31d03bb07d4254fcb4960b05dd747a9 WHIRLPOOL 770f782f539b0ac465c00e726552f4b7fc8824c4a9da1a94ef4103ef56ce17ff1c2ccc75140b71c9f4d3d875885f169d3c1c6d761fed7ff691c83484b86de74f
|
||||
DIST glance-2013.2.1.tar.gz 1616541 SHA256 f04eb070a862c0d14bdd94204a6f17f4a813dbeacc1978dffb53752c360731aa SHA512 42a30004d7677c946216bd934712094f585d1a98c8e4d7a4b51a14af93eac3e251bd7ef16fa9d9915f3c2f75974969306439742aaeaa64bf3d983ab458531ee5 WHIRLPOOL b76513207e56f3ceb18976b901a79fd5fbff2a9779df1179e79dc5d10049d3b100124e61b55e26ef47f5df54f03a1122752939e4b028d7873b0b0b771aabe9ac
|
||||
DIST glance-2013.2.2.tar.gz 1333129 SHA256 311805e1df5005ee554871f0096845c966af3cec41cbcf00f1a7e906582b05e1 SHA512 4516b0ce08be63aa22ffaeb7b0f2bf7ef5e6637d9058461337bdaffb18c5876637cef5240068954f40c72a8021969d755a678c4d7172606592acce1e731594ae WHIRLPOOL a8c6ad325f3e78786762b5717dcee5878540cc0a06f4428cd47657ee85d93db5c2a3d7b47dc758e88e174c9ea141aba48bef902b52671b4d415c5f2d9463da2a
|
||||
|
@ -0,0 +1,139 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-admin/glance/glance-2013.2.2.ebuild,v 1.1 2014/02/20 21:00:22 prometheanfire Exp $
|
||||
|
||||
EAPI=5
|
||||
PYTHON_COMPAT=( python2_7 )
|
||||
|
||||
inherit distutils-r1 user
|
||||
|
||||
DESCRIPTION="Provides services for discovering, registering, and retrieving
|
||||
virtual machine images with Openstack"
|
||||
HOMEPAGE="https://launchpad.net/glance"
|
||||
SRC_URI="http://launchpad.net/${PN}/havana/${PV}/+download/${P}.tar.gz"
|
||||
|
||||
LICENSE="Apache-2.0"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
IUSE="doc mysql postgres +sqlite +swift test"
|
||||
REQUIRED_USE="|| ( mysql postgres sqlite )"
|
||||
|
||||
DEPEND="dev-python/setuptools[${PYTHON_USEDEP}]
|
||||
dev-python/pbr[${PYTHON_USEDEP}]
|
||||
test? ( >=dev-python/coverage-3.6[${PYTHON_USEDEP}]
|
||||
>=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}]
|
||||
dev-python/nose[${PYTHON_USEDEP}]
|
||||
dev-python/nose-exclude[${PYTHON_USEDEP}]
|
||||
>=dev-python/openstack-nose-plugin-0.7[${PYTHON_USEDEP}]
|
||||
>=dev-python/mock-1.0[${PYTHON_USEDEP}]
|
||||
>=dev-python/nosehtmloutput-0.0.3[${PYTHON_USEDEP}]
|
||||
>=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
|
||||
>=dev-python/requests-1.1[${PYTHON_USEDEP}]
|
||||
>=dev-python/testtools-0.9.32[${PYTHON_USEDEP}]
|
||||
>=dev-python/psutil-0.6.1[${PYTHON_USEDEP}]
|
||||
dev-python/mysql-python[${PYTHON_USEDEP}]
|
||||
dev-python/psycopg[${PYTHON_USEDEP}]
|
||||
>=dev-python/pyxattr-0.5.0[${PYTHON_USEDEP}]
|
||||
~dev-python/pep8-1.4.5[${PYTHON_USEDEP}]
|
||||
>=dev-python/pyflakes-0.7.2[${PYTHON_USEDEP}]
|
||||
<dev-python/pyflakes-0.7.4[${PYTHON_USEDEP}]
|
||||
~dev-python/flake8-2.0[${PYTHON_USEDEP}]
|
||||
>=dev-python/hacking-0.5.6[${PYTHON_USEDEP}]
|
||||
<dev-python/hacking-0.8[${PYTHON_USEDEP}]
|
||||
>=dev-python/Babel-1.3[${PYTHON_USEDEP}]
|
||||
=dev-python/pysendfile-2.0.0[${PYTHON_USEDEP}]
|
||||
dev-python/qpid-python[${PYTHON_USEDEP}]
|
||||
dev-python/oslo-sphinx
|
||||
>=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}]
|
||||
<dev-python/sphinx-1.2[${PYTHON_USEDEP}] )"
|
||||
#note to self, wsgiref is a python builtin, no need to package it
|
||||
#>=dev-python/wsgiref-0.1.2[${PYTHON_USEDEP}]
|
||||
|
||||
RDEPEND=">=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}]
|
||||
>=dev-python/eventlet-0.13.0[${PYTHON_USEDEP}]
|
||||
sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}]
|
||||
<dev-python/sqlalchemy-0.7.99[sqlite,${PYTHON_USEDEP}] )
|
||||
mysql? ( >=dev-python/sqlalchemy-0.7.8[mysql,${PYTHON_USEDEP}]
|
||||
<dev-python/sqlalchemy-0.7.99[mysql,${PYTHON_USEDEP}] )
|
||||
postgres? ( >=dev-python/sqlalchemy-0.7.8[postgres,${PYTHON_USEDEP}]
|
||||
<dev-python/sqlalchemy-0.7.99[postgres,${PYTHON_USEDEP}] )
|
||||
>=dev-python/anyjson-0.3.3[${PYTHON_USEDEP}]
|
||||
>=dev-python/pastedeploy-1.5.0[${PYTHON_USEDEP}]
|
||||
>=dev-python/routes-1.12.3[${PYTHON_USEDEP}]
|
||||
>=dev-python/webob-1.2.3[${PYTHON_USEDEP}]
|
||||
<dev-python/webob-1.3[${PYTHON_USEDEP}]
|
||||
virtual/python-argparse[${PYTHON_USEDEP}]
|
||||
>=dev-python/boto-2.4.0[${PYTHON_USEDEP}]
|
||||
!~dev-python/boto-2.13.0[${PYTHON_USEDEP}]
|
||||
>=dev-python/sqlalchemy-migrate-0.7.2[${PYTHON_USEDEP}]
|
||||
dev-python/httplib2[${PYTHON_USEDEP}]
|
||||
>=dev-python/kombu-2.4.8[${PYTHON_USEDEP}]
|
||||
>=dev-python/pycrypto-2.6[${PYTHON_USEDEP}]
|
||||
>=dev-python/iso8601-0.1.8[${PYTHON_USEDEP}]
|
||||
>=dev-python/oslo-config-1.2.1[${PYTHON_USEDEP}]
|
||||
swift? (
|
||||
>=dev-python/python-swiftclient-1.5[${PYTHON_USEDEP}]
|
||||
<dev-python/python-swiftclient-2[${PYTHON_USEDEP}]
|
||||
)
|
||||
>=dev-python/lxml-2.3[${PYTHON_USEDEP}]
|
||||
dev-python/paste[${PYTHON_USEDEP}]
|
||||
dev-python/passlib[${PYTHON_USEDEP}]
|
||||
>=dev-python/jsonschema-1.3.0[${PYTHON_USEDEP}]
|
||||
!~dev-python/jsonschema-1.4.0[${PYTHON_USEDEP}]
|
||||
>=dev-python/python-cinderclient-1.0.6[${PYTHON_USEDEP}]
|
||||
>=dev-python/python-keystoneclient-0.3.2[${PYTHON_USEDEP}]
|
||||
dev-python/pyopenssl[${PYTHON_USEDEP}]
|
||||
>=dev-python/six-1.4.1[${PYTHON_USEDEP}]"
|
||||
|
||||
PATCHES=( "${FILESDIR}/${PN}-2013.2-sphinx_mapping.patch" )
|
||||
|
||||
pkg_setup() {
|
||||
enewgroup glance
|
||||
enewuser glance -1 -1 /var/lib/glance glance
|
||||
}
|
||||
|
||||
python_compile_all() {
|
||||
use doc && "${PYTHON}" setup.py build_sphinx
|
||||
}
|
||||
|
||||
python_test() {
|
||||
# https://bugs.launchpad.net/glance/+bug/1251105
|
||||
# https://bugs.launchpad.net/glance/+bug/1242501
|
||||
# 2013.2 requires =dev-python/iso8601-0.1.4
|
||||
nosetests glance/ || die "tests failed under python2.7"
|
||||
}
|
||||
|
||||
python_install() {
|
||||
distutils-r1_python_install
|
||||
newconfd "${FILESDIR}/glance.confd" glance
|
||||
newinitd "${FILESDIR}/glance.initd" glance
|
||||
|
||||
for function in api registry scrubber; do
|
||||
dosym /etc/init.d/glance /etc/init.d/glance-${function}
|
||||
done
|
||||
|
||||
diropts -m 0750
|
||||
dodir /var/run/glance /var/log/glance /var/lib/glance/images /var/lib/glance/scrubber
|
||||
keepdir /etc/glance
|
||||
keepdir /var/log/glance
|
||||
keepdir /var/lib/glance/images
|
||||
keepdir /var/lib/glance/scrubber
|
||||
insinto /etc/glance
|
||||
|
||||
doins "etc/glance-api-paste.ini"
|
||||
doins "etc/glance-api.conf"
|
||||
doins "etc/glance-cache.conf"
|
||||
doins "etc/glance-registry-paste.ini"
|
||||
doins "etc/glance-registry.conf"
|
||||
doins "etc/glance-scrubber.conf"
|
||||
doins "etc/logging.cnf.sample"
|
||||
doins "etc/policy.json"
|
||||
doins "etc/schema-image.json"
|
||||
|
||||
fowners glance:glance /var/run/glance /var/log/glance /var/lib/glance/images /var/lib/glance/scrubber /etc/glance
|
||||
}
|
||||
|
||||
python_install_all() {
|
||||
use doc && local HTML_DOCS=( doc/build/html/. )
|
||||
distutils-r1_python_install_all
|
||||
}
|
@ -1,32 +1,27 @@
|
||||
# Copyright 1999-2008 Gentoo Foundation
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/css-mode/css-mode-0.11.ebuild,v 1.10 2008/02/14 10:07:30 ulm Exp $
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/css-mode/css-mode-0.11.ebuild,v 1.11 2014/02/21 00:10:55 ulm Exp $
|
||||
|
||||
inherit elisp
|
||||
EAPI=5
|
||||
|
||||
IUSE=""
|
||||
inherit elisp
|
||||
|
||||
DESCRIPTION="A major mode for editing Cascading Style Sheets (CSS)"
|
||||
HOMEPAGE="http://www.garshol.priv.no/download/software/css-mode/"
|
||||
SRC_URI="mirror://gentoo/${P}.tar.bz2"
|
||||
LICENSE="GPL-2"
|
||||
|
||||
LICENSE="GPL-2+"
|
||||
SLOT="0"
|
||||
KEYWORDS="amd64 ppc ppc64 x86 ~x86-fbsd"
|
||||
|
||||
DEPEND=">=sys-apps/sed-4"
|
||||
RDEPEND=""
|
||||
|
||||
SITEFILE="50${PN}-gentoo.el"
|
||||
|
||||
src_unpack() {
|
||||
unpack ${A}
|
||||
|
||||
src_prepare() {
|
||||
# Fix documentation
|
||||
sed -i -e 's,HREF="/visuals/standard.css",HREF="standard.css",' \
|
||||
"${S}/doco.html"
|
||||
sed -i -e 's,HREF="/visuals/standard.css",HREF="standard.css",' doco.html
|
||||
}
|
||||
|
||||
src_install() {
|
||||
elisp_src_install
|
||||
dohtml -A css "${S}/doco.html" "${S}/standard.css"
|
||||
dohtml -A css doco.html standard.css
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
|
||||
;;; css-mode site-lisp configuration
|
||||
|
||||
(add-to-list 'load-path "@SITELISP@")
|
||||
(add-to-list 'auto-mode-alist '("\\.css$" . css-mode))
|
||||
(autoload 'css-mode "css-mode" "Mode for editing Cascading Style Sheets")
|
||||
(add-to-list 'auto-mode-alist '("\\.css\\'" . css-mode))
|
||||
(autoload 'css-mode "css-mode" "Mode for editing Cascading Style Sheets" t)
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
|
||||
<pkgmetadata>
|
||||
<herd>emacs</herd>
|
||||
<upstream>
|
||||
<remote-id type="google-code">distel</remote-id>
|
||||
</upstream>
|
||||
<herd>emacs</herd>
|
||||
<upstream>
|
||||
<remote-id type="google-code">distel</remote-id>
|
||||
</upstream>
|
||||
</pkgmetadata>
|
||||
|
@ -1 +1,2 @@
|
||||
DIST initsplit-1.6.tar.gz 2454 SHA256 64612a8bdc43875b2889549e1182cae39041676dac92151f53bca0473cbc4e4c SHA512 a03217a4d30c539cb0413d517c954015100f17c1183f3ca7d14a7edd5c4ab7e258f05e0c1c8fe5ed6fff1071eda0f9fbe10590a27521bb99eabb4cc819fb748c WHIRLPOOL 9fdbeb2ab62934bdc669ea50b74436a317df8181f06645d4085d3108af4b0d2f3ff6ff87eaf71ec131b0172413285b9b4960ea99b62237ea64f859a1613845eb
|
||||
DIST initsplit-1.7_pre20140203.el.xz 4792 SHA256 4005271af94ca4dad7a3b6b084fcb1e5b93097e98ee15810b766efddd2f8a718 SHA512 f2c894bb9d0359b5e95760541feb83f465950de732266059b9498b7ee7361ebb843e0d900fec92fa5e9c37547ea160836b9fc24f64c56083e3ea4416b4b52e50 WHIRLPOOL d10ba44154fc6030fed39a2cb325ced928501d8bfddc47b5364ac95b0ee55bea6f3a7d01a2dad166622d2baa247a0188b30da6d2fa5f42ad43cbd20259b8ef9d
|
||||
|
@ -0,0 +1,2 @@
|
||||
(add-to-list 'load-path "@SITELISP@")
|
||||
(autoload 'initsplit-byte-compile-files "initsplit")
|
@ -0,0 +1,23 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/initsplit/initsplit-1.7_pre20140203.ebuild,v 1.1 2014/02/20 12:25:30 ulm Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit readme.gentoo elisp
|
||||
|
||||
DESCRIPTION="Split customizations into different files"
|
||||
HOMEPAGE="http://www.emacswiki.org/emacs/InitSplit"
|
||||
# taken from https://github.com/dabrahams/${PN}
|
||||
SRC_URI="http://dev.gentoo.org/~ulm/distfiles/${P}.el.xz"
|
||||
|
||||
LICENSE="GPL-2+"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64 ~ppc ~x86"
|
||||
|
||||
SITEFILE="50${PN}-gentoo.el"
|
||||
DOC_CONTENTS="Initsplit is not enabled as a site default. Add the following
|
||||
line to your ~/.emacs file to enable configuration file splitting:
|
||||
\n\t(load \"initsplit\")
|
||||
\n\nIf you want configuration files byte-compiled, also add this line:
|
||||
\n\t(add-hook 'after-save-hook 'initsplit-byte-compile-files t)"
|
@ -1 +1,2 @@
|
||||
DIST mode-compile-2.29.1.tar.gz 22924 SHA256 9c7dafa3a5c5706316a01071a2769beeecf228d0831fceb53d27d4e47c9d0421 SHA512 bc43d9cae411f5177ce70c736041db74c6db1dc5b766b22b92227e9e1324d304276bd104d8e3cac9ff5a877fc48b6da5b904e1acdb6cca7396fc7c26cc572815 WHIRLPOOL 3980e43e28438f5eefbd1d8e689cc18d9cc922857ec3e32b58c6aa6d056cc6798c2094b65de28705db6dfc95e493a06858a208c536f2c9d217027d47c4b311a9
|
||||
DIST mode-compile-2.29.el.bz2 21579 SHA256 c7cd617d5b1445638621b37f21a062de41f9b3b3eef829d9aa045a5571cb6556 SHA512 31573552298f2ffa8e89dbdb4155f3c95c5e354966ec4966098fe90bffd0e8fd8ecd86a7453adc10fb551622b9929aa58ce3abeb90b605373d6d4a874aa5ba7c WHIRLPOOL 85f1f740d3f3fe311bbc888bcdeba0a9ebb614b0adaae231d0aeb0912862e79c44130880d1e636a7465c9bc8f92261e0eecf961ecf800b60bbba1d76ee5b0e40
|
||||
|
@ -0,0 +1,18 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/mode-compile/mode-compile-2.29.1.ebuild,v 1.1 2014/02/20 17:36:48 ulm Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit elisp
|
||||
|
||||
DESCRIPTION="Smart command for compiling files according to major-mode"
|
||||
HOMEPAGE="https://github.com/emacsmirror/mode-compile
|
||||
http://www.emacswiki.org/emacs/ModeCompile"
|
||||
SRC_URI="https://github.com/emacsmirror/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz"
|
||||
|
||||
LICENSE="GPL-3+"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
|
||||
SITEFILE="50${PN}-gentoo.el"
|
@ -1,2 +1,2 @@
|
||||
DIST mpg123-el-1.55.tar.bz2 33925 SHA256 c388bf8e93b772c90126b905224c43cfc2e709be503e3508b684f05750d19499 SHA512 49737d9eab292599f446d87ace8155be0227fc2f18910e3d184d238f323b40218630a91cef2438dd0e5453a289f32f4fe9cff3f884a7e20cc63dd4668cb48c7f WHIRLPOOL 5b067cdc810c843f693cfd1445e9ddaf57dc19cf0ad7440e23482af5146da3aa008cdafb4828a2191153551d81e3e885d924b119b107c2d50c712d2930c65d0b
|
||||
DIST mpg123-el-1.58.tar.bz2 34097 SHA256 efdd491329ba56096ad971bd5c2e2ceeea296fe8e26340d2370ae63bcdc33606 SHA512 53a67eb219acbeefeb8360a9d43279d2bb3efa48fa5df3787f2b7fad4f6b49402f319925bac3fc17ee1cad0dcbe38494c8162d4eb5e08261b2e505b40a66a987 WHIRLPOOL 83c8d660fd18d3faefff106c62127c0487c47824f9b53f157c27b127cd1dd624dad445217b99e5e3183ab02bf13fef3abdd077451ec8ce934c188fc356522181
|
||||
DIST mpg123-el-1.59.tar.xz 34076 SHA256 6105c3d11099a96cc5cb77909ca8d9e5ea4d5cb78b6a7ca185eb350425e075b4 SHA512 48fae024529be7b88553fc43fb626253f3d3a10d6709378a565a0d407374569e5573e52c0b26abc4d6f2f51ad7f680d655a1ac15ff696f4534c39a9a3536bc0e WHIRLPOOL 6434aa2368976698437c0a7ec12c126861c7f0096f4263f59b555b59c8d20377b5279ce09ceb99bb4b333318541126bb990009234cbd611ffdc2b91e980903f0
|
||||
|
@ -1,34 +1,38 @@
|
||||
# Copyright 1999-2012 Gentoo Foundation
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/mpg123-el/mpg123-el-1.55.ebuild,v 1.7 2012/09/25 21:18:36 ulm Exp $
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/mpg123-el/mpg123-el-1.59.ebuild,v 1.1 2014/02/20 18:25:35 ulm Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit elisp toolchain-funcs
|
||||
|
||||
DESCRIPTION="Emacs front-end to mpg123 audio player and OggVorbis audio player"
|
||||
HOMEPAGE="http://www.gentei.org/~yuuji/software/mpg123el/"
|
||||
SRC_URI="mirror://gentoo/${P}.tar.bz2"
|
||||
SRC_URI="http://dev.gentoo.org/~ulm/distfiles/${P}.tar.xz"
|
||||
|
||||
LICENSE="mpg123-el"
|
||||
SLOT="0"
|
||||
KEYWORDS="amd64 ppc x86"
|
||||
KEYWORDS="~amd64 ~ppc ~x86"
|
||||
IUSE="vorbis"
|
||||
|
||||
DEPEND=""
|
||||
RDEPEND="media-sound/mpg123
|
||||
media-sound/alsa-utils
|
||||
vorbis? ( media-sound/vorbis-tools )"
|
||||
|
||||
SITEFILE="50${PN}-gentoo.el"
|
||||
|
||||
src_compile() {
|
||||
src_prepare() {
|
||||
sed -i -e "s/\(mainloop:\)/\1 ;/" tagput.c || die
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
$(tc-getCC) ${CFLAGS} ${LDFLAGS} -o tagput tagput.c || die
|
||||
$(tc-getCC) ${CFLAGS} ${LDFLAGS} -o id3put id3put.c || die
|
||||
elisp-compile *.el || die
|
||||
elisp-compile *.el
|
||||
}
|
||||
|
||||
src_install() {
|
||||
dobin tagput id3put || die
|
||||
elisp-install ${PN} *.el *.elc || die
|
||||
elisp-site-file-install "${FILESDIR}/${SITEFILE}" || die
|
||||
dobin tagput id3put
|
||||
elisp-install ${PN} *.el *.elc
|
||||
elisp-site-file-install "${FILESDIR}/${SITEFILE}"
|
||||
}
|
@ -1,6 +1,3 @@
|
||||
|
||||
;;; protbuf site-lisp configuration
|
||||
|
||||
(add-to-list 'load-path "@SITELISP@")
|
||||
|
||||
(autoload 'protect-buffer-from-kill-mode "protbuf"
|
@ -1,16 +1,18 @@
|
||||
# Copyright 1999-2007 Gentoo Foundation
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/protbuf/protbuf-1.7-r1.ebuild,v 1.2 2007/12/02 14:07:50 opfer Exp $
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/protbuf/protbuf-1.7-r1.ebuild,v 1.3 2014/02/20 23:14:09 ulm Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit elisp
|
||||
|
||||
DESCRIPTION="Protect Emacs buffers from accidental killing"
|
||||
HOMEPAGE="http://www.emacswiki.org/cgi-bin/wiki.pl?ProtectingBuffers"
|
||||
HOMEPAGE="http://www.splode.com/~friedman/software/emacs-lisp/
|
||||
http://www.emacswiki.org/emacs/ProtectingBuffers"
|
||||
SRC_URI="mirror://gentoo/${P}.tar.bz2"
|
||||
|
||||
LICENSE="GPL-2"
|
||||
LICENSE="GPL-2+"
|
||||
SLOT="0"
|
||||
KEYWORDS="amd64 ~ppc x86"
|
||||
IUSE=""
|
||||
|
||||
SITEFILE=51${PN}-gentoo.el
|
||||
SITEFILE="50${PN}-gentoo.el"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
|
||||
<pkgmetadata>
|
||||
<herd>emacs</herd>
|
||||
<herd>emacs</herd>
|
||||
</pkgmetadata>
|
||||
|
@ -1 +1,2 @@
|
||||
DIST rfcview-0.13.el.xz 8836 SHA256 eff317b01824832288abe4e60884665fc22e3dbec315a1fb1779cf679f0a8d89 SHA512 84cda45b5e941808e2ddc50d5f03d7b2d3831208d08dddd2fe2121a20ddcbb7d24b148b2ec2ba07e0b9a04da81ae4d14269d0062955961679ac5c7532de1e6e5 WHIRLPOOL 6f10e4cd4f2d027804f030ff90430b80b89bfbb1df01b4ed8c30fcba049f11d0d3bb192ad18f453d73c81fbf3406b92f92817c3b9c0fa8c74860a371fbd341b1
|
||||
DIST rfcview-0.5.tar.gz 6116 SHA256 b74f7918fd9bd40138f5679f45ff8ecdb31dfde3c1f0d2011e6c0a09fe37a3fb SHA512 b83deb28624123f1fdf105cf287b03e45965b9443bcc89c5f1a12b9595791494384af284517ca1f994eddebc2245202811b4001f4cd8a8bdecd15f117392bc6a WHIRLPOOL 0c6debab4c322c7badb782012bcb7df0d570c62e73da5a5e37177ec469cf9bff48e60aabfa1dacdf3137301e48bcf3eea424e5403d50bd9652cda58b19b44b8c
|
||||
|
@ -0,0 +1,19 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emacs/rfcview/rfcview-0.13.ebuild,v 1.1 2014/02/20 23:46:50 ulm Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit elisp
|
||||
|
||||
DESCRIPTION="An Emacs mode that reformats IETF RFCs for display"
|
||||
HOMEPAGE="http://www.loveshack.ukfsn.org/emacs/
|
||||
http://www.emacswiki.org/emacs-de/RfcView"
|
||||
# taken from http://www.loveshack.ukfsn.org/emacs/${PN}.el
|
||||
SRC_URI="http://dev.gentoo.org/~ulm/distfiles/${P}.el.xz"
|
||||
|
||||
LICENSE="GPL-3+"
|
||||
SLOT="0"
|
||||
KEYWORDS="~alpha ~amd64 ~x86"
|
||||
|
||||
SITEFILE="50${PN}-gentoo.el"
|
@ -0,0 +1,436 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/wine/wine-1.7.13.ebuild,v 1.1 2014/02/21 06:31:47 tetromino Exp $
|
||||
|
||||
EAPI="5"
|
||||
|
||||
AUTOTOOLS_AUTORECONF=1
|
||||
PLOCALES="ar bg ca cs da de el en en_US eo es fa fi fr he hi hr hu it ja ko lt ml nb_NO nl or pa pl pt_BR pt_PT rm ro ru sk sl sr_RS@cyrillic sr_RS@latin sv te th tr uk wa zh_CN zh_TW"
|
||||
PLOCALE_BACKUP="en"
|
||||
|
||||
inherit autotools-multilib eutils fdo-mime flag-o-matic gnome2-utils l10n multilib pax-utils toolchain-funcs virtualx
|
||||
|
||||
if [[ ${PV} == "9999" ]] ; then
|
||||
EGIT_REPO_URI="git://source.winehq.org/git/wine.git"
|
||||
inherit git-2
|
||||
SRC_URI=""
|
||||
#KEYWORDS=""
|
||||
else
|
||||
MY_P="${PN}-${PV/_/-}"
|
||||
SRC_URI="mirror://sourceforge/${PN}/Source/${MY_P}.tar.bz2"
|
||||
KEYWORDS="-* ~amd64 ~x86 ~x86-fbsd"
|
||||
S=${WORKDIR}/${MY_P}
|
||||
fi
|
||||
|
||||
GV="2.24"
|
||||
MV="4.5.2"
|
||||
PULSE_PATCHES="winepulse-patches-1.7.12"
|
||||
WINE_GENTOO="wine-gentoo-2013.06.24"
|
||||
DESCRIPTION="Free implementation of Windows(tm) on Unix"
|
||||
HOMEPAGE="http://www.winehq.org/"
|
||||
SRC_URI="${SRC_URI}
|
||||
gecko? (
|
||||
abi_x86_32? ( mirror://sourceforge/${PN}/Wine%20Gecko/${GV}/wine_gecko-${GV}-x86.msi )
|
||||
abi_x86_64? ( mirror://sourceforge/${PN}/Wine%20Gecko/${GV}/wine_gecko-${GV}-x86_64.msi )
|
||||
)
|
||||
mono? ( mirror://sourceforge/${PN}/Wine%20Mono/${MV}/wine-mono-${MV}.msi )
|
||||
pulseaudio? ( http://dev.gentoo.org/~tetromino/distfiles/${PN}/${PULSE_PATCHES}.tar.bz2 )
|
||||
http://dev.gentoo.org/~tetromino/distfiles/${PN}/${WINE_GENTOO}.tar.bz2"
|
||||
|
||||
LICENSE="LGPL-2.1"
|
||||
SLOT="0"
|
||||
IUSE="+abi_x86_32 +abi_x86_64 +alsa capi cups custom-cflags dos elibc_glibc +fontconfig +gecko gphoto2 gsm gstreamer +jpeg lcms ldap +mono mp3 ncurses netapi nls odbc openal opencl +opengl osmesa oss +perl +png +prelink pulseaudio +realtime +run-exes samba scanner selinux +ssl test +threads +truetype +udisks v4l +X xcomposite xinerama +xml"
|
||||
REQUIRED_USE="|| ( abi_x86_32 abi_x86_64 )
|
||||
test? ( abi_x86_32 )
|
||||
elibc_glibc? ( threads )
|
||||
mono? ( abi_x86_32 )
|
||||
osmesa? ( opengl )" #286560
|
||||
|
||||
# FIXME: the test suite is unsuitable for us; many tests require net access
|
||||
# or fail due to Xvfb's opengl limitations.
|
||||
RESTRICT="test"
|
||||
|
||||
NATIVE_DEPEND="
|
||||
truetype? ( >=media-libs/freetype-2.0.0 )
|
||||
capi? ( net-dialup/capi4k-utils )
|
||||
ncurses? ( >=sys-libs/ncurses-5.2:= )
|
||||
udisks? ( sys-apps/dbus )
|
||||
fontconfig? ( media-libs/fontconfig:= )
|
||||
gphoto2? ( media-libs/libgphoto2:= )
|
||||
openal? ( media-libs/openal:= )
|
||||
gstreamer? ( media-libs/gstreamer:0.10 media-libs/gst-plugins-base:0.10 )
|
||||
X? (
|
||||
x11-libs/libXcursor
|
||||
x11-libs/libXext
|
||||
x11-libs/libXrandr
|
||||
x11-libs/libXi
|
||||
x11-libs/libXxf86vm
|
||||
)
|
||||
xinerama? ( x11-libs/libXinerama )
|
||||
alsa? ( media-libs/alsa-lib )
|
||||
cups? ( net-print/cups:= )
|
||||
opencl? ( virtual/opencl )
|
||||
opengl? (
|
||||
virtual/glu
|
||||
virtual/opengl
|
||||
)
|
||||
gsm? ( media-sound/gsm:= )
|
||||
jpeg? ( virtual/jpeg:0= )
|
||||
ldap? ( net-nds/openldap:= )
|
||||
lcms? ( media-libs/lcms:2= )
|
||||
mp3? ( >=media-sound/mpg123-1.5.0 )
|
||||
netapi? ( net-fs/samba[netapi(+)] )
|
||||
nls? ( sys-devel/gettext )
|
||||
odbc? ( dev-db/unixODBC:= )
|
||||
osmesa? ( media-libs/mesa[osmesa] )
|
||||
pulseaudio? ( media-sound/pulseaudio )
|
||||
xml? ( dev-libs/libxml2 dev-libs/libxslt )
|
||||
scanner? ( media-gfx/sane-backends:= )
|
||||
ssl? ( net-libs/gnutls:= )
|
||||
png? ( media-libs/libpng:0= )
|
||||
v4l? ( media-libs/libv4l )
|
||||
xcomposite? ( x11-libs/libXcomposite )"
|
||||
|
||||
COMMON_DEPEND="
|
||||
!amd64? ( ${NATIVE_DEPEND} )
|
||||
amd64? (
|
||||
abi_x86_64? ( ${NATIVE_DEPEND} )
|
||||
abi_x86_32? (
|
||||
truetype? ( || (
|
||||
>=app-emulation/emul-linux-x86-xlibs-2.1[development]
|
||||
>=media-libs/freetype-2.0.0[abi_x86_32]
|
||||
) )
|
||||
ncurses? ( || (
|
||||
app-emulation/emul-linux-x86-baselibs[development]
|
||||
sys-libs/ncurses[abi_x86_32]
|
||||
) )
|
||||
udisks? ( || (
|
||||
>=app-emulation/emul-linux-x86-baselibs-20130224[development]
|
||||
sys-apps/dbus[abi_x86_32]
|
||||
) )
|
||||
fontconfig? ( || (
|
||||
app-emulation/emul-linux-x86-xlibs[development]
|
||||
media-libs/fontconfig[abi_x86_32]
|
||||
) )
|
||||
gphoto2? (
|
||||
app-emulation/emul-linux-x86-medialibs[development]
|
||||
)
|
||||
openal? ( || (
|
||||
app-emulation/emul-linux-x86-sdl[development]
|
||||
media-libs/openal[abi_x86_32]
|
||||
) )
|
||||
gstreamer? (
|
||||
app-emulation/emul-linux-x86-gstplugins
|
||||
app-emulation/emul-linux-x86-medialibs[development]
|
||||
)
|
||||
X? ( || (
|
||||
app-emulation/emul-linux-x86-xlibs[development]
|
||||
(
|
||||
x11-libs/libXcursor[abi_x86_32]
|
||||
x11-libs/libXext[abi_x86_32]
|
||||
x11-libs/libXrandr[abi_x86_32]
|
||||
x11-libs/libXi[abi_x86_32]
|
||||
x11-libs/libXxf86vm[abi_x86_32]
|
||||
)
|
||||
) )
|
||||
xinerama? ( || (
|
||||
app-emulation/emul-linux-x86-xlibs[development]
|
||||
x11-libs/libXinerama[abi_x86_32]
|
||||
) )
|
||||
alsa? ( || (
|
||||
app-emulation/emul-linux-x86-soundlibs[alsa,development]
|
||||
media-libs/alsa-lib[abi_x86_32]
|
||||
) )
|
||||
cups? ( app-emulation/emul-linux-x86-baselibs )
|
||||
opencl? ( virtual/opencl[abi_x86_32] )
|
||||
opengl? ( || (
|
||||
app-emulation/emul-linux-x86-opengl[development]
|
||||
(
|
||||
virtual/glu[abi_x86_32]
|
||||
virtual/opengl[abi_x86_32]
|
||||
)
|
||||
) )
|
||||
gsm? ( || (
|
||||
app-emulation/emul-linux-x86-soundlibs[development]
|
||||
media-sound/gsm[abi_x86_32]
|
||||
) )
|
||||
jpeg? ( || (
|
||||
app-emulation/emul-linux-x86-baselibs[development]
|
||||
virtual/jpeg:0[abi_x86_32]
|
||||
) )
|
||||
ldap? ( app-emulation/emul-linux-x86-baselibs[development] )
|
||||
lcms? ( || (
|
||||
app-emulation/emul-linux-x86-baselibs[development]
|
||||
media-libs/lcms:2[abi_x86_32]
|
||||
) )
|
||||
mp3? ( || (
|
||||
app-emulation/emul-linux-x86-soundlibs[development]
|
||||
>=media-sound/mpg123-1.5.0[abi_x86_32]
|
||||
) )
|
||||
nls? ( app-emulation/emul-linux-x86-baselibs[development] )
|
||||
odbc? ( app-emulation/emul-linux-x86-db[development] )
|
||||
osmesa? ( || (
|
||||
>=app-emulation/emul-linux-x86-opengl-20121028[development]
|
||||
media-libs/mesa[osmesa,abi_x86_32]
|
||||
) )
|
||||
pulseaudio? ( || (
|
||||
app-emulation/emul-linux-x86-soundlibs[development]
|
||||
>=media-sound/pulseaudio-4.0-r1[abi_x86_32]
|
||||
) )
|
||||
xml? ( >=app-emulation/emul-linux-x86-baselibs-20131008[development] )
|
||||
scanner? ( app-emulation/emul-linux-x86-medialibs[development] )
|
||||
ssl? ( app-emulation/emul-linux-x86-baselibs[development] )
|
||||
png? ( || (
|
||||
app-emulation/emul-linux-x86-baselibs[development]
|
||||
media-libs/libpng:0[abi_x86_32]
|
||||
) )
|
||||
v4l? ( || (
|
||||
app-emulation/emul-linux-x86-medialibs[development]
|
||||
media-libs/libv4l[abi_x86_32]
|
||||
) )
|
||||
xcomposite? ( || (
|
||||
app-emulation/emul-linux-x86-xlibs[development]
|
||||
x11-libs/libXcomposite[abi_x86_32]
|
||||
) )
|
||||
)
|
||||
)"
|
||||
|
||||
RDEPEND="${COMMON_DEPEND}
|
||||
dos? ( games-emulation/dosbox )
|
||||
perl? ( dev-lang/perl dev-perl/XML-Simple )
|
||||
samba? ( >=net-fs/samba-3.0.25 )
|
||||
selinux? ( sec-policy/selinux-wine )
|
||||
udisks? ( sys-fs/udisks:2 )
|
||||
pulseaudio? ( realtime? ( sys-auth/rtkit ) )"
|
||||
|
||||
DEPEND="${COMMON_DEPEND}
|
||||
amd64? ( abi_x86_32? ( !abi_x86_64? ( ${NATIVE_DEPEND} ) ) )
|
||||
X? (
|
||||
x11-proto/inputproto
|
||||
x11-proto/xextproto
|
||||
x11-proto/xf86vidmodeproto
|
||||
)
|
||||
xinerama? ( x11-proto/xineramaproto )
|
||||
prelink? ( sys-devel/prelink )
|
||||
>=sys-kernel/linux-headers-2.6
|
||||
virtual/pkgconfig
|
||||
virtual/yacc
|
||||
sys-devel/flex"
|
||||
|
||||
# These use a non-standard "Wine" category, which is provided by
|
||||
# /etc/xdg/applications-merged/wine.menu
|
||||
QA_DESKTOP_FILE="usr/share/applications/wine-browsedrive.desktop
|
||||
usr/share/applications/wine-notepad.desktop
|
||||
usr/share/applications/wine-uninstaller.desktop
|
||||
usr/share/applications/wine-winecfg.desktop"
|
||||
|
||||
wine_build_environment_check() {
|
||||
[[ ${MERGE_TYPE} = "binary" ]] && return 0
|
||||
|
||||
if use abi_x86_64 && [[ $(( $(gcc-major-version) * 100 + $(gcc-minor-version) )) -lt 404 ]]; then
|
||||
eerror "You need gcc-4.4+ to build 64-bit wine"
|
||||
eerror
|
||||
return 1
|
||||
fi
|
||||
|
||||
if use abi_x86_32 && use opencl && [[ x$(eselect opencl show 2> /dev/null) = "xintel" ]]; then
|
||||
eerror "You cannot build wine with USE=opencl because intel-ocl-sdk is 64-bit only."
|
||||
eerror "See https://bugs.gentoo.org/487864 for more details."
|
||||
eerror
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
pkg_pretend() {
|
||||
wine_build_environment_check || die
|
||||
}
|
||||
|
||||
pkg_setup() {
|
||||
wine_build_environment_check || die
|
||||
}
|
||||
|
||||
src_unpack() {
|
||||
if [[ ${PV} == "9999" ]] ; then
|
||||
git-2_src_unpack
|
||||
else
|
||||
unpack ${MY_P}.tar.bz2
|
||||
fi
|
||||
|
||||
use pulseaudio && unpack "${PULSE_PATCHES}.tar.bz2"
|
||||
unpack "${WINE_GENTOO}.tar.bz2"
|
||||
|
||||
l10n_find_plocales_changes "${S}/po" "" ".po"
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
local md5="$(md5sum server/protocol.def)"
|
||||
local PATCHES=(
|
||||
"${FILESDIR}"/${PN}-1.5.26-winegcc.patch #260726
|
||||
"${FILESDIR}"/${PN}-1.4_rc2-multilib-portage.patch #395615
|
||||
"${FILESDIR}"/${PN}-1.7.12-osmesa-check.patch #429386
|
||||
"${FILESDIR}"/${PN}-1.6-memset-O3.patch #480508
|
||||
)
|
||||
use pulseaudio && PATCHES+=(
|
||||
"../${PULSE_PATCHES}"/*.patch #421365
|
||||
)
|
||||
|
||||
autotools-utils_src_prepare
|
||||
|
||||
if [[ "$(md5sum server/protocol.def)" != "${md5}" ]]; then
|
||||
einfo "server/protocol.def was patched; running tools/make_requests"
|
||||
tools/make_requests || die #432348
|
||||
fi
|
||||
sed -i '/^UPDATE_DESKTOP_DATABASE/s:=.*:=true:' tools/Makefile.in || die
|
||||
if ! use run-exes; then
|
||||
sed -i '/^MimeType/d' tools/wine.desktop || die #117785
|
||||
fi
|
||||
|
||||
# hi-res default icon, #472990, http://bugs.winehq.org/show_bug.cgi?id=24652
|
||||
cp "${WORKDIR}"/${WINE_GENTOO}/icons/oic_winlogo.ico dlls/user32/resources/ || die
|
||||
|
||||
l10n_get_locales > po/LINGUAS # otherwise wine doesn't respect LINGUAS
|
||||
}
|
||||
|
||||
do_configure() {
|
||||
local myeconfargs=( "${myeconfargs[@]}" )
|
||||
|
||||
if use amd64; then
|
||||
if [[ ${ABI} == amd64 ]]; then
|
||||
myeconfargs+=( --enable-win64 )
|
||||
else
|
||||
use netapi && ewarn "Disabling netapi in wine32; see https://bugs.gentoo.org/494394"
|
||||
# We currently don't have 32-bit libnetapi on amd64; #494394
|
||||
myeconfargs+=(
|
||||
--without-netapi
|
||||
--disable-win64
|
||||
)
|
||||
fi
|
||||
|
||||
# Note: using --with-wine64 results in problems with multilib.eclass
|
||||
# CC/LD hackery. We're using separate tools instead.
|
||||
fi
|
||||
|
||||
autotools-utils_src_configure
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
export LDCONFIG=/bin/true
|
||||
use custom-cflags || strip-flags
|
||||
|
||||
local myeconfargs=( # common
|
||||
--sysconfdir=/etc/wine
|
||||
$(use_with alsa)
|
||||
$(use_with capi)
|
||||
$(use_with lcms cms)
|
||||
$(use_with cups)
|
||||
$(use_with ncurses curses)
|
||||
$(use_with udisks dbus)
|
||||
$(use_with fontconfig)
|
||||
$(use_with ssl gnutls)
|
||||
$(use_with gphoto2 gphoto)
|
||||
$(use_with gsm)
|
||||
$(use_with gstreamer)
|
||||
--without-hal
|
||||
$(use_with jpeg)
|
||||
$(use_with ldap)
|
||||
$(use_with mp3 mpg123)
|
||||
$(use_with netapi)
|
||||
$(use_with nls gettext)
|
||||
$(use_with openal)
|
||||
$(use_with opencl)
|
||||
$(use_with opengl)
|
||||
$(use_with osmesa)
|
||||
$(use_with oss)
|
||||
$(use_with png)
|
||||
$(use_with threads pthread)
|
||||
$(use_with scanner sane)
|
||||
$(use_enable test tests)
|
||||
$(use_with truetype freetype)
|
||||
$(use_with v4l)
|
||||
$(use_with X x)
|
||||
$(use_with xcomposite)
|
||||
$(use_with xinerama)
|
||||
$(use_with xml)
|
||||
$(use_with xml xslt)
|
||||
)
|
||||
|
||||
use pulseaudio && myeconfargs+=( --with-pulse )
|
||||
|
||||
if use amd64 && use abi_x86_32; then
|
||||
# Avoid crossdev's i686-pc-linux-gnu-pkg-config if building wine32 on amd64; #472038
|
||||
# set AR and RANLIB to make QA scripts happy; #483342
|
||||
tc-export PKG_CONFIG AR RANLIB
|
||||
fi
|
||||
|
||||
multilib_parallel_foreach_abi do_configure
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
autotools-multilib_src_compile depend
|
||||
autotools-multilib_src_compile all
|
||||
}
|
||||
|
||||
src_test() {
|
||||
if [[ $(id -u) == 0 ]]; then
|
||||
ewarn "Skipping tests since they cannot be run under the root user."
|
||||
ewarn "To run the test ${PN} suite, add userpriv to FEATURES in make.conf"
|
||||
return
|
||||
fi
|
||||
|
||||
# FIXME: win32-only; wine64 tests fail with "could not find the Wine loader"
|
||||
multilib_toolchain_setup x86
|
||||
local BUILD_DIR="${S}-${ABI}"
|
||||
cd "${BUILD_DIR}" || die
|
||||
WINEPREFIX="${T}/.wine-${ABI}" Xemake test
|
||||
}
|
||||
|
||||
src_install() {
|
||||
local DOCS=( ANNOUNCE AUTHORS README )
|
||||
add_locale_docs() {
|
||||
local locale_doc="documentation/README.$1"
|
||||
[[ ! -e ${locale_doc} ]] || DOCS=( "${DOCS[@]}" ${locale_doc} )
|
||||
}
|
||||
l10n_for_each_locale_do add_locale_docs
|
||||
autotools-multilib_src_install
|
||||
|
||||
emake -C "../${WINE_GENTOO}" install DESTDIR="${D}" EPREFIX="${EPREFIX}"
|
||||
if use gecko ; then
|
||||
insinto /usr/share/wine/gecko
|
||||
use abi_x86_32 && doins "${DISTDIR}"/wine_gecko-${GV}-x86.msi
|
||||
use abi_x86_64 && doins "${DISTDIR}"/wine_gecko-${GV}-x86_64.msi
|
||||
fi
|
||||
if use mono ; then
|
||||
insinto /usr/share/wine/mono
|
||||
doins "${DISTDIR}"/wine-mono-${MV}.msi
|
||||
fi
|
||||
if ! use perl ; then
|
||||
rm "${D}"usr/bin/{wine{dump,maker},function_grep.pl} "${D}"usr/share/man/man1/wine{dump,maker}.1 || die
|
||||
fi
|
||||
|
||||
use abi_x86_32 && pax-mark psmr "${D}"usr/bin/wine{,-preloader} #255055
|
||||
use abi_x86_64 && pax-mark psmr "${D}"usr/bin/wine64{,-preloader}
|
||||
|
||||
if use abi_x86_64 && ! use abi_x86_32; then
|
||||
dosym /usr/bin/wine{64,} # 404331
|
||||
dosym /usr/bin/wine{64,}-preloader
|
||||
fi
|
||||
|
||||
# respect LINGUAS when installing man pages, #469418
|
||||
for l in de fr pl; do
|
||||
use linguas_${l} || rm -r "${D}"usr/share/man/${l}*
|
||||
done
|
||||
}
|
||||
|
||||
pkg_preinst() {
|
||||
gnome2_icon_savelist
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
gnome2_icon_cache_update
|
||||
fdo-mime_desktop_database_update
|
||||
}
|
||||
|
||||
pkg_postrm() {
|
||||
gnome2_icon_cache_update
|
||||
fdo-mime_desktop_database_update
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
|
||||
index 3558889..d4d1c7b 100644
|
||||
--- a/tools/ocaml/libs/xb/partial.ml
|
||||
+++ b/tools/ocaml/libs/xb/partial.ml
|
||||
@@ -27,8 +27,15 @@ external header_size: unit -> int = "stub_header_size"
|
||||
external header_of_string_internal: string -> int * int * int * int
|
||||
= "stub_header_of_string"
|
||||
|
||||
+let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
|
||||
+
|
||||
let of_string s =
|
||||
let tid, rid, opint, dlen = header_of_string_internal s in
|
||||
+ (* A packet which is bigger than xenstore_payload_max is illegal.
|
||||
+ This will leave the guest connection is a bad state and will
|
||||
+ be hard to recover from without restarting the connection
|
||||
+ (ie rebooting the guest) *)
|
||||
+ let dlen = min xenstore_payload_max dlen in
|
||||
{
|
||||
tid = tid;
|
||||
rid = rid;
|
||||
@@ -38,6 +45,7 @@ let of_string s =
|
||||
}
|
||||
|
||||
let append pkt s sz =
|
||||
+ if pkt.len > 4096 then failwith "Buffer.add: cannot grow buffer";
|
||||
Buffer.add_string pkt.buf (String.sub s 0 sz)
|
||||
|
||||
let to_complete pkt =
|
||||
diff --git a/tools/ocaml/libs/xb/xs_ring_stubs.c b/tools/ocaml/libs/xb/xs_ring_stubs.c
|
||||
index 00414c5..4888ac5 100644
|
||||
--- a/tools/ocaml/libs/xb/xs_ring_stubs.c
|
||||
+++ b/tools/ocaml/libs/xb/xs_ring_stubs.c
|
||||
@@ -39,21 +39,23 @@ static int xs_ring_read(struct mmap_interface *interface,
|
||||
char *buffer, int len)
|
||||
{
|
||||
struct xenstore_domain_interface *intf = interface->addr;
|
||||
- XENSTORE_RING_IDX cons, prod;
|
||||
+ XENSTORE_RING_IDX cons, prod; /* offsets only */
|
||||
int to_read;
|
||||
|
||||
- cons = intf->req_cons;
|
||||
- prod = intf->req_prod;
|
||||
+ cons = *(volatile uint32*)&intf->req_cons;
|
||||
+ prod = *(volatile uint32*)&intf->req_prod;
|
||||
xen_mb();
|
||||
+ cons = MASK_XENSTORE_IDX(cons);
|
||||
+ prod = MASK_XENSTORE_IDX(prod);
|
||||
if (prod == cons)
|
||||
return 0;
|
||||
- if (MASK_XENSTORE_IDX(prod) > MASK_XENSTORE_IDX(cons))
|
||||
+ if (prod > cons)
|
||||
to_read = prod - cons;
|
||||
else
|
||||
- to_read = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
|
||||
+ to_read = XENSTORE_RING_SIZE - cons;
|
||||
if (to_read < len)
|
||||
len = to_read;
|
||||
- memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), len);
|
||||
+ memcpy(buffer, intf->req + cons, len);
|
||||
xen_mb();
|
||||
intf->req_cons += len;
|
||||
return len;
|
||||
@@ -66,8 +68,8 @@ static int xs_ring_write(struct mmap_interface *interface,
|
||||
XENSTORE_RING_IDX cons, prod;
|
||||
int can_write;
|
||||
|
||||
- cons = intf->rsp_cons;
|
||||
- prod = intf->rsp_prod;
|
||||
+ cons = *(volatile uint32*)&intf->rsp_cons;
|
||||
+ prod = *(volatile uint32*)&intf->rsp_prod;
|
||||
xen_mb();
|
||||
if ( (prod - cons) >= XENSTORE_RING_SIZE )
|
||||
return 0;
|
@ -1,293 +0,0 @@
|
||||
x86: fix various issues with handling guest IRQs
|
||||
|
||||
- properly revoke IRQ access in map_domain_pirq() error path
|
||||
- don't permit replacing an in use IRQ
|
||||
- don't accept inputs in the GSI range for MAP_PIRQ_TYPE_MSI
|
||||
- track IRQ access permission in host IRQ terms, not guest IRQ ones
|
||||
(and with that, also disallow Dom0 access to IRQ0)
|
||||
|
||||
This is CVE-2013-1919 / XSA-46.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
||||
|
||||
--- a/tools/libxl/libxl_create.c
|
||||
+++ b/tools/libxl/libxl_create.c
|
||||
@@ -968,14 +968,16 @@ static void domcreate_launch_dm(libxl__e
|
||||
}
|
||||
|
||||
for (i = 0; i < d_config->b_info.num_irqs; i++) {
|
||||
- uint32_t irq = d_config->b_info.irqs[i];
|
||||
+ int irq = d_config->b_info.irqs[i];
|
||||
|
||||
- LOG(DEBUG, "dom%d irq %"PRIx32, domid, irq);
|
||||
+ LOG(DEBUG, "dom%d irq %d", domid, irq);
|
||||
|
||||
- ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1);
|
||||
+ ret = irq >= 0 ? xc_physdev_map_pirq(CTX->xch, domid, irq, &irq)
|
||||
+ : -EOVERFLOW;
|
||||
+ if (!ret)
|
||||
+ ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1);
|
||||
if ( ret<0 ){
|
||||
- LOGE(ERROR,
|
||||
- "failed give dom%d access to irq %"PRId32, domid, irq);
|
||||
+ LOGE(ERROR, "failed give dom%d access to irq %d", domid, irq);
|
||||
ret = ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
--- a/tools/python/xen/xend/server/irqif.py
|
||||
+++ b/tools/python/xen/xend/server/irqif.py
|
||||
@@ -73,6 +73,12 @@ class IRQController(DevController):
|
||||
|
||||
pirq = get_param('irq')
|
||||
|
||||
+ rc = xc.physdev_map_pirq(domid = self.getDomid(),
|
||||
+ index = pirq,
|
||||
+ pirq = pirq)
|
||||
+ if rc < 0:
|
||||
+ raise VmError('irq: Failed to map irq %x' % (pirq))
|
||||
+
|
||||
rc = xc.domain_irq_permission(domid = self.getDomid(),
|
||||
pirq = pirq,
|
||||
allow_access = True)
|
||||
@@ -81,12 +87,6 @@ class IRQController(DevController):
|
||||
#todo non-fatal
|
||||
raise VmError(
|
||||
'irq: Failed to configure irq: %d' % (pirq))
|
||||
- rc = xc.physdev_map_pirq(domid = self.getDomid(),
|
||||
- index = pirq,
|
||||
- pirq = pirq)
|
||||
- if rc < 0:
|
||||
- raise VmError(
|
||||
- 'irq: Failed to map irq %x' % (pirq))
|
||||
back = dict([(k, config[k]) for k in self.valid_cfg if k in config])
|
||||
return (self.allocateDeviceID(), back, {})
|
||||
|
||||
--- a/xen/arch/x86/domain_build.c
|
||||
+++ b/xen/arch/x86/domain_build.c
|
||||
@@ -1219,7 +1219,7 @@ int __init construct_dom0(
|
||||
/* DOM0 is permitted full I/O capabilities. */
|
||||
rc |= ioports_permit_access(dom0, 0, 0xFFFF);
|
||||
rc |= iomem_permit_access(dom0, 0UL, ~0UL);
|
||||
- rc |= irqs_permit_access(dom0, 0, d->nr_pirqs - 1);
|
||||
+ rc |= irqs_permit_access(dom0, 1, nr_irqs_gsi - 1);
|
||||
|
||||
/*
|
||||
* Modify I/O port access permissions.
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -772,9 +772,13 @@ long arch_do_domctl(
|
||||
goto bind_out;
|
||||
|
||||
ret = -EPERM;
|
||||
- if ( !IS_PRIV(current->domain) &&
|
||||
- !irq_access_permitted(current->domain, bind->machine_irq) )
|
||||
- goto bind_out;
|
||||
+ if ( !IS_PRIV(current->domain) )
|
||||
+ {
|
||||
+ int irq = domain_pirq_to_irq(d, bind->machine_irq);
|
||||
+
|
||||
+ if ( irq <= 0 || !irq_access_permitted(current->domain, irq) )
|
||||
+ goto bind_out;
|
||||
+ }
|
||||
|
||||
ret = -ESRCH;
|
||||
if ( iommu_enabled )
|
||||
@@ -803,9 +807,13 @@ long arch_do_domctl(
|
||||
bind = &(domctl->u.bind_pt_irq);
|
||||
|
||||
ret = -EPERM;
|
||||
- if ( !IS_PRIV(current->domain) &&
|
||||
- !irq_access_permitted(current->domain, bind->machine_irq) )
|
||||
- goto unbind_out;
|
||||
+ if ( !IS_PRIV(current->domain) )
|
||||
+ {
|
||||
+ int irq = domain_pirq_to_irq(d, bind->machine_irq);
|
||||
+
|
||||
+ if ( irq <= 0 || !irq_access_permitted(current->domain, irq) )
|
||||
+ goto unbind_out;
|
||||
+ }
|
||||
|
||||
if ( iommu_enabled )
|
||||
{
|
||||
--- a/xen/arch/x86/irq.c
|
||||
+++ b/xen/arch/x86/irq.c
|
||||
@@ -184,6 +184,14 @@ int create_irq(int node)
|
||||
desc->arch.used = IRQ_UNUSED;
|
||||
irq = ret;
|
||||
}
|
||||
+ else if ( dom0 )
|
||||
+ {
|
||||
+ ret = irq_permit_access(dom0, irq);
|
||||
+ if ( ret )
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "Could not grant Dom0 access to IRQ%d (error %d)\n",
|
||||
+ irq, ret);
|
||||
+ }
|
||||
|
||||
return irq;
|
||||
}
|
||||
@@ -280,6 +288,17 @@ void clear_irq_vector(int irq)
|
||||
void destroy_irq(unsigned int irq)
|
||||
{
|
||||
BUG_ON(!MSI_IRQ(irq));
|
||||
+
|
||||
+ if ( dom0 )
|
||||
+ {
|
||||
+ int err = irq_deny_access(dom0, irq);
|
||||
+
|
||||
+ if ( err )
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "Could not revoke Dom0 access to IRQ%u (error %d)\n",
|
||||
+ irq, err);
|
||||
+ }
|
||||
+
|
||||
dynamic_irq_cleanup(irq);
|
||||
clear_irq_vector(irq);
|
||||
}
|
||||
@@ -1858,7 +1877,7 @@ int map_domain_pirq(
|
||||
|
||||
if ( !IS_PRIV(current->domain) &&
|
||||
!(IS_PRIV_FOR(current->domain, d) &&
|
||||
- irq_access_permitted(current->domain, pirq)))
|
||||
+ irq_access_permitted(current->domain, irq)))
|
||||
return -EPERM;
|
||||
|
||||
if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs )
|
||||
@@ -1887,17 +1906,18 @@ int map_domain_pirq(
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = irq_permit_access(d, pirq);
|
||||
+ ret = irq_permit_access(d, irq);
|
||||
if ( ret )
|
||||
{
|
||||
- dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n",
|
||||
- d->domain_id, pirq);
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "dom%d: could not permit access to IRQ%d (pirq %d)\n",
|
||||
+ d->domain_id, irq, pirq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = prepare_domain_irq_pirq(d, irq, pirq, &info);
|
||||
if ( ret )
|
||||
- return ret;
|
||||
+ goto revoke;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
|
||||
@@ -1921,8 +1941,14 @@ int map_domain_pirq(
|
||||
spin_lock_irqsave(&desc->lock, flags);
|
||||
|
||||
if ( desc->handler != &no_irq_type )
|
||||
+ {
|
||||
+ spin_unlock_irqrestore(&desc->lock, flags);
|
||||
dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n",
|
||||
d->domain_id, irq);
|
||||
+ pci_disable_msi(msi_desc);
|
||||
+ ret = -EBUSY;
|
||||
+ goto done;
|
||||
+ }
|
||||
setup_msi_handler(desc, msi_desc);
|
||||
|
||||
if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV
|
||||
@@ -1951,7 +1977,14 @@ int map_domain_pirq(
|
||||
|
||||
done:
|
||||
if ( ret )
|
||||
+ {
|
||||
cleanup_domain_irq_pirq(d, irq, info);
|
||||
+ revoke:
|
||||
+ 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);
|
||||
+ }
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2017,10 +2050,11 @@ int unmap_domain_pirq(struct domain *d,
|
||||
if ( !forced_unbind )
|
||||
cleanup_domain_irq_pirq(d, irq, info);
|
||||
|
||||
- ret = irq_deny_access(d, pirq);
|
||||
+ ret = irq_deny_access(d, irq);
|
||||
if ( ret )
|
||||
- dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
|
||||
- d->domain_id, pirq);
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "dom%d: could not deny access to IRQ%d (pirq %d)\n",
|
||||
+ d->domain_id, irq, pirq);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
--- a/xen/arch/x86/physdev.c
|
||||
+++ b/xen/arch/x86/physdev.c
|
||||
@@ -147,7 +147,7 @@ int physdev_map_pirq(domid_t domid, int
|
||||
if ( irq == -1 )
|
||||
irq = create_irq(NUMA_NO_NODE);
|
||||
|
||||
- if ( irq < 0 || irq >= nr_irqs )
|
||||
+ if ( irq < nr_irqs_gsi || irq >= nr_irqs )
|
||||
{
|
||||
dprintk(XENLOG_G_ERR, "dom%d: can't create irq for msi!\n",
|
||||
d->domain_id);
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <xen/paging.h>
|
||||
#include <xen/hypercall.h>
|
||||
#include <asm/current.h>
|
||||
+#include <asm/irq.h>
|
||||
#include <asm/page.h>
|
||||
#include <public/domctl.h>
|
||||
#include <xsm/xsm.h>
|
||||
@@ -897,9 +898,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
|
||||
else if ( xsm_irq_permission(d, pirq, allow) )
|
||||
ret = -EPERM;
|
||||
else if ( allow )
|
||||
- ret = irq_permit_access(d, pirq);
|
||||
+ ret = pirq_permit_access(d, pirq);
|
||||
else
|
||||
- ret = irq_deny_access(d, pirq);
|
||||
+ ret = pirq_deny_access(d, pirq);
|
||||
|
||||
rcu_unlock_domain(d);
|
||||
}
|
||||
--- a/xen/common/event_channel.c
|
||||
+++ b/xen/common/event_channel.c
|
||||
@@ -369,7 +369,7 @@ static long evtchn_bind_pirq(evtchn_bind
|
||||
if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
|
||||
return -EINVAL;
|
||||
|
||||
- if ( !is_hvm_domain(d) && !irq_access_permitted(d, pirq) )
|
||||
+ if ( !is_hvm_domain(d) && !pirq_access_permitted(d, pirq) )
|
||||
return -EPERM;
|
||||
|
||||
spin_lock(&d->event_lock);
|
||||
--- a/xen/include/xen/iocap.h
|
||||
+++ b/xen/include/xen/iocap.h
|
||||
@@ -28,4 +28,22 @@
|
||||
#define irq_access_permitted(d, i) \
|
||||
rangeset_contains_singleton((d)->irq_caps, i)
|
||||
|
||||
+#define pirq_permit_access(d, i) ({ \
|
||||
+ struct domain *d__ = (d); \
|
||||
+ int i__ = domain_pirq_to_irq(d__, i); \
|
||||
+ i__ > 0 ? rangeset_add_singleton(d__->irq_caps, i__)\
|
||||
+ : -EINVAL; \
|
||||
+})
|
||||
+#define pirq_deny_access(d, i) ({ \
|
||||
+ struct domain *d__ = (d); \
|
||||
+ int i__ = domain_pirq_to_irq(d__, i); \
|
||||
+ i__ > 0 ? rangeset_remove_singleton(d__->irq_caps, i__)\
|
||||
+ : -EINVAL; \
|
||||
+})
|
||||
+#define pirq_access_permitted(d, i) ({ \
|
||||
+ struct domain *d__ = (d); \
|
||||
+ rangeset_contains_singleton(d__->irq_caps, \
|
||||
+ domain_pirq_to_irq(d__, i));\
|
||||
+})
|
||||
+
|
||||
#endif /* __XEN_IOCAP_H__ */
|
@ -1,114 +0,0 @@
|
||||
Add -f FMT / --format FMT arg to qemu-nbd
|
||||
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
|
||||
Currently the qemu-nbd program will auto-detect the format of
|
||||
any disk it is given. This behaviour is known to be insecure.
|
||||
For example, if qemu-nbd initially exposes a 'raw' file to an
|
||||
unprivileged app, and that app runs
|
||||
|
||||
'qemu-img create -f qcow2 -o backing_file=/etc/shadow /dev/nbd0'
|
||||
|
||||
then the next time the app is started, the qemu-nbd will now
|
||||
detect it as a 'qcow2' file and expose /etc/shadow to the
|
||||
unprivileged app.
|
||||
|
||||
The only way to avoid this is to explicitly tell qemu-nbd what
|
||||
disk format to use on the command line, completely disabling
|
||||
auto-detection. This patch adds a '-f' / '--format' arg for
|
||||
this purpose, mirroring what is already available via qemu-img
|
||||
and qemu commands.
|
||||
|
||||
qemu-nbd --format raw -p 9000 evil.img
|
||||
|
||||
will now always use raw, regardless of what format 'evil.img'
|
||||
looks like it contains
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
[Use errx, not err. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
||||
|
||||
[ This is a security issue, CVE-2013-1922 / XSA-48. ]
|
||||
|
||||
diff --git a/qemu-nbd.c b/qemu-nbd.c
|
||||
index 291cba2..8fbe2cf 100644
|
||||
--- a/tools/qemu-xen/qemu-nbd.c
|
||||
+++ b/tools/qemu-xen/qemu-nbd.c
|
||||
@@ -247,6 +247,7 @@ out:
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
+ BlockDriver *drv;
|
||||
off_t dev_offset = 0;
|
||||
off_t offset = 0;
|
||||
uint32_t nbdflags = 0;
|
||||
@@ -256,7 +257,7 @@ int main(int argc, char **argv)
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
off_t fd_size;
|
||||
- const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
|
||||
+ const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:t";
|
||||
struct option lopt[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
@@ -271,6 +272,7 @@ int main(int argc, char **argv)
|
||||
{ "snapshot", 0, NULL, 's' },
|
||||
{ "nocache", 0, NULL, 'n' },
|
||||
{ "shared", 1, NULL, 'e' },
|
||||
+ { "format", 1, NULL, 'f' },
|
||||
{ "persistent", 0, NULL, 't' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
@@ -292,6 +294,7 @@ int main(int argc, char **argv)
|
||||
int max_fd;
|
||||
int persistent = 0;
|
||||
pthread_t client_thread;
|
||||
+ const char *fmt = NULL;
|
||||
|
||||
/* The client thread uses SIGTERM to interrupt the server. A signal
|
||||
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
|
||||
@@ -368,6 +371,9 @@ int main(int argc, char **argv)
|
||||
errx(EXIT_FAILURE, "Shared device number must be greater than 0\n");
|
||||
}
|
||||
break;
|
||||
+ case 'f':
|
||||
+ fmt = optarg;
|
||||
+ break;
|
||||
case 't':
|
||||
persistent = 1;
|
||||
break;
|
||||
@@ -478,9 +484,19 @@ int main(int argc, char **argv)
|
||||
bdrv_init();
|
||||
atexit(bdrv_close_all);
|
||||
|
||||
+ if (fmt) {
|
||||
+ drv = bdrv_find_format(fmt);
|
||||
+ if (!drv) {
|
||||
+ errx(EXIT_FAILURE, "Unknown file format '%s'", fmt);
|
||||
+ }
|
||||
+ } else {
|
||||
+ drv = NULL;
|
||||
+ }
|
||||
+
|
||||
bs = bdrv_new("hda");
|
||||
srcpath = argv[optind];
|
||||
- if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) {
|
||||
+ ret = bdrv_open(bs, srcpath, flags, drv);
|
||||
+ if (ret < 0) {
|
||||
errno = -ret;
|
||||
err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]);
|
||||
}
|
||||
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
|
||||
index 44996cc..f56c68e 100644
|
||||
--- a/tools/qemu-xen/qemu-nbd.texi
|
||||
+++ b/tools/qemu-xen/qemu-nbd.texi
|
||||
@@ -36,6 +36,8 @@ Export Qemu disk image using NBD protocol.
|
||||
disconnect the specified device
|
||||
@item -e, --shared=@var{num}
|
||||
device can be shared by @var{num} clients (default @samp{1})
|
||||
+@item -f, --format=@var{fmt}
|
||||
+ force block driver for format @var{fmt} instead of auto-detecting
|
||||
@item -t, --persistent
|
||||
don't exit on the last connection
|
||||
@item -v, --verbose
|
@ -1,50 +0,0 @@
|
||||
VT-d: don't permit SVT_NO_VERIFY entries for known device types
|
||||
|
||||
Only in cases where we don't know what to do we should leave the IRTE
|
||||
blank (suppressing all validation), but we should always log a warning
|
||||
in those cases (as being insecure).
|
||||
|
||||
This is CVE-2013-1952 / XSA-49.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: "Zhang, Xiantao" <xiantao.zhang@intel.com>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/intremap.c
|
||||
+++ b/xen/drivers/passthrough/vtd/intremap.c
|
||||
@@ -440,16 +440,15 @@ static void set_msi_source_id(struct pci
|
||||
type = pdev_type(seg, bus, devfn);
|
||||
switch ( type )
|
||||
{
|
||||
+ case DEV_TYPE_PCIe_ENDPOINT:
|
||||
case DEV_TYPE_PCIe_BRIDGE:
|
||||
case DEV_TYPE_PCIe2PCI_BRIDGE:
|
||||
- case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
- break;
|
||||
-
|
||||
- case DEV_TYPE_PCIe_ENDPOINT:
|
||||
set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn));
|
||||
break;
|
||||
|
||||
case DEV_TYPE_PCI:
|
||||
+ case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
+ /* case DEV_TYPE_PCI2PCIe_BRIDGE: */
|
||||
ret = find_upstream_bridge(seg, &bus, &devfn, &secbus);
|
||||
if ( ret == 0 ) /* integrated PCI device */
|
||||
{
|
||||
@@ -461,10 +460,15 @@ static void set_msi_source_id(struct pci
|
||||
if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
|
||||
set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
|
||||
(bus << 8) | pdev->bus);
|
||||
- else if ( pdev_type(seg, bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE )
|
||||
+ else
|
||||
set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
|
||||
PCI_BDF2(bus, devfn));
|
||||
}
|
||||
+ else
|
||||
+ dprintk(XENLOG_WARNING VTDPREFIX,
|
||||
+ "d%d: no upstream bridge for %04x:%02x:%02x.%u\n",
|
||||
+ pdev->domain->domain_id,
|
||||
+ seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||
break;
|
||||
|
||||
default:
|
@ -1,41 +0,0 @@
|
||||
diff -ur xen-4.2.1.orig/xen/drivers/passthrough/vtd/intremap.c xen-4.2.1/xen/drivers/passthrough/vtd/intremap.c
|
||||
--- xen/drivers/passthrough/vtd/intremap.c 2012-12-17 23:01:55.000000000 +0800
|
||||
+++ xen/drivers/passthrough/vtd/intremap.c 2013-05-15 23:09:06.704546506 +0800
|
||||
@@ -440,16 +440,17 @@
|
||||
type = pdev_type(seg, bus, devfn);
|
||||
switch ( type )
|
||||
{
|
||||
+ case DEV_TYPE_PCIe_ENDPOINT:
|
||||
case DEV_TYPE_PCIe_BRIDGE:
|
||||
case DEV_TYPE_PCIe2PCI_BRIDGE:
|
||||
- case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
- break;
|
||||
|
||||
- case DEV_TYPE_PCIe_ENDPOINT:
|
||||
set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn));
|
||||
break;
|
||||
|
||||
case DEV_TYPE_PCI:
|
||||
+ case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
+ /* case DEV_TYPE_PCI2PCIe_BRIDGE: */
|
||||
+
|
||||
ret = find_upstream_bridge(seg, &bus, &devfn, &secbus);
|
||||
if ( ret == 0 ) /* integrated PCI device */
|
||||
{
|
||||
@@ -461,10 +462,15 @@
|
||||
if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
|
||||
set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
|
||||
(bus << 8) | pdev->bus);
|
||||
- else if ( pdev_type(seg, bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE )
|
||||
+ else
|
||||
set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
|
||||
PCI_BDF2(bus, devfn));
|
||||
}
|
||||
+ else
|
||||
+ dprintk(XENLOG_WARNING VTDPREFIX,
|
||||
+ "d%d: no upstream bridge for %04x:%02x:%02x.%u\n",
|
||||
+ pdev->domain->domain_id,
|
||||
+ seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||
break;
|
||||
|
||||
default:
|
@ -1,50 +0,0 @@
|
||||
libxc: limit cpu values when setting vcpu affinity
|
||||
|
||||
When support for pinning more than 64 cpus was added, check for cpu
|
||||
out-of-range values was removed. This can lead to subsequent
|
||||
out-of-bounds cpumap array accesses in case the cpu number is higher
|
||||
than the actual count.
|
||||
|
||||
This patch returns the check.
|
||||
|
||||
This is CVE-2013-2072 / XSA-56
|
||||
|
||||
Signed-off-by: Petr Matousek <pmatouse@redhat.com>
|
||||
|
||||
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
|
||||
index e220f68..e611b24 100644
|
||||
--- a/tools/python/xen/lowlevel/xc/xc.c
|
||||
+++ b/tools/python/xen/lowlevel/xc/xc.c
|
||||
@@ -228,6 +228,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
int vcpu = 0, i;
|
||||
xc_cpumap_t cpumap;
|
||||
PyObject *cpulist = NULL;
|
||||
+ int nr_cpus;
|
||||
|
||||
static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
|
||||
|
||||
@@ -235,6 +236,10 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
&dom, &vcpu, &cpulist) )
|
||||
return NULL;
|
||||
|
||||
+ nr_cpus = xc_get_max_cpus(self->xc_handle);
|
||||
+ if ( nr_cpus == 0 )
|
||||
+ return pyxc_error_to_exception(self->xc_handle);
|
||||
+
|
||||
cpumap = xc_cpumap_alloc(self->xc_handle);
|
||||
if(cpumap == NULL)
|
||||
return pyxc_error_to_exception(self->xc_handle);
|
||||
@@ -244,6 +249,13 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
for ( i = 0; i < PyList_Size(cpulist); i++ )
|
||||
{
|
||||
long cpu = PyInt_AsLong(PyList_GetItem(cpulist, i));
|
||||
+ if ( cpu < 0 || cpu >= nr_cpus )
|
||||
+ {
|
||||
+ free(cpumap);
|
||||
+ errno = EINVAL;
|
||||
+ PyErr_SetFromErrno(xc_error_obj);
|
||||
+ return NULL;
|
||||
+ }
|
||||
cpumap[cpu / 8] |= 1 << (cpu % 8);
|
||||
}
|
||||
}
|
@ -1,417 +0,0 @@
|
||||
From 9737484becab4a25159f1e985700eaee89690d34 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:15 +0100
|
||||
Subject: [PATCH 01/23] libelf: abolish libelf-relocate.c
|
||||
|
||||
This file is not actually used. It's not built in Xen's instance of
|
||||
libelf; in libxc's it's built but nothing in it is called. Do not
|
||||
compile it in libxc, and delete it.
|
||||
|
||||
This reduces the amount of work we need to do in forthcoming patches
|
||||
to libelf (particularly since as libelf-relocate.c is not used it is
|
||||
probably full of bugs).
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
tools/libxc/Makefile | 2 +-
|
||||
xen/common/libelf/libelf-relocate.c | 372 -----------------------------------
|
||||
2 files changed, 1 insertions(+), 373 deletions(-)
|
||||
delete mode 100644 xen/common/libelf/libelf-relocate.c
|
||||
|
||||
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
|
||||
index ca38cbd..d8c6a60 100644
|
||||
--- a/tools/libxc/Makefile
|
||||
+++ b/tools/libxc/Makefile
|
||||
@@ -53,7 +53,7 @@ vpath %.c ../../xen/common/libelf
|
||||
CFLAGS += -I../../xen/common/libelf
|
||||
|
||||
GUEST_SRCS-y += libelf-tools.c libelf-loader.c
|
||||
-GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
|
||||
+GUEST_SRCS-y += libelf-dominfo.c
|
||||
|
||||
# new domain builder
|
||||
GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c
|
||||
diff --git a/xen/common/libelf/libelf-relocate.c b/xen/common/libelf/libelf-relocate.c
|
||||
#deleted file mode 100644
|
||||
index 7ef4b01..0000000
|
||||
--- a/xen/common/libelf/libelf-relocate.c
|
||||
+++ /dev/null
|
||||
@@ -1,372 +0,0 @@
|
||||
-/*
|
||||
- * ELF relocation code (not used by xen kernel right now).
|
||||
- *
|
||||
- * This library is free software; you can redistribute it and/or
|
||||
- * modify it under the terms of the GNU Lesser General Public
|
||||
- * License as published by the Free Software Foundation;
|
||||
- * version 2.1 of the License.
|
||||
- *
|
||||
- * This library is distributed in the hope that it will be useful,
|
||||
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- * Lesser General Public License for more details.
|
||||
- *
|
||||
- * You should have received a copy of the GNU Lesser General Public
|
||||
- * License along with this library; if not, write to the Free Software
|
||||
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
- */
|
||||
-
|
||||
-#include "libelf-private.h"
|
||||
-
|
||||
-/* ------------------------------------------------------------------------ */
|
||||
-
|
||||
-static const char *rel_names_i386[] = {
|
||||
- "R_386_NONE",
|
||||
- "R_386_32",
|
||||
- "R_386_PC32",
|
||||
- "R_386_GOT32",
|
||||
- "R_386_PLT32",
|
||||
- "R_386_COPY",
|
||||
- "R_386_GLOB_DAT",
|
||||
- "R_386_JMP_SLOT",
|
||||
- "R_386_RELATIVE",
|
||||
- "R_386_GOTOFF",
|
||||
- "R_386_GOTPC",
|
||||
- "R_386_32PLT",
|
||||
- "R_386_TLS_TPOFF",
|
||||
- "R_386_TLS_IE",
|
||||
- "R_386_TLS_GOTIE",
|
||||
- "R_386_TLS_LE",
|
||||
- "R_386_TLS_GD",
|
||||
- "R_386_TLS_LDM",
|
||||
- "R_386_16",
|
||||
- "R_386_PC16",
|
||||
- "R_386_8",
|
||||
- "R_386_PC8",
|
||||
- "R_386_TLS_GD_32",
|
||||
- "R_386_TLS_GD_PUSH",
|
||||
- "R_386_TLS_GD_CALL",
|
||||
- "R_386_TLS_GD_POP",
|
||||
- "R_386_TLS_LDM_32",
|
||||
- "R_386_TLS_LDM_PUSH",
|
||||
- "R_386_TLS_LDM_CALL",
|
||||
- "R_386_TLS_LDM_POP",
|
||||
- "R_386_TLS_LDO_32",
|
||||
- "R_386_TLS_IE_32",
|
||||
- "R_386_TLS_LE_32",
|
||||
- "R_386_TLS_DTPMOD32",
|
||||
- "R_386_TLS_DTPOFF32",
|
||||
- "R_386_TLS_TPOFF32",
|
||||
-};
|
||||
-
|
||||
-static int elf_reloc_i386(struct elf_binary *elf, int type,
|
||||
- uint64_t addr, uint64_t value)
|
||||
-{
|
||||
- void *ptr = elf_get_ptr(elf, addr);
|
||||
- uint32_t *u32;
|
||||
-
|
||||
- switch ( type )
|
||||
- {
|
||||
- case 1 /* R_386_32 */ :
|
||||
- u32 = ptr;
|
||||
- *u32 += elf->reloc_offset;
|
||||
- break;
|
||||
- case 2 /* R_386_PC32 */ :
|
||||
- /* nothing */
|
||||
- break;
|
||||
- default:
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* ------------------------------------------------------------------------ */
|
||||
-
|
||||
-static const char *rel_names_x86_64[] = {
|
||||
- "R_X86_64_NONE",
|
||||
- "R_X86_64_64",
|
||||
- "R_X86_64_PC32",
|
||||
- "R_X86_64_GOT32",
|
||||
- "R_X86_64_PLT32",
|
||||
- "R_X86_64_COPY",
|
||||
- "R_X86_64_GLOB_DAT",
|
||||
- "R_X86_64_JUMP_SLOT",
|
||||
- "R_X86_64_RELATIVE",
|
||||
- "R_X86_64_GOTPCREL",
|
||||
- "R_X86_64_32",
|
||||
- "R_X86_64_32S",
|
||||
- "R_X86_64_16",
|
||||
- "R_X86_64_PC16",
|
||||
- "R_X86_64_8",
|
||||
- "R_X86_64_PC8",
|
||||
- "R_X86_64_DTPMOD64",
|
||||
- "R_X86_64_DTPOFF64",
|
||||
- "R_X86_64_TPOFF64",
|
||||
- "R_X86_64_TLSGD",
|
||||
- "R_X86_64_TLSLD",
|
||||
- "R_X86_64_DTPOFF32",
|
||||
- "R_X86_64_GOTTPOFF",
|
||||
- "R_X86_64_TPOFF32",
|
||||
-};
|
||||
-
|
||||
-static int elf_reloc_x86_64(struct elf_binary *elf, int type,
|
||||
- uint64_t addr, uint64_t value)
|
||||
-{
|
||||
- void *ptr = elf_get_ptr(elf, addr);
|
||||
- uint64_t *u64;
|
||||
- uint32_t *u32;
|
||||
- int32_t *s32;
|
||||
-
|
||||
- switch ( type )
|
||||
- {
|
||||
- case 1 /* R_X86_64_64 */ :
|
||||
- u64 = ptr;
|
||||
- value += elf->reloc_offset;
|
||||
- *u64 = value;
|
||||
- break;
|
||||
- case 2 /* R_X86_64_PC32 */ :
|
||||
- u32 = ptr;
|
||||
- *u32 = value - addr;
|
||||
- if ( *u32 != (uint32_t)(value - addr) )
|
||||
- {
|
||||
- elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32
|
||||
- " != 0x%" PRIx32 "\n",
|
||||
- *u32, (uint32_t) (value - addr));
|
||||
- return -1;
|
||||
- }
|
||||
- break;
|
||||
- case 10 /* R_X86_64_32 */ :
|
||||
- u32 = ptr;
|
||||
- value += elf->reloc_offset;
|
||||
- *u32 = value;
|
||||
- if ( *u32 != value )
|
||||
- {
|
||||
- elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32
|
||||
- " != 0x%" PRIx64 "\n",
|
||||
- *u32, value);
|
||||
- return -1;
|
||||
- }
|
||||
- break;
|
||||
- case 11 /* R_X86_64_32S */ :
|
||||
- s32 = ptr;
|
||||
- value += elf->reloc_offset;
|
||||
- *s32 = value;
|
||||
- if ( *s32 != (int64_t) value )
|
||||
- {
|
||||
- elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32
|
||||
- " != 0x%" PRIx64 "\n",
|
||||
- *s32, (int64_t) value);
|
||||
- return -1;
|
||||
- }
|
||||
- break;
|
||||
- default:
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* ------------------------------------------------------------------------ */
|
||||
-
|
||||
-static struct relocs {
|
||||
- const char **names;
|
||||
- int count;
|
||||
- int (*func) (struct elf_binary * elf, int type, uint64_t addr,
|
||||
- uint64_t value);
|
||||
-} relocs[] =
|
||||
-/* *INDENT-OFF* */
|
||||
-{
|
||||
- [EM_386] = {
|
||||
- .names = rel_names_i386,
|
||||
- .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]),
|
||||
- .func = elf_reloc_i386,
|
||||
- },
|
||||
- [EM_X86_64] = {
|
||||
- .names = rel_names_x86_64,
|
||||
- .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]),
|
||||
- .func = elf_reloc_x86_64,
|
||||
- }
|
||||
-};
|
||||
-/* *INDENT-ON* */
|
||||
-
|
||||
-/* ------------------------------------------------------------------------ */
|
||||
-
|
||||
-static const char *rela_name(int machine, int type)
|
||||
-{
|
||||
- if ( machine > sizeof(relocs) / sizeof(relocs[0]) )
|
||||
- return "unknown mach";
|
||||
- if ( !relocs[machine].names )
|
||||
- return "unknown mach";
|
||||
- if ( type > relocs[machine].count )
|
||||
- return "unknown rela";
|
||||
- return relocs[machine].names[type];
|
||||
-}
|
||||
-
|
||||
-static int elf_reloc_section(struct elf_binary *elf,
|
||||
- const elf_shdr * rels,
|
||||
- const elf_shdr * sect, const elf_shdr * syms)
|
||||
-{
|
||||
- const void *ptr, *end;
|
||||
- const elf_shdr *shdr;
|
||||
- const elf_rela *rela;
|
||||
- const elf_rel *rel;
|
||||
- const elf_sym *sym;
|
||||
- uint64_t s_type;
|
||||
- uint64_t r_offset;
|
||||
- uint64_t r_info;
|
||||
- uint64_t r_addend;
|
||||
- int r_type, r_sym;
|
||||
- size_t rsize;
|
||||
- uint64_t shndx, sbase, addr, value;
|
||||
- const char *sname;
|
||||
- int machine;
|
||||
-
|
||||
- machine = elf_uval(elf, elf->ehdr, e_machine);
|
||||
- if ( (machine >= (sizeof(relocs) / sizeof(relocs[0]))) ||
|
||||
- (relocs[machine].func == NULL) )
|
||||
- {
|
||||
- elf_err(elf, "%s: can't handle machine %d\n",
|
||||
- __FUNCTION__, machine);
|
||||
- return -1;
|
||||
- }
|
||||
- if ( elf_swap(elf) )
|
||||
- {
|
||||
- elf_err(elf, "%s: non-native byte order, relocation not supported\n",
|
||||
- __FUNCTION__);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- s_type = elf_uval(elf, rels, sh_type);
|
||||
- rsize = (SHT_REL == s_type) ? elf_size(elf, rel) : elf_size(elf, rela);
|
||||
- ptr = elf_section_start(elf, rels);
|
||||
- end = elf_section_end(elf, rels);
|
||||
-
|
||||
- for ( ; ptr < end; ptr += rsize )
|
||||
- {
|
||||
- switch ( s_type )
|
||||
- {
|
||||
- case SHT_REL:
|
||||
- rel = ptr;
|
||||
- r_offset = elf_uval(elf, rel, r_offset);
|
||||
- r_info = elf_uval(elf, rel, r_info);
|
||||
- r_addend = 0;
|
||||
- break;
|
||||
- case SHT_RELA:
|
||||
- rela = ptr;
|
||||
- r_offset = elf_uval(elf, rela, r_offset);
|
||||
- r_info = elf_uval(elf, rela, r_info);
|
||||
- r_addend = elf_uval(elf, rela, r_addend);
|
||||
- break;
|
||||
- default:
|
||||
- /* can't happen */
|
||||
- return -1;
|
||||
- }
|
||||
- if ( elf_64bit(elf) )
|
||||
- {
|
||||
- r_type = ELF64_R_TYPE(r_info);
|
||||
- r_sym = ELF64_R_SYM(r_info);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- r_type = ELF32_R_TYPE(r_info);
|
||||
- r_sym = ELF32_R_SYM(r_info);
|
||||
- }
|
||||
-
|
||||
- sym = elf_sym_by_index(elf, r_sym);
|
||||
- shndx = elf_uval(elf, sym, st_shndx);
|
||||
- switch ( shndx )
|
||||
- {
|
||||
- case SHN_UNDEF:
|
||||
- sname = "*UNDEF*";
|
||||
- sbase = 0;
|
||||
- break;
|
||||
- case SHN_COMMON:
|
||||
- elf_err(elf, "%s: invalid section: %" PRId64 "\n",
|
||||
- __FUNCTION__, shndx);
|
||||
- return -1;
|
||||
- case SHN_ABS:
|
||||
- sname = "*ABS*";
|
||||
- sbase = 0;
|
||||
- break;
|
||||
- default:
|
||||
- shdr = elf_shdr_by_index(elf, shndx);
|
||||
- if ( shdr == NULL )
|
||||
- {
|
||||
- elf_err(elf, "%s: invalid section: %" PRId64 "\n",
|
||||
- __FUNCTION__, shndx);
|
||||
- return -1;
|
||||
- }
|
||||
- sname = elf_section_name(elf, shdr);
|
||||
- sbase = elf_uval(elf, shdr, sh_addr);
|
||||
- }
|
||||
-
|
||||
- addr = r_offset;
|
||||
- value = elf_uval(elf, sym, st_value);
|
||||
- value += r_addend;
|
||||
-
|
||||
- if ( elf->log_callback && (elf->verbose > 1) )
|
||||
- {
|
||||
- uint64_t st_name = elf_uval(elf, sym, st_name);
|
||||
- const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*";
|
||||
-
|
||||
- elf_msg(elf,
|
||||
- "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 ","
|
||||
- " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]"
|
||||
- " -> addr 0x%" PRIx64 " value 0x%" PRIx64 "\n",
|
||||
- __FUNCTION__, rela_name(machine, r_type), r_type, r_offset,
|
||||
- r_addend, name, elf_uval(elf, sym, st_value), sname, sbase,
|
||||
- addr, value);
|
||||
- }
|
||||
-
|
||||
- if ( relocs[machine].func(elf, r_type, addr, value) == -1 )
|
||||
- {
|
||||
- elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n",
|
||||
- __FUNCTION__, rela_name(machine, r_type), r_type);
|
||||
- return -1;
|
||||
- }
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int elf_reloc(struct elf_binary *elf)
|
||||
-{
|
||||
- const elf_shdr *rels, *sect, *syms;
|
||||
- uint64_t i, count, type;
|
||||
-
|
||||
- count = elf_shdr_count(elf);
|
||||
- for ( i = 0; i < count; i++ )
|
||||
- {
|
||||
- rels = elf_shdr_by_index(elf, i);
|
||||
- type = elf_uval(elf, rels, sh_type);
|
||||
- if ( (type != SHT_REL) && (type != SHT_RELA) )
|
||||
- continue;
|
||||
-
|
||||
- sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info));
|
||||
- syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link));
|
||||
- if ( NULL == sect || NULL == syms )
|
||||
- continue;
|
||||
-
|
||||
- if ( !(elf_uval(elf, sect, sh_flags) & SHF_ALLOC) )
|
||||
- {
|
||||
- elf_msg(elf, "%s: relocations for %s, skipping\n",
|
||||
- __FUNCTION__, elf_section_name(elf, sect));
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n",
|
||||
- __FUNCTION__, elf_section_name(elf, sect),
|
||||
- elf_uval(elf, sect, sh_addr));
|
||||
- if ( elf_reloc_section(elf, rels, sect, syms) != 0 )
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Local variables:
|
||||
- * mode: C
|
||||
- * c-set-style: "BSD"
|
||||
- * c-basic-offset: 4
|
||||
- * tab-width: 4
|
||||
- * indent-tabs-mode: nil
|
||||
- * End:
|
||||
- */
|
||||
--
|
||||
#1.7.2.5
|
||||
|
@ -1,371 +0,0 @@
|
||||
From d0790bdad7496e720416b2d4a04563c4c27e7b95 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:17 +0100
|
||||
Subject: [PATCH 12/23] libelf: Check pointer references in elf_is_elfbinary
|
||||
|
||||
elf_is_elfbinary didn't take a length parameter and could potentially
|
||||
access out of range when provided with a very short image.
|
||||
|
||||
We only need to check the size is enough for the actual dereference in
|
||||
elf_is_elfbinary; callers are just using it to check the magic number
|
||||
and do their own checks (usually via the new elf_ptrval system) before
|
||||
dereferencing other parts of the header.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
---
|
||||
tools/libxc/xc_dom_elfloader.c | 2 +-
|
||||
xen/arch/x86/bzimage.c | 4 ++--
|
||||
xen/common/libelf/libelf-loader.c | 2 +-
|
||||
xen/common/libelf/libelf-tools.c | 9 ++++++---
|
||||
xen/include/xen/libelf.h | 4 +++-
|
||||
5 files changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index b82a08c..ea45886 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -95,7 +95,7 @@ static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if ( !elf_is_elfbinary(dom->kernel_blob) )
|
||||
+ if ( !elf_is_elfbinary(dom->kernel_blob, dom->kernel_size) )
|
||||
{
|
||||
if ( verbose )
|
||||
xc_dom_panic(dom->xch,
|
||||
diff --git a/xen/arch/x86/bzimage.c b/xen/arch/x86/bzimage.c
|
||||
index 5adc223..3600dca 100644
|
||||
--- a/xen/arch/x86/bzimage.c
|
||||
+++ b/xen/arch/x86/bzimage.c
|
||||
@@ -220,7 +220,7 @@ unsigned long __init bzimage_headroom(char *image_start,
|
||||
image_length = hdr->payload_length;
|
||||
}
|
||||
|
||||
- if ( elf_is_elfbinary(image_start) )
|
||||
+ if ( elf_is_elfbinary(image_start, image_length) )
|
||||
return 0;
|
||||
|
||||
orig_image_len = image_length;
|
||||
@@ -251,7 +251,7 @@ int __init bzimage_parse(char *image_base, char **image_start, unsigned long *im
|
||||
*image_len = hdr->payload_length;
|
||||
}
|
||||
|
||||
- if ( elf_is_elfbinary(*image_start) )
|
||||
+ if ( elf_is_elfbinary(*image_start, *image_len) )
|
||||
return 0;
|
||||
|
||||
BUG_ON(!(image_base < *image_start));
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index a3310e7..f8be635 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -29,7 +29,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
|
||||
ELF_HANDLE_DECL(elf_shdr) shdr;
|
||||
uint64_t i, count, section, offset;
|
||||
|
||||
- if ( !elf_is_elfbinary(image_input) )
|
||||
+ if ( !elf_is_elfbinary(image_input, size) )
|
||||
{
|
||||
elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__);
|
||||
return -1;
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index 46ca553..744027e 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -332,11 +332,14 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
-int elf_is_elfbinary(const void *image)
|
||||
+int elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
{
|
||||
- const Elf32_Ehdr *ehdr = image;
|
||||
+ const Elf32_Ehdr *ehdr = image_start;
|
||||
|
||||
- return IS_ELF(*ehdr); /* fixme unchecked */
|
||||
+ if ( image_size < sizeof(*ehdr) )
|
||||
+ return 0;
|
||||
+
|
||||
+ return IS_ELF(*ehdr);
|
||||
}
|
||||
|
||||
int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index ddc3ed7..ac93858 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -350,7 +350,9 @@ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
unsigned int unitsz, unsigned int idx);
|
||||
ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
|
||||
-int elf_is_elfbinary(const void *image);
|
||||
+/* (Only) checks that the image has the right magic number. */
|
||||
+int elf_is_elfbinary(const void *image_start, size_t image_size);
|
||||
+
|
||||
int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
--
|
||||
1.7.2.5
|
||||
#From a965b8f80388603d439ae2b8ee7b9b018a079f90 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:17 +0100
|
||||
#Subject: [PATCH 13/23] libelf: Make all callers call elf_check_broken
|
||||
#
|
||||
#This arranges that if the new pointer reference error checking
|
||||
#tripped, we actually get a message about it. In this patch these
|
||||
#messages do not change the actual return values from the various
|
||||
#functions: so pointer reference errors do not prevent loading. This
|
||||
#is for fear that some existing kernels might cause the code to make
|
||||
#these wild references, which would then break, which is not a good
|
||||
#thing in a security patch.
|
||||
#
|
||||
#In xen/arch/x86/domain_build.c we have to introduce an "out" label and
|
||||
#change all of the "return rc" beyond the relevant point into "goto
|
||||
#out".
|
||||
#
|
||||
#Difference in the 4.2 series, compared to unstable:
|
||||
#
|
||||
#* tools/libxc/xc_hvm_build_x86.c:setup_guest and
|
||||
# xen/arch/arm/kernel.c:kernel_try_elf_prepare have different
|
||||
# error handling in 4.2 to unstable; patch adjusted accordingly.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#
|
||||
#xen-unstable version Reviewed-by: George Dunlap <george.dunlap@eu.citrix.com>
|
||||
#---
|
||||
# tools/libxc/xc_dom_elfloader.c | 25 +++++++++++++++++++++----
|
||||
# tools/libxc/xc_hvm_build_x86.c | 5 +++++
|
||||
# tools/xcutils/readnotes.c | 3 +++
|
||||
# xen/arch/arm/kernel.c | 15 ++++++++++++++-
|
||||
# xen/arch/x86/domain_build.c | 28 +++++++++++++++++++++-------
|
||||
# 5 files changed, 64 insertions(+), 12 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index ea45886..4fb4da2 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -276,6 +276,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
elf_store_field(elf, shdr, e32.sh_name, 0);
|
||||
}
|
||||
|
||||
+ if ( elf_check_broken(&syms) )
|
||||
+ DOMPRINTF("%s: symbols ELF broken: %s", __FUNCTION__,
|
||||
+ elf_check_broken(&syms));
|
||||
+ if ( elf_check_broken(elf) )
|
||||
+ DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
|
||||
+ elf_check_broken(elf));
|
||||
+
|
||||
if ( tables == 0 )
|
||||
{
|
||||
DOMPRINTF("%s: no symbol table present", __FUNCTION__);
|
||||
@@ -312,19 +319,23 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
|
||||
" has no shstrtab", __FUNCTION__);
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* parse binary and get xen meta info */
|
||||
elf_parse_binary(elf);
|
||||
if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
|
||||
- return rc;
|
||||
+ {
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
if ( elf_xen_feature_get(XENFEAT_dom0, dom->parms.f_required) )
|
||||
{
|
||||
xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
|
||||
" support unprivileged (DomU) operation", __FUNCTION__);
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* find kernel segment */
|
||||
@@ -338,7 +349,13 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
|
||||
DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
|
||||
__FUNCTION__, dom->guest_type,
|
||||
dom->kernel_seg.vstart, dom->kernel_seg.vend);
|
||||
- return 0;
|
||||
+ rc = 0;
|
||||
+out:
|
||||
+ if ( elf_check_broken(elf) )
|
||||
+ DOMPRINTF("%s: ELF broken: %s", __FUNCTION__,
|
||||
+ elf_check_broken(elf));
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
|
||||
diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
|
||||
index ccfd8b5..8165287 100644
|
||||
--- a/tools/libxc/xc_hvm_build_x86.c
|
||||
+++ b/tools/libxc/xc_hvm_build_x86.c
|
||||
@@ -403,11 +403,16 @@ static int setup_guest(xc_interface *xch,
|
||||
munmap(page0, PAGE_SIZE);
|
||||
}
|
||||
|
||||
+ if ( elf_check_broken(&elf) )
|
||||
+ ERROR("HVM ELF broken: %s", elf_check_broken(&elf));
|
||||
+
|
||||
free(page_array);
|
||||
return 0;
|
||||
|
||||
error_out:
|
||||
free(page_array);
|
||||
+ if ( elf_check_broken(&elf) )
|
||||
+ ERROR("HVM ELF broken, failing: %s", elf_check_broken(&elf));
|
||||
return -1;
|
||||
}
|
||||
|
||||
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
|
||||
index cfae994..d1f7a30 100644
|
||||
--- a/tools/xcutils/readnotes.c
|
||||
+++ b/tools/xcutils/readnotes.c
|
||||
@@ -301,6 +301,9 @@ int main(int argc, char **argv)
|
||||
printf("__xen_guest: %s\n",
|
||||
elf_strfmt(&elf, elf_section_start(&elf, shdr)));
|
||||
|
||||
+ if (elf_check_broken(&elf))
|
||||
+ printf("warning: broken ELF: %s\n", elf_check_broken(&elf));
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
|
||||
index 2d56130..dec0519 100644
|
||||
--- a/xen/arch/arm/kernel.c
|
||||
+++ b/xen/arch/arm/kernel.c
|
||||
@@ -146,6 +146,8 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
|
||||
{
|
||||
int rc;
|
||||
|
||||
+ memset(&info->elf.elf, 0, sizeof(info->elf.elf));
|
||||
+
|
||||
info->kernel_order = get_order_from_bytes(KERNEL_FLASH_SIZE);
|
||||
info->kernel_img = alloc_xenheap_pages(info->kernel_order, 0);
|
||||
if ( info->kernel_img == NULL )
|
||||
@@ -160,7 +162,7 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
|
||||
#endif
|
||||
elf_parse_binary(&info->elf.elf);
|
||||
if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 )
|
||||
- return rc;
|
||||
+ goto err;
|
||||
|
||||
/*
|
||||
* TODO: can the ELF header be used to find the physical address
|
||||
@@ -169,7 +171,18 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
|
||||
info->entry = info->elf.parms.virt_entry;
|
||||
info->load = kernel_elf_load;
|
||||
|
||||
+ if ( elf_check_broken(&info->elf.elf) )
|
||||
+ printk("Xen: warning: ELF kernel broken: %s\n",
|
||||
+ elf_check_broken(&info->elf.elf));
|
||||
+
|
||||
return 0;
|
||||
+
|
||||
+err:
|
||||
+ if ( elf_check_broken(&info->elf.elf) )
|
||||
+ printk("Xen: ELF kernel broken: %s\n",
|
||||
+ elf_check_broken(&info->elf.elf));
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
int kernel_prepare(struct kernel_info *info)
|
||||
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
|
||||
index a655b21..0dbec96 100644
|
||||
--- a/xen/arch/x86/domain_build.c
|
||||
+++ b/xen/arch/x86/domain_build.c
|
||||
@@ -374,7 +374,7 @@ int __init construct_dom0(
|
||||
#endif
|
||||
elf_parse_binary(&elf);
|
||||
if ( (rc = elf_xen_parse(&elf, &parms)) != 0 )
|
||||
- return rc;
|
||||
+ goto out;
|
||||
|
||||
/* compatibility check */
|
||||
compatible = 0;
|
||||
@@ -413,14 +413,16 @@ int __init construct_dom0(
|
||||
if ( !compatible )
|
||||
{
|
||||
printk("Mismatch between Xen and DOM0 kernel\n");
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if ( parms.elf_notes[XEN_ELFNOTE_SUPPORTED_FEATURES].type != XEN_ENT_NONE &&
|
||||
!test_bit(XENFEAT_dom0, parms.f_supported) )
|
||||
{
|
||||
printk("Kernel does not support Dom0 operation\n");
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
#if defined(__x86_64__)
|
||||
@@ -734,7 +736,8 @@ int __init construct_dom0(
|
||||
(v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
|
||||
{
|
||||
printk("DOM0 image overlaps with Xen private area.\n");
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if ( is_pv_32on64_domain(d) )
|
||||
@@ -914,7 +917,7 @@ int __init construct_dom0(
|
||||
if ( rc < 0 )
|
||||
{
|
||||
printk("Failed to load the kernel binary\n");
|
||||
- return rc;
|
||||
+ goto out;
|
||||
}
|
||||
bootstrap_map(NULL);
|
||||
|
||||
@@ -925,7 +928,8 @@ int __init construct_dom0(
|
||||
{
|
||||
write_ptbase(current);
|
||||
printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
|
||||
- return -1;
|
||||
+ rc = -1;
|
||||
+ goto out;
|
||||
}
|
||||
hypercall_page_initialise(
|
||||
d, (void *)(unsigned long)parms.virt_hypercall);
|
||||
@@ -1272,9 +1276,19 @@ int __init construct_dom0(
|
||||
|
||||
BUG_ON(rc != 0);
|
||||
|
||||
- iommu_dom0_init(dom0);
|
||||
+ if ( elf_check_broken(&elf) )
|
||||
+ printk(" Xen warning: dom0 kernel broken ELF: %s\n",
|
||||
+ elf_check_broken(&elf));
|
||||
|
||||
+ iommu_dom0_init(dom0);
|
||||
return 0;
|
||||
+
|
||||
+out:
|
||||
+ if ( elf_check_broken(&elf) )
|
||||
+ printk(" Xen dom0 kernel broken ELF: %s\n",
|
||||
+ elf_check_broken(&elf));
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
1.7.2.5
|
||||
|
||||
|
@ -1,252 +0,0 @@
|
||||
From 3fb6ccf2faccaf5e22e33a3155ccc72d732896d8 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:18 +0100
|
||||
Subject: [PATCH 14/23] libelf: use C99 bool for booleans
|
||||
|
||||
We want to remove uses of "int" because signed integers have
|
||||
undesirable undefined behaviours on overflow. Malicious compilers can
|
||||
turn apparently-correct code into code with security vulnerabilities
|
||||
etc.
|
||||
|
||||
In this patch we change all the booleans in libelf to C99 bool,
|
||||
from <stdbool.h>.
|
||||
|
||||
For the one visible libelf boolean in libxc's public interface we
|
||||
retain the use of int to avoid changing the ABI; libxc converts it to
|
||||
a bool for consumption by libelf.
|
||||
|
||||
It is OK to change all values only ever used as booleans to _Bool
|
||||
(bool) because conversion from any scalar type to a _Bool works the
|
||||
same as the boolean test in if() or ?: and is always defined (C99
|
||||
6.3.1.2). But we do need to check that all these variables really are
|
||||
only ever used that way. (It is theoretically possible that the old
|
||||
code truncated some 64-bit values to 32-bit ints which might become
|
||||
zero depending on the value, which would mean a behavioural change in
|
||||
this patch, but it seems implausible that treating 0x????????00000000
|
||||
as false could have been intended.)
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_dom_elfloader.c | 8 ++++----
|
||||
xen/common/libelf/libelf-dominfo.c | 2 +-
|
||||
xen/common/libelf/libelf-loader.c | 4 ++--
|
||||
xen/common/libelf/libelf-private.h | 2 +-
|
||||
xen/common/libelf/libelf-tools.c | 10 +++++-----
|
||||
xen/include/xen/libelf.h | 18 ++++++++++--------
|
||||
6 files changed, 23 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 4fb4da2..9ba64ae 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -34,7 +34,7 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void log_callback(struct elf_binary *elf, void *caller_data,
|
||||
- int iserr, const char *fmt, va_list al) {
|
||||
+ bool iserr, const char *fmt, va_list al) {
|
||||
xc_interface *xch = caller_data;
|
||||
|
||||
xc_reportv(xch,
|
||||
@@ -46,7 +46,7 @@ static void log_callback(struct elf_binary *elf, void *caller_data,
|
||||
|
||||
void xc_elf_set_logfile(xc_interface *xch, struct elf_binary *elf,
|
||||
int verbose) {
|
||||
- elf_set_log(elf, log_callback, xch, verbose);
|
||||
+ elf_set_log(elf, log_callback, xch, verbose /* convert to bool */);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -84,7 +84,7 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* parse elf binary */
|
||||
|
||||
-static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
|
||||
+static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
|
||||
{
|
||||
if ( dom->kernel_blob == NULL )
|
||||
{
|
||||
@@ -112,7 +112,7 @@ static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
|
||||
}
|
||||
|
||||
static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
- struct elf_binary *elf, int load)
|
||||
+ struct elf_binary *elf, bool load)
|
||||
{
|
||||
struct elf_binary syms;
|
||||
ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
|
||||
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
|
||||
index 98c80dc..12b6c2a 100644
|
||||
--- a/xen/common/libelf/libelf-dominfo.c
|
||||
+++ b/xen/common/libelf/libelf-dominfo.c
|
||||
@@ -101,7 +101,7 @@ int elf_xen_parse_note(struct elf_binary *elf,
|
||||
/* *INDENT-OFF* */
|
||||
static const struct {
|
||||
char *name;
|
||||
- int str;
|
||||
+ bool str;
|
||||
} note_desc[] = {
|
||||
[XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
|
||||
[XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index f8be635..0dccd4d 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -92,7 +92,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
|
||||
}
|
||||
|
||||
#ifndef __XEN__
|
||||
-void elf_call_log_callback(struct elf_binary *elf, int iserr,
|
||||
+void elf_call_log_callback(struct elf_binary *elf, bool iserr,
|
||||
const char *fmt,...) {
|
||||
va_list al;
|
||||
|
||||
@@ -107,7 +107,7 @@ void elf_call_log_callback(struct elf_binary *elf, int iserr,
|
||||
}
|
||||
|
||||
void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
|
||||
- void *log_caller_data, int verbose)
|
||||
+ void *log_caller_data, bool verbose)
|
||||
{
|
||||
elf->log_callback = log_callback;
|
||||
elf->log_caller_data = log_caller_data;
|
||||
diff --git a/xen/common/libelf/libelf-private.h b/xen/common/libelf/libelf-private.h
|
||||
index 280dfd1..277be04 100644
|
||||
--- a/xen/common/libelf/libelf-private.h
|
||||
+++ b/xen/common/libelf/libelf-private.h
|
||||
@@ -77,7 +77,7 @@
|
||||
#define elf_err(elf, fmt, args ... ) \
|
||||
elf_call_log_callback(elf, 1, fmt , ## args );
|
||||
|
||||
-void elf_call_log_callback(struct elf_binary*, int iserr, const char *fmt,...);
|
||||
+void elf_call_log_callback(struct elf_binary*, bool iserr, const char *fmt,...);
|
||||
|
||||
#define safe_strcpy(d,s) \
|
||||
do { strncpy((d),(s),sizeof((d))-1); \
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index 744027e..fa58f76 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -31,7 +31,7 @@ const char *elf_check_broken(const struct elf_binary *elf)
|
||||
return elf->broken;
|
||||
}
|
||||
|
||||
-static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
+static bool elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
const void *region, uint64_t regionsize)
|
||||
/*
|
||||
* Returns true if the putative memory area [ptrval,ptrval+size>
|
||||
@@ -53,7 +53,7 @@ static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
-int elf_access_ok(struct elf_binary * elf,
|
||||
+bool elf_access_ok(struct elf_binary * elf,
|
||||
uint64_t ptrval, size_t size)
|
||||
{
|
||||
if ( elf_ptrval_in_range(ptrval, size, elf->image_base, elf->size) )
|
||||
@@ -92,7 +92,7 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
|
||||
uint64_t moreoffset, size_t size)
|
||||
{
|
||||
elf_ptrval ptrval = base + moreoffset;
|
||||
- int need_swap = elf_swap(elf);
|
||||
+ bool need_swap = elf_swap(elf);
|
||||
const uint8_t *u8;
|
||||
const uint16_t *u16;
|
||||
const uint32_t *u32;
|
||||
@@ -332,7 +332,7 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
-int elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
+bool elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
{
|
||||
const Elf32_Ehdr *ehdr = image_start;
|
||||
|
||||
@@ -342,7 +342,7 @@ int elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
return IS_ELF(*ehdr);
|
||||
}
|
||||
|
||||
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
{
|
||||
uint64_t p_type = elf_uval(elf, phdr, p_type);
|
||||
uint64_t p_flags = elf_uval(elf, phdr, p_flags);
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index ac93858..951430f 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -29,6 +29,8 @@
|
||||
#error define architectural endianness
|
||||
#endif
|
||||
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
#undef ELFSIZE
|
||||
#include "elfstructs.h"
|
||||
#ifdef __XEN__
|
||||
@@ -42,7 +44,7 @@
|
||||
|
||||
struct elf_binary;
|
||||
typedef void elf_log_callback(struct elf_binary*, void *caller_data,
|
||||
- int iserr, const char *fmt, va_list al);
|
||||
+ bool iserr, const char *fmt, va_list al);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -237,7 +239,7 @@ struct elf_binary {
|
||||
elf_log_callback *log_callback;
|
||||
void *log_caller_data;
|
||||
#endif
|
||||
- int verbose;
|
||||
+ bool verbose;
|
||||
const char *broken;
|
||||
};
|
||||
|
||||
@@ -301,8 +303,8 @@ void elf_memset_safe(struct elf_binary*, elf_ptrval dst, int c, size_t);
|
||||
* outside permitted areas.
|
||||
*/
|
||||
|
||||
-int elf_access_ok(struct elf_binary * elf,
|
||||
- uint64_t ptrval, size_t size);
|
||||
+bool elf_access_ok(struct elf_binary * elf,
|
||||
+ uint64_t ptrval, size_t size);
|
||||
|
||||
#define elf_store_val(elf, type, ptr, val) \
|
||||
({ \
|
||||
@@ -351,9 +353,9 @@ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
|
||||
/* (Only) checks that the image has the right magic number. */
|
||||
-int elf_is_elfbinary(const void *image_start, size_t image_size);
|
||||
+bool elf_is_elfbinary(const void *image_start, size_t image_size);
|
||||
|
||||
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* xc_libelf_loader.c */
|
||||
@@ -367,7 +369,7 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size);
|
||||
void elf_set_verbose(struct elf_binary *elf);
|
||||
#else
|
||||
void elf_set_log(struct elf_binary *elf, elf_log_callback*,
|
||||
- void *log_caller_pointer, int verbose);
|
||||
+ void *log_caller_pointer, bool verbose);
|
||||
#endif
|
||||
|
||||
void elf_parse_binary(struct elf_binary *elf);
|
||||
@@ -419,7 +421,7 @@ struct elf_dom_parms {
|
||||
char xen_ver[16];
|
||||
char loader[16];
|
||||
int pae;
|
||||
- int bsd_symtab;
|
||||
+ bool bsd_symtab;
|
||||
uint64_t virt_base;
|
||||
uint64_t virt_entry;
|
||||
uint64_t virt_hypercall;
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,409 +0,0 @@
|
||||
From 52d8cc2dd3bb3e0f6d51e00280da934e8d91653a Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:18 +0100
|
||||
Subject: [PATCH 16/23] libelf: check loops for running away
|
||||
|
||||
Ensure that libelf does not have any loops which can run away
|
||||
indefinitely even if the input is bogus. (Grepped for \bfor, \bwhile
|
||||
and \bgoto in libelf and xc_dom_*loader*.c.)
|
||||
|
||||
Changes needed:
|
||||
* elf_note_next uses the note's unchecked alleged length, which might
|
||||
wrap round. If it does, return ELF_MAX_PTRVAL (0xfff..fff) instead,
|
||||
which will be beyond the end of the section and so terminate the
|
||||
caller's loop. Also check that the returned psuedopointer is sane.
|
||||
* In various loops over section and program headers, check that the
|
||||
calculated header pointer is still within the image, and quit the
|
||||
loop if it isn't.
|
||||
* Some fixed limits to avoid potentially O(image_size^2) loops:
|
||||
- maximum length of strings: 4K (longer ones ignored totally)
|
||||
- maximum total number of ELF notes: 65536 (any more are ignored)
|
||||
* Check that the total program contents (text, data) we copy or
|
||||
initialise doesn't exceed twice the output image area size.
|
||||
* Remove an entirely useless loop from elf_xen_parse (!)
|
||||
* Replace a nested search loop in in xc_dom_load_elf_symtab in
|
||||
xc_dom_elfloader.c by a precomputation of a bitmap of referenced
|
||||
symtabs.
|
||||
|
||||
We have not changed loops which might, in principle, iterate over the
|
||||
whole image - even if they might do so one byte at a time with a
|
||||
nontrivial access check function in the middle.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_dom_elfloader.c | 33 ++++++++++++++++++-------
|
||||
xen/common/libelf/libelf-dominfo.c | 43 ++++++++++++++++++++------------
|
||||
xen/common/libelf/libelf-loader.c | 47 ++++++++++++++++++++++++++++++++++-
|
||||
xen/common/libelf/libelf-tools.c | 28 ++++++++++++++++++++-
|
||||
xen/include/xen/libelf.h | 13 ++++++++++
|
||||
5 files changed, 135 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 62a0d3b..c5014d2 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "xg_private.h"
|
||||
#include "xc_dom.h"
|
||||
+#include "xc_bitops.h"
|
||||
|
||||
#define XEN_VER "xen-3.0"
|
||||
|
||||
@@ -120,6 +121,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
ELF_PTRVAL_CHAR hdr;
|
||||
size_t size;
|
||||
unsigned h, count, type, i, tables = 0;
|
||||
+ unsigned long *strtab_referenced = NULL;
|
||||
|
||||
if ( elf_swap(elf) )
|
||||
{
|
||||
@@ -220,22 +222,35 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
symtab, maxaddr);
|
||||
|
||||
count = elf_shdr_count(&syms);
|
||||
+ /* elf_shdr_count guarantees that count is reasonable */
|
||||
+
|
||||
+ strtab_referenced = xc_dom_malloc(dom, bitmap_size(count));
|
||||
+ if ( strtab_referenced == NULL )
|
||||
+ return -1;
|
||||
+ bitmap_clear(strtab_referenced, count);
|
||||
+ /* Note the symtabs @h linked to by any strtab @i. */
|
||||
+ for ( i = 0; i < count; i++ )
|
||||
+ {
|
||||
+ shdr2 = elf_shdr_by_index(&syms, i);
|
||||
+ if ( elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB )
|
||||
+ {
|
||||
+ h = elf_uval(&syms, shdr2, sh_link);
|
||||
+ if (h < count)
|
||||
+ set_bit(h, strtab_referenced);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
for ( h = 0; h < count; h++ )
|
||||
{
|
||||
shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
+ /* input has an insane section header count field */
|
||||
+ break;
|
||||
type = elf_uval(&syms, shdr, sh_type);
|
||||
if ( type == SHT_STRTAB )
|
||||
{
|
||||
- /* Look for a strtab @i linked to symtab @h. */
|
||||
- for ( i = 0; i < count; i++ )
|
||||
- {
|
||||
- shdr2 = elf_shdr_by_index(&syms, i);
|
||||
- if ( (elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) &&
|
||||
- (elf_uval(&syms, shdr2, sh_link) == h) )
|
||||
- break;
|
||||
- }
|
||||
/* Skip symtab @h if we found no corresponding strtab @i. */
|
||||
- if ( i == count )
|
||||
+ if ( !test_bit(h, strtab_referenced) )
|
||||
{
|
||||
if ( elf_64bit(&syms) )
|
||||
elf_store_field(elf, shdr, e64.sh_offset, 0);
|
||||
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
|
||||
index cdd0d31..25a10d7 100644
|
||||
--- a/xen/common/libelf/libelf-dominfo.c
|
||||
+++ b/xen/common/libelf/libelf-dominfo.c
|
||||
@@ -221,7 +221,8 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
|
||||
static unsigned elf_xen_parse_notes(struct elf_binary *elf,
|
||||
struct elf_dom_parms *parms,
|
||||
ELF_PTRVAL_CONST_VOID start,
|
||||
- ELF_PTRVAL_CONST_VOID end)
|
||||
+ ELF_PTRVAL_CONST_VOID end,
|
||||
+ unsigned *total_note_count)
|
||||
{
|
||||
unsigned xen_elfnotes = 0;
|
||||
ELF_HANDLE_DECL(elf_note) note;
|
||||
@@ -233,6 +234,12 @@ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
|
||||
ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
|
||||
note = elf_note_next(elf, note) )
|
||||
{
|
||||
+ if ( *total_note_count >= ELF_MAX_TOTAL_NOTE_COUNT )
|
||||
+ {
|
||||
+ elf_mark_broken(elf, "too many ELF notes");
|
||||
+ break;
|
||||
+ }
|
||||
+ (*total_note_count)++;
|
||||
note_name = elf_note_name(elf, note);
|
||||
if ( note_name == NULL )
|
||||
continue;
|
||||
@@ -473,6 +480,7 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
|
||||
ELF_HANDLE_DECL(elf_phdr) phdr;
|
||||
unsigned xen_elfnotes = 0;
|
||||
unsigned i, count, more_notes;
|
||||
+ unsigned total_note_count = 0;
|
||||
|
||||
elf_memset_unchecked(parms, 0, sizeof(*parms));
|
||||
parms->virt_base = UNSET_ADDR;
|
||||
@@ -487,6 +495,9 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
phdr = elf_phdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
|
||||
+ /* input has an insane program header count field */
|
||||
+ break;
|
||||
if ( elf_uval(elf, phdr, p_type) != PT_NOTE )
|
||||
continue;
|
||||
|
||||
@@ -499,7 +510,8 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
|
||||
|
||||
more_notes = elf_xen_parse_notes(elf, parms,
|
||||
elf_segment_start(elf, phdr),
|
||||
- elf_segment_end(elf, phdr));
|
||||
+ elf_segment_end(elf, phdr),
|
||||
+ &total_note_count);
|
||||
if ( more_notes == ELF_NOTE_INVALID )
|
||||
return -1;
|
||||
|
||||
@@ -516,13 +528,17 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
shdr = elf_shdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
+ /* input has an insane section header count field */
|
||||
+ break;
|
||||
|
||||
if ( elf_uval(elf, shdr, sh_type) != SHT_NOTE )
|
||||
continue;
|
||||
|
||||
more_notes = elf_xen_parse_notes(elf, parms,
|
||||
elf_section_start(elf, shdr),
|
||||
- elf_section_end(elf, shdr));
|
||||
+ elf_section_end(elf, shdr),
|
||||
+ &total_note_count);
|
||||
|
||||
if ( more_notes == ELF_NOTE_INVALID )
|
||||
return -1;
|
||||
@@ -540,20 +556,15 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf,
|
||||
*/
|
||||
if ( xen_elfnotes == 0 )
|
||||
{
|
||||
- count = elf_shdr_count(elf);
|
||||
- for ( i = 0; i < count; i++ )
|
||||
+ shdr = elf_shdr_by_name(elf, "__xen_guest");
|
||||
+ if ( ELF_HANDLE_VALID(shdr) )
|
||||
{
|
||||
- shdr = elf_shdr_by_name(elf, "__xen_guest");
|
||||
- if ( ELF_HANDLE_VALID(shdr) )
|
||||
- {
|
||||
- parms->guest_info = elf_section_start(elf, shdr);
|
||||
- parms->elf_note_start = ELF_INVALID_PTRVAL;
|
||||
- parms->elf_note_end = ELF_INVALID_PTRVAL;
|
||||
- elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
|
||||
- elf_strfmt(elf, parms->guest_info));
|
||||
- elf_xen_parse_guest_info(elf, parms);
|
||||
- break;
|
||||
- }
|
||||
+ parms->guest_info = elf_section_start(elf, shdr);
|
||||
+ parms->elf_note_start = ELF_INVALID_PTRVAL;
|
||||
+ parms->elf_note_end = ELF_INVALID_PTRVAL;
|
||||
+ elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
|
||||
+ elf_strfmt(elf, parms->guest_info));
|
||||
+ elf_xen_parse_guest_info(elf, parms);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index c3a9e51..06799af 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -75,6 +75,9 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
shdr = elf_shdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
+ /* input has an insane section header count field */
|
||||
+ break;
|
||||
if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
|
||||
continue;
|
||||
elf->sym_tab = shdr;
|
||||
@@ -170,6 +173,9 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
|
||||
for ( i = 0; i < elf_shdr_count(elf); i++ )
|
||||
{
|
||||
shdr = elf_shdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
+ /* input has an insane section header count field */
|
||||
+ break;
|
||||
type = elf_uval(elf, shdr, sh_type);
|
||||
if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
|
||||
sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
|
||||
@@ -224,6 +230,9 @@ do { \
|
||||
|
||||
for ( i = 0; i < elf_shdr_count(elf); i++ )
|
||||
{
|
||||
+ elf_ptrval old_shdr_p;
|
||||
+ elf_ptrval new_shdr_p;
|
||||
+
|
||||
type = elf_uval(elf, shdr, sh_type);
|
||||
if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
|
||||
{
|
||||
@@ -235,8 +244,16 @@ do { \
|
||||
elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
|
||||
maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
|
||||
}
|
||||
- shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
|
||||
- (unsigned long)elf_uval(elf, elf->ehdr, e_shentsize));
|
||||
+ old_shdr_p = ELF_HANDLE_PTRVAL(shdr);
|
||||
+ new_shdr_p = old_shdr_p + elf_uval(elf, elf->ehdr, e_shentsize);
|
||||
+ if ( new_shdr_p <= old_shdr_p ) /* wrapped or stuck */
|
||||
+ {
|
||||
+ elf_mark_broken(elf, "bad section header length");
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( !elf_access_ok(elf, new_shdr_p, 1) ) /* outside image */
|
||||
+ break;
|
||||
+ shdr = ELF_MAKE_HANDLE(elf_shdr, new_shdr_p);
|
||||
}
|
||||
|
||||
/* Write down the actual sym size. */
|
||||
@@ -256,6 +273,9 @@ void elf_parse_binary(struct elf_binary *elf)
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
phdr = elf_phdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
|
||||
+ /* input has an insane program header count field */
|
||||
+ break;
|
||||
if ( !elf_phdr_is_loadable(elf, phdr) )
|
||||
continue;
|
||||
paddr = elf_uval(elf, phdr, p_paddr);
|
||||
@@ -278,11 +298,20 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
|
||||
ELF_HANDLE_DECL(elf_phdr) phdr;
|
||||
uint64_t i, count, paddr, offset, filesz, memsz;
|
||||
ELF_PTRVAL_VOID dest;
|
||||
+ /*
|
||||
+ * Let bizarre ELFs write the output image up to twice; this
|
||||
+ * calculation is just to ensure our copying loop is no worse than
|
||||
+ * O(domain_size).
|
||||
+ */
|
||||
+ uint64_t remain_allow_copy = (uint64_t)elf->dest_size * 2;
|
||||
|
||||
count = elf_uval(elf, elf->ehdr, e_phnum);
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
phdr = elf_phdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) )
|
||||
+ /* input has an insane program header count field */
|
||||
+ break;
|
||||
if ( !elf_phdr_is_loadable(elf, phdr) )
|
||||
continue;
|
||||
paddr = elf_uval(elf, phdr, p_paddr);
|
||||
@@ -290,6 +319,20 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
|
||||
filesz = elf_uval(elf, phdr, p_filesz);
|
||||
memsz = elf_uval(elf, phdr, p_memsz);
|
||||
dest = elf_get_ptr(elf, paddr);
|
||||
+
|
||||
+ /*
|
||||
+ * We need to check that the input image doesn't have us copy
|
||||
+ * the whole image zillions of times, as that could lead to
|
||||
+ * O(n^2) time behaviour and possible DoS by a malicous ELF.
|
||||
+ */
|
||||
+ if ( remain_allow_copy < memsz )
|
||||
+ {
|
||||
+ elf_mark_broken(elf, "program segments total to more"
|
||||
+ " than the input image size");
|
||||
+ break;
|
||||
+ }
|
||||
+ remain_allow_copy -= memsz;
|
||||
+
|
||||
elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n",
|
||||
__func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
|
||||
if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, memsz) != 0 )
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index 46d4ab1..4a83133 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -131,7 +131,16 @@ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
|
||||
|
||||
unsigned elf_shdr_count(struct elf_binary *elf)
|
||||
{
|
||||
- return elf_uval(elf, elf->ehdr, e_shnum);
|
||||
+ unsigned count = elf_uval(elf, elf->ehdr, e_shnum);
|
||||
+ uint64_t max = elf->size / sizeof(Elf32_Shdr);
|
||||
+ if (max > ~(unsigned)0)
|
||||
+ max = ~(unsigned)0; /* Xen doesn't have limits.h :-/ */
|
||||
+ if (count > max)
|
||||
+ {
|
||||
+ elf_mark_broken(elf, "far too many section headers");
|
||||
+ count = max;
|
||||
+ }
|
||||
+ return count;
|
||||
}
|
||||
|
||||
unsigned elf_phdr_count(struct elf_binary *elf)
|
||||
@@ -149,6 +158,9 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
shdr = elf_shdr_by_index(elf, i);
|
||||
+ if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
+ /* input has an insane section header count field */
|
||||
+ break;
|
||||
sname = elf_section_name(elf, shdr);
|
||||
if ( sname && !strcmp(sname, name) )
|
||||
return shdr;
|
||||
@@ -204,6 +216,11 @@ const char *elf_strval(struct elf_binary *elf, elf_ptrval start)
|
||||
if ( !elf_access_unsigned(elf, start, length, 1) )
|
||||
/* ok */
|
||||
return ELF_UNSAFE_PTR(start);
|
||||
+ if ( length >= ELF_MAX_STRING_LENGTH )
|
||||
+ {
|
||||
+ elf_mark_broken(elf, "excessively long string");
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +344,14 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
|
||||
unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
|
||||
unsigned descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
|
||||
|
||||
- return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz + descsz);
|
||||
+ elf_ptrval ptrval = ELF_HANDLE_PTRVAL(note)
|
||||
+ + elf_size(elf, note) + namesz + descsz;
|
||||
+
|
||||
+ if ( ( ptrval <= ELF_HANDLE_PTRVAL(note) || /* wrapped or stuck */
|
||||
+ !elf_access_ok(elf, ELF_HANDLE_PTRVAL(note), 1) ) )
|
||||
+ ptrval = ELF_MAX_PTRVAL; /* terminate caller's loop */
|
||||
+
|
||||
+ return ELF_MAKE_HANDLE(elf_note, ptrval);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index 87e126a..f95fe88 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -51,6 +51,9 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
|
||||
|
||||
#endif
|
||||
|
||||
+#define ELF_MAX_STRING_LENGTH 4096
|
||||
+#define ELF_MAX_TOTAL_NOTE_COUNT 65536
|
||||
+
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Macros for accessing the input image and output area. */
|
||||
@@ -353,6 +356,16 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
|
||||
uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
unsigned int unitsz, unsigned int idx);
|
||||
+
|
||||
+/*
|
||||
+ * If you use elf_note_next in a loop, you must put a nontrivial upper
|
||||
+ * bound on the returned value as part of your loop condition. In
|
||||
+ * some cases elf_note_next will substitute ELF_PTRVAL_MAX as return
|
||||
+ * value to indicate that the iteration isn't going well (for example,
|
||||
+ * the putative "next" value would be earlier in memory). In this
|
||||
+ * case the caller's loop must terminate. Checking against the
|
||||
+ * end of the notes segment with a strict inequality is sufficient.
|
||||
+ */
|
||||
ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
|
||||
/* (Only) checks that the image has the right magic number. */
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,406 +0,0 @@
|
||||
From 3baaa4ffcd3e7dd6227f9bdf817f90e5b75aeda2 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
Subject: [PATCH 17/23] libelf: abolish obsolete macros
|
||||
|
||||
Abolish ELF_PTRVAL_[CONST_]{CHAR,VOID}; change uses to elf_ptrval.
|
||||
Abolish ELF_HANDLE_DECL_NONCONST; change uses to ELF_HANDLE_DECL.
|
||||
Abolish ELF_OBSOLETE_VOIDP_CAST; simply remove all uses.
|
||||
|
||||
No functional change. (Verified by diffing assembler output.)
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
|
||||
v2: New patch.
|
||||
---
|
||||
tools/libxc/xc_dom_elfloader.c | 8 +++---
|
||||
tools/xcutils/readnotes.c | 2 +-
|
||||
xen/common/libelf/libelf-dominfo.c | 6 ++--
|
||||
xen/common/libelf/libelf-loader.c | 24 +++++++++---------
|
||||
xen/common/libelf/libelf-tools.c | 24 +++++++++---------
|
||||
xen/include/xen/libelf.h | 48 +++++++++---------------------------
|
||||
6 files changed, 44 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index c5014d2..9fc4b94 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -116,9 +116,9 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
struct elf_binary *elf, bool load)
|
||||
{
|
||||
struct elf_binary syms;
|
||||
- ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
|
||||
+ ELF_HANDLE_DECL(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
|
||||
xen_vaddr_t symtab, maxaddr;
|
||||
- ELF_PTRVAL_CHAR hdr;
|
||||
+ elf_ptrval hdr;
|
||||
size_t size;
|
||||
unsigned h, count, type, i, tables = 0;
|
||||
unsigned long *strtab_referenced = NULL;
|
||||
@@ -242,7 +242,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
|
||||
for ( h = 0; h < count; h++ )
|
||||
{
|
||||
- shdr = ELF_OBSOLETE_VOIDP_CAST elf_shdr_by_index(&syms, h);
|
||||
+ shdr = elf_shdr_by_index(&syms, h);
|
||||
if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) )
|
||||
/* input has an insane section header count field */
|
||||
break;
|
||||
@@ -278,7 +278,7 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
if ( load )
|
||||
{
|
||||
shdr2 = elf_shdr_by_index(elf, h);
|
||||
- elf_memcpy_safe(elf, ELF_OBSOLETE_VOIDP_CAST elf_section_start(&syms, shdr),
|
||||
+ elf_memcpy_safe(elf, elf_section_start(&syms, shdr),
|
||||
elf_section_start(elf, shdr2),
|
||||
size);
|
||||
}
|
||||
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
|
||||
index 2ca7732..5fa445e 100644
|
||||
--- a/tools/xcutils/readnotes.c
|
||||
+++ b/tools/xcutils/readnotes.c
|
||||
@@ -80,7 +80,7 @@ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
|
||||
ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
unsigned descsz = elf_uval(elf, note, descsz);
|
||||
- ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
|
||||
+ elf_ptrval desc = elf_note_desc(elf, note);
|
||||
|
||||
/* XXX should be able to cope with a list of values. */
|
||||
switch ( descsz / 2 )
|
||||
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
|
||||
index 25a10d7..412ea70 100644
|
||||
--- a/xen/common/libelf/libelf-dominfo.c
|
||||
+++ b/xen/common/libelf/libelf-dominfo.c
|
||||
@@ -220,8 +220,8 @@ elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
|
||||
|
||||
static unsigned elf_xen_parse_notes(struct elf_binary *elf,
|
||||
struct elf_dom_parms *parms,
|
||||
- ELF_PTRVAL_CONST_VOID start,
|
||||
- ELF_PTRVAL_CONST_VOID end,
|
||||
+ elf_ptrval start,
|
||||
+ elf_ptrval end,
|
||||
unsigned *total_note_count)
|
||||
{
|
||||
unsigned xen_elfnotes = 0;
|
||||
@@ -258,7 +258,7 @@ static unsigned elf_xen_parse_notes(struct elf_binary *elf,
|
||||
elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf,
|
||||
struct elf_dom_parms *parms)
|
||||
{
|
||||
- ELF_PTRVAL_CONST_CHAR h;
|
||||
+ elf_ptrval h;
|
||||
unsigned char name[32], value[128];
|
||||
unsigned len;
|
||||
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index 06799af..e2e75af 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -118,7 +118,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
|
||||
}
|
||||
|
||||
static elf_errorstatus elf_load_image(struct elf_binary *elf,
|
||||
- ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src,
|
||||
+ elf_ptrval dst, elf_ptrval src,
|
||||
uint64_t filesz, uint64_t memsz)
|
||||
{
|
||||
elf_memcpy_safe(elf, dst, src, filesz);
|
||||
@@ -132,7 +132,7 @@ void elf_set_verbose(struct elf_binary *elf)
|
||||
elf->verbose = 1;
|
||||
}
|
||||
|
||||
-static elf_errorstatus elf_load_image(struct elf_binary *elf, ELF_PTRVAL_VOID dst, ELF_PTRVAL_CONST_VOID src, uint64_t filesz, uint64_t memsz)
|
||||
+static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, elf_ptrval src, uint64_t filesz, uint64_t memsz)
|
||||
{
|
||||
elf_errorstatus rc;
|
||||
if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
|
||||
@@ -187,12 +187,12 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
|
||||
|
||||
static void elf_load_bsdsyms(struct elf_binary *elf)
|
||||
{
|
||||
- ELF_HANDLE_DECL_NONCONST(elf_ehdr) sym_ehdr;
|
||||
+ ELF_HANDLE_DECL(elf_ehdr) sym_ehdr;
|
||||
unsigned long sz;
|
||||
- ELF_PTRVAL_VOID maxva;
|
||||
- ELF_PTRVAL_VOID symbase;
|
||||
- ELF_PTRVAL_VOID symtab_addr;
|
||||
- ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
|
||||
+ elf_ptrval maxva;
|
||||
+ elf_ptrval symbase;
|
||||
+ elf_ptrval symtab_addr;
|
||||
+ ELF_HANDLE_DECL(elf_shdr) shdr;
|
||||
unsigned i, type;
|
||||
|
||||
if ( !elf->bsd_symtab_pstart )
|
||||
@@ -226,7 +226,7 @@ do { \
|
||||
elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
|
||||
ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
|
||||
sz);
|
||||
- maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
|
||||
+ maxva = elf_round_up(elf, (unsigned long)maxva + sz);
|
||||
|
||||
for ( i = 0; i < elf_shdr_count(elf); i++ )
|
||||
{
|
||||
@@ -242,7 +242,7 @@ do { \
|
||||
elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
|
||||
/* Mangled to be based on ELF header location. */
|
||||
elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
|
||||
- maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
|
||||
+ maxva = elf_round_up(elf, (unsigned long)maxva + sz);
|
||||
}
|
||||
old_shdr_p = ELF_HANDLE_PTRVAL(shdr);
|
||||
new_shdr_p = old_shdr_p + elf_uval(elf, elf->ehdr, e_shentsize);
|
||||
@@ -297,7 +297,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
|
||||
{
|
||||
ELF_HANDLE_DECL(elf_phdr) phdr;
|
||||
uint64_t i, count, paddr, offset, filesz, memsz;
|
||||
- ELF_PTRVAL_VOID dest;
|
||||
+ elf_ptrval dest;
|
||||
/*
|
||||
* Let bizarre ELFs write the output image up to twice; this
|
||||
* calculation is just to ensure our copying loop is no worse than
|
||||
@@ -334,7 +334,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
|
||||
remain_allow_copy -= memsz;
|
||||
|
||||
elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%"ELF_PRPTRVAL" -> 0x%"ELF_PRPTRVAL"\n",
|
||||
- __func__, i, dest, (ELF_PTRVAL_VOID)(dest + filesz));
|
||||
+ __func__, i, dest, (elf_ptrval)(dest + filesz));
|
||||
if ( elf_load_image(elf, dest, ELF_IMAGE_BASE(elf) + offset, filesz, memsz) != 0 )
|
||||
return -1;
|
||||
}
|
||||
@@ -343,7 +343,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr)
|
||||
+elf_ptrval elf_get_ptr(struct elf_binary *elf, unsigned long addr)
|
||||
{
|
||||
return ELF_REALPTR2PTRVAL(elf->dest_base) + addr - elf->pstart;
|
||||
}
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index 4a83133..e202249 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -171,7 +171,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
|
||||
ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index)
|
||||
{
|
||||
uint64_t count = elf_shdr_count(elf);
|
||||
- ELF_PTRVAL_CONST_VOID ptr;
|
||||
+ elf_ptrval ptr;
|
||||
|
||||
if ( index >= count )
|
||||
return ELF_INVALID_HANDLE(elf_shdr);
|
||||
@@ -185,7 +185,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned ind
|
||||
ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index)
|
||||
{
|
||||
uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
|
||||
- ELF_PTRVAL_CONST_VOID ptr;
|
||||
+ elf_ptrval ptr;
|
||||
|
||||
if ( index >= count )
|
||||
return ELF_INVALID_HANDLE(elf_phdr);
|
||||
@@ -233,24 +233,24 @@ const char *elf_strfmt(struct elf_binary *elf, elf_ptrval start)
|
||||
return str;
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
|
||||
+elf_ptrval elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
|
||||
{
|
||||
return ELF_IMAGE_BASE(elf) + elf_uval(elf, shdr, sh_offset);
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
|
||||
+elf_ptrval elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
|
||||
{
|
||||
return ELF_IMAGE_BASE(elf)
|
||||
+ elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size);
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
+elf_ptrval elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
{
|
||||
return ELF_IMAGE_BASE(elf)
|
||||
+ elf_uval(elf, phdr, p_offset);
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
+elf_ptrval elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
{
|
||||
return ELF_IMAGE_BASE(elf)
|
||||
+ elf_uval(elf, phdr, p_offset) + elf_uval(elf, phdr, p_filesz);
|
||||
@@ -258,8 +258,8 @@ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(el
|
||||
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol)
|
||||
{
|
||||
- ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
|
||||
- ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
|
||||
+ elf_ptrval ptr = elf_section_start(elf, elf->sym_tab);
|
||||
+ elf_ptrval end = elf_section_end(elf, elf->sym_tab);
|
||||
ELF_HANDLE_DECL(elf_sym) sym;
|
||||
uint64_t info, name;
|
||||
const char *sym_name;
|
||||
@@ -283,7 +283,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
|
||||
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index)
|
||||
{
|
||||
- ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
|
||||
+ elf_ptrval ptr = elf_section_start(elf, elf->sym_tab);
|
||||
ELF_HANDLE_DECL(elf_sym) sym;
|
||||
|
||||
sym = ELF_MAKE_HANDLE(elf_sym, ptr + index * elf_size(elf, sym));
|
||||
@@ -295,7 +295,7 @@ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
|
||||
return elf_strval(elf, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note));
|
||||
}
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
|
||||
+elf_ptrval elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
|
||||
|
||||
@@ -304,7 +304,7 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
|
||||
|
||||
uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
- ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
|
||||
+ elf_ptrval desc = elf_note_desc(elf, note);
|
||||
unsigned descsz = elf_uval(elf, note, descsz);
|
||||
|
||||
switch (descsz)
|
||||
@@ -322,7 +322,7 @@ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
|
||||
uint64_t elf_note_numeric_array(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note,
|
||||
unsigned int unitsz, unsigned int idx)
|
||||
{
|
||||
- ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
|
||||
+ elf_ptrval desc = elf_note_desc(elf, note);
|
||||
unsigned descsz = elf_uval(elf, note, descsz);
|
||||
|
||||
if ( descsz % unitsz || idx >= descsz / unitsz )
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index f95fe88..174f8da 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -61,13 +61,8 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
|
||||
/*
|
||||
* We abstract away the pointerness of these pointers, replacing
|
||||
* various void*, char* and struct* with the following:
|
||||
- * PTRVAL A pointer to a byte; one can do pointer arithmetic
|
||||
+ * elf_ptrval A pointer to a byte; one can do pointer arithmetic
|
||||
* on this.
|
||||
- * This replaces variables which were char*,void*
|
||||
- * and their const versions, so we provide four
|
||||
- * different obsolete declaration macros:
|
||||
- * ELF_PTRVAL_{,CONST}{VOID,CHAR}
|
||||
- * New code can simply use the elf_ptrval typedef.
|
||||
* HANDLE A pointer to a struct. There is one of these types
|
||||
* for each pointer type - that is, for each "structname".
|
||||
* In the arguments to the various HANDLE macros, structname
|
||||
@@ -76,8 +71,6 @@ typedef void elf_log_callback(struct elf_binary*, void *caller_data,
|
||||
* pointers. In the current code attempts to do so will
|
||||
* compile, but in the next patch this will become a
|
||||
* compile error.
|
||||
- * We also provide a second declaration macro for
|
||||
- * pointers which were to const; this is obsolete.
|
||||
*/
|
||||
|
||||
typedef uintptr_t elf_ptrval;
|
||||
@@ -85,15 +78,9 @@ typedef uintptr_t elf_ptrval;
|
||||
#define ELF_REALPTR2PTRVAL(realpointer) ((elf_ptrval)(realpointer))
|
||||
/* Converts an actual C pointer into a PTRVAL */
|
||||
|
||||
-#define ELF_HANDLE_DECL_NONCONST(structname) structname##_handle /*obsolete*/
|
||||
#define ELF_HANDLE_DECL(structname) structname##_handle
|
||||
/* Provides a type declaration for a HANDLE. */
|
||||
|
||||
-#define ELF_PTRVAL_VOID elf_ptrval /*obsolete*/
|
||||
-#define ELF_PTRVAL_CHAR elf_ptrval /*obsolete*/
|
||||
-#define ELF_PTRVAL_CONST_VOID elf_ptrval /*obsolete*/
|
||||
-#define ELF_PTRVAL_CONST_CHAR elf_ptrval /*obsolete*/
|
||||
-
|
||||
#ifdef __XEN__
|
||||
# define ELF_PRPTRVAL "lu"
|
||||
/*
|
||||
@@ -124,17 +111,6 @@ typedef uintptr_t elf_ptrval;
|
||||
#define ELF_HANDLE_PTRVAL(handleval) ((handleval).ptrval)
|
||||
/* Converts a HANDLE to a PTRVAL. */
|
||||
|
||||
-#define ELF_OBSOLETE_VOIDP_CAST /*empty*/
|
||||
- /*
|
||||
- * In some places the old code used to need to
|
||||
- * - cast away const (the existing code uses const a fair
|
||||
- * bit but actually sometimes wants to write to its input)
|
||||
- * from a PTRVAL.
|
||||
- * - convert an integer representing a pointer to a PTRVAL
|
||||
- * Nowadays all of these re uintptr_ts so there is no const problem
|
||||
- * and no need for any casting.
|
||||
- */
|
||||
-
|
||||
#define ELF_UNSAFE_PTR(ptrval) ((void*)(elf_ptrval)(ptrval))
|
||||
/*
|
||||
* Turns a PTRVAL into an actual C pointer. Before this is done
|
||||
@@ -212,7 +188,7 @@ struct elf_binary {
|
||||
char data;
|
||||
|
||||
ELF_HANDLE_DECL(elf_ehdr) ehdr;
|
||||
- ELF_PTRVAL_CONST_CHAR sec_strtab;
|
||||
+ elf_ptrval sec_strtab;
|
||||
ELF_HANDLE_DECL(elf_shdr) sym_tab;
|
||||
uint64_t sym_strtab;
|
||||
|
||||
@@ -290,7 +266,7 @@ struct elf_binary {
|
||||
* str should be a HANDLE.
|
||||
*/
|
||||
|
||||
-uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
|
||||
+uint64_t elf_access_unsigned(struct elf_binary *elf, elf_ptrval ptr,
|
||||
uint64_t offset, size_t size);
|
||||
/* Reads a field at arbitrary offset and alignemnt */
|
||||
|
||||
@@ -342,17 +318,17 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned ind
|
||||
ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index);
|
||||
|
||||
const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
|
||||
-ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
-ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
+elf_ptrval elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
+elf_ptrval elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
|
||||
-ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
-ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
+elf_ptrval elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
+elf_ptrval elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index);
|
||||
|
||||
const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
|
||||
-ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
+elf_ptrval elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
unsigned int unitsz, unsigned int idx);
|
||||
@@ -391,7 +367,7 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback*,
|
||||
void elf_parse_binary(struct elf_binary *elf);
|
||||
elf_errorstatus elf_load_binary(struct elf_binary *elf);
|
||||
|
||||
-ELF_PTRVAL_VOID elf_get_ptr(struct elf_binary *elf, unsigned long addr);
|
||||
+elf_ptrval elf_get_ptr(struct elf_binary *elf, unsigned long addr);
|
||||
uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
|
||||
|
||||
void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
|
||||
@@ -426,9 +402,9 @@ struct xen_elfnote {
|
||||
|
||||
struct elf_dom_parms {
|
||||
/* raw */
|
||||
- ELF_PTRVAL_CONST_CHAR guest_info;
|
||||
- ELF_PTRVAL_CONST_VOID elf_note_start;
|
||||
- ELF_PTRVAL_CONST_VOID elf_note_end;
|
||||
+ elf_ptrval guest_info;
|
||||
+ elf_ptrval elf_note_start;
|
||||
+ elf_ptrval elf_note_end;
|
||||
struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1];
|
||||
|
||||
/* parsed */
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,450 +0,0 @@
|
||||
From b06e277b1fc08c7da3befeb3ac3950e1d941585d Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
Subject: [PATCH 18/23] libxc: Add range checking to xc_dom_binloader
|
||||
|
||||
This is a simple binary image loader with its own metadata format.
|
||||
However, it is too careless with image-supplied values.
|
||||
|
||||
Add the following checks:
|
||||
|
||||
* That the image is bigger than the metadata table; otherwise the
|
||||
pointer arithmetic to calculate the metadata table location may
|
||||
yield undefined and dangerous values.
|
||||
|
||||
* When clamping the end of the region to search, that we do not
|
||||
calculate pointers beyond the end of the image. The C
|
||||
specification does not permit this and compilers are becoming ever
|
||||
more determined to miscompile code when they can "prove" various
|
||||
falsehoods based on assertions from the C spec.
|
||||
|
||||
* That the supplied image is big enough for the text we are allegedly
|
||||
copying from it. Otherwise we might have a read overrun and copy
|
||||
the results (perhaps a lot of secret data) into the guest.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_dom_binloader.c | 15 +++++++++++++--
|
||||
1 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
|
||||
index bde93f7..8596a28 100644
|
||||
--- a/tools/libxc/xc_dom_binloader.c
|
||||
+++ b/tools/libxc/xc_dom_binloader.c
|
||||
@@ -123,10 +123,13 @@ static struct xen_bin_image_table *find_table(struct xc_dom_image *dom)
|
||||
uint32_t *probe_ptr;
|
||||
uint32_t *probe_end;
|
||||
|
||||
+ if ( dom->kernel_size < sizeof(*table) )
|
||||
+ return NULL;
|
||||
probe_ptr = dom->kernel_blob;
|
||||
- probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table);
|
||||
- if ( (void*)probe_end > (dom->kernel_blob + 8192) )
|
||||
+ if ( dom->kernel_size > (8192 + sizeof(*table)) )
|
||||
probe_end = dom->kernel_blob + 8192;
|
||||
+ else
|
||||
+ probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table);
|
||||
|
||||
for ( table = NULL; probe_ptr < probe_end; probe_ptr++ )
|
||||
{
|
||||
@@ -282,6 +285,14 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if ( image_size < skip ||
|
||||
+ image_size - skip < text_size )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: image is too small for declared text size",
|
||||
+ __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
memcpy(dest, image + skip, text_size);
|
||||
memset(dest + text_size, 0, bss_size);
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
#From 77c0829fa751f052f7b8ec08287aef6e7ba97bc5 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
#Subject: [PATCH 19/23] libxc: check failure of xc_dom_*_to_ptr, xc_map_foreign_range
|
||||
#
|
||||
#The return values from xc_dom_*_to_ptr and xc_map_foreign_range are
|
||||
#sometimes dereferenced, or subjected to pointer arithmetic, without
|
||||
#checking whether the relevant function failed and returned NULL.
|
||||
#
|
||||
#Add an appropriate error check at every call site.
|
||||
#
|
||||
#Changes in the 4.2 backport of this series:
|
||||
#* Fix tools/libxc/xc_dom_x86.c:setup_pgtables_x86_32.
|
||||
#* Fix tools/libxc/xc_dom_ia64.c:start_info_ia64.
|
||||
#* Fix tools/libxc/ia64/xc_ia64_dom_fwloader.c:xc_dom_load_fw_kernel.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#---
|
||||
# tools/libxc/ia64/xc_ia64_dom_fwloader.c | 2 +
|
||||
# tools/libxc/xc_dom_binloader.c | 6 +++
|
||||
# tools/libxc/xc_dom_core.c | 6 +++
|
||||
# tools/libxc/xc_dom_elfloader.c | 13 +++++++
|
||||
# tools/libxc/xc_dom_ia64.c | 6 +++
|
||||
# tools/libxc/xc_dom_x86.c | 55 +++++++++++++++++++++++++++++++
|
||||
# tools/libxc/xc_domain_restore.c | 27 +++++++++++++++
|
||||
# tools/libxc/xc_offline_page.c | 5 +++
|
||||
# 8 files changed, 120 insertions(+), 0 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/ia64/xc_ia64_dom_fwloader.c b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
index cdf3333..dbd3349 100644
|
||||
--- a/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
+++ b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
@@ -60,6 +60,8 @@ static int xc_dom_load_fw_kernel(struct xc_dom_image *dom)
|
||||
unsigned long i;
|
||||
|
||||
dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
|
||||
+ if ( dest == NULL )
|
||||
+ return -1;
|
||||
memcpy(dest, dom->kernel_blob, FW_SIZE);
|
||||
|
||||
/* Synchronize cache. */
|
||||
diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
|
||||
index 8596a28..553b366 100644
|
||||
--- a/tools/libxc/xc_dom_binloader.c
|
||||
+++ b/tools/libxc/xc_dom_binloader.c
|
||||
@@ -277,6 +277,12 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
|
||||
DOMPRINTF(" bss_size: 0x%" PRIx32 "", bss_size);
|
||||
|
||||
dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
|
||||
+ if ( dest == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart)"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
if ( dest_size < text_size ||
|
||||
dest_size - text_size < bss_size )
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index 8913e41..a54ddae 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -868,6 +868,12 @@ int xc_dom_build_image(struct xc_dom_image *dom)
|
||||
ramdisklen) != 0 )
|
||||
goto err;
|
||||
ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg);
|
||||
+ if ( ramdiskmap == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg) => NULL",
|
||||
+ __FUNCTION__);
|
||||
+ goto err;
|
||||
+ }
|
||||
if ( unziplen )
|
||||
{
|
||||
if ( xc_dom_do_gunzip(dom->xch,
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 9fc4b94..61b5798 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -139,6 +139,12 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
return 0;
|
||||
size = dom->kernel_seg.vend - dom->bsd_symtab_start;
|
||||
hdr_ptr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
|
||||
+ if ( hdr_ptr == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s/load: xc_dom_vaddr_to_ptr(dom,dom->bsd_symtab_start"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
elf->caller_xdest_base = hdr_ptr;
|
||||
elf->caller_xdest_size = allow_size;
|
||||
hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
|
||||
@@ -384,7 +390,14 @@ static elf_errorstatus xc_dom_load_elf_kernel(struct xc_dom_image *dom)
|
||||
xen_pfn_t pages;
|
||||
|
||||
elf->dest_base = xc_dom_seg_to_ptr_pages(dom, &dom->kernel_seg, &pages);
|
||||
+ if ( elf->dest_base == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom,dom->kernel_seg)"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
elf->dest_size = pages * XC_DOM_PAGE_SIZE(dom);
|
||||
+
|
||||
rc = elf_load_binary(elf);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
|
||||
index dcd1523..7c0eff1 100644
|
||||
--- a/tools/libxc/xc_dom_ia64.c
|
||||
+++ b/tools/libxc/xc_dom_ia64.c
|
||||
@@ -60,6 +60,12 @@ int start_info_ia64(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
sprintf(start_info->magic, dom->guest_type);
|
||||
start_info->flags = dom->flags;
|
||||
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
|
||||
index 0cf1687..75d6b83 100644
|
||||
--- a/tools/libxc/xc_dom_x86.c
|
||||
+++ b/tools/libxc/xc_dom_x86.c
|
||||
@@ -144,6 +144,9 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
xen_vaddr_t addr;
|
||||
xen_pfn_t pgpfn;
|
||||
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
+
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
{
|
||||
@@ -151,6 +154,8 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_i386(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -169,6 +174,11 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
l1tab = NULL;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -219,6 +229,12 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
|
||||
goto out;
|
||||
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr(dom, l3pfn, 1) => NULL",
|
||||
+ __FUNCTION__);
|
||||
+ return l3mfn; /* our one call site will call xc_dom_panic and fail */
|
||||
+ }
|
||||
memset(l3tab, 0, XC_DOM_PAGE_SIZE(dom));
|
||||
|
||||
DOMPRINTF("%s: successfully relocated L3 below 4G. "
|
||||
@@ -262,6 +278,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
}
|
||||
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ goto pfn_error;
|
||||
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
@@ -270,6 +288,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L2 tab, make L3 entry */
|
||||
l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l3off = l3_table_offset_pae(addr);
|
||||
l3tab[l3off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
@@ -280,6 +300,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_pae(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -306,6 +328,11 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
#undef L1_PROT
|
||||
@@ -344,6 +371,9 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
uint64_t addr;
|
||||
xen_pfn_t pgpfn;
|
||||
|
||||
+ if ( l4tab == NULL )
|
||||
+ goto pfn_error;
|
||||
+
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
{
|
||||
@@ -351,6 +381,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L3 tab, make L4 entry */
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l4off = l4_table_offset_x86_64(addr);
|
||||
l4tab[l4off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT;
|
||||
@@ -361,6 +393,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L2 tab, make L3 entry */
|
||||
l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l3off = l3_table_offset_x86_64(addr);
|
||||
l3tab[l3off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
@@ -373,6 +407,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_x86_64(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -393,6 +429,11 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
l1tab = NULL;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
#undef L1_PROT
|
||||
@@ -410,6 +451,8 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size) )
|
||||
return -1;
|
||||
dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
|
||||
+ if ( dom->p2m_guest == NULL )
|
||||
+ return -1;
|
||||
|
||||
/* allocate special pages */
|
||||
dom->start_info_pfn = xc_dom_alloc_page(dom, "start info");
|
||||
@@ -434,6 +477,12 @@ static int start_info_x86_32(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
|
||||
start_info->magic[sizeof(start_info->magic) - 1] = '\0';
|
||||
@@ -474,6 +523,12 @@ static int start_info_x86_64(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
|
||||
start_info->magic[sizeof(start_info->magic) - 1] = '\0';
|
||||
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
|
||||
index b4c0b10..3994f8f 100644
|
||||
--- a/tools/libxc/xc_domain_restore.c
|
||||
+++ b/tools/libxc/xc_domain_restore.c
|
||||
@@ -1556,6 +1556,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
mfn = ctx->p2m[pfn];
|
||||
buf = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, mfn);
|
||||
+ if ( buf == NULL )
|
||||
+ {
|
||||
+ ERROR("xc_map_foreign_range for generation id"
|
||||
+ " buffer failed");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
generationid = *(unsigned long long *)(buf + offset);
|
||||
*(unsigned long long *)(buf + offset) = generationid + 1;
|
||||
@@ -1713,6 +1719,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
l3tab = (uint64_t *)
|
||||
xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ, ctx->p2m[i]);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for l3tab)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
for ( j = 0; j < 4; j++ )
|
||||
l3ptes[j] = l3tab[j];
|
||||
@@ -1739,6 +1750,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
l3tab = (uint64_t *)
|
||||
xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, ctx->p2m[i]);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for l3tab, 2nd)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
for ( j = 0; j < 4; j++ )
|
||||
l3tab[j] = l3ptes[j];
|
||||
@@ -1909,6 +1925,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
SET_FIELD(ctxt, user_regs.edx, mfn);
|
||||
start_info = xc_map_foreign_range(
|
||||
xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for start_info)");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
|
||||
SET_FIELD(start_info, shared_info, shared_info_frame<<PAGE_SHIFT);
|
||||
SET_FIELD(start_info, flags, 0);
|
||||
@@ -2056,6 +2078,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
/* Restore contents of shared-info page. No checking needed. */
|
||||
new_shared_info = xc_map_foreign_range(
|
||||
xch, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
|
||||
+ if ( new_shared_info == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for new_shared_info)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* restore saved vcpu_info and arch specific info */
|
||||
MEMCPY_FIELD(new_shared_info, old_shared_info, vcpu_info);
|
||||
diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
|
||||
index 089a361..36b9812 100644
|
||||
--- a/tools/libxc/xc_offline_page.c
|
||||
+++ b/tools/libxc/xc_offline_page.c
|
||||
@@ -714,6 +714,11 @@ int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
|
||||
|
||||
new_p = xc_map_foreign_range(xch, domid, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE, new_mfn);
|
||||
+ if ( new_p == NULL )
|
||||
+ {
|
||||
+ ERROR("failed to map new_p for copy, guest may be broken?");
|
||||
+ goto failed;
|
||||
+ }
|
||||
memcpy(new_p, backup, PAGE_SIZE);
|
||||
munmap(new_p, PAGE_SIZE);
|
||||
mops.arg1.mfn = new_mfn;
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,56 +0,0 @@
|
||||
From a672da4b2d58ef12be9d7407160e9fb43cac75d9 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
Subject: [PATCH 02/23] libxc: introduce xc_dom_seg_to_ptr_pages
|
||||
|
||||
Provide a version of xc_dom_seg_to_ptr which returns the number of
|
||||
guest pages it has actually mapped. This is useful for callers who
|
||||
want to do range checking; we will use this later in this series.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
---
|
||||
tools/libxc/xc_dom.h | 19 ++++++++++++++++---
|
||||
1 files changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
|
||||
index 6a72aa9..9af2195 100644
|
||||
--- a/tools/libxc/xc_dom.h
|
||||
+++ b/tools/libxc/xc_dom.h
|
||||
@@ -278,14 +278,27 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first,
|
||||
void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn);
|
||||
void xc_dom_unmap_all(struct xc_dom_image *dom);
|
||||
|
||||
-static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
|
||||
- struct xc_dom_seg *seg)
|
||||
+static inline void *xc_dom_seg_to_ptr_pages(struct xc_dom_image *dom,
|
||||
+ struct xc_dom_seg *seg,
|
||||
+ xen_pfn_t *pages_out)
|
||||
{
|
||||
xen_vaddr_t segsize = seg->vend - seg->vstart;
|
||||
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
xen_pfn_t pages = (segsize + page_size - 1) / page_size;
|
||||
+ void *retval;
|
||||
+
|
||||
+ retval = xc_dom_pfn_to_ptr(dom, seg->pfn, pages);
|
||||
+
|
||||
+ *pages_out = retval ? pages : 0;
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
|
||||
+ struct xc_dom_seg *seg)
|
||||
+{
|
||||
+ xen_pfn_t dummy;
|
||||
|
||||
- return xc_dom_pfn_to_ptr(dom, seg->pfn, pages);
|
||||
+ return xc_dom_seg_to_ptr_pages(dom, seg, &dummy);
|
||||
}
|
||||
|
||||
static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,381 +0,0 @@
|
||||
From 8dc90d163650ce8aa36ae0b46debab83cc61edb6 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
Subject: [PATCH 20/23] libxc: check return values from malloc
|
||||
|
||||
A sufficiently malformed input to libxc (such as a malformed input ELF
|
||||
or other guest-controlled data) might cause one of libxc's malloc() to
|
||||
fail. In this case we need to make sure we don't dereference or do
|
||||
pointer arithmetic on the result.
|
||||
|
||||
Search for all occurrences of \b(m|c|re)alloc in libxc, and all
|
||||
functions which call them, and add appropriate error checking where
|
||||
missing.
|
||||
|
||||
This includes the functions xc_dom_malloc*, which now print a message
|
||||
when they fail so that callers don't have to do so.
|
||||
|
||||
The function xc_cpuid_to_str wasn't provided with a sane return value
|
||||
and has a pretty strange API, which now becomes a little stranger.
|
||||
There are no in-tree callers.
|
||||
|
||||
Changes in the Xen 4.2 version of this series:
|
||||
* No need to fix code relating to ARM.
|
||||
* No need to fix code relating to superpage support.
|
||||
* Additionally fix `dom->p2m_host = xc_dom_malloc...' in xc_dom_ia64.c.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_cpuid_x86.c | 20 ++++++++++++++++++--
|
||||
tools/libxc/xc_dom_core.c | 13 +++++++++++++
|
||||
tools/libxc/xc_dom_elfloader.c | 2 ++
|
||||
tools/libxc/xc_dom_ia64.c | 6 ++++++
|
||||
tools/libxc/xc_dom_x86.c | 3 +++
|
||||
tools/libxc/xc_domain_restore.c | 5 +++++
|
||||
tools/libxc/xc_linux_osdep.c | 4 ++++
|
||||
tools/libxc/xc_private.c | 2 ++
|
||||
tools/libxc/xenctrl.h | 2 +-
|
||||
9 files changed, 54 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
|
||||
index 0882ce6..da435ce 100644
|
||||
--- a/tools/libxc/xc_cpuid_x86.c
|
||||
+++ b/tools/libxc/xc_cpuid_x86.c
|
||||
@@ -589,6 +589,8 @@ static int xc_cpuid_do_domctl(
|
||||
static char *alloc_str(void)
|
||||
{
|
||||
char *s = malloc(33);
|
||||
+ if ( s == NULL )
|
||||
+ return s;
|
||||
memset(s, 0, 33);
|
||||
return s;
|
||||
}
|
||||
@@ -600,6 +602,8 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs)
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
strs[i] = alloc_str();
|
||||
+ if ( strs[i] == NULL )
|
||||
+ continue;
|
||||
for ( j = 0; j < 32; j++ )
|
||||
strs[i][j] = !!((regs[i] & (1U << (31 - j)))) ? '1' : '0';
|
||||
}
|
||||
@@ -680,7 +684,7 @@ int xc_cpuid_check(
|
||||
const char **config,
|
||||
char **config_transformed)
|
||||
{
|
||||
- int i, j;
|
||||
+ int i, j, rc;
|
||||
unsigned int regs[4];
|
||||
|
||||
memset(config_transformed, 0, 4 * sizeof(*config_transformed));
|
||||
@@ -692,6 +696,11 @@ int xc_cpuid_check(
|
||||
if ( config[i] == NULL )
|
||||
continue;
|
||||
config_transformed[i] = alloc_str();
|
||||
+ if ( config_transformed[i] == NULL )
|
||||
+ {
|
||||
+ rc = -ENOMEM;
|
||||
+ goto fail_rc;
|
||||
+ }
|
||||
for ( j = 0; j < 32; j++ )
|
||||
{
|
||||
unsigned char val = !!((regs[i] & (1U << (31 - j))));
|
||||
@@ -708,12 +717,14 @@ int xc_cpuid_check(
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
+ rc = -EPERM;
|
||||
+ fail_rc:
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
free(config_transformed[i]);
|
||||
config_transformed[i] = NULL;
|
||||
}
|
||||
- return -EPERM;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -758,6 +769,11 @@ int xc_cpuid_set(
|
||||
}
|
||||
|
||||
config_transformed[i] = alloc_str();
|
||||
+ if ( config_transformed[i] == NULL )
|
||||
+ {
|
||||
+ rc = -ENOMEM;
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
for ( j = 0; j < 32; j++ )
|
||||
{
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index a54ddae..3cbf9f7 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -120,9 +120,17 @@ void *xc_dom_malloc(struct xc_dom_image *dom, size_t size)
|
||||
{
|
||||
struct xc_dom_mem *block;
|
||||
|
||||
+ if ( size > SIZE_MAX - sizeof(*block) )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: unreasonable allocation size", __FUNCTION__);
|
||||
+ return NULL;
|
||||
+ }
|
||||
block = malloc(sizeof(*block) + size);
|
||||
if ( block == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: allocation failed", __FUNCTION__);
|
||||
return NULL;
|
||||
+ }
|
||||
memset(block, 0, sizeof(*block) + size);
|
||||
block->next = dom->memblocks;
|
||||
dom->memblocks = block;
|
||||
@@ -138,7 +146,10 @@ void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
|
||||
|
||||
block = malloc(sizeof(*block));
|
||||
if ( block == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: allocation failed", __FUNCTION__);
|
||||
return NULL;
|
||||
+ }
|
||||
memset(block, 0, sizeof(*block));
|
||||
block->mmap_len = size;
|
||||
block->mmap_ptr = mmap(NULL, block->mmap_len,
|
||||
@@ -146,6 +157,7 @@ void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size)
|
||||
-1, 0);
|
||||
if ( block->mmap_ptr == MAP_FAILED )
|
||||
{
|
||||
+ DOMPRINTF("%s: mmap failed", __FUNCTION__);
|
||||
free(block);
|
||||
return NULL;
|
||||
}
|
||||
@@ -202,6 +214,7 @@ void *xc_dom_malloc_filemap(struct xc_dom_image *dom,
|
||||
close(fd);
|
||||
if ( block != NULL )
|
||||
free(block);
|
||||
+ DOMPRINTF("%s: failed (on file `%s')", __FUNCTION__, filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 61b5798..be58276 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -329,6 +329,8 @@ static elf_errorstatus xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
|
||||
return rc;
|
||||
|
||||
elf = xc_dom_malloc(dom, sizeof(*elf));
|
||||
+ if ( elf == NULL )
|
||||
+ return -1;
|
||||
dom->private_loader = elf;
|
||||
rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
|
||||
xc_elf_set_logfile(dom->xch, elf, 1);
|
||||
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
|
||||
index 7c0eff1..076821c 100644
|
||||
--- a/tools/libxc/xc_dom_ia64.c
|
||||
+++ b/tools/libxc/xc_dom_ia64.c
|
||||
@@ -188,6 +188,12 @@ int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
|
||||
/* setup initial p2m */
|
||||
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr);
|
||||
+ if ( dom->p2m_host == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_malloc failed for p2m_host",
|
||||
+ __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
for ( pfn = 0; pfn < nbr; pfn++ )
|
||||
dom->p2m_host[pfn] = start + pfn;
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
|
||||
index 75d6b83..448d9a1 100644
|
||||
--- a/tools/libxc/xc_dom_x86.c
|
||||
+++ b/tools/libxc/xc_dom_x86.c
|
||||
@@ -780,6 +780,9 @@ int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
}
|
||||
|
||||
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
|
||||
+ if ( dom->p2m_host == NULL )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if ( dom->superpages )
|
||||
{
|
||||
int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
|
||||
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
|
||||
index 3994f8f..f9ed6b2 100644
|
||||
--- a/tools/libxc/xc_domain_restore.c
|
||||
+++ b/tools/libxc/xc_domain_restore.c
|
||||
@@ -1180,6 +1180,11 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx,
|
||||
|
||||
/* Map relevant mfns */
|
||||
pfn_err = calloc(j, sizeof(*pfn_err));
|
||||
+ if ( pfn_err == NULL )
|
||||
+ {
|
||||
+ PERROR("allocation for pfn_err failed");
|
||||
+ return -1;
|
||||
+ }
|
||||
region_base = xc_map_foreign_bulk(
|
||||
xch, dom, PROT_WRITE, region_mfn, pfn_err, j);
|
||||
|
||||
diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c
|
||||
index 787e742..98e041c 100644
|
||||
--- a/tools/libxc/xc_linux_osdep.c
|
||||
+++ b/tools/libxc/xc_linux_osdep.c
|
||||
@@ -378,6 +378,8 @@ static void *linux_privcmd_map_foreign_range(xc_interface *xch, xc_osdep_handle
|
||||
|
||||
num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
|
||||
arr = calloc(num, sizeof(xen_pfn_t));
|
||||
+ if ( arr == NULL )
|
||||
+ return NULL;
|
||||
|
||||
for ( i = 0; i < num; i++ )
|
||||
arr[i] = mfn + i;
|
||||
@@ -402,6 +404,8 @@ static void *linux_privcmd_map_foreign_ranges(xc_interface *xch, xc_osdep_handle
|
||||
num_per_entry = chunksize >> XC_PAGE_SHIFT;
|
||||
num = num_per_entry * nentries;
|
||||
arr = calloc(num, sizeof(xen_pfn_t));
|
||||
+ if ( arr == NULL )
|
||||
+ return NULL;
|
||||
|
||||
for ( i = 0; i < nentries; i++ )
|
||||
for ( j = 0; j < num_per_entry; j++ )
|
||||
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
|
||||
index 3e03a91..848ceed 100644
|
||||
--- a/tools/libxc/xc_private.c
|
||||
+++ b/tools/libxc/xc_private.c
|
||||
@@ -771,6 +771,8 @@ const char *xc_strerror(xc_interface *xch, int errcode)
|
||||
errbuf = pthread_getspecific(errbuf_pkey);
|
||||
if (errbuf == NULL) {
|
||||
errbuf = malloc(XS_BUFSIZE);
|
||||
+ if ( errbuf == NULL )
|
||||
+ return "(failed to allocate errbuf)";
|
||||
pthread_setspecific(errbuf_pkey, errbuf);
|
||||
}
|
||||
|
||||
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
|
||||
index b7741ca..8952048 100644
|
||||
--- a/tools/libxc/xenctrl.h
|
||||
+++ b/tools/libxc/xenctrl.h
|
||||
@@ -1778,7 +1778,7 @@ int xc_cpuid_set(xc_interface *xch,
|
||||
int xc_cpuid_apply_policy(xc_interface *xch,
|
||||
domid_t domid);
|
||||
void xc_cpuid_to_str(const unsigned int *regs,
|
||||
- char **strs);
|
||||
+ char **strs); /* some strs[] may be NULL if ENOMEM */
|
||||
int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
|
||||
#endif
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
#From 052a689aa526ca51fd70528d4b0f83dfb2de99c1 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
#Subject: [PATCH 21/23] libxc: range checks in xc_dom_p2m_host and _guest
|
||||
#
|
||||
#These functions take guest pfns and look them up in the p2m. They did
|
||||
#no range checking.
|
||||
#
|
||||
#However, some callers, notably xc_dom_boot.c:setup_hypercall_page want
|
||||
#to pass untrusted guest-supplied value(s). It is most convenient to
|
||||
#detect this here and return INVALID_MFN.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Changes from Xen 4.2 version of this patch:
|
||||
#* 4.2 lacks dom->rambase_pfn, so don't add/subtract/check it.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#---
|
||||
# tools/libxc/xc_dom.h | 4 ++++
|
||||
# 1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
|
||||
index 0161459..d801f66 100644
|
||||
--- a/tools/libxc/xc_dom.h
|
||||
+++ b/tools/libxc/xc_dom.h
|
||||
@@ -331,6 +331,8 @@ static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn)
|
||||
{
|
||||
if (dom->shadow_enabled)
|
||||
return pfn;
|
||||
+ if (pfn >= dom->total_pages)
|
||||
+ return INVALID_MFN;
|
||||
return dom->p2m_host[pfn];
|
||||
}
|
||||
|
||||
@@ -339,6 +341,8 @@ static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom,
|
||||
{
|
||||
if (xc_dom_feature_translated(dom))
|
||||
return pfn;
|
||||
+ if (pfn >= dom->total_pages)
|
||||
+ return INVALID_MFN;
|
||||
return dom->p2m_host[pfn];
|
||||
}
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
#From 2a548e22915535ac13694eb38222903bca7245e3 Mon Sep 17 00:00:00 2001
|
||||
#From: Matthew Daley <mattjd@gmail.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
#Subject: [PATCH 22/23] libxc: check blob size before proceeding in xc_dom_check_gzip
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Matthew Daley <mattjd@gmail.com>
|
||||
#---
|
||||
# tools/libxc/xc_dom_core.c | 5 +++++
|
||||
# 1 files changed, 5 insertions(+), 0 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index 3cbf9f7..f8d1b08 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -284,6 +284,11 @@ size_t xc_dom_check_gzip(xc_interface *xch, void *blob, size_t ziplen)
|
||||
unsigned char *gzlen;
|
||||
size_t unziplen;
|
||||
|
||||
+ if ( ziplen < 6 )
|
||||
+ /* Too small. We need (i.e. the subsequent code relies on)
|
||||
+ * 2 bytes for the magic number plus 4 bytes length. */
|
||||
+ return 0;
|
||||
+
|
||||
if ( strncmp(blob, "\037\213", 2) )
|
||||
/* not gzipped */
|
||||
return 0;
|
||||
--
|
||||
1.7.2.5
|
||||
#From d21d36e84354c04638b60a739a5f7c3d9f8adaf8 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
#Subject: [PATCH 23/23] libxc: Better range check in xc_dom_alloc_segment
|
||||
#
|
||||
#If seg->pfn is too large, the arithmetic in the range check might
|
||||
#overflow, defeating the range check.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
#---
|
||||
# tools/libxc/xc_dom_core.c | 3 ++-
|
||||
# 1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index f8d1b08..e79e38d 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -509,7 +509,8 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
|
||||
seg->vstart = start;
|
||||
seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
|
||||
|
||||
- if ( pages > dom->total_pages || /* double test avoids overflow probs */
|
||||
+ if ( pages > dom->total_pages || /* multiple test avoids overflow probs */
|
||||
+ seg->pfn > dom->total_pages ||
|
||||
pages > dom->total_pages - seg->pfn)
|
||||
{
|
||||
xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
|
||||
--
|
||||
1.7.2.5
|
||||
|
||||
|
@ -1,156 +0,0 @@
|
||||
From 8c738fa5c1f3cfcd935b6191b3526f7ac8b2a5bd Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
Subject: [PATCH 03/23] libxc: Fix range checking in xc_dom_pfn_to_ptr etc.
|
||||
|
||||
* Ensure that xc_dom_pfn_to_ptr (when called with count==0) does not
|
||||
return a previously-allocated block which is entirely before the
|
||||
requested pfn (!)
|
||||
|
||||
* Provide a version of xc_dom_pfn_to_ptr, xc_dom_pfn_to_ptr_retcount,
|
||||
which provides the length of the mapped region via an out parameter.
|
||||
|
||||
* Change xc_dom_vaddr_to_ptr to always provide the length of the
|
||||
mapped region and change the call site in xc_dom_binloader.c to
|
||||
check it. The call site in xc_dom_load_elf_symtab will be corrected
|
||||
in a forthcoming patch, and for now ignores the returned length.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_dom.h | 16 +++++++++++++---
|
||||
tools/libxc/xc_dom_binloader.c | 11 ++++++++++-
|
||||
tools/libxc/xc_dom_core.c | 13 +++++++++++++
|
||||
tools/libxc/xc_dom_elfloader.c | 3 ++-
|
||||
4 files changed, 38 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
|
||||
index 9af2195..9f8037e 100644
|
||||
--- a/tools/libxc/xc_dom.h
|
||||
+++ b/tools/libxc/xc_dom.h
|
||||
@@ -275,6 +275,8 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
|
||||
|
||||
void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first,
|
||||
xen_pfn_t count);
|
||||
+void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image *dom, xen_pfn_t first,
|
||||
+ xen_pfn_t count, xen_pfn_t *count_out);
|
||||
void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn);
|
||||
void xc_dom_unmap_all(struct xc_dom_image *dom);
|
||||
|
||||
@@ -302,13 +304,21 @@ static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom,
|
||||
}
|
||||
|
||||
static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom,
|
||||
- xen_vaddr_t vaddr)
|
||||
+ xen_vaddr_t vaddr,
|
||||
+ size_t *safe_region_out)
|
||||
{
|
||||
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
xen_pfn_t page = (vaddr - dom->parms.virt_base) / page_size;
|
||||
unsigned int offset = (vaddr - dom->parms.virt_base) % page_size;
|
||||
- void *ptr = xc_dom_pfn_to_ptr(dom, page, 0);
|
||||
- return (ptr ? (ptr + offset) : NULL);
|
||||
+ xen_pfn_t safe_region_count;
|
||||
+ void *ptr;
|
||||
+
|
||||
+ *safe_region_out = 0;
|
||||
+ ptr = xc_dom_pfn_to_ptr_retcount(dom, page, 0, &safe_region_count);
|
||||
+ if ( ptr == NULL )
|
||||
+ return ptr;
|
||||
+ *safe_region_out = (safe_region_count << XC_DOM_PAGE_SHIFT(dom)) - offset;
|
||||
+ return ptr;
|
||||
}
|
||||
|
||||
static inline int xc_dom_feature_translated(struct xc_dom_image *dom)
|
||||
diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
|
||||
index 769e97d..bde93f7 100644
|
||||
--- a/tools/libxc/xc_dom_binloader.c
|
||||
+++ b/tools/libxc/xc_dom_binloader.c
|
||||
@@ -249,6 +249,7 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
|
||||
char *image = dom->kernel_blob;
|
||||
char *dest;
|
||||
size_t image_size = dom->kernel_size;
|
||||
+ size_t dest_size;
|
||||
uint32_t start_addr;
|
||||
uint32_t load_end_addr;
|
||||
uint32_t bss_end_addr;
|
||||
@@ -272,7 +273,15 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
|
||||
DOMPRINTF(" text_size: 0x%" PRIx32 "", text_size);
|
||||
DOMPRINTF(" bss_size: 0x%" PRIx32 "", bss_size);
|
||||
|
||||
- dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
|
||||
+ dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
|
||||
+
|
||||
+ if ( dest_size < text_size ||
|
||||
+ dest_size - text_size < bss_size )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: mapped region is too small for image", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
memcpy(dest, image + skip, text_size);
|
||||
memset(dest + text_size, 0, bss_size);
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index 2a01d7c..8913e41 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -351,10 +351,19 @@ int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size)
|
||||
void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
|
||||
xen_pfn_t count)
|
||||
{
|
||||
+ xen_pfn_t count_out_dummy;
|
||||
+ return xc_dom_pfn_to_ptr_retcount(dom, pfn, count, &count_out_dummy);
|
||||
+}
|
||||
+
|
||||
+void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image *dom, xen_pfn_t pfn,
|
||||
+ xen_pfn_t count, xen_pfn_t *count_out)
|
||||
+{
|
||||
struct xc_dom_phys *phys;
|
||||
unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
|
||||
char *mode = "unset";
|
||||
|
||||
+ *count_out = 0;
|
||||
+
|
||||
if ( pfn > dom->total_pages || /* multiple checks to avoid overflows */
|
||||
count > dom->total_pages ||
|
||||
pfn > dom->total_pages - count )
|
||||
@@ -384,6 +393,7 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
|
||||
phys->count);
|
||||
return NULL;
|
||||
}
|
||||
+ *count_out = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -391,6 +401,9 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
|
||||
just hand out a pointer to it */
|
||||
if ( pfn < phys->first )
|
||||
continue;
|
||||
+ if ( pfn >= phys->first + phys->count )
|
||||
+ continue;
|
||||
+ *count_out = phys->count - (pfn - phys->first);
|
||||
}
|
||||
return phys->ptr + ((pfn - phys->first) << page_shift);
|
||||
}
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 2e69559..031b5b6 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -130,10 +130,11 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
|
||||
if ( load )
|
||||
{
|
||||
+ size_t allow_size; /* will be used in a forthcoming XSA-55 patch */
|
||||
if ( !dom->bsd_symtab_start )
|
||||
return 0;
|
||||
size = dom->kernel_seg.vend - dom->bsd_symtab_start;
|
||||
- hdr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start);
|
||||
+ hdr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
|
||||
*(int *)hdr = size - sizeof(int);
|
||||
}
|
||||
else
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,55 +0,0 @@
|
||||
From 035634047d10c678cbb8801c4263747bdaf4e5b1 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
Subject: [PATCH 04/23] libelf: add `struct elf_binary*' parameter to elf_load_image
|
||||
|
||||
The meat of this function is going to need a copy of the elf pointer,
|
||||
in forthcoming patches.
|
||||
|
||||
No functional change in this patch.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
---
|
||||
xen/common/libelf/libelf-loader.c | 8 +++++---
|
||||
1 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index ab58b8b..0559d88 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -108,7 +108,8 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
|
||||
elf->verbose = verbose;
|
||||
}
|
||||
|
||||
-static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz)
|
||||
+static int elf_load_image(struct elf_binary *elf,
|
||||
+ void *dst, const void *src, uint64_t filesz, uint64_t memsz)
|
||||
{
|
||||
memcpy(dst, src, filesz);
|
||||
memset(dst + filesz, 0, memsz - filesz);
|
||||
@@ -122,7 +123,8 @@ void elf_set_verbose(struct elf_binary *elf)
|
||||
elf->verbose = 1;
|
||||
}
|
||||
|
||||
-static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz)
|
||||
+static int elf_load_image(struct elf_binary *elf,
|
||||
+ void *dst, const void *src, uint64_t filesz, uint64_t memsz)
|
||||
{
|
||||
int rc;
|
||||
if ( filesz > ULONG_MAX || memsz > ULONG_MAX )
|
||||
@@ -279,7 +281,7 @@ int elf_load_binary(struct elf_binary *elf)
|
||||
dest = elf_get_ptr(elf, paddr);
|
||||
elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n",
|
||||
__func__, i, dest, dest + filesz);
|
||||
- if ( elf_load_image(dest, elf->image + offset, filesz, memsz) != 0 )
|
||||
+ if ( elf_load_image(elf, dest, elf->image + offset, filesz, memsz) != 0 )
|
||||
return -1;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,174 +0,0 @@
|
||||
From 83ec905922b496e1a5756e3a88405eb6c2c6ba88 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
Subject: [PATCH 05/23] libelf: abolish elf_sval and elf_access_signed
|
||||
|
||||
These are not used anywhere.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
xen/common/libelf/libelf-tools.c | 28 ----------------------------
|
||||
xen/include/xen/libelf.h | 11 -----------
|
||||
2 files changed, 0 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index cb97908..2f54142 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -48,34 +48,6 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr,
|
||||
}
|
||||
}
|
||||
|
||||
-int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
|
||||
- uint64_t offset, size_t size)
|
||||
-{
|
||||
- int need_swap = elf_swap(elf);
|
||||
- const int8_t *s8;
|
||||
- const int16_t *s16;
|
||||
- const int32_t *s32;
|
||||
- const int64_t *s64;
|
||||
-
|
||||
- switch ( size )
|
||||
- {
|
||||
- case 1:
|
||||
- s8 = ptr + offset;
|
||||
- return *s8;
|
||||
- case 2:
|
||||
- s16 = ptr + offset;
|
||||
- return need_swap ? bswap_16(*s16) : *s16;
|
||||
- case 4:
|
||||
- s32 = ptr + offset;
|
||||
- return need_swap ? bswap_32(*s32) : *s32;
|
||||
- case 8:
|
||||
- s64 = ptr + offset;
|
||||
- return need_swap ? bswap_64(*s64) : *s64;
|
||||
- default:
|
||||
- return 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
|
||||
{
|
||||
int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index e8f6508..38e490c 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -136,23 +136,12 @@ struct elf_binary {
|
||||
offsetof(typeof(*(str)),e32.elem), \
|
||||
sizeof((str)->e32.elem)))
|
||||
|
||||
-#define elf_sval(elf, str, elem) \
|
||||
- ((ELFCLASS64 == (elf)->class) \
|
||||
- ? elf_access_signed((elf), (str), \
|
||||
- offsetof(typeof(*(str)),e64.elem), \
|
||||
- sizeof((str)->e64.elem)) \
|
||||
- : elf_access_signed((elf), (str), \
|
||||
- offsetof(typeof(*(str)),e32.elem), \
|
||||
- sizeof((str)->e32.elem)))
|
||||
-
|
||||
#define elf_size(elf, str) \
|
||||
((ELFCLASS64 == (elf)->class) \
|
||||
? sizeof((str)->e64) : sizeof((str)->e32))
|
||||
|
||||
uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
|
||||
uint64_t offset, size_t size);
|
||||
-int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
|
||||
- uint64_t offset, size_t size);
|
||||
|
||||
uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
#From 682a04488e7b3bd6c3448ab60599566eb7c6177a Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
#Subject: [PATCH 06/23] libelf: move include of <asm/guest_access.h> to top of file
|
||||
#
|
||||
#libelf-loader.c #includes <asm/guest_access.h>, when being compiled
|
||||
#for Xen. Currently it does this in the middle of the file.
|
||||
#
|
||||
#Move this #include to the top of the file, before libelf-private.h.
|
||||
#This is necessary because in forthcoming patches we will introduce
|
||||
#private #defines of memcpy etc. which would interfere with definitions
|
||||
#in headers #included from guest_access.h.
|
||||
#
|
||||
#No semantic or functional change in this patch.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
#Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
#---
|
||||
# xen/common/libelf/libelf-loader.c | 5 ++++-
|
||||
# 1 files changed, 4 insertions(+), 1 deletions(-)
|
||||
#
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index 0559d88..ec0706b 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -16,6 +16,10 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
+#ifdef __XEN__
|
||||
+#include <asm/guest_access.h>
|
||||
+#endif
|
||||
+
|
||||
#include "libelf-private.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -116,7 +120,6 @@ static int elf_load_image(struct elf_binary *elf,
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
-#include <asm/guest_access.h>
|
||||
|
||||
void elf_set_verbose(struct elf_binary *elf)
|
||||
{
|
||||
--
|
||||
1.7.2.5
|
||||
#From de9089b449d2508b1ba05590905c7ebaee00c8c4 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:16 +0100
|
||||
#Subject: [PATCH 07/23] libelf/xc_dom_load_elf_symtab: Do not use "syms" uninitialised
|
||||
#
|
||||
#xc_dom_load_elf_symtab (with load==0) calls elf_round_up, but it
|
||||
#mistakenly used the uninitialised variable "syms" when calculating
|
||||
#dom->bsd_symtab_start. This should be a reference to "elf".
|
||||
#
|
||||
#This change might have the effect of rounding the value differently.
|
||||
#Previously if the uninitialised value (a single byte on the stack) was
|
||||
#ELFCLASS64 (ie, 2), the alignment would be to 8 bytes, otherwise to 4.
|
||||
#
|
||||
#However, the value is calculated from dom->kernel_seg.vend so this
|
||||
#could only make a difference if that value wasn't already aligned to 8
|
||||
#bytes.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
#---
|
||||
# tools/libxc/xc_dom_elfloader.c | 2 +-
|
||||
# 1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
#
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 031b5b6..e82f6e9 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -144,7 +144,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
hdr = xc_dom_malloc(dom, size);
|
||||
if ( hdr == NULL )
|
||||
return 0;
|
||||
- dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend);
|
||||
+ dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
|
||||
}
|
||||
|
||||
memcpy(hdr + sizeof(int),
|
||||
--
|
||||
1.7.2.5
|
@ -1,252 +0,0 @@
|
||||
From 3fb6ccf2faccaf5e22e33a3155ccc72d732896d8 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:18 +0100
|
||||
Subject: [PATCH 14/23] libelf: use C99 bool for booleans
|
||||
|
||||
We want to remove uses of "int" because signed integers have
|
||||
undesirable undefined behaviours on overflow. Malicious compilers can
|
||||
turn apparently-correct code into code with security vulnerabilities
|
||||
etc.
|
||||
|
||||
In this patch we change all the booleans in libelf to C99 bool,
|
||||
from <stdbool.h>.
|
||||
|
||||
For the one visible libelf boolean in libxc's public interface we
|
||||
retain the use of int to avoid changing the ABI; libxc converts it to
|
||||
a bool for consumption by libelf.
|
||||
|
||||
It is OK to change all values only ever used as booleans to _Bool
|
||||
(bool) because conversion from any scalar type to a _Bool works the
|
||||
same as the boolean test in if() or ?: and is always defined (C99
|
||||
6.3.1.2). But we do need to check that all these variables really are
|
||||
only ever used that way. (It is theoretically possible that the old
|
||||
code truncated some 64-bit values to 32-bit ints which might become
|
||||
zero depending on the value, which would mean a behavioural change in
|
||||
this patch, but it seems implausible that treating 0x????????00000000
|
||||
as false could have been intended.)
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/xc_dom_elfloader.c | 8 ++++----
|
||||
xen/common/libelf/libelf-dominfo.c | 2 +-
|
||||
xen/common/libelf/libelf-loader.c | 4 ++--
|
||||
xen/common/libelf/libelf-private.h | 2 +-
|
||||
xen/common/libelf/libelf-tools.c | 10 +++++-----
|
||||
xen/include/xen/libelf.h | 18 ++++++++++--------
|
||||
6 files changed, 23 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 4fb4da2..9ba64ae 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -34,7 +34,7 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void log_callback(struct elf_binary *elf, void *caller_data,
|
||||
- int iserr, const char *fmt, va_list al) {
|
||||
+ bool iserr, const char *fmt, va_list al) {
|
||||
xc_interface *xch = caller_data;
|
||||
|
||||
xc_reportv(xch,
|
||||
@@ -46,7 +46,7 @@ static void log_callback(struct elf_binary *elf, void *caller_data,
|
||||
|
||||
void xc_elf_set_logfile(xc_interface *xch, struct elf_binary *elf,
|
||||
int verbose) {
|
||||
- elf_set_log(elf, log_callback, xch, verbose);
|
||||
+ elf_set_log(elf, log_callback, xch, verbose /* convert to bool */);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -84,7 +84,7 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* parse elf binary */
|
||||
|
||||
-static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
|
||||
+static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
|
||||
{
|
||||
if ( dom->kernel_blob == NULL )
|
||||
{
|
||||
@@ -112,7 +112,7 @@ static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
|
||||
}
|
||||
|
||||
static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
- struct elf_binary *elf, int load)
|
||||
+ struct elf_binary *elf, bool load)
|
||||
{
|
||||
struct elf_binary syms;
|
||||
ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
|
||||
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
|
||||
index 98c80dc..12b6c2a 100644
|
||||
--- a/xen/common/libelf/libelf-dominfo.c
|
||||
+++ b/xen/common/libelf/libelf-dominfo.c
|
||||
@@ -101,7 +101,7 @@ int elf_xen_parse_note(struct elf_binary *elf,
|
||||
/* *INDENT-OFF* */
|
||||
static const struct {
|
||||
char *name;
|
||||
- int str;
|
||||
+ bool str;
|
||||
} note_desc[] = {
|
||||
[XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
|
||||
[XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
|
||||
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
|
||||
index f8be635..0dccd4d 100644
|
||||
--- a/xen/common/libelf/libelf-loader.c
|
||||
+++ b/xen/common/libelf/libelf-loader.c
|
||||
@@ -92,7 +92,7 @@ int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
|
||||
}
|
||||
|
||||
#ifndef __XEN__
|
||||
-void elf_call_log_callback(struct elf_binary *elf, int iserr,
|
||||
+void elf_call_log_callback(struct elf_binary *elf, bool iserr,
|
||||
const char *fmt,...) {
|
||||
va_list al;
|
||||
|
||||
@@ -107,7 +107,7 @@ void elf_call_log_callback(struct elf_binary *elf, int iserr,
|
||||
}
|
||||
|
||||
void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback,
|
||||
- void *log_caller_data, int verbose)
|
||||
+ void *log_caller_data, bool verbose)
|
||||
{
|
||||
elf->log_callback = log_callback;
|
||||
elf->log_caller_data = log_caller_data;
|
||||
diff --git a/xen/common/libelf/libelf-private.h b/xen/common/libelf/libelf-private.h
|
||||
index 280dfd1..277be04 100644
|
||||
--- a/xen/common/libelf/libelf-private.h
|
||||
+++ b/xen/common/libelf/libelf-private.h
|
||||
@@ -77,7 +77,7 @@
|
||||
#define elf_err(elf, fmt, args ... ) \
|
||||
elf_call_log_callback(elf, 1, fmt , ## args );
|
||||
|
||||
-void elf_call_log_callback(struct elf_binary*, int iserr, const char *fmt,...);
|
||||
+void elf_call_log_callback(struct elf_binary*, bool iserr, const char *fmt,...);
|
||||
|
||||
#define safe_strcpy(d,s) \
|
||||
do { strncpy((d),(s),sizeof((d))-1); \
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index 744027e..fa58f76 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -31,7 +31,7 @@ const char *elf_check_broken(const struct elf_binary *elf)
|
||||
return elf->broken;
|
||||
}
|
||||
|
||||
-static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
+static bool elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
const void *region, uint64_t regionsize)
|
||||
/*
|
||||
* Returns true if the putative memory area [ptrval,ptrval+size>
|
||||
@@ -53,7 +53,7 @@ static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
-int elf_access_ok(struct elf_binary * elf,
|
||||
+bool elf_access_ok(struct elf_binary * elf,
|
||||
uint64_t ptrval, size_t size)
|
||||
{
|
||||
if ( elf_ptrval_in_range(ptrval, size, elf->image_base, elf->size) )
|
||||
@@ -92,7 +92,7 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
|
||||
uint64_t moreoffset, size_t size)
|
||||
{
|
||||
elf_ptrval ptrval = base + moreoffset;
|
||||
- int need_swap = elf_swap(elf);
|
||||
+ bool need_swap = elf_swap(elf);
|
||||
const uint8_t *u8;
|
||||
const uint16_t *u16;
|
||||
const uint32_t *u32;
|
||||
@@ -332,7 +332,7 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
-int elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
+bool elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
{
|
||||
const Elf32_Ehdr *ehdr = image_start;
|
||||
|
||||
@@ -342,7 +342,7 @@ int elf_is_elfbinary(const void *image_start, size_t image_size)
|
||||
return IS_ELF(*ehdr);
|
||||
}
|
||||
|
||||
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
|
||||
{
|
||||
uint64_t p_type = elf_uval(elf, phdr, p_type);
|
||||
uint64_t p_flags = elf_uval(elf, phdr, p_flags);
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index ac93858..951430f 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -29,6 +29,8 @@
|
||||
#error define architectural endianness
|
||||
#endif
|
||||
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
#undef ELFSIZE
|
||||
#include "elfstructs.h"
|
||||
#ifdef __XEN__
|
||||
@@ -42,7 +44,7 @@
|
||||
|
||||
struct elf_binary;
|
||||
typedef void elf_log_callback(struct elf_binary*, void *caller_data,
|
||||
- int iserr, const char *fmt, va_list al);
|
||||
+ bool iserr, const char *fmt, va_list al);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -237,7 +239,7 @@ struct elf_binary {
|
||||
elf_log_callback *log_callback;
|
||||
void *log_caller_data;
|
||||
#endif
|
||||
- int verbose;
|
||||
+ bool verbose;
|
||||
const char *broken;
|
||||
};
|
||||
|
||||
@@ -301,8 +303,8 @@ void elf_memset_safe(struct elf_binary*, elf_ptrval dst, int c, size_t);
|
||||
* outside permitted areas.
|
||||
*/
|
||||
|
||||
-int elf_access_ok(struct elf_binary * elf,
|
||||
- uint64_t ptrval, size_t size);
|
||||
+bool elf_access_ok(struct elf_binary * elf,
|
||||
+ uint64_t ptrval, size_t size);
|
||||
|
||||
#define elf_store_val(elf, type, ptr, val) \
|
||||
({ \
|
||||
@@ -351,9 +353,9 @@ uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
|
||||
/* (Only) checks that the image has the right magic number. */
|
||||
-int elf_is_elfbinary(const void *image_start, size_t image_size);
|
||||
+bool elf_is_elfbinary(const void *image_start, size_t image_size);
|
||||
|
||||
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* xc_libelf_loader.c */
|
||||
@@ -367,7 +369,7 @@ int elf_init(struct elf_binary *elf, const char *image, size_t size);
|
||||
void elf_set_verbose(struct elf_binary *elf);
|
||||
#else
|
||||
void elf_set_log(struct elf_binary *elf, elf_log_callback*,
|
||||
- void *log_caller_pointer, int verbose);
|
||||
+ void *log_caller_pointer, bool verbose);
|
||||
#endif
|
||||
|
||||
void elf_parse_binary(struct elf_binary *elf);
|
||||
@@ -419,7 +421,7 @@ struct elf_dom_parms {
|
||||
char xen_ver[16];
|
||||
char loader[16];
|
||||
int pae;
|
||||
- int bsd_symtab;
|
||||
+ bool bsd_symtab;
|
||||
uint64_t virt_base;
|
||||
uint64_t virt_entry;
|
||||
uint64_t virt_hypercall;
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,382 +0,0 @@
|
||||
From 77c0829fa751f052f7b8ec08287aef6e7ba97bc5 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:19 +0100
|
||||
Subject: [PATCH 19/23] libxc: check failure of xc_dom_*_to_ptr, xc_map_foreign_range
|
||||
|
||||
The return values from xc_dom_*_to_ptr and xc_map_foreign_range are
|
||||
sometimes dereferenced, or subjected to pointer arithmetic, without
|
||||
checking whether the relevant function failed and returned NULL.
|
||||
|
||||
Add an appropriate error check at every call site.
|
||||
|
||||
Changes in the 4.2 backport of this series:
|
||||
* Fix tools/libxc/xc_dom_x86.c:setup_pgtables_x86_32.
|
||||
* Fix tools/libxc/xc_dom_ia64.c:start_info_ia64.
|
||||
* Fix tools/libxc/ia64/xc_ia64_dom_fwloader.c:xc_dom_load_fw_kernel.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
---
|
||||
tools/libxc/ia64/xc_ia64_dom_fwloader.c | 2 +
|
||||
tools/libxc/xc_dom_binloader.c | 6 +++
|
||||
tools/libxc/xc_dom_core.c | 6 +++
|
||||
tools/libxc/xc_dom_elfloader.c | 13 +++++++
|
||||
tools/libxc/xc_dom_ia64.c | 6 +++
|
||||
tools/libxc/xc_dom_x86.c | 55 +++++++++++++++++++++++++++++++
|
||||
tools/libxc/xc_domain_restore.c | 27 +++++++++++++++
|
||||
tools/libxc/xc_offline_page.c | 5 +++
|
||||
8 files changed, 120 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/tools/libxc/ia64/xc_ia64_dom_fwloader.c b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
index cdf3333..dbd3349 100644
|
||||
--- a/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
+++ b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
|
||||
@@ -60,6 +60,8 @@ static int xc_dom_load_fw_kernel(struct xc_dom_image *dom)
|
||||
unsigned long i;
|
||||
|
||||
dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
|
||||
+ if ( dest == NULL )
|
||||
+ return -1;
|
||||
memcpy(dest, dom->kernel_blob, FW_SIZE);
|
||||
|
||||
/* Synchronize cache. */
|
||||
diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
|
||||
index 8596a28..553b366 100644
|
||||
--- a/tools/libxc/xc_dom_binloader.c
|
||||
+++ b/tools/libxc/xc_dom_binloader.c
|
||||
@@ -277,6 +277,12 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image *dom)
|
||||
DOMPRINTF(" bss_size: 0x%" PRIx32 "", bss_size);
|
||||
|
||||
dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart, &dest_size);
|
||||
+ if ( dest == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart)"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
if ( dest_size < text_size ||
|
||||
dest_size - text_size < bss_size )
|
||||
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
|
||||
index 8913e41..a54ddae 100644
|
||||
--- a/tools/libxc/xc_dom_core.c
|
||||
+++ b/tools/libxc/xc_dom_core.c
|
||||
@@ -868,6 +868,12 @@ int xc_dom_build_image(struct xc_dom_image *dom)
|
||||
ramdisklen) != 0 )
|
||||
goto err;
|
||||
ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg);
|
||||
+ if ( ramdiskmap == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg) => NULL",
|
||||
+ __FUNCTION__);
|
||||
+ goto err;
|
||||
+ }
|
||||
if ( unziplen )
|
||||
{
|
||||
if ( xc_dom_do_gunzip(dom->xch,
|
||||
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
|
||||
index 9fc4b94..61b5798 100644
|
||||
--- a/tools/libxc/xc_dom_elfloader.c
|
||||
+++ b/tools/libxc/xc_dom_elfloader.c
|
||||
@@ -139,6 +139,12 @@ static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
|
||||
return 0;
|
||||
size = dom->kernel_seg.vend - dom->bsd_symtab_start;
|
||||
hdr_ptr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start, &allow_size);
|
||||
+ if ( hdr_ptr == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s/load: xc_dom_vaddr_to_ptr(dom,dom->bsd_symtab_start"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
elf->caller_xdest_base = hdr_ptr;
|
||||
elf->caller_xdest_size = allow_size;
|
||||
hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
|
||||
@@ -384,7 +390,14 @@ static elf_errorstatus xc_dom_load_elf_kernel(struct xc_dom_image *dom)
|
||||
xen_pfn_t pages;
|
||||
|
||||
elf->dest_base = xc_dom_seg_to_ptr_pages(dom, &dom->kernel_seg, &pages);
|
||||
+ if ( elf->dest_base == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_vaddr_to_ptr(dom,dom->kernel_seg)"
|
||||
+ " => NULL", __FUNCTION__);
|
||||
+ return -1;
|
||||
+ }
|
||||
elf->dest_size = pages * XC_DOM_PAGE_SIZE(dom);
|
||||
+
|
||||
rc = elf_load_binary(elf);
|
||||
if ( rc < 0 )
|
||||
{
|
||||
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
|
||||
index dcd1523..7c0eff1 100644
|
||||
--- a/tools/libxc/xc_dom_ia64.c
|
||||
+++ b/tools/libxc/xc_dom_ia64.c
|
||||
@@ -60,6 +60,12 @@ int start_info_ia64(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
sprintf(start_info->magic, dom->guest_type);
|
||||
start_info->flags = dom->flags;
|
||||
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
|
||||
index 0cf1687..75d6b83 100644
|
||||
--- a/tools/libxc/xc_dom_x86.c
|
||||
+++ b/tools/libxc/xc_dom_x86.c
|
||||
@@ -144,6 +144,9 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
xen_vaddr_t addr;
|
||||
xen_pfn_t pgpfn;
|
||||
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
+
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
{
|
||||
@@ -151,6 +154,8 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_i386(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -169,6 +174,11 @@ static int setup_pgtables_x86_32(struct xc_dom_image *dom)
|
||||
l1tab = NULL;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -219,6 +229,12 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
|
||||
goto out;
|
||||
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr(dom, l3pfn, 1) => NULL",
|
||||
+ __FUNCTION__);
|
||||
+ return l3mfn; /* our one call site will call xc_dom_panic and fail */
|
||||
+ }
|
||||
memset(l3tab, 0, XC_DOM_PAGE_SIZE(dom));
|
||||
|
||||
DOMPRINTF("%s: successfully relocated L3 below 4G. "
|
||||
@@ -262,6 +278,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
}
|
||||
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ goto pfn_error;
|
||||
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
@@ -270,6 +288,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L2 tab, make L3 entry */
|
||||
l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l3off = l3_table_offset_pae(addr);
|
||||
l3tab[l3off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
@@ -280,6 +300,8 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_pae(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -306,6 +328,11 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
|
||||
l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
#undef L1_PROT
|
||||
@@ -344,6 +371,9 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
uint64_t addr;
|
||||
xen_pfn_t pgpfn;
|
||||
|
||||
+ if ( l4tab == NULL )
|
||||
+ goto pfn_error;
|
||||
+
|
||||
for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
|
||||
addr += PAGE_SIZE_X86 )
|
||||
{
|
||||
@@ -351,6 +381,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L3 tab, make L4 entry */
|
||||
l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
|
||||
+ if ( l3tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l4off = l4_table_offset_x86_64(addr);
|
||||
l4tab[l4off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT;
|
||||
@@ -361,6 +393,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L2 tab, make L3 entry */
|
||||
l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
|
||||
+ if ( l2tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l3off = l3_table_offset_x86_64(addr);
|
||||
l3tab[l3off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
|
||||
@@ -373,6 +407,8 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
{
|
||||
/* get L1 tab, make L2 entry */
|
||||
l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
|
||||
+ if ( l1tab == NULL )
|
||||
+ goto pfn_error;
|
||||
l2off = l2_table_offset_x86_64(addr);
|
||||
l2tab[l2off] =
|
||||
pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
|
||||
@@ -393,6 +429,11 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom)
|
||||
l1tab = NULL;
|
||||
}
|
||||
return 0;
|
||||
+
|
||||
+pfn_error:
|
||||
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
|
||||
+ "%s: xc_dom_pfn_to_ptr failed", __FUNCTION__);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
#undef L1_PROT
|
||||
@@ -410,6 +451,8 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size) )
|
||||
return -1;
|
||||
dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
|
||||
+ if ( dom->p2m_guest == NULL )
|
||||
+ return -1;
|
||||
|
||||
/* allocate special pages */
|
||||
dom->start_info_pfn = xc_dom_alloc_page(dom, "start info");
|
||||
@@ -434,6 +477,12 @@ static int start_info_x86_32(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
|
||||
start_info->magic[sizeof(start_info->magic) - 1] = '\0';
|
||||
@@ -474,6 +523,12 @@ static int start_info_x86_64(struct xc_dom_image *dom)
|
||||
|
||||
DOMPRINTF_CALLED(dom->xch);
|
||||
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ DOMPRINTF("%s: xc_dom_pfn_to_ptr failed on start_info", __FUNCTION__);
|
||||
+ return -1; /* our caller throws away our return value :-/ */
|
||||
+ }
|
||||
+
|
||||
memset(start_info, 0, sizeof(*start_info));
|
||||
strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
|
||||
start_info->magic[sizeof(start_info->magic) - 1] = '\0';
|
||||
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
|
||||
index b4c0b10..3994f8f 100644
|
||||
--- a/tools/libxc/xc_domain_restore.c
|
||||
+++ b/tools/libxc/xc_domain_restore.c
|
||||
@@ -1556,6 +1556,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
mfn = ctx->p2m[pfn];
|
||||
buf = xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, mfn);
|
||||
+ if ( buf == NULL )
|
||||
+ {
|
||||
+ ERROR("xc_map_foreign_range for generation id"
|
||||
+ " buffer failed");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
generationid = *(unsigned long long *)(buf + offset);
|
||||
*(unsigned long long *)(buf + offset) = generationid + 1;
|
||||
@@ -1713,6 +1719,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
l3tab = (uint64_t *)
|
||||
xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ, ctx->p2m[i]);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for l3tab)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
for ( j = 0; j < 4; j++ )
|
||||
l3ptes[j] = l3tab[j];
|
||||
@@ -1739,6 +1750,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
l3tab = (uint64_t *)
|
||||
xc_map_foreign_range(xch, dom, PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, ctx->p2m[i]);
|
||||
+ if ( l3tab == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for l3tab, 2nd)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
for ( j = 0; j < 4; j++ )
|
||||
l3tab[j] = l3ptes[j];
|
||||
@@ -1909,6 +1925,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
SET_FIELD(ctxt, user_regs.edx, mfn);
|
||||
start_info = xc_map_foreign_range(
|
||||
xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
|
||||
+ if ( start_info == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for start_info)");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
|
||||
SET_FIELD(start_info, shared_info, shared_info_frame<<PAGE_SHIFT);
|
||||
SET_FIELD(start_info, flags, 0);
|
||||
@@ -2056,6 +2078,11 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
|
||||
/* Restore contents of shared-info page. No checking needed. */
|
||||
new_shared_info = xc_map_foreign_range(
|
||||
xch, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
|
||||
+ if ( new_shared_info == NULL )
|
||||
+ {
|
||||
+ PERROR("xc_map_foreign_range failed (for new_shared_info)");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* restore saved vcpu_info and arch specific info */
|
||||
MEMCPY_FIELD(new_shared_info, old_shared_info, vcpu_info);
|
||||
diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
|
||||
index 089a361..36b9812 100644
|
||||
--- a/tools/libxc/xc_offline_page.c
|
||||
+++ b/tools/libxc/xc_offline_page.c
|
||||
@@ -714,6 +714,11 @@ int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
|
||||
|
||||
new_p = xc_map_foreign_range(xch, domid, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE, new_mfn);
|
||||
+ if ( new_p == NULL )
|
||||
+ {
|
||||
+ ERROR("failed to map new_p for copy, guest may be broken?");
|
||||
+ goto failed;
|
||||
+ }
|
||||
memcpy(new_p, backup, PAGE_SIZE);
|
||||
munmap(new_p, PAGE_SIZE);
|
||||
mops.arg1.mfn = new_mfn;
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,261 +0,0 @@
|
||||
From 59f66d58180832af6b99a9e4489031b5c2f627ab Mon Sep 17 00:00:00 2001
|
||||
From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Date: Fri, 14 Jun 2013 16:43:17 +0100
|
||||
Subject: [PATCH 09/23] tools/xcutils/readnotes: adjust print_l1_mfn_valid_note
|
||||
|
||||
Use the new PTRVAL macros and elf_access_unsigned in
|
||||
print_l1_mfn_valid_note.
|
||||
|
||||
No functional change unless the input is wrong, or we are reading a
|
||||
file for a different endianness.
|
||||
|
||||
Separated out from the previous patch because this change does produce
|
||||
a difference in the generated code.
|
||||
|
||||
This is part of the fix to a security issue, XSA-55.
|
||||
|
||||
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
tools/xcutils/readnotes.c | 11 ++++++-----
|
||||
1 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
|
||||
index 2af047d..7ff2530 100644
|
||||
--- a/tools/xcutils/readnotes.c
|
||||
+++ b/tools/xcutils/readnotes.c
|
||||
@@ -77,22 +77,23 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
|
||||
}
|
||||
|
||||
static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
|
||||
- const elf_note *note)
|
||||
+ ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
int descsz = elf_uval(elf, note, descsz);
|
||||
- const uint32_t *desc32 = elf_note_desc(elf, note);
|
||||
- const uint64_t *desc64 = elf_note_desc(elf, note);
|
||||
+ ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
|
||||
|
||||
/* XXX should be able to cope with a list of values. */
|
||||
switch ( descsz / 2 )
|
||||
{
|
||||
case 8:
|
||||
printf("%s: mask=%#"PRIx64" value=%#"PRIx64"\n", prefix,
|
||||
- desc64[0], desc64[1]);
|
||||
+ elf_access_unsigned(elf, desc, 0, 8),
|
||||
+ elf_access_unsigned(elf, desc, 8, 8));
|
||||
break;
|
||||
case 4:
|
||||
printf("%s: mask=%#"PRIx32" value=%#"PRIx32"\n", prefix,
|
||||
- desc32[0],desc32[1]);
|
||||
+ (uint32_t)elf_access_unsigned(elf, desc, 0, 4),
|
||||
+ (uint32_t)elf_access_unsigned(elf, desc, 4, 4));
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
#From db14d5bd9b6508adfcd2b910f454fae12fa4ba00 Mon Sep 17 00:00:00 2001
|
||||
#From: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Date: Fri, 14 Jun 2013 16:43:17 +0100
|
||||
#Subject: [PATCH 10/23] libelf: check nul-terminated strings properly
|
||||
#
|
||||
#It is not safe to simply take pointers into the ELF and use them as C
|
||||
#pointers. They might not be properly nul-terminated (and the pointers
|
||||
#might be wild).
|
||||
#
|
||||
#So we are going to introduce a new function elf_strval for safely
|
||||
#getting strings. This will check that the addresses are in range and
|
||||
#that there is a proper nul-terminated string. Of course it might
|
||||
#discover that there isn't. In that case, it will be made to fail.
|
||||
#This means that elf_note_name might fail, too.
|
||||
#
|
||||
#For the benefit of call sites which are just going to pass the value
|
||||
#to a printf-like function, we provide elf_strfmt which returns
|
||||
#"(invalid)" on failure rather than NULL.
|
||||
#
|
||||
#In this patch we introduce dummy definitions of these functions. We
|
||||
#introduce calls to elf_strval and elf_strfmt everywhere, and update
|
||||
#all the call sites with appropriate error checking.
|
||||
#
|
||||
#There is not yet any semantic change, since before this patch all the
|
||||
#places where we introduce elf_strval dereferenced the value anyway, so
|
||||
#it mustn't have been NULL.
|
||||
#
|
||||
#In future patches, when elf_strval is made able return NULL, when it
|
||||
#does so it will mark the elf "broken" so that an appropriate
|
||||
#diagnostic can be printed.
|
||||
#
|
||||
#This is part of the fix to a security issue, XSA-55.
|
||||
#
|
||||
#Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
#Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
#Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
#---
|
||||
# tools/xcutils/readnotes.c | 11 ++++++++---
|
||||
# xen/common/libelf/libelf-dominfo.c | 13 ++++++++++---
|
||||
# xen/common/libelf/libelf-tools.c | 10 +++++++---
|
||||
# xen/include/xen/libelf.h | 7 +++++--
|
||||
# 4 files changed, 30 insertions(+), 11 deletions(-)
|
||||
#
|
||||
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
|
||||
index 7ff2530..cfae994 100644
|
||||
--- a/tools/xcutils/readnotes.c
|
||||
+++ b/tools/xcutils/readnotes.c
|
||||
@@ -63,7 +63,7 @@ struct setup_header {
|
||||
static void print_string_note(const char *prefix, struct elf_binary *elf,
|
||||
ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
- printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
|
||||
+ printf("%s: %s\n", prefix, elf_strfmt(elf, elf_note_desc(elf, note)));
|
||||
}
|
||||
|
||||
static void print_numeric_note(const char *prefix, struct elf_binary *elf,
|
||||
@@ -103,10 +103,14 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
|
||||
{
|
||||
ELF_HANDLE_DECL(elf_note) note;
|
||||
int notes_found = 0;
|
||||
+ const char *this_note_name;
|
||||
|
||||
for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
|
||||
{
|
||||
- if (0 != strcmp(elf_note_name(elf, note), "Xen"))
|
||||
+ this_note_name = elf_note_name(elf, note);
|
||||
+ if (NULL == this_note_name)
|
||||
+ continue;
|
||||
+ if (0 != strcmp(this_note_name, "Xen"))
|
||||
continue;
|
||||
|
||||
notes_found++;
|
||||
@@ -294,7 +298,8 @@ int main(int argc, char **argv)
|
||||
|
||||
shdr = elf_shdr_by_name(&elf, "__xen_guest");
|
||||
if (ELF_HANDLE_VALID(shdr))
|
||||
- printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));
|
||||
+ printf("__xen_guest: %s\n",
|
||||
+ elf_strfmt(&elf, elf_section_start(&elf, shdr)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
|
||||
index 7140d59..b217f8f 100644
|
||||
--- a/xen/common/libelf/libelf-dominfo.c
|
||||
+++ b/xen/common/libelf/libelf-dominfo.c
|
||||
@@ -137,7 +137,10 @@ int elf_xen_parse_note(struct elf_binary *elf,
|
||||
|
||||
if ( note_desc[type].str )
|
||||
{
|
||||
- str = elf_note_desc(elf, note);
|
||||
+ str = elf_strval(elf, elf_note_desc(elf, note));
|
||||
+ if (str == NULL)
|
||||
+ /* elf_strval will mark elf broken if it fails so no need to log */
|
||||
+ return 0;
|
||||
elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__,
|
||||
note_desc[type].name, str);
|
||||
parms->elf_notes[type].type = XEN_ENT_STR;
|
||||
@@ -220,6 +223,7 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
|
||||
{
|
||||
int xen_elfnotes = 0;
|
||||
ELF_HANDLE_DECL(elf_note) note;
|
||||
+ const char *note_name;
|
||||
|
||||
parms->elf_note_start = start;
|
||||
parms->elf_note_end = end;
|
||||
@@ -227,7 +231,10 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
|
||||
ELF_HANDLE_PTRVAL(note) < parms->elf_note_end;
|
||||
note = elf_note_next(elf, note) )
|
||||
{
|
||||
- if ( strcmp(elf_note_name(elf, note), "Xen") )
|
||||
+ note_name = elf_note_name(elf, note);
|
||||
+ if ( note_name == NULL )
|
||||
+ continue;
|
||||
+ if ( strcmp(note_name, "Xen") )
|
||||
continue;
|
||||
if ( elf_xen_parse_note(elf, parms, note) )
|
||||
return -1;
|
||||
@@ -541,7 +548,7 @@ int elf_xen_parse(struct elf_binary *elf,
|
||||
parms->elf_note_start = ELF_INVALID_PTRVAL;
|
||||
parms->elf_note_end = ELF_INVALID_PTRVAL;
|
||||
elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__,
|
||||
- parms->guest_info);
|
||||
+ elf_strfmt(elf, parms->guest_info));
|
||||
elf_xen_parse_guest_info(elf, parms);
|
||||
break;
|
||||
}
|
||||
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
|
||||
index f1fd886..3a0cde1 100644
|
||||
--- a/xen/common/libelf/libelf-tools.c
|
||||
+++ b/xen/common/libelf/libelf-tools.c
|
||||
@@ -119,7 +119,7 @@ const char *elf_section_name(struct elf_binary *elf,
|
||||
if ( ELF_PTRVAL_INVALID(elf->sec_strtab) )
|
||||
return "unknown";
|
||||
|
||||
- return elf->sec_strtab + elf_uval(elf, shdr, sh_name);
|
||||
+ return elf_strval(elf, elf->sec_strtab + elf_uval(elf, shdr, sh_name));
|
||||
}
|
||||
|
||||
ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr)
|
||||
@@ -151,6 +151,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
|
||||
ELF_PTRVAL_CONST_VOID end = elf_section_end(elf, elf->sym_tab);
|
||||
ELF_HANDLE_DECL(elf_sym) sym;
|
||||
uint64_t info, name;
|
||||
+ const char *sym_name;
|
||||
|
||||
for ( ; ptr < end; ptr += elf_size(elf, sym) )
|
||||
{
|
||||
@@ -159,7 +160,10 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
|
||||
name = elf_uval(elf, sym, st_name);
|
||||
if ( ELF32_ST_BIND(info) != STB_GLOBAL )
|
||||
continue;
|
||||
- if ( strcmp(elf->sym_strtab + name, symbol) )
|
||||
+ sym_name = elf_strval(elf, elf->sym_strtab + name);
|
||||
+ if ( sym_name == NULL ) /* out of range, oops */
|
||||
+ return ELF_INVALID_HANDLE(elf_sym);
|
||||
+ if ( strcmp(sym_name, symbol) )
|
||||
continue;
|
||||
return sym;
|
||||
}
|
||||
@@ -177,7 +181,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
|
||||
|
||||
const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
|
||||
{
|
||||
- return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note);
|
||||
+ return elf_strval(elf, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note));
|
||||
}
|
||||
|
||||
ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
|
||||
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
|
||||
index cefd3d3..af5b5c5 100644
|
||||
--- a/xen/include/xen/libelf.h
|
||||
+++ b/xen/include/xen/libelf.h
|
||||
@@ -252,6 +252,9 @@ uint64_t elf_access_unsigned(struct elf_binary *elf, ELF_PTRVAL_CONST_VOID ptr,
|
||||
uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
|
||||
|
||||
|
||||
+#define elf_strval(elf,x) ((const char*)(x)) /* may return NULL in the future */
|
||||
+#define elf_strfmt(elf,x) ((const char*)(x)) /* will return (invalid) instead */
|
||||
+
|
||||
#define elf_memcpy_safe(elf, dst, src, sz) memcpy((dst),(src),(sz))
|
||||
#define elf_memset_safe(elf, dst, c, sz) memset((dst),(c),(sz))
|
||||
/*
|
||||
@@ -279,7 +282,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
|
||||
ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
|
||||
ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
|
||||
|
||||
-const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
+const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
|
||||
ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
ELF_PTRVAL_CONST_VOID elf_section_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
|
||||
|
||||
@@ -289,7 +292,7 @@ ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(el
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
|
||||
ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
|
||||
|
||||
-const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
+const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
|
||||
ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
|
||||
uint64_t elf_note_numeric_array(struct elf_binary *, ELF_HANDLE_DECL(elf_note),
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -1,334 +0,0 @@
|
||||
libxl: Restrict permissions on PV console device xenstore nodes
|
||||
|
||||
Matthew Daley has observed that the PV console protocol places sensitive host
|
||||
state into a guest writeable xenstore locations, this includes:
|
||||
|
||||
- The pty used to communicate between the console backend daemon and its
|
||||
client, allowing the guest administrator to read and write arbitrary host
|
||||
files.
|
||||
- The output file, allowing the guest administrator to write arbitrary host
|
||||
files or to target arbitrary qemu chardevs which include sockets, udp, ptr,
|
||||
pipes etc (see -chardev in qemu(1) for a more complete list).
|
||||
- The maximum buffer size, allowing the guest administrator to consume more
|
||||
resources than the host administrator has configured.
|
||||
- The backend to use (qemu vs xenconsoled), potentially allowing the guest
|
||||
administrator to confuse host software.
|
||||
|
||||
So we arrange to make the sensitive keys in the xenstore frontend directory
|
||||
read only for the guest. This is safe since the xenstore permissions model,
|
||||
unlike POSIX directory permissions, does not allow the guest to remove and
|
||||
recreate a node if it has write access to the containing directory.
|
||||
|
||||
There are a few associated wrinkles:
|
||||
|
||||
- The primary PV console is "special". It's xenstore node is not under the
|
||||
usual /devices/ subtree and it does not use the customary xenstore state
|
||||
machine protocol. Unfortunately its directory is used for other things,
|
||||
including the vnc-port node, which we do not want the guest to be able to
|
||||
write to. Rather than trying to track down all the possible secondary uses
|
||||
of this directory just make it r/o to the guest. All newly created
|
||||
subdirectories inherit these permissions and so are now safe by default.
|
||||
|
||||
- The other serial consoles do use the customary xenstore state machine and
|
||||
therefore need write access to at least the "protocol" and "state" nodes,
|
||||
however they may also want to use arbitrary "feature-foo" nodes (although
|
||||
I'm not aware of any) and therefore we cannot simply lock down the entire
|
||||
frontend directory. Instead we add support to libxl__device_generic_add for
|
||||
frontend keys which are explicitly read only and use that to lock down the
|
||||
sensitive keys.
|
||||
|
||||
- Minios' console frontend wants to write the "type" node, which it has no
|
||||
business doing since this is a host/toolstack level decision. This fails
|
||||
now that the node has become read only to the PV guest. Since the toolstack
|
||||
already writes this node just remove the attempt to set it.
|
||||
|
||||
This is CVE-XXXX-XXX / XSA-57
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
|
||||
Conflicts:
|
||||
tools/libxl/libxl.c (no vtpm, free front_ro on error in
|
||||
libxl__device_console_add)
|
||||
|
||||
diff --git a/extras/mini-os/console/xenbus.c b/extras/mini-os/console/xenbus.c
|
||||
index 77de82a..e65baf7 100644
|
||||
--- a/extras/mini-os/console/xenbus.c
|
||||
+++ b/extras/mini-os/console/xenbus.c
|
||||
@@ -122,12 +122,6 @@ again:
|
||||
goto abort_transaction;
|
||||
}
|
||||
|
||||
- err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu");
|
||||
- if (err) {
|
||||
- message = "writing type";
|
||||
- goto abort_transaction;
|
||||
- }
|
||||
-
|
||||
snprintf(path, sizeof(path), "%s/state", nodename);
|
||||
err = xenbus_switch_state(xbt, path, XenbusStateConnected);
|
||||
if (err) {
|
||||
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
|
||||
index a6e9601..32d788a 100644
|
||||
--- a/tools/libxl/libxl.c
|
||||
+++ b/tools/libxl/libxl.c
|
||||
@@ -1920,8 +1920,9 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,
|
||||
flexarray_append(front, disk->is_cdrom ? "cdrom" : "disk");
|
||||
|
||||
libxl__device_generic_add(gc, t, device,
|
||||
- libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ NULL);
|
||||
|
||||
rc = libxl__xs_transaction_commit(gc, &t);
|
||||
if (!rc) break;
|
||||
@@ -2633,8 +2634,9 @@ void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
|
||||
flexarray_append(front, libxl__sprintf(gc,
|
||||
LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
|
||||
libxl__device_generic_add(gc, XBT_NULL, device,
|
||||
- libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ NULL);
|
||||
|
||||
aodev->dev = device;
|
||||
aodev->action = DEVICE_CONNECT;
|
||||
@@ -2830,7 +2832,7 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
|
||||
libxl__device_console *console,
|
||||
libxl__domain_build_state *state)
|
||||
{
|
||||
- flexarray_t *front;
|
||||
+ flexarray_t *front, *ro_front;
|
||||
flexarray_t *back;
|
||||
libxl__device device;
|
||||
int rc;
|
||||
@@ -2845,6 +2847,11 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
|
||||
rc = ERROR_NOMEM;
|
||||
goto out;
|
||||
}
|
||||
+ ro_front = flexarray_make(16, 1);
|
||||
+ if (!ro_front) {
|
||||
+ rc = ERROR_NOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
back = flexarray_make(16, 1);
|
||||
if (!back) {
|
||||
rc = ERROR_NOMEM;
|
||||
@@ -2871,21 +2878,24 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
|
||||
|
||||
flexarray_append(front, "backend-id");
|
||||
flexarray_append(front, libxl__sprintf(gc, "%d", console->backend_domid));
|
||||
- flexarray_append(front, "limit");
|
||||
- flexarray_append(front, libxl__sprintf(gc, "%d", LIBXL_XENCONSOLE_LIMIT));
|
||||
- flexarray_append(front, "type");
|
||||
+
|
||||
+ flexarray_append(ro_front, "limit");
|
||||
+ flexarray_append(ro_front, libxl__sprintf(gc, "%d", LIBXL_XENCONSOLE_LIMIT));
|
||||
+ flexarray_append(ro_front, "type");
|
||||
if (console->consback == LIBXL__CONSOLE_BACKEND_XENCONSOLED)
|
||||
- flexarray_append(front, "xenconsoled");
|
||||
+ flexarray_append(ro_front, "xenconsoled");
|
||||
else
|
||||
- flexarray_append(front, "ioemu");
|
||||
- flexarray_append(front, "output");
|
||||
- flexarray_append(front, console->output);
|
||||
+ flexarray_append(ro_front, "ioemu");
|
||||
+ flexarray_append(ro_front, "output");
|
||||
+ flexarray_append(ro_front, console->output);
|
||||
+ flexarray_append(ro_front, "tty");
|
||||
+ flexarray_append(ro_front, "");
|
||||
|
||||
if (state) {
|
||||
- flexarray_append(front, "port");
|
||||
- flexarray_append(front, libxl__sprintf(gc, "%"PRIu32, state->console_port));
|
||||
- flexarray_append(front, "ring-ref");
|
||||
- flexarray_append(front, libxl__sprintf(gc, "%lu", state->console_mfn));
|
||||
+ flexarray_append(ro_front, "port");
|
||||
+ flexarray_append(ro_front, libxl__sprintf(gc, "%"PRIu32, state->console_port));
|
||||
+ flexarray_append(ro_front, "ring-ref");
|
||||
+ flexarray_append(ro_front, libxl__sprintf(gc, "%lu", state->console_mfn));
|
||||
} else {
|
||||
flexarray_append(front, "state");
|
||||
flexarray_append(front, libxl__sprintf(gc, "%d", 1));
|
||||
@@ -2894,11 +2904,13 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
|
||||
}
|
||||
|
||||
libxl__device_generic_add(gc, XBT_NULL, &device,
|
||||
- libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, ro_front, ro_front->count));
|
||||
rc = 0;
|
||||
out_free:
|
||||
flexarray_free(back);
|
||||
+ flexarray_free(ro_front);
|
||||
flexarray_free(front);
|
||||
out:
|
||||
return rc;
|
||||
@@ -2982,8 +2994,9 @@ int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
|
||||
flexarray_append(front, libxl__sprintf(gc, "%d", 1));
|
||||
|
||||
libxl__device_generic_add(gc, XBT_NULL, &device,
|
||||
- libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ NULL);
|
||||
rc = 0;
|
||||
out_free:
|
||||
flexarray_free(back);
|
||||
@@ -3096,8 +3109,9 @@ int libxl__device_vfb_add(libxl__gc *gc, uint32_t domid, libxl_device_vfb *vfb)
|
||||
flexarray_append_pair(front, "state", libxl__sprintf(gc, "%d", 1));
|
||||
|
||||
libxl__device_generic_add(gc, XBT_NULL, &device,
|
||||
- libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ NULL);
|
||||
rc = 0;
|
||||
out_free:
|
||||
flexarray_free(front);
|
||||
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
|
||||
index c3283f1..1c04a21 100644
|
||||
--- a/tools/libxl/libxl_device.c
|
||||
+++ b/tools/libxl/libxl_device.c
|
||||
@@ -84,11 +84,12 @@ out:
|
||||
}
|
||||
|
||||
int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,
|
||||
- libxl__device *device, char **bents, char **fents)
|
||||
+ libxl__device *device, char **bents, char **fents, char **ro_fents)
|
||||
{
|
||||
libxl_ctx *ctx = libxl__gc_owner(gc);
|
||||
char *frontend_path, *backend_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;
|
||||
|
||||
@@ -100,22 +101,37 @@ int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,
|
||||
frontend_perms[1].id = device->backend_domid;
|
||||
frontend_perms[1].perms = XS_PERM_READ;
|
||||
|
||||
- backend_perms[0].id = device->backend_domid;
|
||||
- backend_perms[0].perms = XS_PERM_NONE;
|
||||
- backend_perms[1].id = device->domid;
|
||||
- backend_perms[1].perms = XS_PERM_READ;
|
||||
+ ro_frontend_perms[0].id = backend_perms[0].id = device->backend_domid;
|
||||
+ ro_frontend_perms[0].perms = backend_perms[0].perms = XS_PERM_NONE;
|
||||
+ ro_frontend_perms[1].id = backend_perms[1].id = device->domid;
|
||||
+ ro_frontend_perms[1].perms = backend_perms[1].perms = XS_PERM_READ;
|
||||
|
||||
retry_transaction:
|
||||
if (create_transaction)
|
||||
t = xs_transaction_start(ctx->xsh);
|
||||
/* FIXME: read frontend_path and check state before removing stuff */
|
||||
|
||||
- if (fents) {
|
||||
+ if (fents || ro_fents) {
|
||||
xs_rm(ctx->xsh, t, frontend_path);
|
||||
xs_mkdir(ctx->xsh, t, frontend_path);
|
||||
- xs_set_permissions(ctx->xsh, t, frontend_path, frontend_perms, ARRAY_SIZE(frontend_perms));
|
||||
+ /* Console 0 is a special case. It doesn't use the regular PV
|
||||
+ * state machine but also the frontend directory has
|
||||
+ * historically contained other information, such as the
|
||||
+ * vnc-port, which we don't want the guest fiddling with.
|
||||
+ */
|
||||
+ if (device->kind == LIBXL__DEVICE_KIND_CONSOLE && device->devid == 0)
|
||||
+ xs_set_permissions(ctx->xsh, t, frontend_path,
|
||||
+ ro_frontend_perms, ARRAY_SIZE(ro_frontend_perms));
|
||||
+ else
|
||||
+ xs_set_permissions(ctx->xsh, t, frontend_path,
|
||||
+ frontend_perms, ARRAY_SIZE(frontend_perms));
|
||||
xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/backend", frontend_path), backend_path, strlen(backend_path));
|
||||
- libxl__xs_writev(gc, t, frontend_path, fents);
|
||||
+ if (fents)
|
||||
+ libxl__xs_writev_perms(gc, t, frontend_path, fents,
|
||||
+ frontend_perms, ARRAY_SIZE(frontend_perms));
|
||||
+ if (ro_fents)
|
||||
+ libxl__xs_writev_perms(gc, t, frontend_path, ro_fents,
|
||||
+ ro_frontend_perms, ARRAY_SIZE(ro_frontend_perms));
|
||||
}
|
||||
|
||||
if (bents) {
|
||||
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
|
||||
index 13fa509..ae96a74 100644
|
||||
--- a/tools/libxl/libxl_internal.h
|
||||
+++ b/tools/libxl/libxl_internal.h
|
||||
@@ -516,6 +516,11 @@ _hidden char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array, int
|
||||
/* treats kvs as pairs of keys and values and writes each to dir. */
|
||||
_hidden int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
|
||||
const char *dir, char **kvs);
|
||||
+/* as writev but also sets the permissions on each path */
|
||||
+_hidden int libxl__xs_writev_perms(libxl__gc *gc, xs_transaction_t t,
|
||||
+ const char *dir, char *kvs[],
|
||||
+ struct xs_permissions *perms,
|
||||
+ unsigned int num_perms);
|
||||
/* _atonce creates a transaction and writes all keys at once */
|
||||
_hidden int libxl__xs_writev_atonce(libxl__gc *gc,
|
||||
const char *dir, char **kvs);
|
||||
@@ -930,7 +935,7 @@ _hidden int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
|
||||
libxl__domain_build_state *state);
|
||||
|
||||
_hidden int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,
|
||||
- libxl__device *device, char **bents, char **fents);
|
||||
+ 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 int libxl__parse_backend_path(libxl__gc *gc, const char *path,
|
||||
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
|
||||
index 48986f3..d373b4d 100644
|
||||
--- a/tools/libxl/libxl_pci.c
|
||||
+++ b/tools/libxl/libxl_pci.c
|
||||
@@ -106,7 +106,8 @@ int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
|
||||
|
||||
libxl__device_generic_add(gc, XBT_NULL, &device,
|
||||
libxl__xs_kvs_of_flexarray(gc, back, back->count),
|
||||
- libxl__xs_kvs_of_flexarray(gc, front, front->count));
|
||||
+ libxl__xs_kvs_of_flexarray(gc, front, front->count),
|
||||
+ NULL);
|
||||
|
||||
out:
|
||||
if (back)
|
||||
diff --git a/tools/libxl/libxl_xshelp.c b/tools/libxl/libxl_xshelp.c
|
||||
index 52af484..d7eaa66 100644
|
||||
--- a/tools/libxl/libxl_xshelp.c
|
||||
+++ b/tools/libxl/libxl_xshelp.c
|
||||
@@ -41,8 +41,10 @@ char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array, int length)
|
||||
return kvs;
|
||||
}
|
||||
|
||||
-int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
|
||||
- const char *dir, char *kvs[])
|
||||
+int libxl__xs_writev_perms(libxl__gc *gc, xs_transaction_t t,
|
||||
+ const char *dir, char *kvs[],
|
||||
+ struct xs_permissions *perms,
|
||||
+ unsigned int num_perms)
|
||||
{
|
||||
libxl_ctx *ctx = libxl__gc_owner(gc);
|
||||
char *path;
|
||||
@@ -56,11 +58,19 @@ int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
|
||||
if (path && kvs[i + 1]) {
|
||||
int length = strlen(kvs[i + 1]);
|
||||
xs_write(ctx->xsh, t, path, kvs[i + 1], length);
|
||||
+ if (perms)
|
||||
+ xs_set_permissions(ctx->xsh, t, path, perms, num_perms);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
|
||||
+ const char *dir, char *kvs[])
|
||||
+{
|
||||
+ return libxl__xs_writev_perms(gc, t, dir, kvs, NULL, 0);
|
||||
+}
|
||||
+
|
||||
int libxl__xs_writev_atonce(libxl__gc *gc,
|
||||
const char *dir, char *kvs[])
|
||||
{
|
||||
|
@ -1,69 +0,0 @@
|
||||
libxl: fix vif rate parsing
|
||||
|
||||
strtok can return NULL here. We don't need to use strtok anyway, so just
|
||||
use a simple strchr method.
|
||||
|
||||
Coverity-ID: 1055642
|
||||
|
||||
This is CVE-2013-4369 / XSA-68
|
||||
|
||||
Signed-off-by: Matthew Daley <mattjd@gmail.com>
|
||||
|
||||
Fix type. Add test case
|
||||
|
||||
Signed-off-by: Ian Campbell <Ian.campbell@citrix.com>
|
||||
|
||||
diff --git a/tools/libxl/check-xl-vif-parse b/tools/libxl/check-xl-vif-parse
|
||||
index 0473182..02c6dba 100755
|
||||
--- a/tools/libxl/check-xl-vif-parse
|
||||
+++ b/tools/libxl/check-xl-vif-parse
|
||||
@@ -206,4 +206,8 @@ expected </dev/null
|
||||
one $e rate=4294967295GB/s@5us
|
||||
one $e rate=4296MB/s@4294s
|
||||
|
||||
+# test include of single '@'
|
||||
+expected </dev/null
|
||||
+one $e rate=@
|
||||
+
|
||||
complete
|
||||
diff --git a/tools/libxl/libxlu_vif.c b/tools/libxl/libxlu_vif.c
|
||||
index 3b3de0f..0665e62 100644
|
||||
--- a/tools/libxl/libxlu_vif.c
|
||||
+++ b/tools/libxl/libxlu_vif.c
|
||||
@@ -95,23 +95,30 @@ int xlu_vif_parse_rate(XLU_Config *cfg, const char *rate, libxl_device_nic *nic)
|
||||
uint64_t bytes_per_sec = 0;
|
||||
uint64_t bytes_per_interval = 0;
|
||||
uint32_t interval_usecs = 50000UL; /* Default to 50ms */
|
||||
- char *ratetok, *tmprate;
|
||||
+ char *p, *tmprate;
|
||||
int rc = 0;
|
||||
|
||||
tmprate = strdup(rate);
|
||||
+ if (tmprate == NULL) {
|
||||
+ rc = ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ p = strchr(tmprate, '@');
|
||||
+ if (p != NULL)
|
||||
+ *p++ = 0;
|
||||
+
|
||||
if (!strcmp(tmprate,"")) {
|
||||
xlu__vif_err(cfg, "no rate specified", rate);
|
||||
rc = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- ratetok = strtok(tmprate, "@");
|
||||
- rc = vif_parse_rate_bytes_per_sec(cfg, ratetok, &bytes_per_sec);
|
||||
+ rc = vif_parse_rate_bytes_per_sec(cfg, tmprate, &bytes_per_sec);
|
||||
if (rc) goto out;
|
||||
|
||||
- ratetok = strtok(NULL, "@");
|
||||
- if (ratetok != NULL) {
|
||||
- rc = vif_parse_rate_interval_usecs(cfg, ratetok, &interval_usecs);
|
||||
+ if (p != NULL) {
|
||||
+ rc = vif_parse_rate_interval_usecs(cfg, p, &interval_usecs);
|
||||
if (rc) goto out;
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 067c122873c67bd1d9620f8340f9c9c209135388 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Daley <mattjd@gmail.com>
|
||||
Date: Tue, 10 Sep 2013 23:12:45 +1200
|
||||
Subject: [PATCH] tools/ocaml: fix erroneous free of cpumap in
|
||||
stub_xc_vcpu_getaffinity
|
||||
|
||||
Not sure how it got there...
|
||||
|
||||
Coverity-ID: 1056196
|
||||
|
||||
This is CVE-2013-4370 / XSA-69
|
||||
|
||||
Signed-off-by: Matthew Daley <mattjd@gmail.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
tools/ocaml/libs/xc/xenctrl_stubs.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c b/tools/ocaml/libs/xc/xenctrl_stubs.c
|
||||
index df756ad..f5cf0ed 100644
|
||||
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
|
||||
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
|
||||
@@ -461,8 +461,6 @@ CAMLprim value stub_xc_vcpu_getaffinity(value xch, value domid,
|
||||
|
||||
retval = xc_vcpu_getaffinity(_H(xch), _D(domid),
|
||||
Int_val(vcpu), c_cpumap);
|
||||
- free(c_cpumap);
|
||||
-
|
||||
if (retval < 0) {
|
||||
free(c_cpumap);
|
||||
failwith_xc(_H(xch));
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 94db3e1cb356a0d2de1753888ceb0eb767404ec4 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Daley <mattjd@gmail.com>
|
||||
Date: Tue, 10 Sep 2013 22:18:46 +1200
|
||||
Subject: [PATCH] libxl: fix out-of-memory error handling in
|
||||
libxl_list_cpupool
|
||||
|
||||
...otherwise it will return freed memory. All the current users of this
|
||||
function check already for a NULL return, so use that.
|
||||
|
||||
Coverity-ID: 1056194
|
||||
|
||||
This is CVE-2013-4371 / XSA-70
|
||||
|
||||
Signed-off-by: Matthew Daley <mattjd@gmail.com>
|
||||
Acked-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
tools/libxl/libxl.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
|
||||
index 0879f23..17653ef 100644
|
||||
--- a/tools/libxl/libxl.c
|
||||
+++ b/tools/libxl/libxl.c
|
||||
@@ -651,6 +651,7 @@ libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool_out)
|
||||
if (!tmp) {
|
||||
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
|
||||
libxl_cpupoolinfo_list_free(ptr, i);
|
||||
+ ptr = NULL;
|
||||
goto out;
|
||||
}
|
||||
ptr = tmp;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -1,74 +0,0 @@
|
||||
tools: xenstored: if the reply is too big then send E2BIG error
|
||||
|
||||
This fixes the issue for both C and ocaml xenstored, however only the ocaml
|
||||
xenstored is vulnerable in its default configuration.
|
||||
|
||||
Adding a new error appears to be safe, since bit libxenstore and the Linux
|
||||
driver at least treat an unknown error code as EINVAL.
|
||||
|
||||
This is XSA-72
|
||||
|
||||
Original ocaml patch by Jerome Maloberti <jerome.maloberti@citrix.com>
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Signed-off-by: Thomas Sanders <thomas.sanders@citrix.com>
|
||||
|
||||
diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
|
||||
index 273fe4d..47695f8 100644
|
||||
--- a/tools/ocaml/xenstored/connection.ml
|
||||
+++ b/tools/ocaml/xenstored/connection.ml
|
||||
@@ -18,6 +18,8 @@ exception End_of_file
|
||||
|
||||
open Stdext
|
||||
|
||||
+let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
|
||||
+
|
||||
type watch = {
|
||||
con: t;
|
||||
token: string;
|
||||
@@ -112,8 +114,15 @@ let restrict con domid =
|
||||
let set_target con target_domid =
|
||||
con.perm <- Perms.Connection.set_target (get_perm con) ~perms:[Perms.READ; Perms.WRITE] target_domid
|
||||
|
||||
+let is_backend_mmap con = match con.xb.Xenbus.Xb.backend with
|
||||
+ | Xenbus.Xb.Xenmmap _ -> true
|
||||
+ | _ -> false
|
||||
+
|
||||
let send_reply con tid rid ty data =
|
||||
- Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid ty data)
|
||||
+ if (String.length data) > xenstore_payload_max && (is_backend_mmap con) then
|
||||
+ Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid Xenbus.Xb.Op.Error "E2BIG\000")
|
||||
+ else
|
||||
+ Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid ty data)
|
||||
|
||||
let send_error con tid rid err = send_reply con tid rid Xenbus.Xb.Op.Error (err ^ "\000")
|
||||
let send_ack con tid rid ty = send_reply con tid rid ty "OK\000"
|
||||
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
|
||||
index 0f8ba64..ccfdaa3 100644
|
||||
--- a/tools/xenstore/xenstored_core.c
|
||||
+++ b/tools/xenstore/xenstored_core.c
|
||||
@@ -629,6 +629,11 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
|
||||
{
|
||||
struct buffered_data *bdata;
|
||||
|
||||
+ if ( len > XENSTORE_PAYLOAD_MAX ) {
|
||||
+ send_error(conn, E2BIG);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* Message is a child of the connection context for auto-cleanup. */
|
||||
bdata = new_buffer(conn);
|
||||
bdata->buffer = talloc_array(bdata, char, len);
|
||||
diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h
|
||||
index 99d24e3..585f0c8 100644
|
||||
--- a/xen/include/public/io/xs_wire.h
|
||||
+++ b/xen/include/public/io/xs_wire.h
|
||||
@@ -83,7 +83,8 @@ __attribute__((unused))
|
||||
XSD_ERROR(EROFS),
|
||||
XSD_ERROR(EBUSY),
|
||||
XSD_ERROR(EAGAIN),
|
||||
- XSD_ERROR(EISCONN)
|
||||
+ XSD_ERROR(EISCONN),
|
||||
+ XSD_ERROR(E2BIG)
|
||||
};
|
||||
#endif
|
||||
|
@ -1,373 +0,0 @@
|
||||
# Copyright 1999-2013 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen-tools/xen-tools-4.2.2-r3.ebuild,v 1.8 2013/11/09 08:14:57 mgorny Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python{2_6,2_7} )
|
||||
PYTHON_REQ_USE='xml,threads'
|
||||
|
||||
IPXE_TARBALL_URL="http://dev.gentoo.org/~idella4/tarballs/ipxe.tar.gz"
|
||||
XEN_SEABIOS_URL="http://dev.gentoo.org/~idella4/tarballs/seabios-0-20121121.tar.bz2"
|
||||
XSAPATCHES="http://dev.gentoo.org/~idella4/"
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
KEYWORDS="amd64 x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz
|
||||
$IPXE_TARBALL_URL
|
||||
$XEN_SEABIOS_URL
|
||||
$XSAPATCHES/patches/XSA-55patches.tar.gz"
|
||||
S="${WORKDIR}/xen-${PV}"
|
||||
fi
|
||||
|
||||
inherit bash-completion-r1 eutils flag-o-matic multilib python-single-r1 toolchain-funcs udev ${live_eclass}
|
||||
|
||||
DESCRIPTION="Xend daemon and tools"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
DOCS=( README docs/README.xen-bugtool )
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="api custom-cflags debug doc flask hvm qemu pygrub screen static-libs xend"
|
||||
|
||||
REQUIRED_USE="hvm? ( qemu )
|
||||
${PYTHON_REQUIRED_USE}"
|
||||
|
||||
DEPEND="dev-libs/lzo:2
|
||||
dev-libs/yajl
|
||||
dev-libs/libgcrypt
|
||||
dev-python/lxml[${PYTHON_USEDEP}]
|
||||
dev-python/pypam[${PYTHON_USEDEP}]
|
||||
sys-libs/zlib
|
||||
sys-power/iasl
|
||||
dev-ml/findlib
|
||||
hvm? ( media-libs/libsdl )
|
||||
api? ( dev-libs/libxml2
|
||||
net-misc/curl )
|
||||
${PYTHON_DEPS}
|
||||
pygrub? ( ${PYTHON_DEPS//${PYTHON_REQ_USE}/ncurses} )
|
||||
sys-devel/bin86
|
||||
sys-devel/dev86
|
||||
dev-lang/perl
|
||||
app-misc/pax-utils
|
||||
doc? (
|
||||
app-doc/doxygen
|
||||
dev-tex/latex2html[png,gif]
|
||||
media-gfx/transfig
|
||||
media-gfx/graphviz
|
||||
dev-tex/xcolor
|
||||
dev-texlive/texlive-latexextra
|
||||
virtual/latex-base
|
||||
dev-tex/latexmk
|
||||
dev-texlive/texlive-latex
|
||||
dev-texlive/texlive-pictures
|
||||
dev-texlive/texlive-latexrecommended
|
||||
)
|
||||
hvm? ( x11-proto/xproto )"
|
||||
RDEPEND="sys-apps/iproute2
|
||||
net-misc/bridge-utils
|
||||
screen? (
|
||||
app-misc/screen
|
||||
app-admin/logrotate
|
||||
)
|
||||
virtual/udev"
|
||||
|
||||
# hvmloader is used to bootstrap a fully virtualized kernel
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="usr/lib/xen/boot/hvmloader"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
pkg_setup() {
|
||||
python-single-r1_pkg_setup
|
||||
export "CONFIG_LOMOUNT=y"
|
||||
|
||||
if has_version dev-libs/libgcrypt; then
|
||||
export "CONFIG_GCRYPT=y"
|
||||
fi
|
||||
|
||||
if use qemu; then
|
||||
export "CONFIG_IOEMU=y"
|
||||
else
|
||||
export "CONFIG_IOEMU=n"
|
||||
fi
|
||||
|
||||
if ! use x86 && ! has x86 $(get_all_abis) && use hvm; then
|
||||
eerror "HVM (VT-x and AMD-v) cannot be built on this system. An x86 or"
|
||||
eerror "an amd64 multilib profile is required. Remove the hvm use flag"
|
||||
eerror "to build xen-tools on your current profile."
|
||||
die "USE=hvm is unsupported on this system."
|
||||
fi
|
||||
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]] ; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64 ; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
use api && export "LIBXENAPI_BINDINGS=y"
|
||||
use flask && export "FLASK_ENABLE=y"
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config, fixes to gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4-fix_dotconfig-gcc.patch
|
||||
|
||||
# Xend
|
||||
if ! use xend; then
|
||||
sed -e 's:xm xen-bugtool xen-python-path xend:xen-bugtool xen-python-path:' \
|
||||
-i tools/misc/Makefile || die "Disabling xend failed"
|
||||
sed -e 's:^XEND_INITD:#XEND_INITD:' \
|
||||
-i tools/examples/Makefile || die "Disabling xend failed"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
|
||||
# try and remove all the default cflags
|
||||
find "${S}" \( -name Makefile -o -name Rules.mk -o -name Config.mk \) \
|
||||
-exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} + || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
if ! use pygrub; then
|
||||
sed -e '/^SUBDIRS-$(PYTHON_TOOLS) += pygrub$/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Disable hvm support on systems that don't support x86_32 binaries.
|
||||
if ! use hvm; then
|
||||
sed -e '/^CONFIG_IOEMU := y$/d' -i config/*.mk || die
|
||||
sed -e '/SUBDIRS-$(CONFIG_X86) += firmware/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Don't bother with qemu, only needed for fully virtualised guests
|
||||
if ! use qemu; then
|
||||
sed -e "/^CONFIG_IOEMU := y$/d" -i config/*.mk || die
|
||||
sed -e "s:install-tools\: tools/ioemu-dir:install-tools\: :g" -i Makefile || die
|
||||
fi
|
||||
|
||||
# Fix texi2html build error with new texi2html, qemu.doc.html
|
||||
epatch "${FILESDIR}"/${PN}-4-docfix.patch \
|
||||
"${FILESDIR}"/${PN}-4-qemu-xen-doc.patch
|
||||
|
||||
# Fix network broadcast on bridged networks
|
||||
epatch "${FILESDIR}/${PN}-3.4.0-network-bridge-broadcast.patch"
|
||||
|
||||
# Prevent the downloading of ipxe, seabios
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-anti-download.patch
|
||||
cp "${DISTDIR}"/ipxe.tar.gz tools/firmware/etherboot/ || die
|
||||
mv ../seabios-dir-remote tools/firmware/ || die
|
||||
pushd tools/firmware/ > /dev/null
|
||||
ln -s seabios-dir-remote seabios-dir || die
|
||||
popd > /dev/null
|
||||
|
||||
# Fix bridge by idella4, bug #362575
|
||||
epatch "${FILESDIR}/${PN}-4.1.1-bridge.patch"
|
||||
|
||||
# Don't build ipxe with pie on hardened, Bug #360805
|
||||
if gcc-specs-pie; then
|
||||
epatch "${FILESDIR}"/ipxe-nopie.patch
|
||||
fi
|
||||
|
||||
# Prevent double stripping of files at install
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-nostrip.patch
|
||||
|
||||
# fix jobserver in Makefile
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-jserver.patch
|
||||
|
||||
# add missing header
|
||||
epatch "${FILESDIR}"/xen-4-ulong.patch \
|
||||
"${FILESDIR}"/${PN}-4.2-xen_disk_leak.patch
|
||||
|
||||
# Set dom0-min-mem to kb; Bug #472982
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2-configsxp.patch
|
||||
|
||||
#Security patches, currently valid
|
||||
epatch "${FILESDIR}"/xen-4-CVE-2012-6075-XSA-41.patch \
|
||||
"${FILESDIR}"/xen-4-CVE-2013-1922-XSA-48.patch \
|
||||
"${FILESDIR}"/xen-4-CVE-2013-1952-XSA-49.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-1-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-2-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-3-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-4-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-5to7-XSA-55.patch \
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-8-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-9to10-XSA-55.patch \
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-11-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-12to13-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-14-XSA-55.patch \
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-15-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-16-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-17-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-18to19-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-20to23-XSA-55.patch \
|
||||
"${FILESDIR}"/xen-4-CVE-2013-2072-XSA-56.patch \
|
||||
"${FILESDIR}"/xen-4.2-CVE-XSA-57.patch
|
||||
|
||||
# Bug 472438
|
||||
sed -e 's:^BASH_COMPLETION_DIR ?= $(CONFIG_DIR)/bash_completion.d:BASH_COMPLETION_DIR ?= $(SHARE_DIR)/bash-completion:' \
|
||||
-i Config.mk || die
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
export VARTEXFONTS="${T}/fonts"
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
|
||||
use custom-cflags || unset CFLAGS
|
||||
if test-flag-CC -fno-strict-overflow; then
|
||||
append-flags -fno-strict-overflow
|
||||
fi
|
||||
|
||||
unset LDFLAGS
|
||||
unset CFLAGS
|
||||
emake CC="$(tc-getCC)" LD="$(tc-getLD)" -C tools ${myopt}
|
||||
|
||||
use doc && emake -C docs txt html
|
||||
emake -C docs man-pages
|
||||
}
|
||||
|
||||
src_install() {
|
||||
# Override auto-detection in the build system, bug #382573
|
||||
export INITD_DIR=/tmp/init.d
|
||||
export CONFIG_LEAF_DIR=../tmp/default
|
||||
|
||||
# Let the build system compile installed Python modules.
|
||||
local PYTHONDONTWRITEBYTECODE
|
||||
export PYTHONDONTWRITEBYTECODE
|
||||
|
||||
emake DESTDIR="${ED}" DOCDIR="/usr/share/doc/${PF}" \
|
||||
XEN_PYTHON_NATIVE_INSTALL=y install-tools
|
||||
# Fix the remaining Python shebangs.
|
||||
python_fix_shebang "${ED}"
|
||||
|
||||
# Remove RedHat-specific stuff
|
||||
rm -rf "${ED}"tmp || die
|
||||
|
||||
# uncomment lines in xl.conf
|
||||
sed -e 's:^#autoballoon=1:autoballoon=1:' \
|
||||
-e 's:^#lockfile="/var/lock/xl":lockfile="/var/lock/xl":' \
|
||||
-e 's:^#vifscript="vif-bridge":vifscript="vif-bridge":' \
|
||||
-i tools/examples/xl.conf || die
|
||||
|
||||
# Reset bash completion dir; Bug 472438
|
||||
mv "${D}"bash-completion "${D}"usr/share/ || die
|
||||
|
||||
if use doc; then
|
||||
emake DESTDIR="${D}" DOCDIR="/usr/share/doc/${PF}" install-docs
|
||||
|
||||
dohtml -r docs/
|
||||
docinto pdf
|
||||
dodoc ${DOCS[@]}
|
||||
[ -d "${D}"/usr/share/doc/xen ] && mv "${D}"/usr/share/doc/xen/* "${D}"/usr/share/doc/${PF}/html
|
||||
fi
|
||||
|
||||
rm -rf "${D}"/usr/share/doc/xen/
|
||||
doman docs/man?/*
|
||||
|
||||
if use xend; then
|
||||
newinitd "${FILESDIR}"/xend.initd-r2 xend || die "Couldn't install xen.initd"
|
||||
fi
|
||||
newconfd "${FILESDIR}"/xendomains.confd xendomains
|
||||
newconfd "${FILESDIR}"/xenstored.confd xenstored
|
||||
newconfd "${FILESDIR}"/xenconsoled.confd xenconsoled
|
||||
newinitd "${FILESDIR}"/xendomains.initd-r2 xendomains
|
||||
newinitd "${FILESDIR}"/xenstored.initd xenstored
|
||||
newinitd "${FILESDIR}"/xenconsoled.initd xenconsoled
|
||||
|
||||
if use screen; then
|
||||
cat "${FILESDIR}"/xendomains-screen.confd >> "${ED}"/etc/conf.d/xendomains || die
|
||||
cp "${FILESDIR}"/xen-consoles.logrotate "${ED}"/etc/xen/ || die
|
||||
keepdir /var/log/xen-consoles
|
||||
fi
|
||||
|
||||
if [[ "${ARCH}" == 'amd64' ]] && use qemu; then
|
||||
mkdir -p "${D}"usr/$(get_libdir)/xen/bin || die
|
||||
mv "${D}"usr/lib/xen/bin/qemu* "${D}"usr/$(get_libdir)/xen/bin/ || die
|
||||
fi
|
||||
|
||||
# For -static-libs wrt Bug 384355
|
||||
if ! use static-libs; then
|
||||
rm -f "${ED}"usr/$(get_libdir)/*.a "${ED}"usr/$(get_libdir)/ocaml/*/*.a
|
||||
fi
|
||||
|
||||
# xend expects these to exist
|
||||
keepdir /var/run/xenstored /var/lib/xenstored /var/xen/dump /var/lib/xen /var/log/xen
|
||||
|
||||
# for xendomains
|
||||
keepdir /etc/xen/auto
|
||||
|
||||
# Temp QA workaround
|
||||
dodir "$(udev_get_udevdir)"
|
||||
mv "${ED}"/etc/udev/* "${ED}/$(udev_get_udevdir)"
|
||||
rm -rf "${ED}"/etc/udev
|
||||
|
||||
# Remove files failing QA AFTER emake installs them, avoiding seeking absent files
|
||||
find "${ED}" \( -name openbios-sparc32 -o -name openbios-sparc64 \
|
||||
-o -name openbios-ppc -o -name palcode-clipper \) -delete || die
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the offical wiki page:"
|
||||
elog "http://www.gentoo.org/doc/en/xen-guide.xml"
|
||||
elog "http://wiki.xen.org/wiki/Main_Page"
|
||||
|
||||
if [[ "$(scanelf -s __guard -q "${PYTHON}")" ]] ; then
|
||||
echo
|
||||
ewarn "xend may not work when python is built with stack smashing protection (ssp)."
|
||||
ewarn "If 'xm create' fails with '<ProtocolError for /RPC2: -1 >', see bug #141866"
|
||||
ewarn "This problem may be resolved as of Xen 3.0.4, if not post in the bug."
|
||||
fi
|
||||
|
||||
# TODO: we need to have the current Python slot here.
|
||||
if ! has_version "dev-lang/python[ncurses]"; then
|
||||
echo
|
||||
ewarn "NB: Your dev-lang/python is built without USE=ncurses."
|
||||
ewarn "Please rebuild python with USE=ncurses to make use of xenmon.py."
|
||||
fi
|
||||
|
||||
if has_version "sys-apps/iproute2[minimal]"; then
|
||||
echo
|
||||
ewarn "Your sys-apps/iproute2 is built with USE=minimal. Networking"
|
||||
ewarn "will not work until you rebuild iproute2 without USE=minimal."
|
||||
fi
|
||||
|
||||
if ! use hvm; then
|
||||
echo
|
||||
elog "HVM (VT-x and AMD-V) support has been disabled. If you need hvm"
|
||||
elog "support enable the hvm use flag."
|
||||
elog "An x86 or amd64 multilib system is required to build HVM support."
|
||||
echo
|
||||
elog "The qemu use flag has been removed and replaced with hvm."
|
||||
fi
|
||||
|
||||
if use xend; then
|
||||
echo
|
||||
elog "xend capability has been enabled and installed"
|
||||
fi
|
||||
|
||||
if grep -qsF XENSV= "${ROOT}/etc/conf.d/xend"; then
|
||||
echo
|
||||
elog "xensv is broken upstream (Gentoo bug #142011)."
|
||||
elog "Please remove '${ROOT%/}/etc/conf.d/xend', as it is no longer needed."
|
||||
fi
|
||||
}
|
@ -1,414 +0,0 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen-tools/xen-tools-4.2.2-r7.ebuild,v 1.1 2014/02/13 07:59:09 dlan Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python{2_6,2_7} )
|
||||
PYTHON_REQ_USE='xml,threads'
|
||||
|
||||
IPXE_TARBALL_URL="http://dev.gentoo.org/~idella4/tarballs/ipxe.tar.gz"
|
||||
XEN_SEABIOS_URL="http://dev.gentoo.org/~idella4/tarballs/seabios-0-20121121.tar.bz2"
|
||||
XSAPATCHES="http://dev.gentoo.org/~idella4/"
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz
|
||||
$IPXE_TARBALL_URL
|
||||
$XEN_SEABIOS_URL
|
||||
$XSAPATCHES/patches/XSA-55patches.tar.gz"
|
||||
S="${WORKDIR}/xen-${PV}"
|
||||
fi
|
||||
|
||||
inherit bash-completion-r1 eutils flag-o-matic multilib python-single-r1 toolchain-funcs udev ${live_eclass}
|
||||
|
||||
DESCRIPTION="Xend daemon and tools"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
DOCS=( README docs/README.xen-bugtool )
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="api custom-cflags debug doc flask hvm qemu ocaml pygrub screen static-libs xend"
|
||||
|
||||
REQUIRED_USE="hvm? ( qemu )
|
||||
${PYTHON_REQUIRED_USE}"
|
||||
|
||||
DEPEND="dev-libs/lzo:2
|
||||
dev-libs/glib:2
|
||||
dev-libs/yajl
|
||||
dev-libs/libgcrypt
|
||||
dev-python/lxml[${PYTHON_USEDEP}]
|
||||
dev-python/pypam[${PYTHON_USEDEP}]
|
||||
sys-libs/zlib
|
||||
sys-power/iasl
|
||||
dev-ml/findlib
|
||||
hvm? ( media-libs/libsdl )
|
||||
${PYTHON_DEPS}
|
||||
api? ( dev-libs/libxml2
|
||||
net-misc/curl )
|
||||
${PYTHON_DEPS}
|
||||
pygrub? ( ${PYTHON_DEPS//${PYTHON_REQ_USE}/ncurses} )
|
||||
sys-devel/bin86
|
||||
sys-devel/dev86
|
||||
dev-lang/perl
|
||||
app-misc/pax-utils
|
||||
doc? (
|
||||
app-doc/doxygen
|
||||
dev-tex/latex2html[png,gif]
|
||||
media-gfx/transfig
|
||||
media-gfx/graphviz
|
||||
dev-tex/xcolor
|
||||
dev-texlive/texlive-latexextra
|
||||
virtual/latex-base
|
||||
dev-tex/latexmk
|
||||
dev-texlive/texlive-latex
|
||||
dev-texlive/texlive-pictures
|
||||
dev-texlive/texlive-latexrecommended
|
||||
)
|
||||
hvm? ( x11-proto/xproto
|
||||
!net-libs/libiscsi )"
|
||||
RDEPEND="sys-apps/iproute2
|
||||
net-misc/bridge-utils
|
||||
ocaml? ( >=dev-lang/ocaml-4 )
|
||||
screen? (
|
||||
app-misc/screen
|
||||
app-admin/logrotate
|
||||
)
|
||||
virtual/udev"
|
||||
|
||||
# hvmloader is used to bootstrap a fully virtualized kernel
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="usr/lib/xen/boot/hvmloader"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
XSA_PATCHES=(
|
||||
"${FILESDIR}"/xen-4-CVE-2012-6075-XSA-41.patch
|
||||
"${FILESDIR}"/xen-4-CVE-2013-1922-XSA-48.patch
|
||||
"${FILESDIR}"/xen-4-CVE-2013-1952-XSA-49.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-1-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-2-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-3-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-4-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-5to7-XSA-55.patch
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-8-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-9to10-XSA-55.patch
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-11-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-12to13-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-14-XSA-55.patch
|
||||
"${WORKDIR}"/files/xen-4.2-CVE-2013-15-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-16-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-17-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-18to19-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-2013-20to23-XSA-55.patch
|
||||
"${FILESDIR}"/xen-4-CVE-2013-2072-XSA-56.patch
|
||||
"${FILESDIR}"/xen-4.2-CVE-XSA-57.patch
|
||||
"${FILESDIR}"/${PN}-4-CVE-2013-4369-XSA-68.patch
|
||||
"${FILESDIR}"/${PN}-4-CVE-2013-4370-XSA-69.patch
|
||||
"${FILESDIR}"/${PN}-4-CVE-2013-4371-XSA-70.patch
|
||||
"${FILESDIR}"/${PN}-4-CVE-2013-4416-XSA-72.patch
|
||||
"${FILESDIR}"/${PN/-tools/}-4-CVE-XSA-86.patch #bug #500530
|
||||
"${FILESDIR}"/${PN}-4-CVE-2014-1950-XSA-88.patch #bug #501080
|
||||
)
|
||||
|
||||
pkg_setup() {
|
||||
python-single-r1_pkg_setup
|
||||
export "CONFIG_LOMOUNT=y"
|
||||
|
||||
if has_version dev-libs/libgcrypt; then
|
||||
export "CONFIG_GCRYPT=y"
|
||||
fi
|
||||
|
||||
if use qemu; then
|
||||
export "CONFIG_IOEMU=y"
|
||||
else
|
||||
export "CONFIG_IOEMU=n"
|
||||
fi
|
||||
|
||||
if ! use x86 && ! has x86 $(get_all_abis) && use hvm; then
|
||||
eerror "HVM (VT-x and AMD-v) cannot be built on this system. An x86 or"
|
||||
eerror "an amd64 multilib profile is required. Remove the hvm use flag"
|
||||
eerror "to build xen-tools on your current profile."
|
||||
die "USE=hvm is unsupported on this system."
|
||||
fi
|
||||
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]] ; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64 ; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
use api && export "LIBXENAPI_BINDINGS=y"
|
||||
use flask && export "FLASK_ENABLE=y"
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config, fixes to gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4-fix_dotconfig-gcc.patch
|
||||
|
||||
# Xend
|
||||
if ! use xend; then
|
||||
sed -e 's:xm xen-bugtool xen-python-path xend:xen-bugtool xen-python-path:' \
|
||||
-i tools/misc/Makefile || die "Disabling xend failed"
|
||||
sed -e 's:^XEND_INITD:#XEND_INITD:' \
|
||||
-i tools/examples/Makefile || die "Disabling xend failed"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
|
||||
# try and remove all the default cflags
|
||||
find "${S}" \( -name Makefile -o -name Rules.mk -o -name Config.mk \) \
|
||||
-exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} + || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
if ! use pygrub; then
|
||||
sed -e '/^SUBDIRS-$(PYTHON_TOOLS) += pygrub$/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Disable hvm support on systems that don't support x86_32 binaries.
|
||||
if ! use hvm; then
|
||||
sed -e '/^CONFIG_IOEMU := y$/d' -i config/*.mk || die
|
||||
sed -e '/SUBDIRS-$(CONFIG_X86) += firmware/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Don't bother with qemu, only needed for fully virtualised guests
|
||||
if ! use qemu; then
|
||||
sed -e "/^CONFIG_IOEMU := y$/d" -i config/*.mk || die
|
||||
sed -e "s:install-tools\: tools/ioemu-dir:install-tools\: :g" -i Makefile || die
|
||||
fi
|
||||
|
||||
# Fix texi2html build error with new texi2html, qemu.doc.html
|
||||
epatch "${FILESDIR}"/${PN}-4-docfix.patch \
|
||||
"${FILESDIR}"/${PN}-4-qemu-xen-doc.patch
|
||||
|
||||
# Fix network broadcast on bridged networks
|
||||
epatch "${FILESDIR}/${PN}-3.4.0-network-bridge-broadcast.patch"
|
||||
|
||||
# Prevent the downloading of ipxe, seabios
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-anti-download.patch
|
||||
cp "${DISTDIR}"/ipxe.tar.gz tools/firmware/etherboot/ || die
|
||||
mv ../seabios-dir-remote tools/firmware/ || die
|
||||
pushd tools/firmware/ > /dev/null
|
||||
ln -s seabios-dir-remote seabios-dir || die
|
||||
popd > /dev/null
|
||||
|
||||
# Fix bridge by idella4, bug #362575
|
||||
epatch "${FILESDIR}/${PN}-4.1.1-bridge.patch"
|
||||
|
||||
# Don't build ipxe with pie on hardened, Bug #360805
|
||||
if gcc-specs-pie; then
|
||||
epatch "${FILESDIR}"/ipxe-nopie.patch
|
||||
fi
|
||||
|
||||
# Prevent double stripping of files at install
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-nostrip.patch
|
||||
|
||||
# fix jobserver in Makefile
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-jserver.patch
|
||||
|
||||
# add missing header
|
||||
epatch "${FILESDIR}"/xen-4-ulong.patch \
|
||||
"${FILESDIR}"/${PN}-4.2-xen_disk_leak.patch
|
||||
|
||||
# Set dom0-min-mem to kb; Bug #472982
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2-configsxp.patch
|
||||
|
||||
# Bug 463840
|
||||
epatch "${FILESDIR}"/${P}-install.patch
|
||||
epatch "${FILESDIR}"/${P}-rt-link.patch
|
||||
|
||||
[[ ${XSA_PATCHES[@]} ]] && epatch "${XSA_PATCHES[@]}"
|
||||
|
||||
# Bug 472438
|
||||
sed -e 's:^BASH_COMPLETION_DIR ?= $(CONFIG_DIR)/bash_completion.d:BASH_COMPLETION_DIR ?= $(SHARE_DIR)/bash-completion:' \
|
||||
-i Config.mk || die
|
||||
|
||||
# Bug 445986
|
||||
sed -e 's:$(MAKE) PYTHON=$(PYTHON) subdirs-$@:LC_ALL=C "$(MAKE)" PYTHON=$(PYTHON) subdirs-$@:' -i tools/firmware/Makefile || die
|
||||
|
||||
# Bug 379537
|
||||
epatch "${FILESDIR}"/fix-gold-ld.patch
|
||||
|
||||
# fix QA warning, create /var/run/, /var/lock dynamically
|
||||
sed -i -e "/\$(INSTALL_DIR) \$(DESTDIR)\$(XEN_RUN_DIR)/d" \
|
||||
tools/libxl/Makefile || die
|
||||
|
||||
sed -i -e "/\/var\/run\//d" \
|
||||
tools/xenstore/Makefile \
|
||||
tools/pygrub/Makefile || die
|
||||
|
||||
sed -i -e "/\/var\/lock\/subsys/d" \
|
||||
tools/Makefile || die
|
||||
|
||||
# xencommons, Bug #492332, sed lighter weight than patching
|
||||
sed -e 's:\$QEMU_XEN -xen-domid:test -e "\$QEMU_XEN" \&\& &:' \
|
||||
-i tools/hotplug/Linux/init.d/xencommons || die
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
export VARTEXFONTS="${T}/fonts"
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
|
||||
use custom-cflags || unset CFLAGS
|
||||
if test-flag-CC -fno-strict-overflow; then
|
||||
append-flags -fno-strict-overflow
|
||||
fi
|
||||
|
||||
unset LDFLAGS
|
||||
unset CFLAGS
|
||||
emake V=1 CC="$(tc-getCC)" LD="$(tc-getLD)" AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" -C tools ${myopt}
|
||||
|
||||
use doc && emake -C docs txt html
|
||||
emake -C docs man-pages
|
||||
}
|
||||
|
||||
src_install() {
|
||||
# Override auto-detection in the build system, bug #382573
|
||||
export INITD_DIR=/tmp/init.d
|
||||
export CONFIG_LEAF_DIR=../tmp/default
|
||||
|
||||
# Let the build system compile installed Python modules.
|
||||
local PYTHONDONTWRITEBYTECODE
|
||||
export PYTHONDONTWRITEBYTECODE
|
||||
|
||||
emake DESTDIR="${ED}" DOCDIR="/usr/share/doc/${PF}" install-tools \
|
||||
XEN_PYTHON_NATIVE_INSTALL=y install-tools
|
||||
# Fix the remaining Python shebangs.
|
||||
python_fix_shebang "${ED}"
|
||||
|
||||
# Remove RedHat-specific stuff
|
||||
rm -rf "${D}"tmp || die
|
||||
|
||||
# uncomment lines in xl.conf
|
||||
sed -e 's:^#autoballoon=1:autoballoon=1:' \
|
||||
-e 's:^#lockfile="/var/lock/xl":lockfile="/var/lock/xl":' \
|
||||
-e 's:^#vifscript="vif-bridge":vifscript="vif-bridge":' \
|
||||
-i tools/examples/xl.conf || die
|
||||
|
||||
# Reset bash completion dir; Bug 472438
|
||||
mv "${D}"bash-completion "${D}"usr/share/ || die
|
||||
|
||||
if use doc; then
|
||||
emake DESTDIR="${D}" DOCDIR="/usr/share/doc/${PF}" install-docs
|
||||
|
||||
dohtml -r docs/
|
||||
docinto pdf
|
||||
dodoc ${DOCS[@]}
|
||||
[ -d "${D}"/usr/share/doc/xen ] && mv "${D}"/usr/share/doc/xen/* "${D}"/usr/share/doc/${PF}/html
|
||||
fi
|
||||
|
||||
rm -rf "${D}"/usr/share/doc/xen/
|
||||
doman docs/man?/*
|
||||
|
||||
if use xend; then
|
||||
newinitd "${FILESDIR}"/xend.initd-r2 xend || die "Couldn't install xen.initd"
|
||||
fi
|
||||
newconfd "${FILESDIR}"/xendomains.confd xendomains
|
||||
newconfd "${FILESDIR}"/xenstored.confd xenstored
|
||||
newconfd "${FILESDIR}"/xenconsoled.confd xenconsoled
|
||||
newinitd "${FILESDIR}"/xendomains.initd-r2 xendomains
|
||||
newinitd "${FILESDIR}"/xenstored.initd xenstored
|
||||
newinitd "${FILESDIR}"/xenconsoled.initd xenconsoled
|
||||
newinitd "${FILESDIR}"/xencommons.initd xencommons
|
||||
newconfd "${FILESDIR}"/xencommons.confd xencommons
|
||||
|
||||
if use screen; then
|
||||
cat "${FILESDIR}"/xendomains-screen.confd >> "${ED}"/etc/conf.d/xendomains || die
|
||||
cp "${FILESDIR}"/xen-consoles.logrotate "${ED}"/etc/xen/ || die
|
||||
keepdir /var/log/xen-consoles
|
||||
fi
|
||||
|
||||
if [[ "${ARCH}" == 'amd64' ]] && use qemu; then
|
||||
mkdir -p "${D}"usr/$(get_libdir)/xen/bin || die
|
||||
mv "${D}"usr/lib/xen/bin/qemu* "${D}"usr/$(get_libdir)/xen/bin/ || die
|
||||
fi
|
||||
|
||||
# For -static-libs wrt Bug 384355
|
||||
if ! use static-libs; then
|
||||
rm -f "${D}"usr/$(get_libdir)/*.a "${D}"usr/$(get_libdir)/ocaml/*/*.a
|
||||
fi
|
||||
|
||||
# xend expects these to exist
|
||||
keepdir /var/run/xenstored /var/lib/xenstored /var/xen/dump /var/lib/xen /var/log/xen
|
||||
|
||||
# for xendomains
|
||||
keepdir /etc/xen/auto
|
||||
|
||||
# Temp QA workaround
|
||||
dodir "$(udev_get_udevdir)"
|
||||
mv "${D}"/etc/udev/* "${D}/$(udev_get_udevdir)"
|
||||
rm -rf "${D}"/etc/udev
|
||||
|
||||
# Remove files failing QA AFTER emake installs them, avoiding seeking absent files
|
||||
find "${D}" \( -name openbios-sparc32 -o -name openbios-sparc64 \
|
||||
-o -name openbios-ppc -o -name palcode-clipper \) -delete || die
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the offical wiki page:"
|
||||
elog "http://www.gentoo.org/doc/en/xen-gu"${D}"usr/ide.xml"
|
||||
elog "http://wiki.xen.org/wiki/Main_Page"
|
||||
elog ""
|
||||
elog "Recommended to utilise the xencommons script to config sytem at boot."
|
||||
elog "Add by use of rc-update on completion of the install"
|
||||
|
||||
if [[ "$(scanelf -s __guard -q "${PYTHON}")" ]] ; then
|
||||
echo
|
||||
ewarn "xend may not work when python is built with stack smashing protection (ssp)."
|
||||
ewarn "If 'xm create' fails with '<ProtocolError for /RPC2: -1 >', see bug #141866"
|
||||
ewarn "This problem may be resolved as of Xen 3.0.4, if not post in the bug."
|
||||
fi
|
||||
|
||||
# TODO: we need to have the current Python slot here.
|
||||
if ! has_version "dev-lang/python[ncurses]"; then
|
||||
echo
|
||||
ewarn "NB: Your dev-lang/python is built without USE=ncurses."
|
||||
ewarn "Please rebuild python with USE=ncurses to make use of xenmon.py."
|
||||
fi
|
||||
|
||||
if has_version "sys-apps/iproute2[minimal]"; then
|
||||
echo
|
||||
ewarn "Your sys-apps/iproute2 is built with USE=minimal. Networking"
|
||||
ewarn "will not work until you rebuild iproute2 without USE=minimal."
|
||||
fi
|
||||
|
||||
if ! use hvm; then
|
||||
echo
|
||||
elog "HVM (VT-x and AMD-V) support has been disabled. If you need hvm"
|
||||
elog "support enable the hvm use flag."
|
||||
elog "An x86 or amd64 multilib system is required to build HVM support."
|
||||
fi
|
||||
|
||||
if use xend; then
|
||||
echo
|
||||
elog "xend capability has been enabled and installed"
|
||||
fi
|
||||
|
||||
if grep -qsF XENSV= "${ROOT}/etc/conf.d/xend"; then
|
||||
echo
|
||||
elog "xensv is broken upstream (Gentoo bug #142011)."
|
||||
elog "Please remove '${ROOT%/}/etc/conf.d/xend', as it is no longer needed."
|
||||
fi
|
||||
}
|
@ -1,406 +0,0 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen-tools/xen-tools-4.2.3.ebuild,v 1.1 2014/02/14 10:17:46 dlan Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python{2_6,2_7} )
|
||||
PYTHON_REQ_USE='xml,threads'
|
||||
|
||||
IPXE_TARBALL_URL="http://dev.gentoo.org/~idella4/tarballs/ipxe.tar.gz"
|
||||
XEN_SEABIOS_URL="http://dev.gentoo.org/~idella4/tarballs/seabios-0-20121121.tar.bz2"
|
||||
XSAPATCHES="http://dev.gentoo.org/~idella4/"
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
UPSTREAM_VER=0
|
||||
GENTOO_VER=
|
||||
|
||||
[[ -n ${UPSTREAM_VER} ]] && \
|
||||
UPSTRAM_PATCHSET_URI="http://dev.gentoo.org/~dlan/distfiles/${P/-tools/}-upstream-patches-${UPSTREAM_VER}.tar.xz"
|
||||
[[ -n ${GENTOO_VER} ]] && \
|
||||
GENTOO_PATCHSET_URI="http://dev.gentoo.org/~dlan/distfiles/${P/-tools/}-gentoo-patches-${GENTOO_VER}.tar.xz"
|
||||
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz
|
||||
$IPXE_TARBALL_URL
|
||||
$XEN_SEABIOS_URL
|
||||
${UPSTRAM_PATCHSET_URI}
|
||||
${GENTOO_PATCHSET_URI}"
|
||||
S="${WORKDIR}/xen-${PV}"
|
||||
fi
|
||||
|
||||
inherit bash-completion-r1 eutils flag-o-matic multilib python-single-r1 toolchain-funcs udev ${live_eclass}
|
||||
|
||||
DESCRIPTION="Xend daemon and tools"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
DOCS=( README docs/README.xen-bugtool )
|
||||
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="api custom-cflags debug doc flask hvm qemu ocaml pygrub screen static-libs xend"
|
||||
|
||||
REQUIRED_USE="hvm? ( qemu )
|
||||
${PYTHON_REQUIRED_USE}"
|
||||
|
||||
DEPEND="dev-libs/lzo:2
|
||||
dev-libs/glib:2
|
||||
dev-libs/yajl
|
||||
dev-libs/libgcrypt
|
||||
dev-python/lxml[${PYTHON_USEDEP}]
|
||||
dev-python/pypam[${PYTHON_USEDEP}]
|
||||
sys-libs/zlib
|
||||
sys-power/iasl
|
||||
dev-ml/findlib
|
||||
hvm? ( media-libs/libsdl )
|
||||
${PYTHON_DEPS}
|
||||
api? ( dev-libs/libxml2
|
||||
net-misc/curl )
|
||||
${PYTHON_DEPS}
|
||||
pygrub? ( ${PYTHON_DEPS//${PYTHON_REQ_USE}/ncurses} )
|
||||
sys-devel/bin86
|
||||
sys-devel/dev86
|
||||
dev-lang/perl
|
||||
app-misc/pax-utils
|
||||
doc? (
|
||||
app-doc/doxygen
|
||||
dev-tex/latex2html[png,gif]
|
||||
media-gfx/transfig
|
||||
media-gfx/graphviz
|
||||
dev-tex/xcolor
|
||||
dev-texlive/texlive-latexextra
|
||||
virtual/latex-base
|
||||
dev-tex/latexmk
|
||||
dev-texlive/texlive-latex
|
||||
dev-texlive/texlive-pictures
|
||||
dev-texlive/texlive-latexrecommended
|
||||
)
|
||||
hvm? ( x11-proto/xproto
|
||||
!net-libs/libiscsi )"
|
||||
RDEPEND="sys-apps/iproute2
|
||||
net-misc/bridge-utils
|
||||
ocaml? ( >=dev-lang/ocaml-4 )
|
||||
screen? (
|
||||
app-misc/screen
|
||||
app-admin/logrotate
|
||||
)
|
||||
virtual/udev"
|
||||
|
||||
# hvmloader is used to bootstrap a fully virtualized kernel
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="usr/lib/xen/boot/hvmloader"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
pkg_setup() {
|
||||
python-single-r1_pkg_setup
|
||||
export "CONFIG_LOMOUNT=y"
|
||||
|
||||
if has_version dev-libs/libgcrypt; then
|
||||
export "CONFIG_GCRYPT=y"
|
||||
fi
|
||||
|
||||
if use qemu; then
|
||||
export "CONFIG_IOEMU=y"
|
||||
else
|
||||
export "CONFIG_IOEMU=n"
|
||||
fi
|
||||
|
||||
if ! use x86 && ! has x86 $(get_all_abis) && use hvm; then
|
||||
eerror "HVM (VT-x and AMD-v) cannot be built on this system. An x86 or"
|
||||
eerror "an amd64 multilib profile is required. Remove the hvm use flag"
|
||||
eerror "to build xen-tools on your current profile."
|
||||
die "USE=hvm is unsupported on this system."
|
||||
fi
|
||||
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]] ; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64 ; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
use api && export "LIBXENAPI_BINDINGS=y"
|
||||
use flask && export "FLASK_ENABLE=y"
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Upstream's patchset
|
||||
if [[ -n ${UPSTREAM_VER} ]]; then
|
||||
EPATCH_SUFFIX="patch" \
|
||||
EPATCH_FORCE="yes" \
|
||||
epatch "${WORKDIR}"/patches-upstream
|
||||
fi
|
||||
|
||||
# Gentoo's patchset
|
||||
if [[ -n ${GENTOO_VER} ]]; then
|
||||
EPATCH_SUFFIX="patch" \
|
||||
EPATCH_FORCE="yes" \
|
||||
epatch "${WORKDIR}"/patches-gentoo
|
||||
fi
|
||||
|
||||
# Drop .config, fixes to gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4-fix_dotconfig-gcc.patch
|
||||
|
||||
# Xend
|
||||
if ! use xend; then
|
||||
sed -e 's:xm xen-bugtool xen-python-path xend:xen-bugtool xen-python-path:' \
|
||||
-i tools/misc/Makefile || die "Disabling xend failed"
|
||||
sed -e 's:^XEND_INITD:#XEND_INITD:' \
|
||||
-i tools/examples/Makefile || die "Disabling xend failed"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
|
||||
# try and remove all the default cflags
|
||||
find "${S}" \( -name Makefile -o -name Rules.mk -o -name Config.mk \) \
|
||||
-exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} + || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
if ! use pygrub; then
|
||||
sed -e '/^SUBDIRS-$(PYTHON_TOOLS) += pygrub$/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Disable hvm support on systems that don't support x86_32 binaries.
|
||||
if ! use hvm; then
|
||||
sed -e '/^CONFIG_IOEMU := y$/d' -i config/*.mk || die
|
||||
sed -e '/SUBDIRS-$(CONFIG_X86) += firmware/d' -i tools/Makefile || die
|
||||
fi
|
||||
|
||||
# Don't bother with qemu, only needed for fully virtualised guests
|
||||
if ! use qemu; then
|
||||
sed -e "/^CONFIG_IOEMU := y$/d" -i config/*.mk || die
|
||||
sed -e "s:install-tools\: tools/ioemu-dir:install-tools\: :g" -i Makefile || die
|
||||
fi
|
||||
|
||||
# Fix texi2html build error with new texi2html, qemu.doc.html
|
||||
epatch "${FILESDIR}"/${PN}-4-docfix.patch \
|
||||
"${FILESDIR}"/${PN}-4-qemu-xen-doc.patch
|
||||
|
||||
# Fix network broadcast on bridged networks
|
||||
epatch "${FILESDIR}/${PN}-3.4.0-network-bridge-broadcast.patch"
|
||||
|
||||
# Prevent the downloading of ipxe, seabios
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-anti-download.patch
|
||||
cp "${DISTDIR}"/ipxe.tar.gz tools/firmware/etherboot/ || die
|
||||
mv ../seabios-dir-remote tools/firmware/ || die
|
||||
pushd tools/firmware/ > /dev/null
|
||||
ln -s seabios-dir-remote seabios-dir || die
|
||||
popd > /dev/null
|
||||
|
||||
# Fix bridge by idella4, bug #362575
|
||||
epatch "${FILESDIR}/${PN}-4.1.1-bridge.patch"
|
||||
|
||||
# Don't build ipxe with pie on hardened, Bug #360805
|
||||
if gcc-specs-pie; then
|
||||
epatch "${FILESDIR}"/ipxe-nopie.patch
|
||||
fi
|
||||
|
||||
# Prevent double stripping of files at install
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-nostrip.patch
|
||||
|
||||
# fix jobserver in Makefile
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2.0-jserver.patch
|
||||
|
||||
# add missing header, Bug #467200
|
||||
epatch "${FILESDIR}"/xen-4-ulong.patch \
|
||||
"${FILESDIR}"/${PN}-4.2-xen_disk_leak.patch
|
||||
|
||||
# Set dom0-min-mem to kb; Bug #472982
|
||||
epatch "${FILESDIR}"/${PN/-tools/}-4.2-configsxp.patch
|
||||
|
||||
# Bug 463840
|
||||
epatch "${FILESDIR}"/${PN}-4.2.2-install.patch
|
||||
epatch "${FILESDIR}"/${PN}-4.2.2-rt-link.patch
|
||||
|
||||
# Bug 472438
|
||||
sed -e 's:^BASH_COMPLETION_DIR ?= $(CONFIG_DIR)/bash_completion.d:BASH_COMPLETION_DIR ?= $(SHARE_DIR)/bash-completion:' \
|
||||
-i Config.mk || die
|
||||
|
||||
# Bug 445986
|
||||
sed -e 's:$(MAKE) PYTHON=$(PYTHON) subdirs-$@:LC_ALL=C "$(MAKE)" PYTHON=$(PYTHON) subdirs-$@:' -i tools/firmware/Makefile || die
|
||||
|
||||
# Bug 379537
|
||||
epatch "${FILESDIR}"/fix-gold-ld.patch
|
||||
|
||||
# fix QA warning, create /var/run/, /var/lock dynamically
|
||||
sed -i -e "/\$(INSTALL_DIR) \$(DESTDIR)\$(XEN_RUN_DIR)/d" \
|
||||
tools/libxl/Makefile || die
|
||||
|
||||
sed -i -e "/\/var\/run\//d" \
|
||||
tools/xenstore/Makefile \
|
||||
tools/pygrub/Makefile || die
|
||||
|
||||
sed -i -e "/\/var\/lock\/subsys/d" \
|
||||
tools/Makefile || die
|
||||
|
||||
# xencommons, Bug #492332, sed lighter weight than patching
|
||||
sed -e 's:\$QEMU_XEN -xen-domid:test -e "\$QEMU_XEN" \&\& &:' \
|
||||
-i tools/hotplug/Linux/init.d/xencommons || die
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
export VARTEXFONTS="${T}/fonts"
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
|
||||
use custom-cflags || unset CFLAGS
|
||||
if test-flag-CC -fno-strict-overflow; then
|
||||
append-flags -fno-strict-overflow
|
||||
fi
|
||||
|
||||
unset LDFLAGS
|
||||
unset CFLAGS
|
||||
emake V=1 CC="$(tc-getCC)" LD="$(tc-getLD)" AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" -C tools ${myopt}
|
||||
|
||||
use doc && emake -C docs txt html
|
||||
emake -C docs man-pages
|
||||
}
|
||||
|
||||
src_install() {
|
||||
# Override auto-detection in the build system, bug #382573
|
||||
export INITD_DIR=/tmp/init.d
|
||||
export CONFIG_LEAF_DIR=../tmp/default
|
||||
|
||||
# Let the build system compile installed Python modules.
|
||||
local PYTHONDONTWRITEBYTECODE
|
||||
export PYTHONDONTWRITEBYTECODE
|
||||
|
||||
emake DESTDIR="${ED}" DOCDIR="/usr/share/doc/${PF}" install-tools \
|
||||
XEN_PYTHON_NATIVE_INSTALL=y install-tools
|
||||
# Fix the remaining Python shebangs.
|
||||
python_fix_shebang "${ED}"
|
||||
|
||||
# Remove RedHat-specific stuff
|
||||
rm -rf "${D}"tmp || die
|
||||
|
||||
# uncomment lines in xl.conf
|
||||
sed -e 's:^#autoballoon=1:autoballoon=1:' \
|
||||
-e 's:^#lockfile="/var/lock/xl":lockfile="/var/lock/xl":' \
|
||||
-e 's:^#vifscript="vif-bridge":vifscript="vif-bridge":' \
|
||||
-i tools/examples/xl.conf || die
|
||||
|
||||
# Reset bash completion dir; Bug 472438
|
||||
mv "${D}"bash-completion "${D}"usr/share/ || die
|
||||
|
||||
if use doc; then
|
||||
emake DESTDIR="${D}" DOCDIR="/usr/share/doc/${PF}" install-docs
|
||||
|
||||
dohtml -r docs/
|
||||
docinto pdf
|
||||
dodoc ${DOCS[@]}
|
||||
[ -d "${D}"/usr/share/doc/xen ] && mv "${D}"/usr/share/doc/xen/* "${D}"/usr/share/doc/${PF}/html
|
||||
fi
|
||||
|
||||
rm -rf "${D}"/usr/share/doc/xen/
|
||||
doman docs/man?/*
|
||||
|
||||
if use xend; then
|
||||
newinitd "${FILESDIR}"/xend.initd-r2 xend || die "Couldn't install xen.initd"
|
||||
fi
|
||||
newconfd "${FILESDIR}"/xendomains.confd xendomains
|
||||
newconfd "${FILESDIR}"/xenstored.confd xenstored
|
||||
newconfd "${FILESDIR}"/xenconsoled.confd xenconsoled
|
||||
newinitd "${FILESDIR}"/xendomains.initd-r2 xendomains
|
||||
newinitd "${FILESDIR}"/xenstored.initd xenstored
|
||||
newinitd "${FILESDIR}"/xenconsoled.initd xenconsoled
|
||||
newinitd "${FILESDIR}"/xencommons.initd xencommons
|
||||
newconfd "${FILESDIR}"/xencommons.confd xencommons
|
||||
|
||||
if use screen; then
|
||||
cat "${FILESDIR}"/xendomains-screen.confd >> "${ED}"/etc/conf.d/xendomains || die
|
||||
cp "${FILESDIR}"/xen-consoles.logrotate "${ED}"/etc/xen/ || die
|
||||
keepdir /var/log/xen-consoles
|
||||
fi
|
||||
|
||||
if [[ "${ARCH}" == 'amd64' ]] && use qemu; then
|
||||
mkdir -p "${D}"usr/$(get_libdir)/xen/bin || die
|
||||
mv "${D}"usr/lib/xen/bin/qemu* "${D}"usr/$(get_libdir)/xen/bin/ || die
|
||||
fi
|
||||
|
||||
# For -static-libs wrt Bug 384355
|
||||
if ! use static-libs; then
|
||||
rm -f "${D}"usr/$(get_libdir)/*.a "${D}"usr/$(get_libdir)/ocaml/*/*.a
|
||||
fi
|
||||
|
||||
# xend expects these to exist
|
||||
keepdir /var/run/xenstored /var/lib/xenstored /var/xen/dump /var/lib/xen /var/log/xen
|
||||
|
||||
# for xendomains
|
||||
keepdir /etc/xen/auto
|
||||
|
||||
# Temp QA workaround
|
||||
dodir "$(udev_get_udevdir)"
|
||||
mv "${D}"/etc/udev/* "${D}/$(udev_get_udevdir)"
|
||||
rm -rf "${D}"/etc/udev
|
||||
|
||||
# Remove files failing QA AFTER emake installs them, avoiding seeking absent files
|
||||
find "${D}" \( -name openbios-sparc32 -o -name openbios-sparc64 \
|
||||
-o -name openbios-ppc -o -name palcode-clipper \) -delete || die
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the offical wiki page:"
|
||||
elog "http://www.gentoo.org/doc/en/xen-gu"${D}"usr/ide.xml"
|
||||
elog "http://wiki.xen.org/wiki/Main_Page"
|
||||
elog ""
|
||||
elog "Recommended to utilise the xencommons script to config sytem at boot."
|
||||
elog "Add by use of rc-update on completion of the install"
|
||||
|
||||
if [[ "$(scanelf -s __guard -q "${PYTHON}")" ]] ; then
|
||||
echo
|
||||
ewarn "xend may not work when python is built with stack smashing protection (ssp)."
|
||||
ewarn "If 'xm create' fails with '<ProtocolError for /RPC2: -1 >', see bug #141866"
|
||||
ewarn "This problem may be resolved as of Xen 3.0.4, if not post in the bug."
|
||||
fi
|
||||
|
||||
# TODO: we need to have the current Python slot here.
|
||||
if ! has_version "dev-lang/python[ncurses]"; then
|
||||
echo
|
||||
ewarn "NB: Your dev-lang/python is built without USE=ncurses."
|
||||
ewarn "Please rebuild python with USE=ncurses to make use of xenmon.py."
|
||||
fi
|
||||
|
||||
if has_version "sys-apps/iproute2[minimal]"; then
|
||||
echo
|
||||
ewarn "Your sys-apps/iproute2 is built with USE=minimal. Networking"
|
||||
ewarn "will not work until you rebuild iproute2 without USE=minimal."
|
||||
fi
|
||||
|
||||
if ! use hvm; then
|
||||
echo
|
||||
elog "HVM (VT-x and AMD-V) support has been disabled. If you need hvm"
|
||||
elog "support enable the hvm use flag."
|
||||
elog "An x86 or amd64 multilib system is required to build HVM support."
|
||||
fi
|
||||
|
||||
if use xend; then
|
||||
echo
|
||||
elog "xend capability has been enabled and installed"
|
||||
fi
|
||||
|
||||
if grep -qsF XENSV= "${ROOT}/etc/conf.d/xend"; then
|
||||
echo
|
||||
elog "xensv is broken upstream (Gentoo bug #142011)."
|
||||
elog "Please remove '${ROOT%/}/etc/conf.d/xend', as it is no longer needed."
|
||||
fi
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
x86: make vcpu_destroy_pagetables() preemptible
|
||||
|
||||
... as it may take significant amounts of time.
|
||||
|
||||
The function, being moved to mm.c as the better home for it anyway, and
|
||||
to avoid having to make a new helper function there non-static, is
|
||||
given a "preemptible" parameter temporarily (until, in a subsequent
|
||||
patch, its other caller is also being made capable of dealing with
|
||||
preemption).
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domain.c
|
||||
+++ b/xen/arch/x86/domain.c
|
||||
@@ -73,8 +73,6 @@ void (*dead_idle) (void) __read_mostly =
|
||||
static void paravirt_ctxt_switch_from(struct vcpu *v);
|
||||
static void paravirt_ctxt_switch_to(struct vcpu *v);
|
||||
|
||||
-static void vcpu_destroy_pagetables(struct vcpu *v);
|
||||
-
|
||||
static void default_idle(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
@@ -1058,7 +1056,7 @@ void arch_vcpu_reset(struct vcpu *v)
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
{
|
||||
destroy_gdt(v);
|
||||
- vcpu_destroy_pagetables(v);
|
||||
+ vcpu_destroy_pagetables(v, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2069,63 +2067,6 @@ static int relinquish_memory(
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void vcpu_destroy_pagetables(struct vcpu *v)
|
||||
-{
|
||||
- struct domain *d = v->domain;
|
||||
- unsigned long pfn;
|
||||
-
|
||||
-#ifdef __x86_64__
|
||||
- if ( is_pv_32on64_vcpu(v) )
|
||||
- {
|
||||
- pfn = l4e_get_pfn(*(l4_pgentry_t *)
|
||||
- __va(pagetable_get_paddr(v->arch.guest_table)));
|
||||
-
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- }
|
||||
-
|
||||
- l4e_write(
|
||||
- (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
|
||||
- l4e_empty());
|
||||
-
|
||||
- v->arch.cr3 = 0;
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- pfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- v->arch.guest_table = pagetable_null();
|
||||
- }
|
||||
-
|
||||
-#ifdef __x86_64__
|
||||
- /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
|
||||
- pfn = pagetable_get_pfn(v->arch.guest_table_user);
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( !is_pv_32bit_vcpu(v) )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- }
|
||||
- v->arch.guest_table_user = pagetable_null();
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- v->arch.cr3 = 0;
|
||||
-}
|
||||
-
|
||||
int domain_relinquish_resources(struct domain *d)
|
||||
{
|
||||
int ret;
|
||||
@@ -2143,7 +2084,11 @@ int domain_relinquish_resources(struct d
|
||||
|
||||
/* Drop the in-use references to page-table bases. */
|
||||
for_each_vcpu ( d, v )
|
||||
- vcpu_destroy_pagetables(v);
|
||||
+ {
|
||||
+ ret = vcpu_destroy_pagetables(v, 1);
|
||||
+ if ( ret )
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
if ( !is_hvm_domain(d) )
|
||||
{
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -2808,6 +2808,82 @@ static void put_superpage(unsigned long
|
||||
|
||||
#endif
|
||||
|
||||
+static int put_old_guest_table(struct vcpu *v)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if ( !v->arch.old_guest_table )
|
||||
+ return 0;
|
||||
+
|
||||
+ switch ( rc = put_page_and_type_preemptible(v->arch.old_guest_table, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
+
|
||||
+ v->arch.old_guest_table = NULL;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int vcpu_destroy_pagetables(struct vcpu *v, bool_t preemptible)
|
||||
+{
|
||||
+ unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
+ struct page_info *page;
|
||||
+ int rc = put_old_guest_table(v);
|
||||
+
|
||||
+ if ( rc )
|
||||
+ return rc;
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ if ( is_pv_32on64_vcpu(v) )
|
||||
+ mfn = l4e_get_pfn(*(l4_pgentry_t *)mfn_to_virt(mfn));
|
||||
+#endif
|
||||
+
|
||||
+ if ( mfn )
|
||||
+ {
|
||||
+ page = mfn_to_page(mfn);
|
||||
+ if ( paging_mode_refcounts(v->domain) )
|
||||
+ put_page(page);
|
||||
+ else
|
||||
+ rc = put_page_and_type_preemptible(page, preemptible);
|
||||
+ }
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ if ( is_pv_32on64_vcpu(v) )
|
||||
+ {
|
||||
+ if ( !rc )
|
||||
+ l4e_write(
|
||||
+ (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
|
||||
+ l4e_empty());
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ if ( !rc )
|
||||
+ {
|
||||
+ v->arch.guest_table = pagetable_null();
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
|
||||
+ mfn = pagetable_get_pfn(v->arch.guest_table_user);
|
||||
+ if ( mfn )
|
||||
+ {
|
||||
+ page = mfn_to_page(mfn);
|
||||
+ if ( paging_mode_refcounts(v->domain) )
|
||||
+ put_page(page);
|
||||
+ else
|
||||
+ rc = put_page_and_type_preemptible(page, preemptible);
|
||||
+ }
|
||||
+ if ( !rc )
|
||||
+ v->arch.guest_table_user = pagetable_null();
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ v->arch.cr3 = 0;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
|
||||
int new_guest_cr3(unsigned long mfn)
|
||||
{
|
||||
@@ -2994,12 +3070,21 @@ long do_mmuext_op(
|
||||
unsigned int foreigndom)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
- int rc = 0, i = 0, okay;
|
||||
unsigned long type;
|
||||
- unsigned int done = 0;
|
||||
+ unsigned int i = 0, done = 0;
|
||||
struct vcpu *curr = current;
|
||||
struct domain *d = curr->domain;
|
||||
struct domain *pg_owner;
|
||||
+ int okay, rc = put_old_guest_table(curr);
|
||||
+
|
||||
+ if ( unlikely(rc) )
|
||||
+ {
|
||||
+ if ( likely(rc == -EAGAIN) )
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmuext_op, "hihi", uops, count, pdone,
|
||||
+ foreigndom);
|
||||
+ return rc;
|
||||
+ }
|
||||
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
--- a/xen/arch/x86/x86_64/compat/mm.c
|
||||
+++ b/xen/arch/x86/x86_64/compat/mm.c
|
||||
@@ -365,7 +365,7 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
: mcs->call.args[1];
|
||||
unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
|
||||
|
||||
- BUG_ON(left == arg1);
|
||||
+ BUG_ON(left == arg1 && left != i);
|
||||
BUG_ON(left > count);
|
||||
guest_handle_add_offset(nat_ops, i - left);
|
||||
guest_handle_subtract_offset(cmp_uops, left);
|
||||
--- a/xen/include/asm-x86/domain.h
|
||||
+++ b/xen/include/asm-x86/domain.h
|
||||
@@ -464,6 +464,7 @@ struct arch_vcpu
|
||||
pagetable_t guest_table_user; /* (MFN) x86/64 user-space pagetable */
|
||||
#endif
|
||||
pagetable_t guest_table; /* (MFN) guest notion of cr3 */
|
||||
+ struct page_info *old_guest_table; /* partially destructed pagetable */
|
||||
/* guest_table holds a ref to the page, and also a type-count unless
|
||||
* shadow refcounts are in use */
|
||||
pagetable_t shadow_table[4]; /* (MFN) shadow(s) of guest */
|
||||
--- a/xen/include/asm-x86/mm.h
|
||||
+++ b/xen/include/asm-x86/mm.h
|
||||
@@ -605,6 +605,7 @@ void audit_domains(void);
|
||||
int new_guest_cr3(unsigned long pfn);
|
||||
void make_cr3(struct vcpu *v, unsigned long mfn);
|
||||
void update_cr3(struct vcpu *v);
|
||||
+int vcpu_destroy_pagetables(struct vcpu *, bool_t preemptible);
|
||||
void propagate_page_fault(unsigned long addr, u16 error_code);
|
||||
void *do_page_walk(struct vcpu *v, unsigned long addr);
|
||||
|
@ -1,169 +0,0 @@
|
||||
x86: make new_guest_cr3() preemptible
|
||||
|
||||
... as it may take significant amounts of time.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -2889,44 +2889,69 @@ int new_guest_cr3(unsigned long mfn)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
struct domain *d = curr->domain;
|
||||
- int okay;
|
||||
+ int rc;
|
||||
unsigned long old_base_mfn;
|
||||
|
||||
#ifdef __x86_64__
|
||||
if ( is_pv_32on64_domain(d) )
|
||||
{
|
||||
- okay = paging_mode_refcounts(d)
|
||||
- ? 0 /* Old code was broken, but what should it be? */
|
||||
- : mod_l4_entry(
|
||||
+ rc = paging_mode_refcounts(d)
|
||||
+ ? -EINVAL /* Old code was broken, but what should it be? */
|
||||
+ : mod_l4_entry(
|
||||
__va(pagetable_get_paddr(curr->arch.guest_table)),
|
||||
l4e_from_pfn(
|
||||
mfn,
|
||||
(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)),
|
||||
- pagetable_get_pfn(curr->arch.guest_table), 0, 0, curr) == 0;
|
||||
- if ( unlikely(!okay) )
|
||||
+ pagetable_get_pfn(curr->arch.guest_table), 0, 1, curr);
|
||||
+ switch ( rc )
|
||||
{
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ default:
|
||||
MEM_LOG("Error while installing new compat baseptr %lx", mfn);
|
||||
- return 0;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
invalidate_shadow_ldt(curr, 0);
|
||||
write_ptbase(curr);
|
||||
|
||||
- return 1;
|
||||
+ return 0;
|
||||
}
|
||||
#endif
|
||||
- okay = paging_mode_refcounts(d)
|
||||
- ? get_page_from_pagenr(mfn, d)
|
||||
- : !get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 0);
|
||||
- if ( unlikely(!okay) )
|
||||
+ rc = put_old_guest_table(curr);
|
||||
+ if ( unlikely(rc) )
|
||||
+ return rc;
|
||||
+
|
||||
+ old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
|
||||
+ /*
|
||||
+ * This is particularly important when getting restarted after the
|
||||
+ * previous attempt got preempted in the put-old-MFN phase.
|
||||
+ */
|
||||
+ if ( old_base_mfn == mfn )
|
||||
{
|
||||
- MEM_LOG("Error while installing new baseptr %lx", mfn);
|
||||
+ write_ptbase(curr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- invalidate_shadow_ldt(curr, 0);
|
||||
+ rc = paging_mode_refcounts(d)
|
||||
+ ? (get_page_from_pagenr(mfn, d) ? 0 : -EINVAL)
|
||||
+ : get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 1);
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ default:
|
||||
+ MEM_LOG("Error while installing new baseptr %lx", mfn);
|
||||
+ return rc;
|
||||
+ }
|
||||
|
||||
- old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
|
||||
+ invalidate_shadow_ldt(curr, 0);
|
||||
|
||||
curr->arch.guest_table = pagetable_from_pfn(mfn);
|
||||
update_cr3(curr);
|
||||
@@ -2935,13 +2960,25 @@ int new_guest_cr3(unsigned long mfn)
|
||||
|
||||
if ( likely(old_base_mfn != 0) )
|
||||
{
|
||||
+ struct page_info *page = mfn_to_page(old_base_mfn);
|
||||
+
|
||||
if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(old_base_mfn));
|
||||
+ put_page(page);
|
||||
else
|
||||
- put_page_and_type(mfn_to_page(old_base_mfn));
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static struct domain *get_pg_owner(domid_t domid)
|
||||
@@ -3239,8 +3276,13 @@ long do_mmuext_op(
|
||||
}
|
||||
|
||||
case MMUEXT_NEW_BASEPTR:
|
||||
- okay = (!paging_mode_translate(d)
|
||||
- && new_guest_cr3(op.arg1.mfn));
|
||||
+ if ( paging_mode_translate(d) )
|
||||
+ okay = 0;
|
||||
+ else
|
||||
+ {
|
||||
+ rc = new_guest_cr3(op.arg1.mfn);
|
||||
+ okay = !rc;
|
||||
+ }
|
||||
break;
|
||||
|
||||
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -2407,12 +2407,23 @@ static int emulate_privileged_op(struct
|
||||
#endif
|
||||
}
|
||||
page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
|
||||
- rc = page ? new_guest_cr3(page_to_mfn(page)) : 0;
|
||||
if ( page )
|
||||
+ {
|
||||
+ rc = new_guest_cr3(page_to_mfn(page));
|
||||
put_page(page);
|
||||
+ }
|
||||
+ else
|
||||
+ rc = -EINVAL;
|
||||
domain_unlock(v->domain);
|
||||
- if ( rc == 0 ) /* not okay */
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EAGAIN: /* retry after preemption */
|
||||
+ goto skip;
|
||||
+ default: /* not okay */
|
||||
goto fail;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
x86: make MMUEXT_NEW_USER_BASEPTR preemptible
|
||||
|
||||
... as it may take significant amounts of time.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -3296,29 +3296,56 @@ long do_mmuext_op(
|
||||
break;
|
||||
}
|
||||
|
||||
+ old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
|
||||
+ /*
|
||||
+ * This is particularly important when getting restarted after the
|
||||
+ * previous attempt got preempted in the put-old-MFN phase.
|
||||
+ */
|
||||
+ if ( old_mfn == op.arg1.mfn )
|
||||
+ break;
|
||||
+
|
||||
if ( op.arg1.mfn != 0 )
|
||||
{
|
||||
if ( paging_mode_refcounts(d) )
|
||||
okay = get_page_from_pagenr(op.arg1.mfn, d);
|
||||
else
|
||||
- okay = !get_page_and_type_from_pagenr(
|
||||
- op.arg1.mfn, PGT_root_page_table, d, 0, 0);
|
||||
+ {
|
||||
+ rc = get_page_and_type_from_pagenr(
|
||||
+ op.arg1.mfn, PGT_root_page_table, d, 0, 1);
|
||||
+ okay = !rc;
|
||||
+ }
|
||||
if ( unlikely(!okay) )
|
||||
{
|
||||
- MEM_LOG("Error while installing new mfn %lx", op.arg1.mfn);
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ else if ( rc != -EAGAIN )
|
||||
+ MEM_LOG("Error while installing new mfn %lx",
|
||||
+ op.arg1.mfn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
|
||||
curr->arch.guest_table_user = pagetable_from_pfn(op.arg1.mfn);
|
||||
|
||||
if ( old_mfn != 0 )
|
||||
{
|
||||
+ struct page_info *page = mfn_to_page(old_mfn);
|
||||
+
|
||||
if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(old_mfn));
|
||||
+ put_page(page);
|
||||
else
|
||||
- put_page_and_type(mfn_to_page(old_mfn));
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ okay = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
break;
|
@ -1,200 +0,0 @@
|
||||
x86: make vcpu_reset() preemptible
|
||||
|
||||
... as dropping the old page tables may take significant amounts of
|
||||
time.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domain.c
|
||||
+++ b/xen/arch/x86/domain.c
|
||||
@@ -1051,17 +1051,16 @@ int arch_set_info_guest(
|
||||
#undef c
|
||||
}
|
||||
|
||||
-void arch_vcpu_reset(struct vcpu *v)
|
||||
+int arch_vcpu_reset(struct vcpu *v)
|
||||
{
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
{
|
||||
destroy_gdt(v);
|
||||
- vcpu_destroy_pagetables(v, 0);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- vcpu_end_shutdown_deferral(v);
|
||||
+ return vcpu_destroy_pagetables(v);
|
||||
}
|
||||
+
|
||||
+ vcpu_end_shutdown_deferral(v);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2085,7 +2084,7 @@ int domain_relinquish_resources(struct d
|
||||
/* Drop the in-use references to page-table bases. */
|
||||
for_each_vcpu ( d, v )
|
||||
{
|
||||
- ret = vcpu_destroy_pagetables(v, 1);
|
||||
+ ret = vcpu_destroy_pagetables(v);
|
||||
if ( ret )
|
||||
return ret;
|
||||
}
|
||||
--- a/xen/arch/x86/hvm/hvm.c
|
||||
+++ b/xen/arch/x86/hvm/hvm.c
|
||||
@@ -3509,8 +3509,11 @@ static void hvm_s3_suspend(struct domain
|
||||
|
||||
for_each_vcpu ( d, v )
|
||||
{
|
||||
+ int rc;
|
||||
+
|
||||
vlapic_reset(vcpu_vlapic(v));
|
||||
- vcpu_reset(v);
|
||||
+ rc = vcpu_reset(v);
|
||||
+ ASSERT(!rc);
|
||||
}
|
||||
|
||||
vpic_reset(d);
|
||||
--- a/xen/arch/x86/hvm/vlapic.c
|
||||
+++ b/xen/arch/x86/hvm/vlapic.c
|
||||
@@ -252,10 +252,13 @@ static void vlapic_init_sipi_action(unsi
|
||||
{
|
||||
case APIC_DM_INIT: {
|
||||
bool_t fpu_initialised;
|
||||
+ int rc;
|
||||
+
|
||||
domain_lock(target->domain);
|
||||
/* Reset necessary VCPU state. This does not include FPU state. */
|
||||
fpu_initialised = target->fpu_initialised;
|
||||
- vcpu_reset(target);
|
||||
+ rc = vcpu_reset(target);
|
||||
+ ASSERT(!rc);
|
||||
target->fpu_initialised = fpu_initialised;
|
||||
vlapic_reset(vcpu_vlapic(target));
|
||||
domain_unlock(target->domain);
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -2827,7 +2827,7 @@ static int put_old_guest_table(struct vc
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int vcpu_destroy_pagetables(struct vcpu *v, bool_t preemptible)
|
||||
+int vcpu_destroy_pagetables(struct vcpu *v)
|
||||
{
|
||||
unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
struct page_info *page;
|
||||
@@ -2847,7 +2847,7 @@ int vcpu_destroy_pagetables(struct vcpu
|
||||
if ( paging_mode_refcounts(v->domain) )
|
||||
put_page(page);
|
||||
else
|
||||
- rc = put_page_and_type_preemptible(page, preemptible);
|
||||
+ rc = put_page_and_type_preemptible(page, 1);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
@@ -2873,7 +2873,7 @@ int vcpu_destroy_pagetables(struct vcpu
|
||||
if ( paging_mode_refcounts(v->domain) )
|
||||
put_page(page);
|
||||
else
|
||||
- rc = put_page_and_type_preemptible(page, preemptible);
|
||||
+ rc = put_page_and_type_preemptible(page, 1);
|
||||
}
|
||||
if ( !rc )
|
||||
v->arch.guest_table_user = pagetable_null();
|
||||
--- a/xen/common/domain.c
|
||||
+++ b/xen/common/domain.c
|
||||
@@ -779,14 +779,18 @@ void domain_unpause_by_systemcontroller(
|
||||
domain_unpause(d);
|
||||
}
|
||||
|
||||
-void vcpu_reset(struct vcpu *v)
|
||||
+int vcpu_reset(struct vcpu *v)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
+ int rc;
|
||||
|
||||
vcpu_pause(v);
|
||||
domain_lock(d);
|
||||
|
||||
- arch_vcpu_reset(v);
|
||||
+ set_bit(_VPF_in_reset, &v->pause_flags);
|
||||
+ rc = arch_vcpu_reset(v);
|
||||
+ if ( rc )
|
||||
+ goto out_unlock;
|
||||
|
||||
set_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
@@ -802,9 +806,13 @@ void vcpu_reset(struct vcpu *v)
|
||||
#endif
|
||||
cpumask_clear(v->cpu_affinity_tmp);
|
||||
clear_bit(_VPF_blocked, &v->pause_flags);
|
||||
+ clear_bit(_VPF_in_reset, &v->pause_flags);
|
||||
|
||||
+ out_unlock:
|
||||
domain_unlock(v->domain);
|
||||
vcpu_unpause(v);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -306,8 +306,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
|
||||
|
||||
if ( guest_handle_is_null(op->u.vcpucontext.ctxt) )
|
||||
{
|
||||
- vcpu_reset(v);
|
||||
- ret = 0;
|
||||
+ ret = vcpu_reset(v);
|
||||
+ if ( ret == -EAGAIN )
|
||||
+ ret = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_domctl, "h", u_domctl);
|
||||
goto svc_out;
|
||||
}
|
||||
|
||||
--- a/xen/include/asm-x86/mm.h
|
||||
+++ b/xen/include/asm-x86/mm.h
|
||||
@@ -605,7 +605,7 @@ void audit_domains(void);
|
||||
int new_guest_cr3(unsigned long pfn);
|
||||
void make_cr3(struct vcpu *v, unsigned long mfn);
|
||||
void update_cr3(struct vcpu *v);
|
||||
-int vcpu_destroy_pagetables(struct vcpu *, bool_t preemptible);
|
||||
+int vcpu_destroy_pagetables(struct vcpu *);
|
||||
void propagate_page_fault(unsigned long addr, u16 error_code);
|
||||
void *do_page_walk(struct vcpu *v, unsigned long addr);
|
||||
|
||||
--- a/xen/include/xen/domain.h
|
||||
+++ b/xen/include/xen/domain.h
|
||||
@@ -13,7 +13,7 @@ typedef union {
|
||||
struct vcpu *alloc_vcpu(
|
||||
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
|
||||
struct vcpu *alloc_dom0_vcpu0(void);
|
||||
-void vcpu_reset(struct vcpu *v);
|
||||
+int vcpu_reset(struct vcpu *);
|
||||
|
||||
struct xen_domctl_getdomaininfo;
|
||||
void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info);
|
||||
@@ -67,7 +67,7 @@ void arch_dump_vcpu_info(struct vcpu *v)
|
||||
|
||||
void arch_dump_domain_info(struct domain *d);
|
||||
|
||||
-void arch_vcpu_reset(struct vcpu *v);
|
||||
+int arch_vcpu_reset(struct vcpu *);
|
||||
|
||||
extern spinlock_t vcpu_alloc_lock;
|
||||
bool_t domctl_lock_acquire(void);
|
||||
--- a/xen/include/xen/sched.h
|
||||
+++ b/xen/include/xen/sched.h
|
||||
@@ -644,6 +644,9 @@ static inline struct domain *next_domain
|
||||
/* VCPU is blocked due to missing mem_sharing ring. */
|
||||
#define _VPF_mem_sharing 6
|
||||
#define VPF_mem_sharing (1UL<<_VPF_mem_sharing)
|
||||
+ /* VCPU is being reset. */
|
||||
+#define _VPF_in_reset 7
|
||||
+#define VPF_in_reset (1UL<<_VPF_in_reset)
|
||||
|
||||
static inline int vcpu_runnable(struct vcpu *v)
|
||||
{
|
@ -1,204 +0,0 @@
|
||||
x86: make arch_set_info_guest() preemptible
|
||||
|
||||
.. as the root page table validation (and the dropping of an eventual
|
||||
old one) can require meaningful amounts of time.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domain.c
|
||||
+++ b/xen/arch/x86/domain.c
|
||||
@@ -858,6 +858,9 @@ int arch_set_info_guest(
|
||||
|
||||
if ( !v->is_initialised )
|
||||
{
|
||||
+ if ( !compat && !(flags & VGCF_in_kernel) && !c.nat->ctrlreg[1] )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
v->arch.pv_vcpu.ldt_base = c(ldt_base);
|
||||
v->arch.pv_vcpu.ldt_ents = c(ldt_ents);
|
||||
}
|
||||
@@ -955,24 +958,44 @@ int arch_set_info_guest(
|
||||
if ( rc != 0 )
|
||||
return rc;
|
||||
|
||||
+ set_bit(_VPF_in_reset, &v->pause_flags);
|
||||
+
|
||||
if ( !compat )
|
||||
- {
|
||||
cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]);
|
||||
- cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
|
||||
-
|
||||
- if ( !cr3_page )
|
||||
- {
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- if ( !paging_mode_refcounts(d)
|
||||
- && !get_page_type(cr3_page, PGT_base_page_table) )
|
||||
- {
|
||||
- put_page(cr3_page);
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ else
|
||||
+ cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
|
||||
+#endif
|
||||
+ cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
|
||||
|
||||
+ if ( !cr3_page )
|
||||
+ rc = -EINVAL;
|
||||
+ else if ( paging_mode_refcounts(d) )
|
||||
+ /* nothing */;
|
||||
+ else if ( cr3_page == v->arch.old_guest_table )
|
||||
+ {
|
||||
+ v->arch.old_guest_table = NULL;
|
||||
+ put_page(cr3_page);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /*
|
||||
+ * Since v->arch.guest_table{,_user} are both NULL, this effectively
|
||||
+ * is just a call to put_old_guest_table().
|
||||
+ */
|
||||
+ if ( !compat )
|
||||
+ rc = vcpu_destroy_pagetables(v);
|
||||
+ if ( !rc )
|
||||
+ rc = get_page_type_preemptible(cr3_page,
|
||||
+ !compat ? PGT_root_page_table
|
||||
+ : PGT_l3_page_table);
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ }
|
||||
+ if ( rc )
|
||||
+ /* handled below */;
|
||||
+ else if ( !compat )
|
||||
+ {
|
||||
v->arch.guest_table = pagetable_from_page(cr3_page);
|
||||
#ifdef __x86_64__
|
||||
if ( c.nat->ctrlreg[1] )
|
||||
@@ -980,56 +1003,44 @@ int arch_set_info_guest(
|
||||
cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[1]);
|
||||
cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
|
||||
|
||||
- if ( !cr3_page ||
|
||||
- (!paging_mode_refcounts(d)
|
||||
- && !get_page_type(cr3_page, PGT_base_page_table)) )
|
||||
+ if ( !cr3_page )
|
||||
+ rc = -EINVAL;
|
||||
+ else if ( !paging_mode_refcounts(d) )
|
||||
{
|
||||
- if (cr3_page)
|
||||
- put_page(cr3_page);
|
||||
- cr3_page = pagetable_get_page(v->arch.guest_table);
|
||||
- v->arch.guest_table = pagetable_null();
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(cr3_page);
|
||||
- else
|
||||
- put_page_and_type(cr3_page);
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
+ rc = get_page_type_preemptible(cr3_page, PGT_root_page_table);
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ v->arch.old_guest_table =
|
||||
+ pagetable_get_page(v->arch.guest_table);
|
||||
+ v->arch.guest_table = pagetable_null();
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- v->arch.guest_table_user = pagetable_from_page(cr3_page);
|
||||
- }
|
||||
- else if ( !(flags & VGCF_in_kernel) )
|
||||
- {
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
+ if ( !rc )
|
||||
+ v->arch.guest_table_user = pagetable_from_page(cr3_page);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
l4_pgentry_t *l4tab;
|
||||
|
||||
- cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
|
||||
- cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
|
||||
-
|
||||
- if ( !cr3_page)
|
||||
- {
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (!paging_mode_refcounts(d)
|
||||
- && !get_page_type(cr3_page, PGT_l3_page_table) )
|
||||
- {
|
||||
- put_page(cr3_page);
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
|
||||
*l4tab = l4e_from_pfn(page_to_mfn(cr3_page),
|
||||
_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
|
||||
#endif
|
||||
}
|
||||
+ if ( rc )
|
||||
+ {
|
||||
+ if ( cr3_page )
|
||||
+ put_page(cr3_page);
|
||||
+ destroy_gdt(v);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ clear_bit(_VPF_in_reset, &v->pause_flags);
|
||||
|
||||
if ( v->vcpu_id == 0 )
|
||||
update_domain_wallclock_time(d);
|
||||
--- a/xen/common/compat/domain.c
|
||||
+++ b/xen/common/compat/domain.c
|
||||
@@ -50,6 +50,10 @@ int compat_vcpu_op(int cmd, int vcpuid,
|
||||
rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt);
|
||||
domain_unlock(d);
|
||||
|
||||
+ if ( rc == -EAGAIN )
|
||||
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
|
||||
+ cmd, vcpuid, arg);
|
||||
+
|
||||
xfree(cmp_ctxt);
|
||||
break;
|
||||
}
|
||||
--- a/xen/common/domain.c
|
||||
+++ b/xen/common/domain.c
|
||||
@@ -849,6 +849,11 @@ long do_vcpu_op(int cmd, int vcpuid, XEN
|
||||
domain_unlock(d);
|
||||
|
||||
free_vcpu_guest_context(ctxt);
|
||||
+
|
||||
+ if ( rc == -EAGAIN )
|
||||
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
|
||||
+ cmd, vcpuid, arg);
|
||||
+
|
||||
break;
|
||||
|
||||
case VCPUOP_up: {
|
||||
--- a/xen/common/domctl.c
|
||||
+++ b/xen/common/domctl.c
|
||||
@@ -338,6 +338,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
|
||||
domain_pause(d);
|
||||
ret = arch_set_info_guest(v, c);
|
||||
domain_unpause(d);
|
||||
+
|
||||
+ if ( ret == -EAGAIN )
|
||||
+ ret = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_domctl, "h", u_domctl);
|
||||
}
|
||||
|
||||
svc_out:
|
@ -1,127 +0,0 @@
|
||||
x86: make page table unpinning preemptible
|
||||
|
||||
... as it may take significant amounts of time.
|
||||
|
||||
Since we can't re-invoke the operation in a second attempt, the
|
||||
continuation logic must be slightly tweaked so that we make sure
|
||||
do_mmuext_op() gets run one more time even when the preempted unpin
|
||||
operation was the last one in a batch.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -3123,6 +3123,14 @@ long do_mmuext_op(
|
||||
return rc;
|
||||
}
|
||||
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(uops)) )
|
||||
+ {
|
||||
+ /* See the curr->arch.old_guest_table related
|
||||
+ * hypercall_create_continuation() below. */
|
||||
+ return (int)foreigndom;
|
||||
+ }
|
||||
+
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
count &= ~MMU_UPDATE_PREEMPTED;
|
||||
@@ -3146,7 +3154,7 @@ long do_mmuext_op(
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
- if ( hypercall_preempt_check() )
|
||||
+ if ( curr->arch.old_guest_table || hypercall_preempt_check() )
|
||||
{
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
@@ -3266,7 +3274,17 @@ long do_mmuext_op(
|
||||
break;
|
||||
}
|
||||
|
||||
- put_page_and_type(page);
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
put_page(page);
|
||||
|
||||
/* A page is dirtied when its pin status is cleared. */
|
||||
@@ -3587,9 +3605,27 @@ long do_mmuext_op(
|
||||
}
|
||||
|
||||
if ( rc == -EAGAIN )
|
||||
+ {
|
||||
+ ASSERT(i < count);
|
||||
rc = hypercall_create_continuation(
|
||||
__HYPERVISOR_mmuext_op, "hihi",
|
||||
uops, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
|
||||
+ }
|
||||
+ else if ( curr->arch.old_guest_table )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(void) null;
|
||||
+
|
||||
+ ASSERT(rc || i == count);
|
||||
+ set_xen_guest_handle(null, NULL);
|
||||
+ /*
|
||||
+ * In order to have a way to communicate the final return value to
|
||||
+ * our continuation, we pass this in place of "foreigndom", building
|
||||
+ * on the fact that this argument isn't needed anymore.
|
||||
+ */
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmuext_op, "hihi", null,
|
||||
+ MMU_UPDATE_PREEMPTED, null, rc);
|
||||
+ }
|
||||
|
||||
put_pg_owner(pg_owner);
|
||||
|
||||
--- a/xen/arch/x86/x86_64/compat/mm.c
|
||||
+++ b/xen/arch/x86/x86_64/compat/mm.c
|
||||
@@ -268,6 +268,13 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
int rc = 0;
|
||||
XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
|
||||
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(cmp_uops)) )
|
||||
+ {
|
||||
+ set_xen_guest_handle(nat_ops, NULL);
|
||||
+ return do_mmuext_op(nat_ops, count, pdone, foreigndom);
|
||||
+ }
|
||||
+
|
||||
preempt_mask = count & MMU_UPDATE_PREEMPTED;
|
||||
count ^= preempt_mask;
|
||||
|
||||
@@ -370,12 +377,18 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
guest_handle_add_offset(nat_ops, i - left);
|
||||
guest_handle_subtract_offset(cmp_uops, left);
|
||||
left = 1;
|
||||
- BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
|
||||
- BUG_ON(left != arg1);
|
||||
- if (!test_bit(_MCSF_in_multicall, &mcs->flags))
|
||||
- regs->_ecx += count - i;
|
||||
+ if ( arg1 != MMU_UPDATE_PREEMPTED )
|
||||
+ {
|
||||
+ BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops,
|
||||
+ cmp_uops));
|
||||
+ if ( !test_bit(_MCSF_in_multicall, &mcs->flags) )
|
||||
+ regs->_ecx += count - i;
|
||||
+ else
|
||||
+ mcs->compat_call.args[1] += count - i;
|
||||
+ }
|
||||
else
|
||||
- mcs->compat_call.args[1] += count - i;
|
||||
+ BUG_ON(hypercall_xlat_continuation(&left, 0));
|
||||
+ BUG_ON(left != arg1);
|
||||
}
|
||||
else
|
||||
BUG_ON(err > 0);
|
@ -1,255 +0,0 @@
|
||||
x86: make page table handling error paths preemptible
|
||||
|
||||
... as they may take significant amounts of time.
|
||||
|
||||
This requires cloning the tweaked continuation logic from
|
||||
do_mmuext_op() to do_mmu_update().
|
||||
|
||||
Note that in mod_l[34]_entry() a negative "preemptible" value gets
|
||||
passed to put_page_from_l[34]e() now, telling the callee to store the
|
||||
respective page in current->arch.old_guest_table (for a hypercall
|
||||
continuation to pick up), rather than carrying out the put right away.
|
||||
This is going to be made a little more explicit by a subsequent cleanup
|
||||
patch.
|
||||
|
||||
This is part of CVE-2013-1918 / XSA-45.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -1241,7 +1241,16 @@ static int put_page_from_l3e(l3_pgentry_
|
||||
#endif
|
||||
|
||||
if ( unlikely(partial > 0) )
|
||||
+ {
|
||||
+ ASSERT(preemptible >= 0);
|
||||
return __put_page_type(l3e_get_page(l3e), preemptible);
|
||||
+ }
|
||||
+
|
||||
+ if ( preemptible < 0 )
|
||||
+ {
|
||||
+ current->arch.old_guest_table = l3e_get_page(l3e);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
return put_page_and_type_preemptible(l3e_get_page(l3e), preemptible);
|
||||
}
|
||||
@@ -1254,7 +1263,17 @@ static int put_page_from_l4e(l4_pgentry_
|
||||
(l4e_get_pfn(l4e) != pfn) )
|
||||
{
|
||||
if ( unlikely(partial > 0) )
|
||||
+ {
|
||||
+ ASSERT(preemptible >= 0);
|
||||
return __put_page_type(l4e_get_page(l4e), preemptible);
|
||||
+ }
|
||||
+
|
||||
+ if ( preemptible < 0 )
|
||||
+ {
|
||||
+ current->arch.old_guest_table = l4e_get_page(l4e);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
return put_page_and_type_preemptible(l4e_get_page(l4e), preemptible);
|
||||
}
|
||||
return 1;
|
||||
@@ -1549,12 +1568,17 @@ static int alloc_l3_table(struct page_in
|
||||
if ( rc < 0 && rc != -EAGAIN && rc != -EINTR )
|
||||
{
|
||||
MEM_LOG("Failure in alloc_l3_table: entry %d", i);
|
||||
+ if ( i )
|
||||
+ {
|
||||
+ page->nr_validated_ptes = i;
|
||||
+ page->partial_pte = 0;
|
||||
+ current->arch.old_guest_table = page;
|
||||
+ }
|
||||
while ( i-- > 0 )
|
||||
{
|
||||
if ( !is_guest_l3_slot(i) )
|
||||
continue;
|
||||
unadjust_guest_l3e(pl3e[i], d);
|
||||
- put_page_from_l3e(pl3e[i], pfn, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,22 +1608,24 @@ static int alloc_l4_table(struct page_in
|
||||
page->nr_validated_ptes = i;
|
||||
page->partial_pte = partial ?: 1;
|
||||
}
|
||||
- else if ( rc == -EINTR )
|
||||
+ else if ( rc < 0 )
|
||||
{
|
||||
+ if ( rc != -EINTR )
|
||||
+ MEM_LOG("Failure in alloc_l4_table: entry %d", i);
|
||||
if ( i )
|
||||
{
|
||||
page->nr_validated_ptes = i;
|
||||
page->partial_pte = 0;
|
||||
- rc = -EAGAIN;
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ else
|
||||
+ {
|
||||
+ if ( current->arch.old_guest_table )
|
||||
+ page->nr_validated_ptes++;
|
||||
+ current->arch.old_guest_table = page;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- else if ( rc < 0 )
|
||||
- {
|
||||
- MEM_LOG("Failure in alloc_l4_table: entry %d", i);
|
||||
- while ( i-- > 0 )
|
||||
- if ( is_guest_l4_slot(d, i) )
|
||||
- put_page_from_l4e(pl4e[i], pfn, 0, 0);
|
||||
- }
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
@@ -2047,7 +2073,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
|
||||
pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);
|
||||
}
|
||||
|
||||
- put_page_from_l3e(ol3e, pfn, 0, 0);
|
||||
+ put_page_from_l3e(ol3e, pfn, 0, -preemptible);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2110,7 +2136,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- put_page_from_l4e(ol4e, pfn, 0, 0);
|
||||
+ put_page_from_l4e(ol4e, pfn, 0, -preemptible);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2268,7 +2294,15 @@ static int alloc_page_type(struct page_i
|
||||
PRtype_info ": caf=%08lx taf=%" PRtype_info,
|
||||
page_to_mfn(page), get_gpfn_from_mfn(page_to_mfn(page)),
|
||||
type, page->count_info, page->u.inuse.type_info);
|
||||
- page->u.inuse.type_info = 0;
|
||||
+ if ( page != current->arch.old_guest_table )
|
||||
+ page->u.inuse.type_info = 0;
|
||||
+ else
|
||||
+ {
|
||||
+ ASSERT((page->u.inuse.type_info &
|
||||
+ (PGT_count_mask | PGT_validated)) == 1);
|
||||
+ get_page_light(page);
|
||||
+ page->u.inuse.type_info |= PGT_partial;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3218,21 +3252,17 @@ long do_mmuext_op(
|
||||
}
|
||||
|
||||
if ( (rc = xsm_memory_pin_page(d, pg_owner, page)) != 0 )
|
||||
- {
|
||||
- put_page_and_type(page);
|
||||
okay = 0;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if ( unlikely(test_and_set_bit(_PGT_pinned,
|
||||
- &page->u.inuse.type_info)) )
|
||||
+ else if ( unlikely(test_and_set_bit(_PGT_pinned,
|
||||
+ &page->u.inuse.type_info)) )
|
||||
{
|
||||
MEM_LOG("Mfn %lx already pinned", page_to_mfn(page));
|
||||
- put_page_and_type(page);
|
||||
okay = 0;
|
||||
- break;
|
||||
}
|
||||
|
||||
+ if ( unlikely(!okay) )
|
||||
+ goto pin_drop;
|
||||
+
|
||||
/* A page is dirtied when its pin status is set. */
|
||||
paging_mark_dirty(pg_owner, page_to_mfn(page));
|
||||
|
||||
@@ -3246,7 +3276,13 @@ long do_mmuext_op(
|
||||
&page->u.inuse.type_info));
|
||||
spin_unlock(&pg_owner->page_alloc_lock);
|
||||
if ( drop_ref )
|
||||
- put_page_and_type(page);
|
||||
+ {
|
||||
+ pin_drop:
|
||||
+ if ( type == PGT_l1_page_table )
|
||||
+ put_page_and_type(page);
|
||||
+ else
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ }
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -3652,11 +3688,28 @@ long do_mmu_update(
|
||||
void *va;
|
||||
unsigned long gpfn, gmfn, mfn;
|
||||
struct page_info *page;
|
||||
- int rc = 0, i = 0;
|
||||
- unsigned int cmd, done = 0, pt_dom;
|
||||
- struct vcpu *v = current;
|
||||
+ unsigned int cmd, i = 0, done = 0, pt_dom;
|
||||
+ struct vcpu *curr = current, *v = curr;
|
||||
struct domain *d = v->domain, *pt_owner = d, *pg_owner;
|
||||
struct domain_mmap_cache mapcache;
|
||||
+ int rc = put_old_guest_table(curr);
|
||||
+
|
||||
+ if ( unlikely(rc) )
|
||||
+ {
|
||||
+ if ( likely(rc == -EAGAIN) )
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmu_update, "hihi", ureqs, count, pdone,
|
||||
+ foreigndom);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(ureqs)) )
|
||||
+ {
|
||||
+ /* See the curr->arch.old_guest_table related
|
||||
+ * hypercall_create_continuation() below. */
|
||||
+ return (int)foreigndom;
|
||||
+ }
|
||||
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
@@ -3705,7 +3758,7 @@ long do_mmu_update(
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
- if ( hypercall_preempt_check() )
|
||||
+ if ( curr->arch.old_guest_table || hypercall_preempt_check() )
|
||||
{
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
@@ -3886,9 +3939,27 @@ long do_mmu_update(
|
||||
}
|
||||
|
||||
if ( rc == -EAGAIN )
|
||||
+ {
|
||||
+ ASSERT(i < count);
|
||||
rc = hypercall_create_continuation(
|
||||
__HYPERVISOR_mmu_update, "hihi",
|
||||
ureqs, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
|
||||
+ }
|
||||
+ else if ( curr->arch.old_guest_table )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(void) null;
|
||||
+
|
||||
+ ASSERT(rc || i == count);
|
||||
+ set_xen_guest_handle(null, NULL);
|
||||
+ /*
|
||||
+ * In order to have a way to communicate the final return value to
|
||||
+ * our continuation, we pass this in place of "foreigndom", building
|
||||
+ * on the fact that this argument isn't needed anymore.
|
||||
+ */
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmu_update, "hihi", null,
|
||||
+ MMU_UPDATE_PREEMPTED, null, rc);
|
||||
+ }
|
||||
|
||||
put_pg_owner(pg_owner);
|
||||
|
@ -1,127 +0,0 @@
|
||||
x86/xsave: fix information leak on AMD CPUs
|
||||
|
||||
Just like for FXSAVE/FXRSTOR, XSAVE/XRSTOR also don't save/restore the
|
||||
last instruction and operand pointers as well as the last opcode if
|
||||
there's no pending unmasked exception (see CVE-2006-1056 and commit
|
||||
9747:4d667a139318).
|
||||
|
||||
While the FXSR solution sits in the save path, I prefer to have this in
|
||||
the restore path because there the handling is simpler (namely in the
|
||||
context of the pending changes to properly save the selector values for
|
||||
32-bit guest code).
|
||||
|
||||
Also this is using FFREE instead of EMMS, as it doesn't seem unlikely
|
||||
that in the future we may see CPUs with x87 and SSE/AVX but no MMX
|
||||
support. The goal here anyway is just to avoid an FPU stack overflow.
|
||||
I would have preferred to use FFREEP instead of FFREE (freeing two
|
||||
stack slots at once), but AMD doesn't document that instruction.
|
||||
|
||||
This is CVE-2013-2076 / XSA-52.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/xstate.c
|
||||
+++ b/xen/arch/x86/xstate.c
|
||||
@@ -78,6 +78,21 @@ void xrstor(struct vcpu *v, uint64_t mas
|
||||
|
||||
struct xsave_struct *ptr = v->arch.xsave_area;
|
||||
|
||||
+ /*
|
||||
+ * AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
|
||||
+ * is pending. Clear the x87 state here by setting it to fixed
|
||||
+ * values. The hypervisor data segment can be sometimes 0 and
|
||||
+ * sometimes new user value. Both should be ok. Use the FPU saved
|
||||
+ * data block as a safe address because it should be in L1.
|
||||
+ */
|
||||
+ if ( (mask & ptr->xsave_hdr.xstate_bv & XSTATE_FP) &&
|
||||
+ !(ptr->fpu_sse.fsw & 0x0080) &&
|
||||
+ boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
|
||||
+ asm volatile ( "fnclex\n\t" /* clear exceptions */
|
||||
+ "ffree %%st(7)\n\t" /* clear stack tag */
|
||||
+ "fildl %0" /* load to clear state */
|
||||
+ : : "m" (ptr->fpu_sse) );
|
||||
+
|
||||
asm volatile (
|
||||
".byte " REX_PREFIX "0x0f,0xae,0x2f"
|
||||
:
|
||||
#x86/xsave: recover from faults on XRSTOR
|
||||
#
|
||||
#Just like FXRSTOR, XRSTOR can raise #GP if bad content is being passed
|
||||
#to it in the memory block (i.e. aspects not under the control of the
|
||||
#hypervisor, other than e.g. proper alignment of the block).
|
||||
#
|
||||
#Also correct the comment explaining why FXRSTOR needs exception
|
||||
#recovery code to not wrongly state that this can only be a result of
|
||||
#the control tools passing a bad image.
|
||||
#
|
||||
#This is CVE-2013-2077 / XSA-53.
|
||||
#
|
||||
#Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
#
|
||||
--- a/xen/arch/x86/i387.c
|
||||
+++ b/xen/arch/x86/i387.c
|
||||
@@ -53,7 +53,7 @@ static inline void fpu_fxrstor(struct vc
|
||||
/*
|
||||
* FXRSTOR can fault if passed a corrupted data block. We handle this
|
||||
* possibility, which may occur if the block was passed to us by control
|
||||
- * tools, by silently clearing the block.
|
||||
+ * tools or through VCPUOP_initialise, by silently clearing the block.
|
||||
*/
|
||||
asm volatile (
|
||||
#ifdef __i386__
|
||||
--- a/xen/arch/x86/xstate.c
|
||||
+++ b/xen/arch/x86/xstate.c
|
||||
@@ -93,10 +93,25 @@ void xrstor(struct vcpu *v, uint64_t mas
|
||||
"fildl %0" /* load to clear state */
|
||||
: : "m" (ptr->fpu_sse) );
|
||||
|
||||
- asm volatile (
|
||||
- ".byte " REX_PREFIX "0x0f,0xae,0x2f"
|
||||
- :
|
||||
- : "m" (*ptr), "a" (lmask), "d" (hmask), "D"(ptr) );
|
||||
+ /*
|
||||
+ * XRSTOR can fault if passed a corrupted data block. We handle this
|
||||
+ * possibility, which may occur if the block was passed to us by control
|
||||
+ * tools or through VCPUOP_initialise, by silently clearing the block.
|
||||
+ */
|
||||
+ asm volatile ( "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
|
||||
+ ".section .fixup,\"ax\"\n"
|
||||
+ "2: mov %5,%%ecx \n"
|
||||
+ " xor %1,%1 \n"
|
||||
+ " rep stosb \n"
|
||||
+ " lea %2,%0 \n"
|
||||
+ " mov %3,%1 \n"
|
||||
+ " jmp 1b \n"
|
||||
+ ".previous \n"
|
||||
+ _ASM_EXTABLE(1b, 2b)
|
||||
+ : "+&D" (ptr), "+&a" (lmask)
|
||||
+ : "m" (*ptr), "g" (lmask), "d" (hmask),
|
||||
+ "m" (xsave_cntxt_size)
|
||||
+ : "ecx" );
|
||||
}
|
||||
|
||||
bool_t xsave_enabled(const struct vcpu *v)
|
||||
#x86/xsave: properly check guest input to XSETBV
|
||||
#
|
||||
#Other than the HVM emulation path, the PV case so far failed to check
|
||||
#that YMM state requires SSE state to be enabled, allowing for a #GP to
|
||||
#occur upon passing the inputs to XSETBV inside the hypervisor.
|
||||
#
|
||||
#This is CVE-2013-2078 / XSA-54.
|
||||
#
|
||||
#Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
#
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -2205,6 +2205,11 @@ static int emulate_privileged_op(struct
|
||||
if ( !(new_xfeature & XSTATE_FP) || (new_xfeature & ~xfeature_mask) )
|
||||
goto fail;
|
||||
|
||||
+ /* YMM state takes SSE state as prerequisite. */
|
||||
+ if ( (xfeature_mask & new_xfeature & XSTATE_YMM) &&
|
||||
+ !(new_xfeature & XSTATE_SSE) )
|
||||
+ goto fail;
|
||||
+
|
||||
v->arch.xcr0 = new_xfeature;
|
||||
v->arch.xcr0_accum |= new_xfeature;
|
||||
set_xcr0(new_xfeature);
|
@ -1,130 +0,0 @@
|
||||
x86: fix page refcount handling in page table pin error path
|
||||
|
||||
In the original patch 7 of the series addressing XSA-45 I mistakenly
|
||||
took the addition of the call to get_page_light() in alloc_page_type()
|
||||
to cover two decrements that would happen: One for the PGT_partial bit
|
||||
that is getting set along with the call, and the other for the page
|
||||
reference the caller hold (and would be dropping on its error path).
|
||||
But of course the additional page reference is tied to the PGT_partial
|
||||
bit, and hence any caller of a function that may leave
|
||||
->arch.old_guest_table non-NULL for error cleanup purposes has to make
|
||||
sure a respective page reference gets retained.
|
||||
|
||||
Similar issues were then also spotted elsewhere: In effect all callers
|
||||
of get_page_type_preemptible() need to deal with errors in similar
|
||||
ways. To make sure error handling can work this way without leaking
|
||||
page references, a respective assertion gets added to that function.
|
||||
|
||||
This is CVE-2013-1432 / XSA-58.
|
||||
|
||||
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domain.c
|
||||
+++ b/xen/arch/x86/domain.c
|
||||
@@ -941,6 +941,10 @@ int arch_set_info_guest(
|
||||
if ( v->vcpu_id == 0 )
|
||||
d->vm_assist = c(vm_assist);
|
||||
|
||||
+ rc = put_old_guest_table(current);
|
||||
+ if ( rc )
|
||||
+ return rc;
|
||||
+
|
||||
if ( !compat )
|
||||
rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
|
||||
#ifdef CONFIG_COMPAT
|
||||
@@ -980,18 +984,24 @@ int arch_set_info_guest(
|
||||
}
|
||||
else
|
||||
{
|
||||
- /*
|
||||
- * Since v->arch.guest_table{,_user} are both NULL, this effectively
|
||||
- * is just a call to put_old_guest_table().
|
||||
- */
|
||||
if ( !compat )
|
||||
- rc = vcpu_destroy_pagetables(v);
|
||||
+ rc = put_old_guest_table(v);
|
||||
if ( !rc )
|
||||
rc = get_page_type_preemptible(cr3_page,
|
||||
!compat ? PGT_root_page_table
|
||||
: PGT_l3_page_table);
|
||||
- if ( rc == -EINTR )
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ default:
|
||||
+ if ( cr3_page == current->arch.old_guest_table )
|
||||
+ cr3_page = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
if ( rc )
|
||||
/* handled below */;
|
||||
@@ -1018,6 +1028,11 @@ int arch_set_info_guest(
|
||||
pagetable_get_page(v->arch.guest_table);
|
||||
v->arch.guest_table = pagetable_null();
|
||||
break;
|
||||
+ default:
|
||||
+ if ( cr3_page == current->arch.old_guest_table )
|
||||
+ cr3_page = NULL;
|
||||
+ case 0:
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
if ( !rc )
|
||||
--- a/xen/arch/x86/mm.c
|
||||
+++ b/xen/arch/x86/mm.c
|
||||
@@ -718,7 +718,8 @@ static int get_page_and_type_from_pagenr
|
||||
get_page_type_preemptible(page, type) :
|
||||
(get_page_type(page, type) ? 0 : -EINVAL));
|
||||
|
||||
- if ( unlikely(rc) && partial >= 0 )
|
||||
+ if ( unlikely(rc) && partial >= 0 &&
|
||||
+ (!preemptible || page != current->arch.old_guest_table) )
|
||||
put_page(page);
|
||||
|
||||
return rc;
|
||||
@@ -2638,6 +2639,7 @@ int put_page_type_preemptible(struct pag
|
||||
|
||||
int get_page_type_preemptible(struct page_info *page, unsigned long type)
|
||||
{
|
||||
+ ASSERT(!current->arch.old_guest_table);
|
||||
return __get_page_type(page, type, 1);
|
||||
}
|
||||
|
||||
@@ -2848,7 +2850,7 @@ static void put_superpage(unsigned long
|
||||
|
||||
#endif
|
||||
|
||||
-static int put_old_guest_table(struct vcpu *v)
|
||||
+int put_old_guest_table(struct vcpu *v)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -3253,7 +3255,8 @@ long do_mmuext_op(
|
||||
rc = -EAGAIN;
|
||||
else if ( rc != -EAGAIN )
|
||||
MEM_LOG("Error while pinning mfn %lx", page_to_mfn(page));
|
||||
- put_page(page);
|
||||
+ if ( page != curr->arch.old_guest_table )
|
||||
+ put_page(page);
|
||||
break;
|
||||
}
|
||||
|
||||
--- a/xen/include/asm-x86/mm.h
|
||||
+++ b/xen/include/asm-x86/mm.h
|
||||
@@ -374,6 +374,7 @@ void put_page_type(struct page_info *pag
|
||||
int get_page_type(struct page_info *page, unsigned long type);
|
||||
int put_page_type_preemptible(struct page_info *page);
|
||||
int get_page_type_preemptible(struct page_info *page, unsigned long type);
|
||||
+int put_old_guest_table(struct vcpu *);
|
||||
int get_page_from_l1e(
|
||||
l1_pgentry_t l1e, struct domain *l1e_owner, struct domain *pg_owner);
|
||||
void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner);
|
||||
|
@ -1,41 +0,0 @@
|
||||
x86: restrict XEN_DOMCTL_getmemlist
|
||||
|
||||
Coverity ID 1055652
|
||||
|
||||
(See the code comment.)
|
||||
|
||||
This is CVE-2013-4553 / XSA-74.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
Reviewed-by: Tim Deegan <tim@xen.org>
|
||||
|
||||
--- a/xen/arch/x86/domctl.c
|
||||
+++ b/xen/arch/x86/domctl.c
|
||||
@@ -385,6 +385,26 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * XSA-74: This sub-hypercall is broken in several ways:
|
||||
+ * - lock order inversion (p2m locks inside page_alloc_lock)
|
||||
+ * - no preemption on huge max_pfns input
|
||||
+ * - not (re-)checking d->is_dying with page_alloc_lock held
|
||||
+ * - not honoring start_pfn input (which libxc also doesn't set)
|
||||
+ * Additionally it is rather useless, as the result is stale by
|
||||
+ * the time the caller gets to look at it.
|
||||
+ * As it only has a single, non-production consumer (xen-mceinj),
|
||||
+ * rather than trying to fix it we restrict it for the time being.
|
||||
+ */
|
||||
+ if ( /* No nested locks inside copy_to_guest_offset(). */
|
||||
+ paging_mode_external(current->domain) ||
|
||||
+ /* Arbitrary limit capping processing time. */
|
||||
+ max_pfns > GB(4) / PAGE_SIZE )
|
||||
+ {
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
spin_lock(&d->page_alloc_lock);
|
||||
|
||||
if ( unlikely(d->is_dying) ) {
|
@ -1,153 +0,0 @@
|
||||
flask: fix reading strings from guest memory
|
||||
|
||||
Since the string size is being specified by the guest, we must range
|
||||
check it properly before doing allocations based on it. While for the
|
||||
two cases that are exposed only to trusted guests (via policy
|
||||
restriction) this just uses an arbitrary upper limit (PAGE_SIZE), for
|
||||
the FLASK_[GS]ETBOOL case (which any guest can use) the upper limit
|
||||
gets enforced based on the longest name across all boolean settings.
|
||||
|
||||
This is XSA-84.
|
||||
|
||||
Reported-by: Matthew Daley <mattd@bugfuzz.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
|
||||
|
||||
--- a/xen/xsm/flask/flask_op.c
|
||||
+++ b/xen/xsm/flask/flask_op.c
|
||||
@@ -53,6 +53,7 @@ static DEFINE_SPINLOCK(sel_sem);
|
||||
/* global data for booleans */
|
||||
static int bool_num = 0;
|
||||
static int *bool_pending_values = NULL;
|
||||
+static size_t bool_maxstr;
|
||||
static int flask_security_make_bools(void);
|
||||
|
||||
extern int ss_initialized;
|
||||
@@ -71,9 +72,15 @@ static int domain_has_security(struct do
|
||||
perms, NULL);
|
||||
}
|
||||
|
||||
-static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf, uint32_t size)
|
||||
+static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf,
|
||||
+ size_t size, size_t max_size)
|
||||
{
|
||||
- char *tmp = xmalloc_bytes(size + 1);
|
||||
+ char *tmp;
|
||||
+
|
||||
+ if ( size > max_size )
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ tmp = xmalloc_array(char, size + 1);
|
||||
if ( !tmp )
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -99,7 +106,7 @@ static int flask_security_user(struct xe
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
- rv = flask_copyin_string(arg->u.user, &user, arg->size);
|
||||
+ rv = flask_copyin_string(arg->u.user, &user, arg->size, PAGE_SIZE);
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
@@ -210,7 +217,7 @@ static int flask_security_context(struct
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
- rv = flask_copyin_string(arg->context, &buf, arg->size);
|
||||
+ rv = flask_copyin_string(arg->context, &buf, arg->size, PAGE_SIZE);
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
@@ -303,7 +310,7 @@ static int flask_security_resolve_bool(s
|
||||
if ( arg->bool_id != -1 )
|
||||
return 0;
|
||||
|
||||
- rv = flask_copyin_string(arg->name, &name, arg->size);
|
||||
+ rv = flask_copyin_string(arg->name, &name, arg->size, bool_maxstr);
|
||||
if ( rv )
|
||||
return rv;
|
||||
|
||||
@@ -334,7 +341,7 @@ static int flask_security_set_bool(struc
|
||||
int num;
|
||||
int *values;
|
||||
|
||||
- rv = security_get_bools(&num, NULL, &values);
|
||||
+ rv = security_get_bools(&num, NULL, &values, NULL);
|
||||
if ( rv != 0 )
|
||||
goto out;
|
||||
|
||||
@@ -440,7 +447,7 @@ static int flask_security_make_bools(voi
|
||||
|
||||
xfree(bool_pending_values);
|
||||
|
||||
- ret = security_get_bools(&num, NULL, &values);
|
||||
+ ret = security_get_bools(&num, NULL, &values, &bool_maxstr);
|
||||
if ( ret != 0 )
|
||||
goto out;
|
||||
|
||||
--- a/xen/xsm/flask/include/conditional.h
|
||||
+++ b/xen/xsm/flask/include/conditional.h
|
||||
@@ -13,7 +13,9 @@
|
||||
#ifndef _FLASK_CONDITIONAL_H_
|
||||
#define _FLASK_CONDITIONAL_H_
|
||||
|
||||
-int security_get_bools(int *len, char ***names, int **values);
|
||||
+#include <xen/types.h>
|
||||
+
|
||||
+int security_get_bools(int *len, char ***names, int **values, size_t *maxstr);
|
||||
|
||||
int security_set_bools(int len, int *values);
|
||||
|
||||
--- a/xen/xsm/flask/ss/services.c
|
||||
+++ b/xen/xsm/flask/ss/services.c
|
||||
@@ -1900,7 +1900,7 @@ int security_find_bool(const char *name)
|
||||
return rv;
|
||||
}
|
||||
|
||||
-int security_get_bools(int *len, char ***names, int **values)
|
||||
+int security_get_bools(int *len, char ***names, int **values, size_t *maxstr)
|
||||
{
|
||||
int i, rc = -ENOMEM;
|
||||
|
||||
@@ -1908,6 +1908,8 @@ int security_get_bools(int *len, char **
|
||||
if ( names )
|
||||
*names = NULL;
|
||||
*values = NULL;
|
||||
+ if ( maxstr )
|
||||
+ *maxstr = 0;
|
||||
|
||||
*len = policydb.p_bools.nprim;
|
||||
if ( !*len )
|
||||
@@ -1929,16 +1931,17 @@ int security_get_bools(int *len, char **
|
||||
|
||||
for ( i = 0; i < *len; i++ )
|
||||
{
|
||||
- size_t name_len;
|
||||
+ size_t name_len = strlen(policydb.p_bool_val_to_name[i]);
|
||||
+
|
||||
(*values)[i] = policydb.bool_val_to_struct[i]->state;
|
||||
if ( names ) {
|
||||
- name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
|
||||
- (*names)[i] = (char*)xmalloc_array(char, name_len);
|
||||
+ (*names)[i] = xmalloc_array(char, name_len + 1);
|
||||
if ( !(*names)[i] )
|
||||
goto err;
|
||||
- strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
|
||||
- (*names)[i][name_len - 1] = 0;
|
||||
+ strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len + 1);
|
||||
}
|
||||
+ if ( maxstr && name_len > *maxstr )
|
||||
+ *maxstr = name_len;
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
@@ -2056,7 +2059,7 @@ static int security_preserve_bools(struc
|
||||
struct cond_bool_datum *booldatum;
|
||||
struct cond_node *cur;
|
||||
|
||||
- rc = security_get_bools(&nbools, &bnames, &bvalues);
|
||||
+ rc = security_get_bools(&nbools, &bnames, &bvalues, NULL);
|
||||
if ( rc )
|
||||
goto out;
|
||||
for ( i = 0; i < nbools; i++ )
|
@ -1,31 +0,0 @@
|
||||
From 593bc8c63d582ec0fc2b3a35336106cf9c3a8b34 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Daley <mattd@bugfuzz.com>
|
||||
Date: Sun, 12 Jan 2014 14:29:32 +1300
|
||||
Subject: [PATCH] xsm/flask: correct off-by-one in
|
||||
flask_security_avc_cachestats cpu id check
|
||||
|
||||
This is XSA-85
|
||||
|
||||
Signed-off-by: Matthew Daley <mattd@bugfuzz.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
---
|
||||
xen/xsm/flask/flask_op.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
|
||||
index 4426ab9..22878f5 100644
|
||||
--- a/xen/xsm/flask/flask_op.c
|
||||
+++ b/xen/xsm/flask/flask_op.c
|
||||
@@ -457,7 +457,7 @@ static int flask_security_avc_cachestats(struct xen_flask_cache_stats *arg)
|
||||
{
|
||||
struct avc_cache_stats *st;
|
||||
|
||||
- if ( arg->cpu > nr_cpu_ids )
|
||||
+ if ( arg->cpu >= nr_cpu_ids )
|
||||
return -ENOENT;
|
||||
if ( !cpu_online(arg->cpu) )
|
||||
return -ENOENT;
|
||||
--
|
||||
1.8.5.2
|
||||
|
@ -1,21 +0,0 @@
|
||||
x86: PHYSDEVOP_{prepare,release}_msix are privileged
|
||||
|
||||
Yet this wasn't being enforced.
|
||||
|
||||
This is XSA-87.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/physdev.c
|
||||
+++ b/xen/arch/x86/physdev.c
|
||||
@@ -612,7 +612,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
||||
case PHYSDEVOP_release_msix: {
|
||||
struct physdev_pci_device dev;
|
||||
|
||||
- if ( copy_from_guest(&dev, arg, 1) )
|
||||
+ if ( !IS_PRIV(v->domain) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( copy_from_guest(&dev, arg, 1) )
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = pci_prepare_msix(dev.seg, dev.bus, dev.devfn,
|
@ -1,46 +0,0 @@
|
||||
x86/xsave: initialize extended register state when guests enable it
|
||||
|
||||
Till now, when setting previously unset bits in XCR0 we wouldn't touch
|
||||
the active register state, thus leaving in the newly enabled registers
|
||||
whatever a prior user of it left there, i.e. potentially leaking
|
||||
information between guests.
|
||||
|
||||
This is CVE-2013-1442 / XSA-62.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/xstate.c
|
||||
+++ b/xen/arch/x86/xstate.c
|
||||
@@ -307,6 +307,7 @@ int validate_xstate(u64 xcr0, u64 xcr0_a
|
||||
int handle_xsetbv(u32 index, u64 new_bv)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
+ u64 mask;
|
||||
|
||||
if ( index != XCR_XFEATURE_ENABLED_MASK )
|
||||
return -EOPNOTSUPP;
|
||||
@@ -320,9 +321,23 @@ int handle_xsetbv(u32 index, u64 new_bv)
|
||||
if ( !set_xcr0(new_bv) )
|
||||
return -EFAULT;
|
||||
|
||||
+ mask = new_bv & ~curr->arch.xcr0_accum;
|
||||
curr->arch.xcr0 = new_bv;
|
||||
curr->arch.xcr0_accum |= new_bv;
|
||||
|
||||
+ mask &= curr->fpu_dirtied ? ~XSTATE_FP_SSE : XSTATE_NONLAZY;
|
||||
+ if ( mask )
|
||||
+ {
|
||||
+ unsigned long cr0 = read_cr0();
|
||||
+
|
||||
+ clts();
|
||||
+ if ( curr->fpu_dirtied )
|
||||
+ asm ( "stmxcsr %0" : "=m" (curr->arch.xsave_area->fpu_sse.mxcsr) );
|
||||
+ xrstor(curr, mask);
|
||||
+ if ( cr0 & X86_CR0_TS )
|
||||
+ write_cr0(cr0);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,171 +0,0 @@
|
||||
x86: properly handle hvm_copy_from_guest_{phys,virt}() errors
|
||||
|
||||
Ignoring them generally implies using uninitialized data and, in all
|
||||
cases dealt with here, potentially leaking hypervisor stack contents to
|
||||
guests.
|
||||
|
||||
This is XSA-63.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Tim Deegan <tim@xen.org>
|
||||
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/hvm/hvm.c
|
||||
+++ b/xen/arch/x86/hvm/hvm.c
|
||||
@@ -2308,11 +2308,7 @@ void hvm_task_switch(
|
||||
|
||||
rc = hvm_copy_from_guest_virt(
|
||||
&tss, prev_tr.base, sizeof(tss), PFEC_page_present);
|
||||
- if ( rc == HVMCOPY_bad_gva_to_gfn )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_paged_out )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_shared )
|
||||
+ if ( rc != HVMCOPY_okay )
|
||||
goto out;
|
||||
|
||||
eflags = regs->eflags;
|
||||
@@ -2357,13 +2353,11 @@ void hvm_task_switch(
|
||||
|
||||
rc = hvm_copy_from_guest_virt(
|
||||
&tss, tr.base, sizeof(tss), PFEC_page_present);
|
||||
- if ( rc == HVMCOPY_bad_gva_to_gfn )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_paged_out )
|
||||
- goto out;
|
||||
- /* Note: this could be optimised, if the callee functions knew we want RO
|
||||
- * access */
|
||||
- if ( rc == HVMCOPY_gfn_shared )
|
||||
+ /*
|
||||
+ * Note: The HVMCOPY_gfn_shared case could be optimised, if the callee
|
||||
+ * functions knew we want RO access.
|
||||
+ */
|
||||
+ if ( rc != HVMCOPY_okay )
|
||||
goto out;
|
||||
|
||||
|
||||
--- a/xen/arch/x86/hvm/intercept.c
|
||||
+++ b/xen/arch/x86/hvm/intercept.c
|
||||
@@ -87,17 +87,28 @@ static int hvm_mmio_access(struct vcpu *
|
||||
{
|
||||
for ( i = 0; i < p->count; i++ )
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hvm_copy_from_guest_phys(&data,
|
||||
- p->data + (sign * i * p->size),
|
||||
- p->size);
|
||||
- if ( (ret == HVMCOPY_gfn_paged_out) ||
|
||||
- (ret == HVMCOPY_gfn_shared) )
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
{
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
rc = X86EMUL_RETRY;
|
||||
break;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
+ break;
|
||||
}
|
||||
+ if ( rc != X86EMUL_OKAY )
|
||||
+ break;
|
||||
rc = write_handler(v, p->addr + (sign * i * p->size), p->size,
|
||||
data);
|
||||
if ( rc != X86EMUL_OKAY )
|
||||
@@ -165,8 +176,28 @@ static int process_portio_intercept(port
|
||||
for ( i = 0; i < p->count; i++ )
|
||||
{
|
||||
data = 0;
|
||||
- (void)hvm_copy_from_guest_phys(&data, p->data + sign*i*p->size,
|
||||
- p->size);
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
+ {
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
+ rc = X86EMUL_RETRY;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( rc != X86EMUL_OKAY )
|
||||
+ break;
|
||||
rc = action(IOREQ_WRITE, p->addr, p->size, &data);
|
||||
if ( rc != X86EMUL_OKAY )
|
||||
break;
|
||||
--- a/xen/arch/x86/hvm/io.c
|
||||
+++ b/xen/arch/x86/hvm/io.c
|
||||
@@ -340,14 +340,24 @@ static int dpci_ioport_write(uint32_t mp
|
||||
data = p->data;
|
||||
if ( p->data_is_ptr )
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hvm_copy_from_guest_phys(&data,
|
||||
- p->data + (sign * i * p->size),
|
||||
- p->size);
|
||||
- if ( (ret == HVMCOPY_gfn_paged_out) &&
|
||||
- (ret == HVMCOPY_gfn_shared) )
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
+ {
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
return X86EMUL_RETRY;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ return X86EMUL_UNHANDLEABLE;
|
||||
+ }
|
||||
}
|
||||
|
||||
switch ( p->size )
|
||||
--- a/xen/arch/x86/hvm/vmx/realmode.c
|
||||
+++ b/xen/arch/x86/hvm/vmx/realmode.c
|
||||
@@ -39,7 +39,9 @@ static void realmode_deliver_exception(
|
||||
|
||||
again:
|
||||
last_byte = (vector * 4) + 3;
|
||||
- if ( idtr->limit < last_byte )
|
||||
+ if ( idtr->limit < last_byte ||
|
||||
+ hvm_copy_from_guest_phys(&cs_eip, idtr->base + vector * 4, 4) !=
|
||||
+ HVMCOPY_okay )
|
||||
{
|
||||
/* Software interrupt? */
|
||||
if ( insn_len != 0 )
|
||||
@@ -64,8 +66,6 @@ static void realmode_deliver_exception(
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hvm_copy_from_guest_phys(&cs_eip, idtr->base + vector * 4, 4);
|
||||
-
|
||||
frame[0] = regs->eip + insn_len;
|
||||
frame[1] = csr->sel;
|
||||
frame[2] = regs->eflags & ~X86_EFLAGS_RF;
|
@ -1,57 +0,0 @@
|
||||
commit 95a0770282ea2a03f7bc48c6656d5fc79bae0599
|
||||
Author: Tim Deegan <tim@xen.org>
|
||||
Date: Thu Sep 12 14:16:28 2013 +0100
|
||||
|
||||
x86/mm/shadow: Fix initialization of PV shadow L4 tables.
|
||||
|
||||
Shadowed PV L4 tables must have the same Xen mappings as their
|
||||
unshadowed equivalent. This is done by copying the Xen entries
|
||||
verbatim from the idle pagetable, and then using guest_l4_slot()
|
||||
in the SHADOW_FOREACH_L4E() iterator to avoid touching those entries.
|
||||
|
||||
adc5afbf1c70ef55c260fb93e4b8ce5ccb918706 (x86: support up to 16Tb)
|
||||
changed the definition of ROOT_PAGETABLE_XEN_SLOTS to extend right to
|
||||
the top of the address space, which causes the shadow code to
|
||||
copy Xen mappings into guest-kernel-address slots too.
|
||||
|
||||
In the common case, all those slots are zero in the idle pagetable,
|
||||
and no harm is done. But if any slot above #271 is non-zero, Xen will
|
||||
crash when that slot is later cleared (it attempts to drop
|
||||
shadow-pagetable refcounts on its own L4 pagetables).
|
||||
|
||||
Fix by using the new ROOT_PAGETABLE_PV_XEN_SLOTS when appropriate.
|
||||
Monitor pagetables need the full Xen mappings, so they keep using the
|
||||
old name (with its new semantics).
|
||||
|
||||
This is XSA-64.
|
||||
|
||||
Signed-off-by: Tim Deegan <tim@xen.org>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
Xen 4.3.x and xen-unstable are vulnerable.
|
||||
|
||||
diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
|
||||
index 4c4c2ba..3fed0b6 100644
|
||||
--- a/xen/arch/x86/mm/shadow/multi.c
|
||||
+++ b/xen/arch/x86/mm/shadow/multi.c
|
||||
@@ -1433,15 +1433,19 @@ void sh_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
shadow_l4e_t *sl4e;
|
||||
+ unsigned int slots;
|
||||
|
||||
sl4e = sh_map_domain_page(sl4mfn);
|
||||
ASSERT(sl4e != NULL);
|
||||
ASSERT(sizeof (l4_pgentry_t) == sizeof (shadow_l4e_t));
|
||||
|
||||
/* Copy the common Xen mappings from the idle domain */
|
||||
+ slots = (shadow_mode_external(d)
|
||||
+ ? ROOT_PAGETABLE_XEN_SLOTS
|
||||
+ : ROOT_PAGETABLE_PV_XEN_SLOTS);
|
||||
memcpy(&sl4e[ROOT_PAGETABLE_FIRST_XEN_SLOT],
|
||||
&idle_pg_table[ROOT_PAGETABLE_FIRST_XEN_SLOT],
|
||||
- ROOT_PAGETABLE_XEN_SLOTS * sizeof(l4_pgentry_t));
|
||||
+ slots * sizeof(l4_pgentry_t));
|
||||
|
||||
/* Install the per-domain mappings for this domain */
|
||||
sl4e[shadow_l4_table_offset(PERDOMAIN_VIRT_START)] =
|
@ -1,23 +0,0 @@
|
||||
x86: properly set up fbld emulation operand address
|
||||
|
||||
This is CVE-2013-4361 / XSA-66.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
@@ -3156,11 +3156,11 @@ x86_emulate(
|
||||
break;
|
||||
case 4: /* fbld m80dec */
|
||||
ea.bytes = 10;
|
||||
- dst = ea;
|
||||
+ src = ea;
|
||||
if ( (rc = ops->read(src.mem.seg, src.mem.off,
|
||||
&src.val, src.bytes, ctxt)) != 0 )
|
||||
goto done;
|
||||
- emulate_fpu_insn_memdst("fbld", src.val);
|
||||
+ emulate_fpu_insn_memsrc("fbld", src.val);
|
||||
break;
|
||||
case 5: /* fild m64i */
|
||||
ea.bytes = 8;
|
@ -1,37 +0,0 @@
|
||||
x86: check segment descriptor read result in 64-bit OUTS emulation
|
||||
|
||||
When emulating such an operation from a 64-bit context (CS has long
|
||||
mode set), and the data segment is overridden to FS/GS, the result of
|
||||
reading the overridden segment's descriptor (read_descriptor) is not
|
||||
checked. If it fails, data_base is left uninitialized.
|
||||
|
||||
This can lead to 8 bytes of Xen's stack being leaked to the guest
|
||||
(implicitly, i.e. via the address given in a #PF).
|
||||
|
||||
Coverity-ID: 1055116
|
||||
|
||||
This is CVE-2013-4368 / XSA-67.
|
||||
|
||||
Signed-off-by: Matthew Daley <mattjd@gmail.com>
|
||||
|
||||
Fix formatting.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/traps.c
|
||||
+++ b/xen/arch/x86/traps.c
|
||||
@@ -1993,10 +1993,10 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
}
|
||||
}
|
||||
- else
|
||||
- read_descriptor(data_sel, v, regs,
|
||||
- &data_base, &data_limit, &ar,
|
||||
- 0);
|
||||
+ else if ( !read_descriptor(data_sel, v, regs,
|
||||
+ &data_base, &data_limit, &ar, 0) ||
|
||||
+ !(ar & _SEGMENT_S) || !(ar & _SEGMENT_P) )
|
||||
+ goto fail;
|
||||
data_limit = ~0UL;
|
||||
ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
# Copyright 1999-2013 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen/xen-4.2.2-r1.ebuild,v 1.6 2013/11/06 06:45:18 idella4 Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python{2_6,2_7} )
|
||||
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
KEYWORDS="amd64 x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz"
|
||||
fi
|
||||
|
||||
inherit mount-boot flag-o-matic python-any-r1 toolchain-funcs eutils ${live_eclass}
|
||||
|
||||
DESCRIPTION="The Xen virtual machine monitor"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="custom-cflags debug efi flask pae xsm"
|
||||
|
||||
DEPEND="${PYTHON_DEPS}
|
||||
efi? ( >=sys-devel/binutils-2.22[multitarget] )
|
||||
!efi? ( >=sys-devel/binutils-2.22[-multitarget] )"
|
||||
RDEPEND=""
|
||||
PDEPEND="~app-emulation/xen-tools-${PV}"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="boot/xen-syms-${PV}"
|
||||
|
||||
REQUIRED_USE="
|
||||
flask? ( xsm )
|
||||
"
|
||||
|
||||
pkg_setup() {
|
||||
python-any-r1_pkg_setup
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]]; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if use flask ; then
|
||||
export "XSM_ENABLE=y"
|
||||
export "FLASK_ENABLE=y"
|
||||
elif use xsm ; then
|
||||
export "XSM_ENABLE=y"
|
||||
fi
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config and fix gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-pvgrub/}-4-fix_dotconfig-gcc.patch
|
||||
|
||||
if use efi; then
|
||||
epatch "${FILESDIR}"/${PN}-4.2-efi.patch
|
||||
export EFI_VENDOR="gentoo"
|
||||
export EFI_MOUNTPOINT="boot"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
# try and remove all the default custom-cflags
|
||||
find "${S}" -name Makefile -o -name Rules.mk -o -name Config.mk -exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} \; || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
# not strictly necessary to fix this
|
||||
sed -i 's/, "-Werror"//' "${S}/tools/python/setup.py" || die "failed to re-set setup.py"
|
||||
|
||||
#Security patches
|
||||
epatch "${FILESDIR}"/${PN}-4-CVE-2013-1918-XSA-45_[1-7].patch \
|
||||
"${FILESDIR}"/${PN}-4.2-2013-2076-XSA-52to54.patch \
|
||||
"${FILESDIR}"/${PN}-4.2-CVE-2013-1432-XSA-58.patch
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
if use custom-cflags; then
|
||||
filter-flags -fPIE -fstack-protector
|
||||
replace-flags -O3 -O2
|
||||
else
|
||||
unset CFLAGS
|
||||
fi
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
# Send raw LDFLAGS so that --as-needed works
|
||||
emake CC="$(tc-getCC)" LDFLAGS="$(raw-ldflags)" LD="$(tc-getLD)" -C xen ${myopt}
|
||||
}
|
||||
|
||||
src_install() {
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
# The 'make install' doesn't 'mkdir -p' the subdirs
|
||||
if use efi; then
|
||||
mkdir -p "${D}"${EFI_MOUNTPOINT}/efi/${EFI_VENDOR} || die
|
||||
fi
|
||||
|
||||
emake LDFLAGS="$(raw-ldflags)" DESTDIR="${D}" -C xen ${myopt} install
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the unoffical wiki page:"
|
||||
elog " http://www.gentoo.org/doc/en/xen-guide.xml"
|
||||
elog " http://en.gentoo-wiki.com/wiki/Xen/"
|
||||
|
||||
use pae && ewarn "This is a PAE build of Xen. It will *only* boot PAE kernels!"
|
||||
use efi && einfo "The efi executable is installed in boot/efi/gentoo"
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen/xen-4.2.2-r4.ebuild,v 1.2 2014/02/12 14:08:09 keytoaster Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python{2_6,2_7} )
|
||||
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
KEYWORDS="~amd64 ~x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz"
|
||||
fi
|
||||
|
||||
inherit mount-boot flag-o-matic python-any-r1 toolchain-funcs eutils ${live_eclass}
|
||||
|
||||
DESCRIPTION="The Xen virtual machine monitor"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="custom-cflags debug efi flask pae xsm"
|
||||
|
||||
DEPEND="${PYTHON_DEPS}
|
||||
efi? ( >=sys-devel/binutils-2.22[multitarget] )
|
||||
!efi? ( >=sys-devel/binutils-2.22[-multitarget] )"
|
||||
RDEPEND=""
|
||||
PDEPEND="~app-emulation/xen-tools-${PV}"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="boot/xen-syms-${PV}"
|
||||
|
||||
REQUIRED_USE="
|
||||
flask? ( xsm )
|
||||
"
|
||||
|
||||
#Security patches
|
||||
XSA_PATCHES=(
|
||||
"${FILESDIR}"/${PN}-4-CVE-2013-1918-XSA-45_[1-7].patch
|
||||
"${FILESDIR}"/${PN}-4.2-2013-2076-XSA-52to54.patch
|
||||
"${FILESDIR}"/${PN}-4.2-CVE-2013-1432-XSA-58.patch
|
||||
"${FILESDIR}"/${PN}-4.2-CVE-2013-4553-XSA-74.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-4554-XSA-76.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6400-XSA-80.patch
|
||||
"${FILESDIR}"/${PN}-4-XSA-83.patch # bug #499054
|
||||
"${FILESDIR}"/${PN}-4.2-XSA-84.patch # bug #500536
|
||||
"${FILESDIR}"/${PN}-4.2-XSA-85.patch # bug #500528
|
||||
"${FILESDIR}"/${PN}-4.2-XSA-87.patch # bug #499124
|
||||
)
|
||||
|
||||
pkg_setup() {
|
||||
python-any-r1_pkg_setup
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]]; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if use flask ; then
|
||||
export "XSM_ENABLE=y"
|
||||
export "FLASK_ENABLE=y"
|
||||
elif use xsm ; then
|
||||
export "XSM_ENABLE=y"
|
||||
fi
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config and fix gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-pvgrub/}-4-fix_dotconfig-gcc.patch
|
||||
|
||||
if use efi; then
|
||||
epatch "${FILESDIR}"/${PN}-4.2-efi.patch
|
||||
export EFI_VENDOR="gentoo"
|
||||
export EFI_MOUNTPOINT="boot"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
# try and remove all the default custom-cflags
|
||||
find "${S}" -name Makefile -o -name Rules.mk -o -name Config.mk -exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} \; || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
# not strictly necessary to fix this
|
||||
sed -i 's/, "-Werror"//' "${S}/tools/python/setup.py" || die "failed to re-set setup.py"
|
||||
|
||||
[[ ${XSA_PATCHES[@]} ]] && epatch "${XSA_PATCHES[@]}"
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
if use custom-cflags; then
|
||||
filter-flags -fPIE -fstack-protector
|
||||
replace-flags -O3 -O2
|
||||
else
|
||||
unset CFLAGS
|
||||
fi
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
# Send raw LDFLAGS so that --as-needed works
|
||||
emake CC="$(tc-getCC)" LDFLAGS="$(raw-ldflags)" LD="$(tc-getLD)" -C xen ${myopt}
|
||||
}
|
||||
|
||||
src_install() {
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
# The 'make install' doesn't 'mkdir -p' the subdirs
|
||||
if use efi; then
|
||||
mkdir -p "${D}"${EFI_MOUNTPOINT}/efi/${EFI_VENDOR} || die
|
||||
fi
|
||||
|
||||
emake LDFLAGS="$(raw-ldflags)" DESTDIR="${D}" -C xen ${myopt} install
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the unoffical wiki page:"
|
||||
elog " http://www.gentoo.org/doc/en/xen-guide.xml"
|
||||
elog " http://en.gentoo-wiki.com/wiki/Xen/"
|
||||
|
||||
use pae && ewarn "This is a PAE build of Xen. It will *only* boot PAE kernels!"
|
||||
use efi && einfo "The efi executable is installed in boot/efi/gentoo"
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
# Copyright 1999-2013 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen/xen-4.3.1-r1.ebuild,v 1.4 2013/12/31 02:46:00 idella4 Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python2_7 )
|
||||
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
# support dropped for regular 32 bit hypervisor, Bug 493944
|
||||
KEYWORDS="amd64 -x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz"
|
||||
fi
|
||||
|
||||
inherit mount-boot flag-o-matic python-any-r1 toolchain-funcs eutils ${live_eclass}
|
||||
|
||||
DESCRIPTION="The Xen virtual machine monitor"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="custom-cflags debug efi flask pae xsm"
|
||||
|
||||
DEPEND="${PYTHON_DEPS}
|
||||
efi? ( >=sys-devel/binutils-2.22[multitarget] )
|
||||
!efi? ( >=sys-devel/binutils-2.22[-multitarget] )"
|
||||
RDEPEND=""
|
||||
PDEPEND="~app-emulation/xen-tools-${PV}"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="boot/xen-syms-${PV}"
|
||||
|
||||
REQUIRED_USE="flask? ( xsm )"
|
||||
|
||||
pkg_setup() {
|
||||
python-any-r1_pkg_setup
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]]; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if use flask ; then
|
||||
export "XSM_ENABLE=y"
|
||||
export "FLASK_ENABLE=y"
|
||||
elif use xsm ; then
|
||||
export "XSM_ENABLE=y"
|
||||
fi
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config and fix gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-pvgrub/}-4.3-fix_dotconfig-gcc.patch
|
||||
|
||||
if use efi; then
|
||||
epatch "${FILESDIR}"/${PN}-4.2-efi.patch
|
||||
export EFI_VENDOR="gentoo"
|
||||
export EFI_MOUNTPOINT="boot"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
# try and remove all the default custom-cflags
|
||||
find "${S}" -name Makefile -o -name Rules.mk -o -name Config.mk -exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} \; || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
# not strictly necessary to fix this
|
||||
sed -i 's/, "-Werror"//' "${S}/tools/python/setup.py" || die "failed to re-set setup.py"
|
||||
|
||||
# Security patches
|
||||
epatch "${FILESDIR}"/${PN}-CVE-2013-4375-XSA-71.patch \
|
||||
"${FILESDIR}"/${PN}-CVE-2013-4494-XSA-73.patch \
|
||||
"${FILESDIR}"/${PN}-4.3-CVE-2013-6375-XSA-75.patch \
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6375-XSA-78.patch \
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6885-XSA-82.patch
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
if use custom-cflags; then
|
||||
filter-flags -fPIE -fstack-protector
|
||||
replace-flags -O3 -O2
|
||||
else
|
||||
unset CFLAGS
|
||||
fi
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
# Send raw LDFLAGS so that --as-needed works
|
||||
emake CC="$(tc-getCC)" LDFLAGS="$(raw-ldflags)" LD="$(tc-getLD)" -C xen ${myopt}
|
||||
}
|
||||
|
||||
src_install() {
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
use pae && myopt="${myopt} pae=y"
|
||||
|
||||
# The 'make install' doesn't 'mkdir -p' the subdirs
|
||||
if use efi; then
|
||||
mkdir -p "${D}"${EFI_MOUNTPOINT}/efi/${EFI_VENDOR} || die
|
||||
fi
|
||||
|
||||
emake LDFLAGS="$(raw-ldflags)" DESTDIR="${D}" -C xen ${myopt} install
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the unoffical wiki page:"
|
||||
elog " http://www.gentoo.org/doc/en/xen-guide.xml"
|
||||
elog " http://en.gentoo-wiki.com/wiki/Xen/"
|
||||
|
||||
use pae && ewarn "This is a PAE build of Xen. It will *only* boot PAE kernels!"
|
||||
use efi && einfo "The efi executable is installed in boot/efi/gentoo"
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/xen/xen-4.3.1-r4.ebuild,v 1.3 2014/02/07 10:19:00 idella4 Exp $
|
||||
|
||||
EAPI=5
|
||||
|
||||
PYTHON_COMPAT=( python2_7 )
|
||||
|
||||
if [[ $PV == *9999 ]]; then
|
||||
KEYWORDS=""
|
||||
REPO="xen-unstable.hg"
|
||||
EHG_REPO_URI="http://xenbits.xensource.com/${REPO}"
|
||||
S="${WORKDIR}/${REPO}"
|
||||
live_eclass="mercurial"
|
||||
else
|
||||
# Set to match entry in stable 4.3.1-r1, Bug 493944
|
||||
KEYWORDS="~amd64 -x86"
|
||||
SRC_URI="http://bits.xensource.com/oss-xen/release/${PV}/xen-${PV}.tar.gz"
|
||||
fi
|
||||
|
||||
inherit mount-boot flag-o-matic python-any-r1 toolchain-funcs eutils ${live_eclass}
|
||||
|
||||
DESCRIPTION="The Xen virtual machine monitor"
|
||||
HOMEPAGE="http://xen.org/"
|
||||
LICENSE="GPL-2"
|
||||
SLOT="0"
|
||||
IUSE="custom-cflags debug efi flask xsm"
|
||||
|
||||
DEPEND="${PYTHON_DEPS}
|
||||
efi? ( >=sys-devel/binutils-2.22[multitarget] )
|
||||
!efi? ( >=sys-devel/binutils-2.22[-multitarget] )"
|
||||
RDEPEND=""
|
||||
PDEPEND="~app-emulation/xen-tools-${PV}"
|
||||
|
||||
RESTRICT="test"
|
||||
|
||||
# Approved by QA team in bug #144032
|
||||
QA_WX_LOAD="boot/xen-syms-${PV}"
|
||||
|
||||
REQUIRED_USE="flask? ( xsm )"
|
||||
|
||||
# Security patches
|
||||
XSA_PATCHES=(
|
||||
"${FILESDIR}"/${PN}-CVE-2013-4375-XSA-71.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-4494-XSA-73.patch
|
||||
"${FILESDIR}"/${PN}-4.3-CVE-2013-6375-XSA-75.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6375-XSA-78.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6885-XSA-82.patch
|
||||
"${FILESDIR}"/${PN}-4.3-CVE-2013-4553-XSA-74.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-4554-XSA-76.patch
|
||||
"${FILESDIR}"/${PN}-CVE-2013-6400-XSA-80.patch
|
||||
"${FILESDIR}"/${PN}-4-XSA-83.patch #bug #499054
|
||||
"${FILESDIR}"/${PN}-4.3-XSA-87.patch #bug #499124
|
||||
)
|
||||
|
||||
pkg_setup() {
|
||||
python-any-r1_pkg_setup
|
||||
if [[ -z ${XEN_TARGET_ARCH} ]]; then
|
||||
if use x86 && use amd64; then
|
||||
die "Confusion! Both x86 and amd64 are set in your use flags!"
|
||||
elif use x86; then
|
||||
export XEN_TARGET_ARCH="x86_32"
|
||||
elif use amd64; then
|
||||
export XEN_TARGET_ARCH="x86_64"
|
||||
else
|
||||
die "Unsupported architecture!"
|
||||
fi
|
||||
fi
|
||||
|
||||
if use flask ; then
|
||||
export "XSM_ENABLE=y"
|
||||
export "FLASK_ENABLE=y"
|
||||
elif use xsm ; then
|
||||
export "XSM_ENABLE=y"
|
||||
fi
|
||||
}
|
||||
|
||||
src_prepare() {
|
||||
# Drop .config and fix gcc-4.6
|
||||
epatch "${FILESDIR}"/${PN/-pvgrub/}-4.3-fix_dotconfig-gcc.patch
|
||||
|
||||
if use efi; then
|
||||
epatch "${FILESDIR}"/${PN}-4.2-efi.patch
|
||||
export EFI_VENDOR="gentoo"
|
||||
export EFI_MOUNTPOINT="boot"
|
||||
fi
|
||||
|
||||
# if the user *really* wants to use their own custom-cflags, let them
|
||||
if use custom-cflags; then
|
||||
einfo "User wants their own CFLAGS - removing defaults"
|
||||
# try and remove all the default custom-cflags
|
||||
find "${S}" -name Makefile -o -name Rules.mk -o -name Config.mk -exec sed \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O3\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-march=i686\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-fomit-frame-pointer\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-g3*\s\(.*\)/CFLAGS\1=\2 \3/' \
|
||||
-e 's/CFLAGS\(.*\)=\(.*\)-O2\(.*\)/CFLAGS\1=\2\3/' \
|
||||
-i {} \; || die "failed to re-set custom-cflags"
|
||||
fi
|
||||
|
||||
# not strictly necessary to fix this
|
||||
sed -i 's/, "-Werror"//' "${S}/tools/python/setup.py" || die "failed to re-set setup.py"
|
||||
|
||||
[[ ${XSA_PATCHES[@]} ]] && epatch "${XSA_PATCHES[@]}"
|
||||
|
||||
epatch_user
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
|
||||
if use custom-cflags; then
|
||||
filter-flags -fPIE -fstack-protector
|
||||
replace-flags -O3 -O2
|
||||
else
|
||||
unset CFLAGS
|
||||
fi
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
# Send raw LDFLAGS so that --as-needed works
|
||||
emake CC="$(tc-getCC)" LDFLAGS="$(raw-ldflags)" LD="$(tc-getLD)" -C xen ${myopt}
|
||||
}
|
||||
|
||||
src_install() {
|
||||
local myopt
|
||||
use debug && myopt="${myopt} debug=y"
|
||||
|
||||
# The 'make install' doesn't 'mkdir -p' the subdirs
|
||||
if use efi; then
|
||||
mkdir -p "${D}"${EFI_MOUNTPOINT}/efi/${EFI_VENDOR} || die
|
||||
fi
|
||||
|
||||
emake LDFLAGS="$(raw-ldflags)" DESTDIR="${D}" -C xen ${myopt} install
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "Official Xen Guide and the unoffical wiki page:"
|
||||
elog " http://www.gentoo.org/doc/en/xen-guide.xml"
|
||||
elog " http://en.gentoo-wiki.com/wiki/Xen/"
|
||||
|
||||
use efi && einfo "The efi executable is installed in boot/efi/gentoo"
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
DIST hyperdex-1.0.1.tar.gz 969115 SHA256 b661e73e87e61cfb189c2bf8461843c29637d5237357c34e1f95b450d9cf862f SHA512 53db5d1dd05c77edec2c63a61c6dd649301bb49f394a7b0543672bcea9890fcbb956f281726fcb8ffbfd6e987eb4c7a6dddcf1f97a67bb9b2b03aa46a049e2df WHIRLPOOL 5925e96fcba6de2452c8f2b1872808b3c581ace192cff78571fc989f9ebebca0936f5b879adfb7bf83fce460d8378f28b70a63afc3772bd485d2093cc08a5cfe
|
||||
DIST hyperdex-1.0.5.tar.gz 969670 SHA256 a422bf3798757d5997c90b11de6dc037f6bcccaafaf7c495ca75449797c3aa2b SHA512 b39f723e131cc9de5b443a6b2c1ca68240472d7a75a164fe1916fd85cd94eb8081e0638fb35f766bf7aef59fdcbac3811f5a84c0e62e6f3d25d1fac2f7a7257a WHIRLPOOL 80fa500c8d3f14d030ecf90bb31acc65072efcaede160dea0802643c0bc5fe3d0cb3984e05095d142d7aabe4319c57fe4f2789de5deebe6a0617c872379cd987
|
||||
DIST hyperdex-1.1.0.tar.gz 1243852 SHA256 e4e10bb85fb44e0bc479dfad6f6e7ee7aef00edc310b9069db3db44bb0b0e143 SHA512 54cb5ca1f14f4744885639c38ab1a84959100b80df50da1befa86db7fb1046e1045a84378b7dae253935f9c7bcfca6fa37ec1bfe699f611c55fe75b18f0fd37e WHIRLPOOL 5bf9b88f17b4e2a32aff6182a4734f9aeacd5e5ab9b83525edd917a399992612d27161bbcfdc4217cf84ae33530a743a5f75a10f788817a5336c9ab99161b345
|
||||
|
@ -0,0 +1,45 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/dev-db/hyperdex/hyperdex-1.1.0.ebuild,v 1.1 2014/02/21 03:34:49 patrick Exp $
|
||||
EAPI=5
|
||||
|
||||
RESTRICT="test"
|
||||
PYTHON_DEPEND="2:2.6"
|
||||
inherit eutils python
|
||||
|
||||
DESCRIPTION="A searchable distributed Key-Value Store"
|
||||
|
||||
HOMEPAGE="http://hyperdex.org"
|
||||
SRC_URI="http://hyperdex.org/src/${P}.tar.gz"
|
||||
LICENSE="BSD"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64"
|
||||
|
||||
IUSE="+python"
|
||||
# need to add ruby and java useflags too
|
||||
|
||||
DEPEND="dev-cpp/glog
|
||||
dev-cpp/sparsehash
|
||||
dev-libs/cityhash
|
||||
dev-libs/libpo6
|
||||
dev-libs/libe
|
||||
dev-libs/busybee
|
||||
dev-libs/popt
|
||||
dev-libs/replicant"
|
||||
RDEPEND="${DEPEND}"
|
||||
|
||||
pkg_setup() {
|
||||
python_set_active_version 2
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
econf --disable-static \
|
||||
$(use_enable python python-bindings)
|
||||
}
|
||||
|
||||
src_install() {
|
||||
emake DESTDIR="${D}" install || die "Failed to install"
|
||||
newinitd "${FILESDIR}/hyperdex.initd" hyperdex || die "Failed to install init script"
|
||||
newconfd "${FILESDIR}/hyperdex.confd" hyperdex || die "Failed to install config file"
|
||||
find "${D}" -name '*.la' -exec rm {} \; # bad buildsystem! bad!
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
DIST busybee-0.1.0.tar.gz 328831 SHA256 7837c9f66cba77be904cb7ab9da5d35e6acf2cfb23bac20b9c5d17d4b5201398 SHA512 0844f21c0e73f7a9843b71a7f05869b179f19b79c046909205357a95a1865d02079d8c9b3517cf32a6e1c187c91552d68b245cb23ab91782345d6a9172dd123c WHIRLPOOL af631df9047088ab59bb6176727947265514434c7287f5eaaac326d318cbedbbce3eefa9841bd0f38080267486cc91032e11e129279b72beb3e044b2773f3919
|
||||
DIST busybee-0.4.0.tar.gz 360351 SHA256 e5d307785f7ea8dff71b605d289a3439b14f0ba6d40535b34201d4b356da0f03 SHA512 8e1cd94c67aaa340a24fab81549b8f91c4882abe4141b4d8888bc3b2c8efca720a52946cf7b60f168dadcf898ef07169736d825dda0e515a27febc9fae5a25bb WHIRLPOOL 7bcf75f9b2fc72858088964ba54d56de7674eb0c191816fd9e0c370f984412e6258d35b74d544a4102b3c38853065fc534d8f314f57a36f69c0cfaf42ab83bd6
|
||||
DIST busybee-0.4.1.tar.gz 359163 SHA256 601e3146729406fd6abb17d1c98e71c79ceebd84447ac60e45d9a83367dc148a SHA512 e013b78b4b36e468de80aaa03d9214730f741a2acbfc35b33d6ba114336a10d6d5fb30c9a03567ade680121b1c56fa50e404595854bf885ec50d4e5039b71eeb WHIRLPOOL ce2e51aa9bbf811c0e5aaaeafa8b6059545c69136b101c1387a4fe879b1bfddf562a64430dc35755c4b66fe3f5bf17d3262f3b7e16ee1145231d88cc1da40f12
|
||||
|
@ -0,0 +1,18 @@
|
||||
# Copyright 1999-2014 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/dev-libs/busybee/busybee-0.4.1.ebuild,v 1.1 2014/02/21 02:53:14 patrick Exp $
|
||||
EAPI=4
|
||||
|
||||
DESCRIPTION="A messaging abstraction on top of TCP sockets used in HyperDex"
|
||||
|
||||
HOMEPAGE="http://hyperdex.org"
|
||||
SRC_URI="http://hyperdex.org/src/${P}.tar.gz"
|
||||
LICENSE="BSD"
|
||||
SLOT="0"
|
||||
KEYWORDS="~amd64"
|
||||
|
||||
IUSE=""
|
||||
|
||||
DEPEND=">=dev-libs/libpo6-${PV}
|
||||
>=dev-libs/libe-${PV}"
|
||||
RDEPEND="${DEPEND}"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue