diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-31 07:23:14 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-31 07:23:14 +0000 |
commit | 0affe33dcd2b871de43750519c7304b8b84a56c0 (patch) | |
tree | 70c1613b0ee05dce3888d3e54590cdd4f321482e | |
parent | 217dbeadc9aa98754ea15ae381faa1d63afcbd39 (diff) | |
download | aports-0affe33dcd2b871de43750519c7304b8b84a56c0.tar.bz2 aports-0affe33dcd2b871de43750519c7304b8b84a56c0.tar.xz |
main/qemu: security fix for CVE-2015-5154
-rw-r--r-- | main/qemu/APKBUILD | 6 | ||||
-rw-r--r-- | main/qemu/CVE-2015-5154.patch | 175 |
2 files changed, 180 insertions, 1 deletions
diff --git a/main/qemu/APKBUILD b/main/qemu/APKBUILD index f02c4fd5b1..0df7bd1dca 100644 --- a/main/qemu/APKBUILD +++ b/main/qemu/APKBUILD @@ -1,7 +1,7 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=qemu pkgver=2.3.0 -pkgrel=1 +pkgrel=2 pkgdesc="QEMU is a generic machine emulator and virtualizer" url="http://qemu.org/" arch="all" @@ -97,6 +97,7 @@ source="http://wiki.qemu-project.org/download/qemu-$pkgver.tar.bz2 CVE-2015-3456.patch CVE-2015-4037.patch + CVE-2015-5154.patch qemu-guest-agent.confd qemu-guest-agent.initd @@ -297,6 +298,7 @@ bc5f2e41ed3b6d6d30b672adab82e3e1 musl-F_SHLCK-and-F_EXLCK.patch 9afbd6c9586229ce64275f012d665e2a fix-sigevent-and-sigval_t.patch 5e8a68940c4e0267e795a6ddd144e00e CVE-2015-3456.patch 97045abdf8d0543691e52f9fdf0c8d52 CVE-2015-4037.patch +311d3845dda4795bf63107c3dcbf2bea CVE-2015-5154.patch 1663bc6977f6886a58394155b1bf3676 qemu-guest-agent.confd 4cb15a1c3de2691dd65842f2325dfe22 qemu-guest-agent.initd 66660f143235201249dc0648b39b86ee 80-kvm.rules" @@ -307,6 +309,7 @@ eefd597197223899d3b12d8274af493153e270fd06ea8622e33d6eaeae063d40 musl-F_SHLCK-a 9abdf3410dea742cac3552363950c8a7fbcec8dd2bfd68e3c417a284f4e702f5 fix-sigevent-and-sigval_t.patch de69a47daf292fd0cc01c925a23c9fadbac0fb60c322bf89260cccceb47ca204 CVE-2015-3456.patch 6bb3f4bb71716bdde8ff417b76ceb4cee336ae93a65b2ae1db15406f382c0299 CVE-2015-4037.patch +fe575c51bae7da9ea10bd16c953bafd24c69f57a3fb28878dffc2b85f9a475d2 CVE-2015-5154.patch d84e53a94584f37f3bd1b21f44077b5de0d07094c6729f26ae20ab1f7b9cc298 qemu-guest-agent.confd 91f5ba66b56bb9a3e0d134de3ea756794d5f09fe8a14a4b0d3d95f69a9245c60 qemu-guest-agent.initd 37f666f1cdb7d8a62171de69b531681dcb0fba74236729dac8b6c019232eba84 80-kvm.rules" @@ -317,6 +320,7 @@ ec84b27648c01c6e58781295dcd0c2ff8e5a635f9836ef50c1da5d0ed125db1afc4cb5b01cb97606 e3f006c28318669356cd5b778f26774f06b0a40a4ac852573379df63efcc8276869958faec16797a38bf96c6061dfc040309e462d8559984f67eaf4af701ca1a fix-sigevent-and-sigval_t.patch 81485e26e30314b075a154cbce841fa3b803b70d8539a5ce00e57ec2020ab801d88c35631805811d003505dfd1909a5b70307fdbd8a192986f53143669465bd8 CVE-2015-3456.patch 8dc68c2f511a28b0c1896b89922fab8e31dea4eefe18a69e6c068dd799cfc5a5a8b2ed8c3f5d17584932ddb9a2bf72d72fdaaf19c2129babf9a8e8f4ce150659 CVE-2015-4037.patch +47c85d671562fef9000b277f9ae5b10d426952fa36dbe64e1835aa4c592669737b73180730ede79e39dfc19ee4f125cc6d197f6c81a2f7d87db6c223df4f6f4c CVE-2015-5154.patch d90c034cae3f9097466854ed1a9f32ab4b02089fcdf7320e8f4da13b2b1ff65067233f48809911485e4431d7ec1a22448b934121bc9522a2dc489009e87e2b1f qemu-guest-agent.confd 69457d757909b990f4fdfaef621696e5a5d287b42bc58e553cb52d85191788a269e91c0475bfb7223d3a9120c19cdf4d749b4d54013a644f33d0551517cdf094 qemu-guest-agent.initd 9b7a89b20fcf737832cb7b4d5dc7d8301dd88169cbe5339eda69fbb51c2e537d8cb9ec7cf37600899e734209e63410d50d0821bce97e401421db39c294d97be2 80-kvm.rules" diff --git a/main/qemu/CVE-2015-5154.patch b/main/qemu/CVE-2015-5154.patch new file mode 100644 index 0000000000..75e155079d --- /dev/null +++ b/main/qemu/CVE-2015-5154.patch @@ -0,0 +1,175 @@ +From a9de14175548c04e0f8be7fae219246509ba46a9 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf <kwolf@redhat.com> +Date: Wed, 3 Jun 2015 14:13:31 +0200 +Subject: [PATCH 1/3] ide: Check array bounds before writing to io_buffer + (CVE-2015-5154) + +If the end_transfer_func of a command is called because enough data has +been read or written for the current PIO transfer, and it fails to +correctly call the command completion functions, the DRQ bit in the +status register and s->end_transfer_func may remain set. This allows the +guest to access further bytes in s->io_buffer beyond s->data_end, and +eventually overflowing the io_buffer. + +One case where this currently happens is emulation of the ATAPI command +START STOP UNIT. + +This patch fixes the problem by adding explicit array bounds checks +before accessing the buffer instead of relying on end_transfer_func to +function correctly. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf <kwolf@redhat.com> +--- + hw/ide/core.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/hw/ide/core.c b/hw/ide/core.c +index 122e955..44fcc23 100644 +--- a/hw/ide/core.c ++++ b/hw/ide/core.c +@@ -2021,6 +2021,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) + } + + p = s->data_ptr; ++ if (p + 2 > s->data_end) { ++ return; ++ } ++ + *(uint16_t *)p = le16_to_cpu(val); + p += 2; + s->data_ptr = p; +@@ -2042,6 +2046,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) + } + + p = s->data_ptr; ++ if (p + 2 > s->data_end) { ++ return 0; ++ } ++ + ret = cpu_to_le16(*(uint16_t *)p); + p += 2; + s->data_ptr = p; +@@ -2063,6 +2071,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) + } + + p = s->data_ptr; ++ if (p + 4 > s->data_end) { ++ return; ++ } ++ + *(uint32_t *)p = le32_to_cpu(val); + p += 4; + s->data_ptr = p; +@@ -2084,6 +2096,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr) + } + + p = s->data_ptr; ++ if (p + 4 > s->data_end) { ++ return 0; ++ } ++ + ret = cpu_to_le32(*(uint32_t *)p); + p += 4; + s->data_ptr = p; +-- +1.8.3.1 +From aa851d30acfbb9580098ac1dc82885530cb8b3c1 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf <kwolf@redhat.com> +Date: Wed, 3 Jun 2015 14:17:46 +0200 +Subject: [PATCH 2/3] ide/atapi: Fix START STOP UNIT command completion + +The command must be completed on all code paths. START STOP UNIT with +pwrcnd set should succeed without doing anything. + +Signed-off-by: Kevin Wolf <kwolf@redhat.com> +--- + hw/ide/atapi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c +index 950e311..79dd167 100644 +--- a/hw/ide/atapi.c ++++ b/hw/ide/atapi.c +@@ -983,6 +983,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf) + + if (pwrcnd) { + /* eject/load only happens for power condition == 0 */ ++ ide_atapi_cmd_ok(s); + return; + } + +-- +1.8.3.1 + +From 1d3c2268f8708126a34064c2e0c1000b40e6f3e5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf <kwolf@redhat.com> +Date: Wed, 3 Jun 2015 14:41:27 +0200 +Subject: [PATCH 3/3] ide: Clear DRQ after handling all expected accesses + +This is additional hardening against an end_transfer_func that fails to +clear the DRQ status bit. The bit must be unset as soon as the PIO +transfer has completed, so it's better to do this in a central place +instead of duplicating the code in all commands (and forgetting it in +some). + +Signed-off-by: Kevin Wolf <kwolf@redhat.com> +--- + hw/ide/core.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/hw/ide/core.c b/hw/ide/core.c +index 44fcc23..50449ca 100644 +--- a/hw/ide/core.c ++++ b/hw/ide/core.c +@@ -2028,8 +2028,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) + *(uint16_t *)p = le16_to_cpu(val); + p += 2; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + } + + uint32_t ide_data_readw(void *opaque, uint32_t addr) +@@ -2053,8 +2055,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) + ret = cpu_to_le16(*(uint16_t *)p); + p += 2; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + return ret; + } + +@@ -2078,8 +2082,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) + *(uint32_t *)p = le32_to_cpu(val); + p += 4; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + } + + uint32_t ide_data_readl(void *opaque, uint32_t addr) +@@ -2103,8 +2109,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr) + ret = cpu_to_le32(*(uint32_t *)p); + p += 4; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + return ret; + } + +-- +1.8.3.1 + |