diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2012-10-31 15:12:17 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2012-10-31 15:12:47 +0000 |
commit | 3f67a8173b70a833b9e4f1c92131c34330d9e006 (patch) | |
tree | 22d8f2a80fb1551f9b4cdfb2283a2f3db543cb32 /main/qemu | |
parent | f070f69b9e441ee529b5b5be48a96d12c000f8a2 (diff) | |
download | aports-3f67a8173b70a833b9e4f1c92131c34330d9e006.tar.bz2 aports-3f67a8173b70a833b9e4f1c92131c34330d9e006.tar.xz |
main/qemu: fix CVE-2012-2652
fixes #1405
Diffstat (limited to 'main/qemu')
-rw-r--r-- | main/qemu/APKBUILD | 4 | ||||
-rw-r--r-- | main/qemu/CVE-2012-2652.patch | 129 |
2 files changed, 132 insertions, 1 deletions
diff --git a/main/qemu/APKBUILD b/main/qemu/APKBUILD index 5e133a2ca..63c9c4986 100644 --- a/main/qemu/APKBUILD +++ b/main/qemu/APKBUILD @@ -1,7 +1,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=qemu pkgver=1.0.1 -pkgrel=2 +pkgrel=3 pkgdesc="QEMU is a generic machine emulator and virtualizer" url="http://www.nongnu.org/qemu/" arch="all" @@ -39,6 +39,7 @@ $pkgname-img source="http://wiki.qemu.org/download/qemu-$pkgver.tar.gz 80-kvm.rules configure-libm.patch + CVE-2012-2652.patch librt.patch " @@ -141,4 +142,5 @@ img() { md5sums="5efd1091f01e3bc31bfdec27b8edeb00 qemu-1.0.1.tar.gz 66660f143235201249dc0648b39b86ee 80-kvm.rules a69fe6ff552b61606c5550cac4294abc configure-libm.patch +319652a41e46e4920b30c84b93241e93 CVE-2012-2652.patch 9f6c3143d61748eedc8cf8d0e53aee2c librt.patch" diff --git a/main/qemu/CVE-2012-2652.patch b/main/qemu/CVE-2012-2652.patch new file mode 100644 index 000000000..56e8f85e7 --- /dev/null +++ b/main/qemu/CVE-2012-2652.patch @@ -0,0 +1,129 @@ +From: Jim Meyering <jim@meyering.net> +Date: Mon, 28 May 2012 07:27:54 +0000 (+0200) +Subject: block: prevent snapshot mode $TMPDIR symlink attack +X-Git-Tag: v1.1.0-rc4~3 +X-Git-Url: http://git.kernel.org/?p=virt%2Fkvm%2Fqemu-kvm.git;a=commitdiff_plain;h=eba25057b9a5e19d10ace2bc7716667a31297169;hp=e78bd5ab07d65fec77fcae468b2836c79a836d49 + +block: prevent snapshot mode $TMPDIR symlink attack + +In snapshot mode, bdrv_open creates an empty temporary file without +checking for mkstemp or close failure, and ignoring the possibility +of a buffer overrun given a surprisingly long $TMPDIR. +Change the get_tmp_filename function to return int (not void), +so that it can inform its two callers of those failures. +Also avoid the risk of buffer overrun and do not ignore mkstemp +or close failure. +Update both callers (in block.c and vvfat.c) to propagate +temp-file-creation failure to their callers. + +get_tmp_filename creates and closes an empty file, while its +callers later open that presumed-existing file with O_CREAT. +The problem was that a malicious user could provoke mkstemp failure +and race to create a symlink with the selected temporary file name, +thus causing the qemu process (usually root owned) to open through +the symlink, overwriting an attacker-chosen file. + +This addresses CVE-2012-2652. +http://bugzilla.redhat.com/CVE-2012-2652 + +Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> +Signed-off-by: Jim Meyering <meyering@redhat.com> +Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> +--- + +diff --git a/block.c b/block.c +index af2ab4f..7547051 100644 +--- a/block.c ++++ b/block.c +@@ -409,28 +409,36 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options) + return bdrv_create(drv, filename, options); + } + +-#ifdef _WIN32 +-void get_tmp_filename(char *filename, int size) ++/* ++ * Create a uniquely-named empty temporary file. ++ * Return 0 upon success, otherwise a negative errno value. ++ */ ++int get_tmp_filename(char *filename, int size) + { ++#ifdef _WIN32 + char temp_dir[MAX_PATH]; +- +- GetTempPath(MAX_PATH, temp_dir); +- GetTempFileName(temp_dir, "qem", 0, filename); +-} ++ /* GetTempFileName requires that its output buffer (4th param) ++ have length MAX_PATH or greater. */ ++ assert(size >= MAX_PATH); ++ return (GetTempPath(MAX_PATH, temp_dir) ++ && GetTempFileName(temp_dir, "qem", 0, filename) ++ ? 0 : -GetLastError()); + #else +-void get_tmp_filename(char *filename, int size) +-{ + int fd; + const char *tmpdir; +- /* XXX: race condition possible */ + tmpdir = getenv("TMPDIR"); + if (!tmpdir) + tmpdir = "/tmp"; +- snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); ++ if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { ++ return -EOVERFLOW; ++ } + fd = mkstemp(filename); +- close(fd); +-} ++ if (fd < 0 || close(fd)) { ++ return -errno; ++ } ++ return 0; + #endif ++} + + /* + * Detect host devices. By convention, /dev/cdrom[N] is always +@@ -753,7 +761,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, + + bdrv_delete(bs1); + +- get_tmp_filename(tmp_filename, sizeof(tmp_filename)); ++ ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); ++ if (ret < 0) { ++ return ret; ++ } + + /* Real path is meaningless for protocols */ + if (is_protocol) +diff --git a/block/vvfat.c b/block/vvfat.c +index 2dc9d50..0fd3367 100644 +--- a/block/vvfat.c ++++ b/block/vvfat.c +@@ -2808,7 +2808,12 @@ static int enable_write_target(BDRVVVFATState *s) + array_init(&(s->commits), sizeof(commit_t)); + + s->qcow_filename = g_malloc(1024); +- get_tmp_filename(s->qcow_filename, 1024); ++ ret = get_tmp_filename(s->qcow_filename, 1024); ++ if (ret < 0) { ++ g_free(s->qcow_filename); ++ s->qcow_filename = NULL; ++ return ret; ++ } + + bdrv_qcow = bdrv_find_format("qcow"); + options = parse_option_parameters("", bdrv_qcow->create_options, NULL); +diff --git a/block_int.h b/block_int.h +index b80e66d..3d4abc6 100644 +--- a/block_int.h ++++ b/block_int.h +@@ -335,7 +335,7 @@ struct BlockDriverState { + BlockJob *job; + }; + +-void get_tmp_filename(char *filename, int size); ++int get_tmp_filename(char *filename, int size); + + void bdrv_set_io_limits(BlockDriverState *bs, + BlockIOLimit *io_limits); |