diff options
author | Daniel Gryniewicz <dang@gentoo.org> | 2008-07-14 12:55:37 +0000 |
---|---|---|
committer | Daniel Gryniewicz <dang@gentoo.org> | 2008-07-14 12:55:37 +0000 |
commit | 72f3d7c49666585000b220f04753753b0ff0a0be (patch) | |
tree | f55981f660dd8054ac4f45946b3f044431dd43d5 | |
parent | bump to test2 (diff) | |
download | gentoo-2-72f3d7c49666585000b220f04753753b0ff0a0be.tar.gz gentoo-2-72f3d7c49666585000b220f04753753b0ff0a0be.tar.bz2 gentoo-2-72f3d7c49666585000b220f04753753b0ff0a0be.zip |
Add block device bounds checking; bug #231753
(Portage version: 2.2_rc1/cvs/Linux 2.6.25-gentoo-r5 x86_64)
-rw-r--r-- | app-emulation/kvm/ChangeLog | 8 | ||||
-rw-r--r-- | app-emulation/kvm/files/kvm-70-block-rw-range-check.patch | 212 | ||||
-rw-r--r-- | app-emulation/kvm/kvm-70-r1.ebuild | 180 |
3 files changed, 399 insertions, 1 deletions
diff --git a/app-emulation/kvm/ChangeLog b/app-emulation/kvm/ChangeLog index 1d410f42ab87..f4733b667445 100644 --- a/app-emulation/kvm/ChangeLog +++ b/app-emulation/kvm/ChangeLog @@ -1,6 +1,12 @@ # ChangeLog for app-emulation/kvm # Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/ChangeLog,v 1.3 2008/07/10 12:47:39 dang Exp $ +# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/ChangeLog,v 1.4 2008/07/14 12:55:37 dang Exp $ + +*kvm-70-r1 (14 Jul 2008) + + 14 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> + +files/kvm-70-block-rw-range-check.patch, +kvm-70-r1.ebuild: + Add block device bounds checking; bug #231753 10 Jul 2008; Daniel Gryniewicz <dang@gentoo.org> kvm-70.ebuild: Disable the bios flag for now, it doesn't build. Bug #231343 diff --git a/app-emulation/kvm/files/kvm-70-block-rw-range-check.patch b/app-emulation/kvm/files/kvm-70-block-rw-range-check.patch new file mode 100644 index 000000000000..860d10b56b78 --- /dev/null +++ b/app-emulation/kvm/files/kvm-70-block-rw-range-check.patch @@ -0,0 +1,212 @@ +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block.c kvm-70/qemu/block.c +--- kvm-70.orig/qemu/block.c 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block.c 2008-07-14 08:21:55.000000000 -0400 +@@ -124,6 +124,60 @@ void path_combine(char *dest, int dest_s + } + } + ++static int bdrv_rd_badreq_sectors(BlockDriverState *bs, ++ int64_t sector_num, int nb_sectors) ++{ ++ return ++ nb_sectors < 0 || ++ sector_num < 0 || ++ nb_sectors > bs->total_sectors || ++ sector_num > bs->total_sectors - nb_sectors; ++} ++ ++static int bdrv_rd_badreq_bytes(BlockDriverState *bs, ++ int64_t offset, int count) ++{ ++ int64_t size = bs->total_sectors << SECTOR_BITS; ++ return ++ count < 0 || ++ size < 0 || ++ count > size || ++ offset > size - count; ++} ++ ++static int bdrv_wr_badreq_sectors(BlockDriverState *bs, ++ int64_t sector_num, int nb_sectors) ++{ ++ if (sector_num < 0 || ++ nb_sectors < 0) ++ return 1; ++ ++ if (sector_num > bs->total_sectors - nb_sectors) { ++ if (bs->autogrow) ++ bs->total_sectors = sector_num + nb_sectors; ++ else ++ return 1; ++ } ++ return 0; ++} ++ ++static int bdrv_wr_badreq_bytes(BlockDriverState *bs, ++ int64_t offset, int count) ++{ ++ int64_t size = bs->total_sectors << SECTOR_BITS; ++ if (count < 0 || ++ offset < 0) ++ return 1; ++ ++ if (offset > size - count) { ++ if (bs->autogrow) ++ bs->total_sectors = (offset + count + SECTOR_SIZE - 1) >> SECTOR_BITS; ++ else ++ return 1; ++ } ++ return 0; ++} ++ + + static void bdrv_register(BlockDriver *bdrv) + { +@@ -336,6 +390,10 @@ int bdrv_open2(BlockDriverState *bs, con + bs->read_only = 0; + bs->is_temporary = 0; + bs->encrypted = 0; ++ bs->autogrow = 0; ++ ++ if (flags & BDRV_O_AUTOGROW) ++ bs->autogrow = 1; + + if (flags & BDRV_O_SNAPSHOT) { + BlockDriverState *bs1; +@@ -380,6 +438,7 @@ int bdrv_open2(BlockDriverState *bs, con + } + bs->drv = drv; + bs->opaque = qemu_mallocz(drv->instance_size); ++ bs->total_sectors = 0; /* driver will set if it does not do getlength */ + if (bs->opaque == NULL && drv->instance_size > 0) + return -1; + /* Note: for compatibility, we open disk image files as RDWR, and +@@ -445,6 +504,7 @@ void bdrv_close(BlockDriverState *bs) + bs->drv = NULL; + + /* call the change callback */ ++ bs->total_sectors = 0; + bs->media_changed = 1; + if (bs->change_cb) + bs->change_cb(bs->change_opaque); +@@ -517,6 +577,8 @@ int bdrv_read(BlockDriverState *bs, int6 + if (!drv) + return -ENOMEDIUM; + ++ if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors)) ++ return -EDOM; + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(buf, bs->boot_sector_data, 512); + sector_num++; +@@ -557,6 +619,8 @@ int bdrv_write(BlockDriverState *bs, int + return -ENOMEDIUM; + if (bs->read_only) + return -EACCES; ++ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors)) ++ return -EDOM; + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(bs->boot_sector_data, buf, 512); + } +@@ -682,6 +746,8 @@ int bdrv_pread(BlockDriverState *bs, int + return -ENOMEDIUM; + if (!drv->bdrv_pread) + return bdrv_pread_em(bs, offset, buf1, count1); ++ if (bdrv_rd_badreq_bytes(bs, offset, count1)) ++ return -EDOM; + return drv->bdrv_pread(bs, offset, buf1, count1); + } + +@@ -697,6 +763,8 @@ int bdrv_pwrite(BlockDriverState *bs, in + return -ENOMEDIUM; + if (!drv->bdrv_pwrite) + return bdrv_pwrite_em(bs, offset, buf1, count1); ++ if (bdrv_wr_badreq_bytes(bs, offset, count1)) ++ return -EDOM; + return drv->bdrv_pwrite(bs, offset, buf1, count1); + } + +@@ -1102,6 +1170,8 @@ int bdrv_write_compressed(BlockDriverSta + return -ENOMEDIUM; + if (!drv->bdrv_write_compressed) + return -ENOTSUP; ++ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors)) ++ return -EDOM; + return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); + } + +@@ -1248,6 +1318,8 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri + + if (!drv) + return NULL; ++ if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors)) ++ return NULL; + + /* XXX: we assume that nb_sectors == 0 is suppored by the async read */ + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { +@@ -1279,6 +1351,8 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr + return NULL; + if (bs->read_only) + return NULL; ++ if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors)) ++ return NULL; + if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { + memcpy(bs->boot_sector_data, buf, 512); + } +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block.h kvm-70/qemu/block.h +--- kvm-70.orig/qemu/block.h 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block.h 2008-07-14 08:21:55.000000000 -0400 +@@ -45,6 +45,7 @@ typedef struct QEMUSnapshotInfo { + it (default for + bdrv_file_open()) */ + #define BDRV_O_DIRECT 0x0020 ++#define BDRV_O_AUTOGROW 0x0040 /* Allow backing file to extend when writing past end of file */ + + #ifndef QEMU_IMG + void bdrv_info(void); +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block_int.h kvm-70/qemu/block_int.h +--- kvm-70.orig/qemu/block_int.h 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block_int.h 2008-07-14 08:21:55.000000000 -0400 +@@ -97,6 +97,7 @@ struct BlockDriverState { + int locked; /* if true, the media cannot temporarily be ejected */ + int encrypted; /* if true, the media is encrypted */ + int sg; /* if true, the device is a /dev/sg* */ ++ int autogrow; /* if true, the backing store can auto-extend to allocate new extents */ + /* event callback when inserting/removing */ + void (*change_cb)(void *opaque); + void *change_opaque; +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block-qcow2.c kvm-70/qemu/block-qcow2.c +--- kvm-70.orig/qemu/block-qcow2.c 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block-qcow2.c 2008-07-14 08:21:55.000000000 -0400 +@@ -191,7 +191,7 @@ static int qcow_open(BlockDriverState *b + int len, i, shift, ret; + QCowHeader header; + +- ret = bdrv_file_open(&s->hd, filename, flags); ++ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW); + if (ret < 0) + return ret; + if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header)) +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block-qcow.c kvm-70/qemu/block-qcow.c +--- kvm-70.orig/qemu/block-qcow.c 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block-qcow.c 2008-07-14 08:21:55.000000000 -0400 +@@ -95,7 +95,7 @@ static int qcow_open(BlockDriverState *b + int len, i, shift, ret; + QCowHeader header; + +- ret = bdrv_file_open(&s->hd, filename, flags); ++ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW); + if (ret < 0) + return ret; + if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header)) +diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN kvm-70.orig/qemu/block-vmdk.c kvm-70/qemu/block-vmdk.c +--- kvm-70.orig/qemu/block-vmdk.c 2008-06-16 14:25:16.000000000 -0400 ++++ kvm-70/qemu/block-vmdk.c 2008-07-14 08:21:55.000000000 -0400 +@@ -377,7 +377,7 @@ static int vmdk_open(BlockDriverState *b + flags = BDRV_O_RDONLY; + fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename); + +- ret = bdrv_file_open(&s->hd, filename, flags); ++ ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW); + if (ret < 0) + return ret; + if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic)) diff --git a/app-emulation/kvm/kvm-70-r1.ebuild b/app-emulation/kvm/kvm-70-r1.ebuild new file mode 100644 index 000000000000..0060943baddd --- /dev/null +++ b/app-emulation/kvm/kvm-70-r1.ebuild @@ -0,0 +1,180 @@ +# Copyright 1999-2008 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/app-emulation/kvm/kvm-70-r1.ebuild,v 1.1 2008/07/14 12:55:37 dang Exp $ + +inherit eutils flag-o-matic toolchain-funcs linux-mod + +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" + +DESCRIPTION="Kernel-based Virtual Machine userland tools" +HOMEPAGE="http://kvm.qumranet.com/kvmwiki" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="-* ~amd64 ~x86" +# Add bios back when it builds again +IUSE="alsa esd gnutls havekernel ncurses sdl test" +RESTRICT="test" + +RDEPEND="sys-libs/zlib + alsa? ( >=media-libs/alsa-lib-1.0.13 ) + esd? ( media-sound/esound ) + gnutls? ( net-libs/gnutls ) + ncurses? ( sys-libs/ncurses ) + sdl? ( >=media-libs/libsdl-1.2.11 )" + +# bios? ( +# sys-devel/dev86 +# dev-lang/perl +# sys-power/iasl +# ) +DEPEND="${RDEPEND} + gnutls? ( dev-util/pkgconfig ) + app-text/texi2html" + +QA_TEXTRELS="usr/bin/kvm" + +pkg_setup() { + # check kernel version + if use havekernel ; then + ewarn "You have the 'havekernel' use flag set. This means you" + ewarn "must ensure you have a compatible kernel on your own." + elif kernel_is lt 2 6 22; then + eerror "the kvm in your kernel requires an older version of" + eerror "kvm as shown in :" + eerror " http://kvm.qumranet.com/kvmwiki/Downloads" + die "kvm version not compatible" + fi + + # check for kvm support + if use havekernel ; then + ewarn "You have the 'havekernel' use flag set. This means you" + ewarn "must ensure your kernel has KVM support enable on your own" + elif ! linux_chkconfig_present KVM; then + eerror "Please enable KVM support in your kernel, found at:" + eerror + eerror " Virtualization" + eerror " Kernel-based Virtual Machine (KVM) support" + die "KVM support not detected!" + fi + + enewgroup kvm +} + +src_unpack() { + unpack ${A} + + cd "${S}" + # prevent docs to get automatically installed + sed -i '/$(DESTDIR)$(docdir)/d' qemu/Makefile + # Alter target makefiles to accept CFLAGS set via flag-o + sed -i 's/^\(C\|OP_C\|HELPER_C\)FLAGS=/\1FLAGS+=/' \ + qemu/Makefile qemu/Makefile.target + [[ -x /sbin/paxctl ]] && \ + sed -i 's/^VL_LDFLAGS=$/VL_LDFLAGS=-Wl,-z,execheap/' \ + qemu/Makefile.target + # avoid strip + sed -i 's/$(INSTALL) -m 755 -s/$(INSTALL) -m 755/' qemu/Makefile + + epatch \ + "${FILESDIR}"/kvm-45-qemu-configure.patch \ + "${FILESDIR}"/kvm-61-qemu-kvm.patch \ + "${FILESDIR}"/kvm-57-qemu-kvm-cmdline.patch \ + "${FILESDIR}"/kvm-48-kvm.patch \ + "${FILESDIR}"/kvm-57-kernel-longmode.patch \ + "${FILESDIR}"/kvm-68-libkvm-no-kernel.patch \ + "${FILESDIR}"/kvm-69-qemu-no-blobs.patch \ + "${FILESDIR}"/kvm-69-qemu-ifup_ifdown.patch \ + "${FILESDIR}"/kvm-70-qemu-kvm-doc.patch \ + "${FILESDIR}"/kvm-70-block-rw-range-check.patch +} + +src_compile() { + local mycc conf_opts + + use alsa && conf_opts="$conf_opts --enable-alsa" + use esd && conf_opts="$conf_opts --enable-esd" + use gnutls || conf_opts="$conf_opts --disable-vnc-tls" + use ncurses || conf_opts="$conf_opts --disable-curses" + use sdl || conf_opts="$conf_opts --disable-gfx-check --disable-sdl" + conf_opts="$conf_opts --disable-gcc-check" + conf_opts="$conf_opts --prefix=/usr" + + ./configure ${conf_opts} || die "econf failed" + + emake libkvm || die "emake libkvm failed" + + if use test; then + emake user || die "emake user failed" + fi + + mycc=$(cat qemu/config-host.mak | egrep "^CC=" | cut -d "=" -f 2) + + filter-flags -fpie -fstack-protector + + # If using gentoo's compiler set the SPEC to non-hardened + if [ ! -z ${GCC_SPECS} -a -f ${GCC_SPECS} ]; then + local myccver=$(${mycc} -dumpversion) + local gccver=$($(tc-getBUILD_CC) -dumpversion) + + #Is this a SPEC for the right compiler version? + myspec="${GCC_SPECS/${gccver}/${myccver}}" + if [ "${myspec}" == "${GCC_SPECS}" ]; then + shopt -s extglob + GCC_SPECS="${GCC_SPECS/%hardened*specs/vanilla.specs}" + shopt -u extglob + else + unset GCC_SPECS + fi + fi + +# if use bios; then +# emake bios || die "emake bios failed" +# emake vgabios || die "emake vgabios failed" +# fi + + emake qemu || die "emake qemu failed" +} + +src_install() { + # kcmd so we don't install kernel modules which weren't build + emake DESTDIR="${D}" kcmd='#' install || die "make install failed" + + exeinto /usr/bin/ + doexe "${S}/kvm_stat" + + mv "${D}"/usr/share/man/man1/qemu.1 "${D}"/usr/share/man/man1/kvm.1 + mv "${D}"/usr/share/man/man1/qemu-img.1 "${D}"/usr/share/man/man1/kvm-img.1 + mv "${D}"/usr/bin/qemu-img "${D}"/usr/bin/kvm-img + + insinto /etc/udev/rules.d/ + doins scripts/65-kvm.rules + + insinto /etc/kvm/ + insopts -m0755 + newins scripts/qemu-ifup kvm-ifup + newins scripts/qemu-ifdown kvm-ifdown + + dodoc qemu/pc-bios/README + newdoc qemu/qemu-doc.html kvm-doc.html + newdoc qemu/qemu-tech.html kvm-tech.html +} + +pkg_postinst() { + elog "If you don't have kvm compiled into the kernel, make sure you have" + elog "the kernel module loaded before running kvm. The easiest way to" + elog "ensure that the kernel module is loaded is to load it on boot." + elog "For AMD CPUs the module is called 'kvm-amd'" + elog "For Intel CPUs the module is called 'kvm-intel'" + elog "Please review /etc/conf.d/modules for how to load these" + elog + elog "Make sure your user is in the 'kvm' group" + elog "Just run 'gpasswd -a <USER> kvm', then have <USER> re-login." + elog + elog "You will need the Universal TUN/TAP driver compiled into your" + elog "kernel or loaded as a module to use the virtual network device" + elog "if using -net tap. You will also need support for 802.1d" + elog "Ethernet Bridging and a configured bridge if using the provided" + elog "kvm-ifup script from /etc/kvm." + echo +} |