View | Details | Raw Unified | Return to bug 201931 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile (-1 / +1 lines)
Lines 3-9 Link Here
3
PORTNAME=	xen
3
PORTNAME=	xen
4
PKGNAMESUFFIX=	-tools
4
PKGNAMESUFFIX=	-tools
5
PORTVERSION=	4.5.0
5
PORTVERSION=	4.5.0
6
PORTREVISION=	8
6
PORTREVISION=	9
7
CATEGORIES=	sysutils emulators
7
CATEGORIES=	sysutils emulators
8
MASTER_SITES=	http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ \
8
MASTER_SITES=	http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ \
9
		http://code.coreboot.org/p/seabios/downloads/get/:seabios
9
		http://code.coreboot.org/p/seabios/downloads/get/:seabios
(-)files/xsa138-qemut-1.patch (+77 lines)
Line 0 Link Here
1
From 510952d4c33ee69574167ce30829b21c815a165b Mon Sep 17 00:00:00 2001
2
From: Kevin Wolf <kwolf@redhat.com>
3
Date: Wed, 3 Jun 2015 14:13:31 +0200
4
Subject: [PATCH 1/2] ide: Check array bounds before writing to io_buffer
5
 (CVE-2015-5154)
6
7
If the end_transfer_func of a command is called because enough data has
8
been read or written for the current PIO transfer, and it fails to
9
correctly call the command completion functions, the DRQ bit in the
10
status register and s->end_transfer_func may remain set. This allows the
11
guest to access further bytes in s->io_buffer beyond s->data_end, and
12
eventually overflowing the io_buffer.
13
14
One case where this currently happens is emulation of the ATAPI command
15
START STOP UNIT.
16
17
This patch fixes the problem by adding explicit array bounds checks
18
before accessing the buffer instead of relying on end_transfer_func to
19
function correctly.
20
21
Cc: qemu-stable@nongnu.org
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
 hw/ide.c | 16 ++++++++++++++++
25
 1 file changed, 16 insertions(+)
26
27
diff --git a/hw/ide.c b/hw/ide.c
28
index 791666b..211ec88 100644
29
--- a/hw/ide.c
30
+++ b/hw/ide.c
31
@@ -3002,6 +3002,10 @@ static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
32
     buffered_pio_write(s, addr, 2);
33
 
34
     p = s->data_ptr;
35
+    if (p + 2 > s->data_end) {
36
+        return;
37
+    }
38
+
39
     *(uint16_t *)p = le16_to_cpu(val);
40
     p += 2;
41
     s->data_ptr = p;
42
@@ -3021,6 +3025,10 @@ static uint32_t ide_data_readw(void *opaque, uint32_t addr)
43
     buffered_pio_read(s, addr, 2);
44
 
45
     p = s->data_ptr;
46
+    if (p + 2 > s->data_end) {
47
+        return 0;
48
+    }
49
+
50
     ret = cpu_to_le16(*(uint16_t *)p);
51
     p += 2;
52
     s->data_ptr = p;
53
@@ -3040,6 +3048,10 @@ static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
54
     buffered_pio_write(s, addr, 4);
55
 
56
     p = s->data_ptr;
57
+    if (p + 4 > s->data_end) {
58
+        return;
59
+    }
60
+
61
     *(uint32_t *)p = le32_to_cpu(val);
62
     p += 4;
63
     s->data_ptr = p;
64
@@ -3059,6 +3071,10 @@ static uint32_t ide_data_readl(void *opaque, uint32_t addr)
65
     buffered_pio_read(s, addr, 4);
66
 
67
     p = s->data_ptr;
68
+    if (p + 4 > s->data_end) {
69
+        return 0;
70
+    }
71
+
72
     ret = cpu_to_le32(*(uint32_t *)p);
73
     p += 4;
74
     s->data_ptr = p;
75
-- 
76
2.1.4
77
(-)files/xsa138-qemut-2.patch (+71 lines)
Line 0 Link Here
1
From 1ac0f60d558b7fca55c69a61ab4c4538af1f02f9 Mon Sep 17 00:00:00 2001
2
From: Kevin Wolf <kwolf@redhat.com>
3
Date: Wed, 3 Jun 2015 14:41:27 +0200
4
Subject: [PATCH 2/2] ide: Clear DRQ after handling all expected accesses
5
6
This is additional hardening against an end_transfer_func that fails to
7
clear the DRQ status bit. The bit must be unset as soon as the PIO
8
transfer has completed, so it's better to do this in a central place
9
instead of duplicating the code in all commands (and forgetting it in
10
some).
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
 hw/ide.c | 16 ++++++++++++----
