aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2013-06-05 11:01:01 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2013-06-05 11:01:01 +0000
commitef7cc55e6635a229f49ae024c7b4f92945b1aa2d (patch)
treedcef6f214678e3d3be58a4219c9f8e5a9b1fbb8b
parent39ad8b3e5f2f1cb3656f142011b80c945d036a57 (diff)
downloadaports-ef7cc55e6635a229f49ae024c7b4f92945b1aa2d.tar.bz2
aports-ef7cc55e6635a229f49ae024c7b4f92945b1aa2d.tar.xz
main/qemu: security fix CVE-2013-2007
ref #2059 fixes #2062
-rw-r--r--main/qemu/APKBUILD18
-rw-r--r--main/qemu/CVE-2013-2007.patch203
2 files changed, 207 insertions, 14 deletions
diff --git a/main/qemu/APKBUILD b/main/qemu/APKBUILD
index 53a748fbd6..90a643137f 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=4
+pkgrel=5
pkgdesc="QEMU is a generic machine emulator and virtualizer"
url="http://www.nongnu.org/qemu/"
arch="all"
@@ -42,6 +42,7 @@ source="http://wiki.qemu.org/download/qemu-$pkgver.tar.gz
CVE-2012-2652.patch
librt.patch
CVE-2012-6075.patch
+ CVE-2013-2007.patch
"
prepare() {
@@ -145,16 +146,5 @@ md5sums="5efd1091f01e3bc31bfdec27b8edeb00 qemu-1.0.1.tar.gz
a69fe6ff552b61606c5550cac4294abc configure-libm.patch
319652a41e46e4920b30c84b93241e93 CVE-2012-2652.patch
9f6c3143d61748eedc8cf8d0e53aee2c librt.patch
-abf8919e668120c44b4d1570c8a1e6c4 CVE-2012-6075.patch"
-sha256sums="198902e10782517f607c9ed9e629b5e7708ea39eb373ed3ec3f1c8a169d98378 qemu-1.0.1.tar.gz
-37f666f1cdb7d8a62171de69b531681dcb0fba74236729dac8b6c019232eba84 80-kvm.rules
-36dcd4c2540d0d74f94dfae9a24d92f8895d24a2030250b88a2534e4f1355df1 configure-libm.patch
-ac05d15dcd3f5f4d8ccc4333f91ad5c8068f891b210e207b0ce682bd790bbb94 CVE-2012-2652.patch
-5e4e34229aa31b83e3fa762a7af7d4cdbadaf82125cddb8e8caff62b2466c6f7 librt.patch
-33e9ee7b646aa40b58e7ffd6bff36c8d897d84cca03800f243c2737e55ee163d CVE-2012-6075.patch"
-sha512sums="c3c311288bd9e843c3e9dae9ad36e370ffa6a379878fae1067e656e9a1f38e002314e59f0fc46c84df98bdd4d6b7acc6b99907b3cf04a2b100a752b837da0178 qemu-1.0.1.tar.gz
-9b7a89b20fcf737832cb7b4d5dc7d8301dd88169cbe5339eda69fbb51c2e537d8cb9ec7cf37600899e734209e63410d50d0821bce97e401421db39c294d97be2 80-kvm.rules
-93c969bc4d077690f60f199f5628c7ae0ecbaa87bfc903770b0a0914eddfc7f694028281dbb2fb7086055ce341a723c9ad9aa0238ad08f91c9e9c2b21f04e6af configure-libm.patch
-e7e0b49efe9ea67515665daa08927ed161197c8654d8eaf3d56d2084abcb8509ea8d748d65a2c2a021a5e7b95442ed6dba333f3ceb4b7d3a6ec03dbf13786a57 CVE-2012-2652.patch
-66787fc829e09223eab05f8ea57dcf7bc3a2d5a231fa5276b5b5dd20f3852282c2e09f4890ed247150bbebabe88bc3dc6ab7a0af69b6e5f0f8e175d950d04ddf librt.patch
-248720594d216390e9b2df47cc095442c9257a740a2cd6622b941a681f84a3e672494e23b8bdd4213aec263ed8ecf86e1ce49ef9227ea8ba54a96a65ee28f4d2 CVE-2012-6075.patch"
+abf8919e668120c44b4d1570c8a1e6c4 CVE-2012-6075.patch
+bbbe4d5b26b1204ce1f7bd7e2e17dfb8 CVE-2013-2007.patch"
diff --git a/main/qemu/CVE-2013-2007.patch b/main/qemu/CVE-2013-2007.patch
new file mode 100644
index 0000000000..30130e432b
--- /dev/null
+++ b/main/qemu/CVE-2013-2007.patch
@@ -0,0 +1,203 @@
+From 0c29addea85130133632d25361d02524db83a24c Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Wed, 5 Jun 2013 09:08:05 +0000
+Subject: [PATCH] qga: set umask 0077 when daemonizing (CVE-2013-2007)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The qemu guest agent creates a bunch of files with insecure permissions
+when started in daemon mode. For example:
+
+ -rw-rw-rw- 1 root root /var/log/qemu-ga.log
+ -rw-rw-rw- 1 root root /var/run/qga.state
+ -rw-rw-rw- 1 root root /var/log/qga-fsfreeze-hook.log
+
+In addition, at least all files created with the "guest-file-open" QMP
+command, and all files created with shell output redirection (or
+otherwise) by utilities invoked by the fsfreeze hook script are affected.
+
+For now mask all file mode bits for "group" and "others" in
+become_daemon().
+
+Temporarily, for compatibility reasons, stick with the 0666 file-mode in
+case of files newly created by the "guest-file-open" QMP call. Do so
+without changing the umask temporarily.
+
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
+(cherry picked from commit c689b4f1bac352dcfd6ecb9a1d45337de0f1de67)
+
+[AF: Use error_set() instead of error_setg*()]
+Signed-off-by: Andreas Färber <address@hidden>
+(cherry picked from commit ea82ad5c9ed15992f12c0e25a286980a3759f0f9)
+
+Conflicts:
+ qga/commands-posix.c
+---
+ qemu-ga.c | 2 +-
+ qga/guest-agent-commands.c | 117 +++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 115 insertions(+), 4 deletions(-)
+
+diff --git a/qemu-ga.c b/qemu-ga.c
+index 4932013..ae1fb60 100644
+--- a/qemu-ga.c
++++ b/qemu-ga.c
+@@ -186,7 +186,7 @@ static void become_daemon(const char *pidfile)
+ goto fail;
+ }
+
+- umask(0);
++ umask(S_IRWXG | S_IRWXO);
+ sid = setsid();
+ if (sid < 0) {
+ goto fail;
+diff --git a/qga/guest-agent-commands.c b/qga/guest-agent-commands.c
+index 6da9904..2f4b9ac 100644
+--- a/qga/guest-agent-commands.c
++++ b/qga/guest-agent-commands.c
+@@ -23,6 +23,9 @@
+
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/stat.h>
+ #include "qga/guest-agent-core.h"
+ #include "qga-qmp-commands.h"
+ #include "qerror.h"
+@@ -134,9 +137,117 @@ static GuestFileHandle *guest_file_handle_find(int64_t id)
+ return NULL;
+ }
+
++typedef const char * const ccpc;
++
++/* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
++static const struct {
++ ccpc *forms;
++ int oflag_base;
++} guest_file_open_modes[] = {
++ { (ccpc[]){ "r", "rb", NULL }, O_RDONLY },
++ { (ccpc[]){ "w", "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC },
++ { (ccpc[]){ "a", "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND },
++ { (ccpc[]){ "r+", "rb+", "r+b", NULL }, O_RDWR },
++ { (ccpc[]){ "w+", "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC },
++ { (ccpc[]){ "a+", "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND }
++};
++
++static int
++find_open_flag(const char *mode_str, Error **err)
++{
++ unsigned mode;
++
++ for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
++ ccpc *form;
++
++ form = guest_file_open_modes[mode].forms;
++ while (*form != NULL && strcmp(*form, mode_str) != 0) {
++ ++form;
++ }
++ if (*form != NULL) {
++ break;
++ }
++ }
++
++ if (mode == ARRAY_SIZE(guest_file_open_modes)) {
++ error_set(err, QERR_UNSUPPORTED);
++ return -1;
++ }
++ return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK;
++}
++
++#define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \
++ S_IRGRP | S_IWGRP | \
++ S_IROTH | S_IWOTH)
++
++static FILE *
++safe_open_or_create(const char *path, const char *mode, Error **err)
++{
++ Error *local_err = NULL;
++ int oflag;
++
++ oflag = find_open_flag(mode, &local_err);
++ if (local_err == NULL) {
++ int fd;
++
++ /* If the caller wants / allows creation of a new file, we implement it
++ * with a two step process: open() + (open() / fchmod()).
++ *
++ * First we insist on creating the file exclusively as a new file. If
++ * that succeeds, we're free to set any file-mode bits on it. (The
++ * motivation is that we want to set those file-mode bits independently
++ * of the current umask.)
++ *
++ * If the exclusive creation fails because the file already exists
++ * (EEXIST is not possible for any other reason), we just attempt to
++ * open the file, but in this case we won't be allowed to change the
++ * file-mode bits on the preexistent file.
++ *
++ * The pathname should never disappear between the two open()s in
++ * practice. If it happens, then someone very likely tried to race us.
++ * In this case just go ahead and report the ENOENT from the second
++ * open() to the caller.
++ *
++ * If the caller wants to open a preexistent file, then the first
++ * open() is decisive and its third argument is ignored, and the second
++ * open() and the fchmod() are never called.
++ */
++ fd = open(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
++ if (fd == -1 && errno == EEXIST) {
++ oflag &= ~(unsigned)O_CREAT;
++ fd = open(path, oflag);
++ }
++
++ if (fd == -1) {
++ error_set(&local_err, QERR_OPEN_FILE_FAILED, path);
++ } else {
++ qemu_set_cloexec(fd);
++
++ if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
++ error_set(&local_err, QERR_QGA_COMMAND_FAILED, "fchmod() failed");
++ } else {
++ FILE *f;
++
++ f = fdopen(fd, mode);
++ if (f == NULL) {
++ error_set(&local_err, QERR_QGA_COMMAND_FAILED, "fdopen() failed");
++ } else {
++ return f;
++ }
++ }
++
++ close(fd);
++ }
++ }
++
++ error_propagate(err, local_err);
++ return NULL;
++}
++
+ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)
+ {
+ FILE *fh;
++ Error *local_err = NULL;
+ int fd;
+ int64_t ret = -1;
+
+@@ -144,9 +255,9 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, E
+ mode = "r";
+ }
+ slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
+- fh = fopen(path, mode);
+- if (!fh) {
+- error_set(err, QERR_OPEN_FILE_FAILED, path);
++ fh = safe_open_or_create(path, mode, &local_err);
++ if (local_err != NULL) {
++ error_propagate(err, local_err);
+ return -1;
+ }
+
+--
+1.8.0
+
+