diff options
Diffstat (limited to 'meta-oe/recipes-support/mysql/mariadb/fix-cve-2013-1861-2.patch')
-rw-r--r-- | meta-oe/recipes-support/mysql/mariadb/fix-cve-2013-1861-2.patch | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/mysql/mariadb/fix-cve-2013-1861-2.patch b/meta-oe/recipes-support/mysql/mariadb/fix-cve-2013-1861-2.patch new file mode 100644 index 0000000000..c35cdfb641 --- /dev/null +++ b/meta-oe/recipes-support/mysql/mariadb/fix-cve-2013-1861-2.patch | |||
@@ -0,0 +1,257 @@ | |||
1 | From 9f714cdd3bf4bd8ee06cd38dcd2c6e8990a4ec48 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alexey Botchkov <holyfoot@askmonty.org> | ||
3 | Date: Mon, 18 Mar 2013 17:58:00 +0400 | ||
4 | Subject: [PATCH] MDEV-4252 geometry query crashes server. Additional fixes | ||
5 | for possible overflows in length-related calculations in 'spatial' | ||
6 | implementations. Checks added to the ::get_data_size() methods. | ||
7 | max_n_points decreased to occupy less 2G size. An object of that size is | ||
8 | practically inoperable anyway. | ||
9 | |||
10 | Upstream-Status: Backport | ||
11 | Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> | ||
12 | |||
13 | --- | ||
14 | mysql-test/r/gis.result | 12 +++++++++ | ||
15 | mysql-test/t/gis.test | 6 +++++ | ||
16 | sql/spatial.cc | 67 ++++++++++++++++++++++++++++++++++--------------- | ||
17 | sql/spatial.h | 2 +- | ||
18 | 4 files changed, 66 insertions(+), 21 deletions(-) | ||
19 | |||
20 | diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result | ||
21 | index 69e73d0..7566f0b 100644 | ||
22 | --- a/mysql-test/r/gis.result | ||
23 | +++ b/mysql-test/r/gis.result | ||
24 | @@ -1087,7 +1087,19 @@ NULL | ||
25 | # | ||
26 | SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); | ||
27 | ERROR 22007: Illegal non geometric '' value found during parsing | ||
28 | +# | ||
29 | +# MDEV-4252 geometry query crashes server | ||
30 | +# | ||
31 | select astext(0x0100000000030000000100000000000010); | ||
32 | astext(0x0100000000030000000100000000000010) | ||
33 | NULL | ||
34 | +select envelope(0x0100000000030000000100000000000010); | ||
35 | +envelope(0x0100000000030000000100000000000010) | ||
36 | +NULL | ||
37 | +select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); | ||
38 | +geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1) | ||
39 | +NULL | ||
40 | +select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); | ||
41 | +geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1) | ||
42 | +NULL | ||
43 | End of 5.1 tests | ||
44 | diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test | ||
45 | index cc5d158..c42541e 100644 | ||
46 | --- a/mysql-test/t/gis.test | ||
47 | +++ b/mysql-test/t/gis.test | ||
48 | @@ -826,6 +826,12 @@ SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); | ||
49 | --error ER_ILLEGAL_VALUE_FOR_TYPE | ||
50 | SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); | ||
51 | |||
52 | +--echo # | ||
53 | +--echo # MDEV-4252 geometry query crashes server | ||
54 | +--echo # | ||
55 | select astext(0x0100000000030000000100000000000010); | ||
56 | +select envelope(0x0100000000030000000100000000000010); | ||
57 | +select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1); | ||
58 | +select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1); | ||
59 | |||
60 | --echo End of 5.1 tests | ||
61 | diff --git a/sql/spatial.cc b/sql/spatial.cc | ||
62 | index 94d0238..5a4b768 100644 | ||
63 | --- a/sql/spatial.cc | ||
64 | +++ b/sql/spatial.cc | ||
65 | @@ -394,18 +394,19 @@ const char *Geometry::append_points(String *txt, uint32 n_points, | ||
66 | const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data, | ||
67 | uint offset) const | ||
68 | { | ||
69 | - uint32 points; | ||
70 | + uint32 n_points; | ||
71 | /* read number of points */ | ||
72 | if (no_data(data, 4)) | ||
73 | return 0; | ||
74 | - points= uint4korr(data); | ||
75 | + n_points= uint4korr(data); | ||
76 | data+= 4; | ||
77 | |||
78 | - if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points)) | ||
79 | + if (n_points > max_n_points || | ||
80 | + no_data(data, (POINT_DATA_SIZE + offset) * n_points)) | ||
81 | return 0; | ||
82 | |||
83 | /* Calculate MBR for points */ | ||
84 | - while (points--) | ||
85 | + while (n_points--) | ||
86 | { | ||
87 | data+= offset; | ||
88 | mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE); | ||
89 | @@ -484,9 +485,12 @@ const Geometry::Class_info *Gis_point::get_class_info() const | ||
90 | |||
91 | uint32 Gis_line_string::get_data_size() const | ||
92 | { | ||
93 | - if (no_data(m_data, 4)) | ||
94 | + uint32 n_points, size; | ||
95 | + if (no_data(m_data, 4) || | ||
96 | + (n_points= uint4korr(m_data)) > max_n_points || | ||
97 | + no_data(m_data, (size= 4 + n_points * POINT_DATA_SIZE))) | ||
98 | return GET_SIZE_ERROR; | ||
99 | - return 4 + uint4korr(m_data) * POINT_DATA_SIZE; | ||
100 | + return size; | ||
101 | } | ||
102 | |||
103 | |||
104 | @@ -665,6 +669,9 @@ int Gis_line_string::end_point(String *result) const | ||
105 | if (no_data(m_data, 4)) | ||
106 | return 1; | ||
107 | n_points= uint4korr(m_data); | ||
108 | + if (n_points == 0 || n_points > max_n_points || | ||
109 | + no_data(m_data, POINT_DATA_SIZE * n_points)) | ||
110 | + return 1; | ||
111 | return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE); | ||
112 | } | ||
113 | |||
114 | @@ -674,11 +681,14 @@ int Gis_line_string::point_n(uint32 num, String *result) const | ||
115 | uint32 n_points; | ||
116 | if (no_data(m_data, 4)) | ||
117 | return 1; | ||
118 | + num--; | ||
119 | n_points= uint4korr(m_data); | ||
120 | - if ((uint32) (num - 1) >= n_points) // means (num > n_points || num < 1) | ||
121 | + if (num >= n_points || | ||
122 | + num > max_n_points || // means (num > n_points || num < 1) | ||
123 | + no_data(m_data, num * POINT_DATA_SIZE)) | ||
124 | return 1; | ||
125 | |||
126 | - return create_point(result, m_data + 4 + (num - 1) * POINT_DATA_SIZE); | ||
127 | + return create_point(result, m_data + 4 + num*POINT_DATA_SIZE); | ||
128 | } | ||
129 | |||
130 | const Geometry::Class_info *Gis_line_string::get_class_info() const | ||
131 | @@ -692,6 +702,7 @@ const Geometry::Class_info *Gis_line_string::get_class_info() const | ||
132 | uint32 Gis_polygon::get_data_size() const | ||
133 | { | ||
134 | uint32 n_linear_rings; | ||
135 | + uint32 n_points; | ||
136 | const char *data= m_data; | ||
137 | |||
138 | if (no_data(data, 4)) | ||
139 | @@ -701,10 +712,13 @@ uint32 Gis_polygon::get_data_size() const | ||
140 | |||
141 | while (n_linear_rings--) | ||
142 | { | ||
143 | - if (no_data(data, 4)) | ||
144 | + if (no_data(data, 4) || | ||
145 | + (n_points= uint4korr(data)) > max_n_points) | ||
146 | return GET_SIZE_ERROR; | ||
147 | - data+= 4 + uint4korr(data)*POINT_DATA_SIZE; | ||
148 | + data+= 4 + n_points*POINT_DATA_SIZE; | ||
149 | } | ||
150 | + if (no_data(data, 0)) | ||
151 | + return GET_SIZE_ERROR; | ||
152 | return (uint32) (data - m_data); | ||
153 | } | ||
154 | |||
155 | @@ -1037,9 +1051,14 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const | ||
156 | |||
157 | uint32 Gis_multi_point::get_data_size() const | ||
158 | { | ||
159 | - if (no_data(m_data, 4)) | ||
160 | - return GET_SIZE_ERROR; | ||
161 | - return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE); | ||
162 | + uint32 n_points; | ||
163 | + uint32 size; | ||
164 | + | ||
165 | + if (no_data(m_data, 4) || | ||
166 | + (n_points= uint4korr(m_data)) > max_n_points || | ||
167 | + no_data(m_data, (size= 4 + n_points*(POINT_DATA_SIZE + WKB_HEADER_SIZE)))) | ||
168 | + return GET_SIZE_ERROR; | ||
169 | + return size; | ||
170 | } | ||
171 | |||
172 | |||
173 | @@ -1107,7 +1126,8 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const | ||
174 | return 1; | ||
175 | |||
176 | n_points= uint4korr(m_data); | ||
177 | - if (no_data(m_data+4, | ||
178 | + if (n_points > max_n_points || | ||
179 | + no_data(m_data+4, | ||
180 | n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) || | ||
181 | txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) | ||
182 | return 1; | ||
183 | @@ -1160,6 +1180,7 @@ const Geometry::Class_info *Gis_multi_point::get_class_info() const | ||
184 | uint32 Gis_multi_line_string::get_data_size() const | ||
185 | { | ||
186 | uint32 n_line_strings; | ||
187 | + uint32 n_points; | ||
188 | const char *data= m_data; | ||
189 | |||
190 | if (no_data(data, 4)) | ||
191 | @@ -1169,11 +1190,13 @@ uint32 Gis_multi_line_string::get_data_size() const | ||
192 | |||
193 | while (n_line_strings--) | ||
194 | { | ||
195 | - if (no_data(data, WKB_HEADER_SIZE + 4)) | ||
196 | + if (no_data(data, WKB_HEADER_SIZE + 4) || | ||
197 | + (n_points= uint4korr(data + WKB_HEADER_SIZE)) > max_n_points) | ||
198 | return GET_SIZE_ERROR; | ||
199 | - data+= (WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) * | ||
200 | - POINT_DATA_SIZE); | ||
201 | + data+= (WKB_HEADER_SIZE + 4 + n_points*POINT_DATA_SIZE); | ||
202 | } | ||
203 | + if (no_data(data, 0)) | ||
204 | + return GET_SIZE_ERROR; | ||
205 | return (uint32) (data - m_data); | ||
206 | } | ||
207 | |||
208 | @@ -1327,7 +1350,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const | ||
209 | return 1; | ||
210 | n_points= uint4korr(data + WKB_HEADER_SIZE); | ||
211 | length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points; | ||
212 | - if (no_data(data, length)) | ||
213 | + if (n_points > max_n_points || no_data(data, length)) | ||
214 | return 1; | ||
215 | if (!--num) | ||
216 | break; | ||
217 | @@ -1407,6 +1430,7 @@ const Geometry::Class_info *Gis_multi_line_string::get_class_info() const | ||
218 | uint32 Gis_multi_polygon::get_data_size() const | ||
219 | { | ||
220 | uint32 n_polygons; | ||
221 | + uint32 n_points; | ||
222 | const char *data= m_data; | ||
223 | |||
224 | if (no_data(data, 4)) | ||
225 | @@ -1425,11 +1449,14 @@ uint32 Gis_multi_polygon::get_data_size() const | ||
226 | |||
227 | while (n_linear_rings--) | ||
228 | { | ||
229 | - if (no_data(data, 4)) | ||
230 | + if (no_data(data, 4) || | ||
231 | + (n_points= uint4korr(data)) > max_n_points) | ||
232 | return GET_SIZE_ERROR; | ||
233 | - data+= 4 + uint4korr(data) * POINT_DATA_SIZE; | ||
234 | + data+= 4 + n_points * POINT_DATA_SIZE; | ||
235 | } | ||
236 | } | ||
237 | + if (no_data(data, 0)) | ||
238 | + return GET_SIZE_ERROR; | ||
239 | return (uint32) (data - m_data); | ||
240 | } | ||
241 | |||
242 | diff --git a/sql/spatial.h b/sql/spatial.h | ||
243 | index 7d25425..d7632c1 100644 | ||
244 | --- a/sql/spatial.h | ||
245 | +++ b/sql/spatial.h | ||
246 | @@ -199,7 +199,7 @@ class Geometry | ||
247 | public: | ||
248 | // Maximum number of points in feature that can fit into String | ||
249 | static const uint32 max_n_points= | ||
250 | - (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | ||
251 | + (uint32) (INT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / | ||
252 | POINT_DATA_SIZE; | ||
253 | public: | ||
254 | Geometry() {} /* Remove gcc warning */ | ||
255 | -- | ||
256 | 1.8.1.6 | ||
257 | |||