Skip to content
/ server Public

Commit 9fc46b8

Browse files
Alexey Botchkovvuvova
authored andcommitted
MDEV-38372 ASAN error in InnoDB on malformed WKB
Geometry::is_binary_valid() method added, and used to check WKB before storing in the engine.
1 parent 64c9efb commit 9fc46b8

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

mysql-test/suite/funcs_1/r/storedproc.result

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17283,8 +17283,7 @@ set f1 = f1;
1728317283
return f1;
1728417284
END//
1728517285
SELECT fn104('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?\0\0\0\0\0\0?\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@');
17286-
fn104('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?\0\0\0\0\0\0?\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@')
17287-
??@@@@
17286+
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
1728817287
DROP FUNCTION IF EXISTS fn105;
1728917288
CREATE FUNCTION fn105( f1 point) returns point
1729017289
BEGIN
@@ -18418,8 +18417,7 @@ set f1 = f1;
1841818417
SELECT f1;
1841918418
END//
1842018419
CALL sp104('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0?\0\0\0\0\0\0?\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@');
18421-
f1
18422-
??@@@@
18420+
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
1842318421
DROP PROCEDURE IF EXISTS sp105;
1842418422
CREATE PROCEDURE sp105( f1 point)
1842518423
BEGIN

mysql-test/suite/innodb_gis/r/0.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,15 @@ commit;
617617
disconnect a;
618618
connection default;
619619
drop table t1;
620+
#
621+
# MDEV-38372 ASAN error in InnoDB on malformed WKB
622+
#
623+
create table t1 (
624+
id int auto_increment primary key,
625+
geom geometry not null,
626+
spatial index (geom)
627+
) engine=innodb;
628+
insert t1 (geom) values (X'000000000107000000FF000000');
629+
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
630+
drop table t1;
631+
# End of 10.6 tests

mysql-test/suite/innodb_gis/t/0.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,18 @@ disconnect a;
4040
connection default;
4141
drop table t1;
4242

43+
--echo #
44+
--echo # MDEV-38372 ASAN error in InnoDB on malformed WKB
45+
--echo #
46+
create table t1 (
47+
id int auto_increment primary key,
48+
geom geometry not null,
49+
spatial index (geom)
50+
) engine=innodb;
51+
52+
--error ER_CANT_CREATE_GEOMETRY_OBJECT
53+
insert t1 (geom) values (X'000000000107000000FF000000');
54+
drop table t1;
4355

56+
--echo # End of 10.6 tests
4457

sql/spatial.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,19 @@ class Geometry
269269

270270
virtual const Class_info *get_class_info() const=0;
271271
virtual uint32 get_data_size() const=0;
272+
273+
/*
274+
The 'binary_valid' spatial object can be stored in the database
275+
and be the correct argument to the spatial functions.
276+
It can still be not valid by the OPENGIS standard like
277+
having self-intersecting borders.
278+
*/
279+
bool is_binary_valid() const
280+
{
281+
uint32 data_size= get_data_size();
282+
283+
return (data_size == GET_SIZE_ERROR) ? false : !no_data(m_data, data_size);
284+
}
272285
virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0;
273286
/* returns the length of the wkb that was read */
274287
virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,

sql/sql_type_geom.cc

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,12 @@ int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
854854
wkb_type > (uint32) Geometry::wkb_last)
855855
goto err;
856856

857+
const char *dummy;
858+
Geometry_buffer buffer;
859+
Geometry *geom= Geometry::construct(&buffer, from, uint32(length));
860+
if (!geom || !geom->is_binary_valid())
861+
goto err;
862+
857863
if (m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRY &&
858864
m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRYCOLLECTION &&
859865
(uint32) m_type_handler->geometry_type() != wkb_type)
@@ -866,21 +872,14 @@ int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
866872
if (!tab_name)
867873
tab_name= "";
868874

869-
Geometry_buffer buffer;
870-
Geometry *geom= NULL;
871-
String wkt;
872-
const char *dummy;
873-
wkt.set_charset(&my_charset_latin1);
874-
if (!(geom= Geometry::construct(&buffer, from, uint32(length))) ||
875-
geom->as_wkt(&wkt, &dummy))
875+
StringBuffer<STRING_BUFFER_USUAL_SIZE> wkt(&my_charset_latin1);
876+
if (geom->as_wkt(&wkt, &dummy))
876877
goto err;
877878

878879
my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0),
879880
Geometry::ci_collection[m_type_handler->geometry_type()]->m_name.str,
880-
wkt.c_ptr_safe(),
881-
db, tab_name, field_name.str,
882-
(ulong) table->in_use->get_stmt_da()->
883-
current_row_for_warning());
881+
wkt.c_ptr_safe(), db, tab_name, field_name.str,
882+
(ulong) table->in_use->get_stmt_da()->current_row_for_warning());
884883
goto err_exit;
885884
}
886885

0 commit comments

Comments
 (0)