From 74bb4c4ea0742d058b78ca7b1aca76cbc2f8ed1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Honza=20Hor=C3=A1k?= Date: Mon, 3 Jun 2013 17:30:42 +0200 Subject: [PATCH] Fix for CVE-2013-1861 backported from MariaDB Resolves: #921836 --- community-mysql-cve-2013-1861.patch | 170 ++++++++++++++++++++++++++++ community-mysql.spec | 4 + 2 files changed, 174 insertions(+) create mode 100644 community-mysql-cve-2013-1861.patch diff --git a/community-mysql-cve-2013-1861.patch b/community-mysql-cve-2013-1861.patch new file mode 100644 index 0000000..e8a27cf --- /dev/null +++ b/community-mysql-cve-2013-1861.patch @@ -0,0 +1,170 @@ +diff -up mysql-5.5.31/mysql-test/r/gis.result.cve mysql-5.5.31/mysql-test/r/gis.result +--- mysql-5.5.31/mysql-test/r/gis.result.cve 2013-06-03 16:32:33.732025515 +0200 ++++ mysql-5.5.31/mysql-test/r/gis.result 2013-06-03 16:34:04.519691044 +0200 +@@ -1113,4 +1113,19 @@ SELECT 1 FROM g1 WHERE a >= ANY + (SELECT 1 FROM g1 WHERE a = geomfromtext('') OR a) ; + 1 + DROP TABLE g1; ++# ++# TODO-424 geometry query crashes server ++# ++select astext(0x0100000000030000000100000000000010); ++astext(0x0100000000030000000100000000000010) ++NULL ++select area(0x0100000000030000000100000000000010); ++area(0x0100000000030000000100000000000010) ++NULL ++select astext(exteriorring(0x0100000000030000000100000000000010)); ++astext(exteriorring(0x0100000000030000000100000000000010)) ++NULL ++select astext(centroid(0x0100000000030000000100000000000010)); ++astext(centroid(0x0100000000030000000100000000000010)) ++NULL + End of 5.5 tests +diff -up mysql-5.5.31/mysql-test/t/gis.test.cve mysql-5.5.31/mysql-test/t/gis.test +--- mysql-5.5.31/mysql-test/t/gis.test.cve 2013-06-03 16:32:33.733025512 +0200 ++++ mysql-5.5.31/mysql-test/t/gis.test 2013-06-03 16:34:38.942560749 +0200 +@@ -868,4 +868,11 @@ SELECT 1 FROM g1 WHERE a >= ANY + + DROP TABLE g1; + ++--echo # ++--echo # TODO-424 geometry query crashes server ++--echo # ++select astext(0x0100000000030000000100000000000010); ++select area(0x0100000000030000000100000000000010); ++select astext(exteriorring(0x0100000000030000000100000000000010)); ++select astext(centroid(0x0100000000030000000100000000000010)); + --echo End of 5.5 tests +diff -up mysql-5.5.31/sql/spatial.cc.cve mysql-5.5.31/sql/spatial.cc +--- mysql-5.5.31/sql/spatial.cc.cve 2013-03-25 14:14:58.000000000 +0100 ++++ mysql-5.5.31/sql/spatial.cc 2013-06-03 16:45:52.790665557 +0200 +@@ -538,7 +538,7 @@ bool Gis_line_string::get_data_as_wkt(St + n_points= uint4korr(data); + data += 4; + +- if (n_points < 1 || ++ if (n_points < 1 || n_points > max_n_points || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) || + txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) + return 1; +@@ -576,7 +576,8 @@ int Gis_line_string::geom_length(double + return 1; + n_points= uint4korr(data); + data+= 4; +- if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) ++ if (n_points < 1 || n_points > max_n_points || ++ no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + return 1; + + get_point(&prev_x, &prev_y, data); +@@ -610,7 +611,7 @@ int Gis_line_string::is_closed(int *clos + return 0; + } + data+= 4; +- if (n_points == 0 || ++ if (n_points == 0 || n_points > max_n_points || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + return 1; + +@@ -780,7 +781,7 @@ bool Gis_polygon::get_data_as_wkt(String + return 1; + n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) || ++ if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) || + txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) + return 1; + txt->qs_append('('); +@@ -834,7 +835,7 @@ int Gis_polygon::area(double *ar, const + if (no_data(data, 4)) + return 1; + n_points= uint4korr(data); +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) ++ if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) + return 1; + get_point(&prev_x, &prev_y, data+4); + data+= (4+SIZEOF_STORED_DOUBLE*2); +@@ -870,7 +871,8 @@ int Gis_polygon::exterior_ring(String *r + n_points= uint4korr(data); + data+= 4; + length= n_points * POINT_DATA_SIZE; +- if (no_data(data, length) || result->reserve(1+4+4+ length)) ++ if (n_points > max_n_points || ++ no_data(data, length) || result->reserve(1+4+4+ length)) + return 1; + + result->q_append((char) wkb_ndr); +@@ -916,7 +918,8 @@ int Gis_polygon::interior_ring_n(uint32 + n_points= uint4korr(data); + points_size= n_points * POINT_DATA_SIZE; + data+= 4; +- if (no_data(data, points_size) || result->reserve(1+4+4+ points_size)) ++ if (n_points > max_n_points || ++ no_data(data, points_size) || result->reserve(1+4+4+ points_size)) + return 1; + + result->q_append((char) wkb_ndr); +@@ -955,7 +958,7 @@ int Gis_polygon::centroid_xy(double *x, + return 1; + org_n_points= n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) ++ if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) + return 1; + get_point(&prev_x, &prev_y, data); + data+= (SIZEOF_STORED_DOUBLE*2); +@@ -1242,7 +1245,7 @@ bool Gis_multi_line_string::get_data_as_ + return 1; + n_points= uint4korr(data + WKB_HEADER_SIZE); + data+= WKB_HEADER_SIZE + 4; +- if (no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || ++ if (n_points > max_n_points || no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || + txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) + return 1; + txt->qs_append('('); +@@ -1503,7 +1506,8 @@ bool Gis_multi_polygon::get_data_as_wkt( + return 1; + uint32 n_points= uint4korr(data); + data+= 4; +- if (no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || ++ if (n_points > max_n_points || ++ no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || + txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points, + 512)) + return 1; +@@ -1586,6 +1590,8 @@ int Gis_multi_polygon::geometry_n(uint32 + if (no_data(data, 4)) + return 1; + n_points= uint4korr(data); ++ if (n_points > max_n_points) ++ return 1; + data+= 4 + POINT_DATA_SIZE * n_points; + } + } while (--num); +diff -up mysql-5.5.31/sql/spatial.h.cve mysql-5.5.31/sql/spatial.h +--- mysql-5.5.31/sql/spatial.h.cve 2013-03-25 14:14:58.000000000 +0100 ++++ mysql-5.5.31/sql/spatial.h 2013-06-03 16:32:33.737025500 +0200 +@@ -200,6 +200,11 @@ struct Geometry_buffer; + class Geometry + { + public: ++ // Maximum number of points in feature that can fit into String ++ static const uint32 max_n_points= ++ (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / ++ POINT_DATA_SIZE; ++ + Geometry() {} /* Remove gcc warning */ + virtual ~Geometry() {} /* Remove gcc warning */ + static void *operator new(size_t size, void *buffer) +@@ -383,10 +388,6 @@ public: + + class Gis_line_string: public Geometry + { +- // Maximum number of points in LineString that can fit into String +- static const uint32 max_n_points= +- (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / +- POINT_DATA_SIZE; + public: + Gis_line_string() {} /* Remove gcc warning */ + virtual ~Gis_line_string() {} /* Remove gcc warning */ diff --git a/community-mysql.spec b/community-mysql.spec index b37f6dd..176c6df 100644 --- a/community-mysql.spec +++ b/community-mysql.spec @@ -61,6 +61,7 @@ Patch22: community-mysql-major.patch Patch23: community-mysql-sharedir.patch Patch24: community-mysql-man-pages.patch Patch25: community-mysql-tmpdir.patch +Patch26: community-mysql-cve-2013-1861.patch BuildRequires: perl, readline-devel, openssl-devel BuildRequires: cmake, ncurses-devel, zlib-devel, libaio-devel @@ -244,6 +245,7 @@ the MySQL sources. %patch23 -p1 %patch24 -p1 %patch25 -p1 +%patch26 -p1 # workaround for upstream bug #56342 rm -f mysql-test/t/ssl_8k_key-master.opt @@ -708,6 +710,8 @@ install -m 0644 mysql-test/rh-skipped-tests.list ${RPM_BUILD_ROOT}%{_datadir}/my - Use /var/tmp as default tmpdir to prevent potential issues Resolves: #905635 - Fix test suite requirements +- Fix for CVE-2013-1861 backported from MariaDB + Resolves: #921836 * Wed May 29 2013 Jan Stanek 5.5.31-6 - Added missing command-line options to man-pages (#948930)