Gentoo Archives: gentoo-commits

From: "Ian Delaney (idella4)" <idella4@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in app-emulation/xen-tools/files: xen-4-CVE-XSA-86.patch
Date: Sat, 08 Feb 2014 08:13:48
Message-Id: 20140208081343.554162004C@flycatcher.gentoo.org
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