diff options
| author | Natanael Copa <ncopa@alpinelinux.org> | 2013-06-05 11:01:01 +0000 |
|---|---|---|
| committer | Natanael Copa <ncopa@alpinelinux.org> | 2013-06-05 11:01:01 +0000 |
| commit | ef7cc55e6635a229f49ae024c7b4f92945b1aa2d (patch) | |
| tree | dcef6f214678e3d3be58a4219c9f8e5a9b1fbb8b | |
| parent | 39ad8b3e5f2f1cb3656f142011b80c945d036a57 (diff) | |
| download | aports-ef7cc55e6635a229f49ae024c7b4f92945b1aa2d.tar.bz2 aports-ef7cc55e6635a229f49ae024c7b4f92945b1aa2d.tar.xz | |
main/qemu: security fix CVE-2013-2007
| -rw-r--r-- | main/qemu/APKBUILD | 18 | ||||
| -rw-r--r-- | main/qemu/CVE-2013-2007.patch | 203 |
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 + + |