15
 1 file changed, 12 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/ide.c b/hw/ide.c
18
index 211ec88..7b84d1b 100644
19
--- a/hw/ide.c
20
+++ b/hw/ide.c
21
@@ -3009,8 +3009,10 @@ static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
22
     *(uint16_t *)p = le16_to_cpu(val);
23
     p += 2;
24
     s->data_ptr = p;
25
-    if (p >= s->data_end)
26
+    if (p >= s->data_end) {
27
+        s->status &= ~DRQ_STAT;
28
         s->end_transfer_func(s);
29
+    }
30
 }
31
 
32
 static uint32_t ide_data_readw(void *opaque, uint32_t addr)
33
@@ -3032,8 +3034,10 @@ static uint32_t ide_data_readw(void *opaque, uint32_t addr)
34
     ret = cpu_to_le16(*(uint16_t *)p);
35
     p += 2;
36
     s->data_ptr = p;
37
-    if (p >= s->data_end)
38
+    if (p >= s->data_end) {
39
+        s->status &= ~DRQ_STAT;
40
         s->end_transfer_func(s);
41
+    }
42
     return ret;
43
 }
44
 
45
@@ -3055,8 +3059,10 @@ static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
46
     *(uint32_t *)p = le32_to_cpu(val);
47
     p += 4;
48
     s->data_ptr = p;
49
-    if (p >= s->data_end)
50
+    if (p >= s->data_end) {
51
+        s->status &= ~DRQ_STAT;
52
         s->end_transfer_func(s);
53
+    }
54
 }
55
 
56
 static uint32_t ide_data_readl(void *opaque, uint32_t addr)
57
@@ -3078,8 +3084,10 @@ static uint32_t ide_data_readl(void *opaque, uint32_t addr)
58
     ret = cpu_to_le32(*(uint32_t *)p);
59
     p += 4;
60
     s->data_ptr = p;
61
-    if (p >= s->data_end)
62
+    if (p >= s->data_end) {
63
+        s->status &= ~DRQ_STAT;
64
         s->end_transfer_func(s);
65
+    }
66
     return ret;
67
 }
68
 
69
-- 
70
2.1.4
71
(-)files/xsa138-qemuu-1.patch (+76 lines)
Line 0 Link Here
1
From a9de14175548c04e0f8be7fae219246509ba46a9 Mon Sep 17 00:00:00 2001
2
From: Kevin Wolf <kwolf@redhat.com>
3
Date: Wed, 3 Jun 2015 14:13:31 +0200
4
Subject: [PATCH 1/3] ide: Check array bounds before writing to io_buffer
5
 (CVE-2015-5154)
6
7
If the end_transfer_func of a command is called because enough data has
8
been read or written for the current PIO transfer, and it fails to
9
correctly call the command completion functions, the DRQ bit in the
10
status register and s->end_transfer_func may remain set. This allows the
11
guest to access further bytes in s->io_buffer beyond s->data_end, and
12
eventually overflowing the io_buffer.
13
14
One case where this currently happens is emulation of the ATAPI command
15
START STOP UNIT.
16
17
This patch fixes the problem by adding explicit array bounds checks
18
before accessing the buffer instead of relying on end_transfer_func to
19
function correctly.
20
21
Cc: qemu-stable@nongnu.org
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
 hw/ide/core.c | 16 ++++++++++++++++
25
 1 file changed, 16 insertions(+)
26
27
diff --git a/hw/ide/core.c b/hw/ide/core.c
28
index 122e955..44fcc23 100644
29
--- a/hw/ide/core.c
30
+++ b/hw/ide/core.c
31
@@ -2021,6 +2021,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
32
     }
33
 
34
     p = s->data_ptr;
35
+    if (p + 2 > s->data_end) {
36
+        return;
37
+    }
38
+
39
     *(uint16_t *)p = le16_to_cpu(val);
40
     p += 2;
41
     s->data_ptr = p;
42
@@ -2042,6 +2046,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
43
     }
44
 
45
     p = s->data_ptr;
46
+    if (p + 2 > s->data_end) {
47
+        return 0;
48
+    }
49
+
50
     ret = cpu_to_le16(*(uint16_t *)p);
51
     p += 2;
52
     s->data_ptr = p;
53
@@ -2063,6 +2071,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
54
     }
