1 |
idella4 14/02/08 08:13:43 |
2 |
|
3 |
Added: xen-4-CVE-XSA-86.patch |
4 |
Log: |
5 |
revbump; only to 4.3.1 (for now), add sec. patch XSA-86 patch wrt bug #500530 |
6 |
|
7 |
(Portage version: 2.2.8/cvs/Linux x86_64, signed Manifest commit with key 0xB8072B0D) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 app-emulation/xen-tools/files/xen-4-CVE-XSA-86.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-emulation/xen-tools/files/xen-4-CVE-XSA-86.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/app-emulation/xen-tools/files/xen-4-CVE-XSA-86.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: xen-4-CVE-XSA-86.patch |
16 |
=================================================================== |
17 |
From: Xen.org security team <security () xen org> |
18 |
Date: Thu, 06 Feb 2014 12:39:17 +0000 |
19 |
|
20 |
From b4c452646efd37b4cd0996256dd0ab7bf6ccb7f6 Mon Sep 17 00:00:00 2001 |
21 |
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= |
22 |
<marmarek@××××××××××××××××××.com> |
23 |
Date: Mon, 20 Jan 2014 15:51:56 +0000 |
24 |
Subject: [PATCH] libvchan: Fix handling of invalid ring buffer indices |
25 |
MIME-Version: 1.0 |
26 |
Content-Type: text/plain; charset=UTF-8 |
27 |
Content-Transfer-Encoding: 8bit |
28 |
|
29 |
The remote (hostile) process can set ring buffer indices to any value |
30 |
at any time. If that happens, it is possible to get "buffer space" |
31 |
(either for writing data, or ready for reading) negative or greater |
32 |
than buffer size. This will end up with buffer overflow in the second |
33 |
memcpy inside of do_send/do_recv. |
34 |
|
35 |
Fix this by introducing new available bytes accessor functions |
36 |
raw_get_data_ready and raw_get_buffer_space which are robust against |
37 |
mad ring states, and only return sanitised values. |
38 |
|
39 |
Proof sketch of correctness: |
40 |
|
41 |
Now {rd,wr}_{cons,prod} are only ever used in the raw available bytes |
42 |
functions, and in do_send and do_recv. |
43 |
|
44 |
The raw available bytes functions do unsigned arithmetic on the |
45 |
returned values. If the result is "negative" or too big it will be |
46 |
>ring_size (since we used unsigned arithmetic). Otherwise the result |
47 |
is a positive in-range value representing a reasonable ring state, in |
48 |
which case we can safely convert it to int (as the rest of the code |
49 |
expects). |
50 |
|
51 |
do_send and do_recv immediately mask the ring index value with the |
52 |
ring size. The result is always going to be plausible. If the ring |
53 |
state has become mad, the worst case is that our behaviour is |
54 |
inconsistent with the peer's ring pointer. I.e. we read or write to |
55 |
arguably-incorrect parts of the ring - but always parts of the ring. |
56 |
And of course if a peer misoperates the ring they can achieve this |
57 |
effect anyway. |
58 |
|
59 |
So the security problem is fixed. |
60 |
|
61 |
This is XSA-86. |
62 |
|
63 |
(The patch is essentially Ian Jackson's work, although parts of the |
64 |
commit message are by Marek.) |
65 |
|
66 |
Signed-off-by: Marek Marczykowski-Górecki <marmarek@××××××××××××××××××.com> |
67 |
Signed-off-by: Ian Jackson <ian.jackson@×××××××××.com> |
68 |
Cc: Marek Marczykowski-Górecki <marmarek@××××××××××××××××××.com> |
69 |
Cc: Joanna Rutkowska <joanna@××××××××××××××××××.com> |
70 |
--- |
71 |
tools/libvchan/io.c | 47 +++++++++++++++++++++++++++++++++++++++++------ |
72 |
1 file changed, 41 insertions(+), 6 deletions(-) |
73 |
|
74 |
diff --git a/tools/libvchan/io.c b/tools/libvchan/io.c |
75 |
index 2383364..804c63c 100644 |
76 |
--- a/tools/libvchan/io.c |
77 |
+++ b/tools/libvchan/io.c |
78 |
@@ -111,12 +111,26 @@ static inline int send_notify(struct libxenvchan *ctrl, uint8_t bit) |
79 |
return 0; |
80 |
} |
81 |
|
82 |
+/* |
83 |
+ * Get the amount of buffer space available, and do nothing about |
84 |
+ * notifications. |
85 |
+ */ |
86 |
+static inline int raw_get_data_ready(struct libxenvchan *ctrl) |
87 |
+{ |
88 |
+ uint32_t ready = rd_prod(ctrl) - rd_cons(ctrl); |
89 |
+ if (ready >= rd_ring_size(ctrl)) |
90 |
+ /* We have no way to return errors. Locking up the ring is |
91 |
+ * better than the alternatives. */ |
92 |
+ return 0; |
93 |
+ return ready; |
94 |
+} |
95 |
+ |
96 |
/** |
97 |
* Get the amount of buffer space available and enable notifications if needed. |
98 |
*/ |
99 |
static inline int fast_get_data_ready(struct libxenvchan *ctrl, size_t request) |
100 |
{ |
101 |
- int ready = rd_prod(ctrl) - rd_cons(ctrl); |
102 |
+ int ready = raw_get_data_ready(ctrl); |
103 |
if (ready >= request) |
104 |
return ready; |
105 |
/* We plan to consume all data; please tell us if you send more */ |
106 |
@@ -126,7 +140,7 @@ static inline int fast_get_data_ready(struct libxenvchan *ctrl, size_t request) |
107 |
* will not get notified even though the actual amount of data ready is |
108 |
* above request. Reread rd_prod to cover this case. |
109 |
*/ |
110 |
- return rd_prod(ctrl) - rd_cons(ctrl); |
111 |
+ return raw_get_data_ready(ctrl); |
112 |
} |
113 |
|
114 |
int libxenvchan_data_ready(struct libxenvchan *ctrl) |
115 |
@@ -135,7 +149,21 @@ int libxenvchan_data_ready(struct libxenvchan *ctrl) |
116 |
* when it changes |
117 |
*/ |
118 |
request_notify(ctrl, VCHAN_NOTIFY_WRITE); |
119 |
- return rd_prod(ctrl) - rd_cons(ctrl); |
120 |
+ return raw_get_data_ready(ctrl); |
121 |
+} |
122 |
+ |
123 |
+/** |
124 |
+ * Get the amount of buffer space available, and do nothing |
125 |
+ * about notifications |
126 |
+ */ |
127 |
+static inline int raw_get_buffer_space(struct libxenvchan *ctrl) |
128 |
+{ |
129 |
+ uint32_t ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl)); |
130 |
+ if (ready > wr_ring_size(ctrl)) |
131 |
+ /* We have no way to return errors. Locking up the ring is |
132 |
+ * better than the alternatives. */ |
133 |
+ return 0; |
134 |
+ return ready; |
135 |
} |
136 |
|
137 |
/** |
138 |
@@ -143,7 +171,7 @@ int libxenvchan_data_ready(struct libxenvchan *ctrl) |
139 |
*/ |
140 |
static inline int fast_get_buffer_space(struct libxenvchan *ctrl, size_t request) |
141 |
{ |
142 |
- int ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl)); |
143 |
+ int ready = raw_get_buffer_space(ctrl); |
144 |
if (ready >= request) |
145 |
return ready; |
146 |
/* We plan to fill the buffer; please tell us when you've read it */ |
147 |
@@ -153,7 +181,7 @@ static inline int fast_get_buffer_space(struct libxenvchan *ctrl, size_t request |
148 |
* will not get notified even though the actual amount of buffer space |
149 |
* is above request. Reread wr_cons to cover this case. |
150 |
*/ |
151 |
- return wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl)); |
152 |
+ return raw_get_buffer_space(ctrl); |
153 |
} |
154 |
|
155 |
int libxenvchan_buffer_space(struct libxenvchan *ctrl) |
156 |
@@ -162,7 +190,7 @@ int libxenvchan_buffer_space(struct libxenvchan *ctrl) |
157 |
* when it changes |
158 |
*/ |
159 |
request_notify(ctrl, VCHAN_NOTIFY_READ); |
160 |
- return wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl)); |
161 |
+ return raw_get_buffer_space(ctrl); |
162 |
} |
163 |
|
164 |
int libxenvchan_wait(struct libxenvchan *ctrl) |
165 |
@@ -176,6 +204,8 @@ int libxenvchan_wait(struct libxenvchan *ctrl) |
166 |
|
167 |
/** |
168 |
* returns -1 on error, or size on success |
169 |
+ * |
170 |
+ * caller must have checked that enough space is available |
171 |
*/ |
172 |
static int do_send(struct libxenvchan *ctrl, const void *data, size_t size) |
173 |
{ |
174 |
@@ -248,6 +278,11 @@ int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size) |
175 |
} |
176 |
} |
177 |
|
178 |
+/** |
179 |
+ * returns -1 on error, or size on success |
180 |
+ * |
181 |
+ * caller must have checked that enough data is available |
182 |
+ */ |
183 |
static int do_recv(struct libxenvchan *ctrl, void *data, size_t size) |
184 |
{ |
185 |
int real_idx = rd_cons(ctrl) & (rd_ring_size(ctrl) - 1); |
186 |
-- |
187 |
1.7.10.4 |