[community-mysql] Fix for CVE-2013-1861 backported from MariaDB Resolves: #921836

Honza Horak hhorak at fedoraproject.org
Mon Jun 3 15:31:18 UTC 2013


commit 80c5bbde954f2af1be78abe8de6156328b73287c
Author: Honza HorĂ¡k <hhorak at redhat.com>
Date:   Mon Jun 3 17:30:42 2013 +0200

    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(+), 0 deletions(-)
---
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 <jstanek at redhat.com> 5.5.31-6
 - Added missing command-line options to man-pages (#948930)


More information about the scm-commits mailing list