55
 
56
     p = s->data_ptr;
57
+    if (p + 4 > s->data_end) {
58
+        return;
59
+    }
60
+
61
     *(uint32_t *)p = le32_to_cpu(val);
62
     p += 4;
63
     s->data_ptr = p;
64
@@ -2084,6 +2096,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
65
     }
66
 
67
     p = s->data_ptr;
68
+    if (p + 4 > s->data_end) {
69
+        return 0;
70
+    }
71
+
72
     ret = cpu_to_le32(*(uint32_t *)p);
73
     p += 4;
74
     s->data_ptr = p;
75
-- 
76
1.8.3.1
(-)files/xsa138-qemuu-2.patch (+28 lines)
Line 0 Link Here
1
From aa851d30acfbb9580098ac1dc82885530cb8b3c1 Mon Sep 17 00:00:00 2001
2
From: Kevin Wolf <kwolf@redhat.com>
3
Date: Wed, 3 Jun 2015 14:17:46 +0200
4
Subject: [PATCH 2/3] ide/atapi: Fix START STOP UNIT command completion
5
6
The command must be completed on all code paths. START STOP UNIT with
7
pwrcnd set should succeed without doing anything.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
 hw/ide/atapi.c | 1 +
12
 1 file changed, 1 insertion(+)
13
14
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
15
index 950e311..79dd167 100644
16
--- a/hw/ide/atapi.c
17
+++ b/hw/ide/atapi.c
18
@@ -983,6 +983,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
19
20
     if (pwrcnd) {
21
         /* eject/load only happens for power condition == 0 */
22
+        ide_atapi_cmd_ok(s);
23
         return;
24
     }
25
26
--
27
1.8.3.1
28
(-)files/xsa138-qemuu-3.patch (+71 lines)
Line 0 Link Here
1
From 1d3c2268f8708126a34064c2e0c1000b40e6f3e5 Mon Sep 17 00:00:00 2001
2
From: Kevin Wolf <kwolf@redhat.com>
3
Date: Wed, 3 Jun 2015 14:41:27 +0200
4
Subject: [PATCH 3/3] ide: Clear DRQ after handling all expected accesses
5
6
This is additional hardening against an end_transfer_func that fails to
7
clear the DRQ status bit. The bit must be unset as soon as the PIO
8
transfer has completed, so it's better to do this in a central place
9
instead of duplicating the code in all commands (and forgetting it in
10
some).
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
 hw/ide/core.c | 16 ++++++++++++----
15
 1 file changed, 12 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/ide/core.c b/hw/ide/core.c
18
index 44fcc23..50449ca 100644
19
--- a/hw/ide/core.c
20
+++ b/hw/ide/core.c
21
@@ -2028,8 +2028,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
22
     *(uint16_t *)p = le16_to_cpu(val);
23
     p += 2;
24
     s->data_ptr = p;
25
-    if (p >= s->data_end)
26
+    if (p >= s->data_end) {
27
+        s->status &= ~DRQ_STAT;
28
         s->end_transfer_func(s);
29
+    }
30
 }
31
32
 uint32_t ide_data_readw(void *opaque, uint32_t addr)
33
@@ -2053,8 +2055,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
34
     ret = cpu_to_le16(*(uint16_t *)p);
35
     p += 2;
36
     s->data_ptr = p;
37
-    if (p >= s->data_end)
38
+    if (p >= s->data_end) {
39
+        s->status &= ~DRQ_STAT;
40
         s->end_transfer_func(s);
41
+    }
42
     return ret;
43
 }
44
45
@@ -2078,8 +2082,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
46
     *(uint32_t *)p = le32_to_cpu(val);
47
     p += 4;
48
     s->data_ptr = p;
49
-    if (p >= s->data_end)
50
+    if (p >= s->data_end) {
51
+        s->status &= ~DRQ_STAT;
52
         s->end_transfer_func(s);
53
+    }
54
 }
55
56
 uint32_t ide_data_readl(void *opaque, uint32_t addr)
57
@@ -2103,8 +2109,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
58
     ret = cpu_to_le32(*(uint32_t *)p);
59
     p += 4;
60
     s->data_ptr = p;
61
-    if (p >= s->data_end)
62
+    if (p >= s->data_end) {
63
+        s->status &= ~DRQ_STAT;
64
         s->end_transfer_func(s);
65
+    }
66
     return ret;
67
 }
68
69
--
70
1.8.3.1
71

Return to bug 201931