[MDEV-26161] crash in Gis_point::calculate_haversine Created: 2021-07-16  Updated: 2023-04-27

Status: Stalled
Project: MariaDB Server
Component/s: GIS
Affects Version/s: 10.6.3, 10.2, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: sbester1 Assignee: Alexey Botchkov
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux x64


Issue Links:
Blocks
is blocked by MDEV-27666 User variable not parsed as geometry ... Closed
is blocked by MDEV-27838 Add handling of correct byte order in... Open
Relates
relates to MDEV-13467 Feature request: Support for ST_Dista... Closed
relates to MDEV-27639 Create better descriptive error messa... Open

 Description   

 
Version: '10.6.3-MariaDB'  MariaDB Server
 
Thread 26 "mysqld" received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0  in Gis_point::calculate_haversine at ./sql/spatial.cc:1112
#1  in Gis_multi_point::spherical_distance_multipoints at ./sql/spatial.cc:2365
#2  in Item_func_sphere_distance::spherical_distance_points at ./sql/item_geofunc.cc:2637
#3  in Item_func_sphere_distance::val_real at ./sql/item_geofunc.cc:2568
#4  in Item_func::is_null at ./sql/item_func.h:176
#5  in mysql_do at ./sql/sql_do.cc:35
#6  in mysql_execute_command at ./sql/sql_parse.cc:3976
#7  in mysql_parse at ./sql/sql_parse.cc:8026
#8  in dispatch_command at ./sql/sql_parse.cc:1896
#9  in do_command at ./sql/sql_parse.cc:1405
#10 in do_handle_one_connection at ./sql/sql_connect.cc:1410
#11 in handle_one_connection at ./sql/sql_connect.cc:1312
#12 in pfs_spawn_thread at ./storage/perfschema/pfs.cc:2201

Testcase

do st_distance_sphere(
 st_asbinary(
  polygon(
   linestring(
    point(-19655,-18908), 
    point(-10261,-7746), 
    point(31432,-18255), 
    point(-19655,-18908)
   ),
   linestring(
    point(-10494,19004),
    point(-18181,-24299),
    point(20616,19685),
    point(-10494,19004)
   ),
   linestring(
    point(8904,-21761),
    point(-24528,3798),
    point(-2502,-2889),
    point(8904,-21761)
   ),
   linestring(
    point(-7451,-19434),
    point(-30558,-27426),
    point(19086,17469),
    point(-7451,-19434)
   )
  )
 ),
 multipoint(
  point(124,204)
 ),
 3232164176
);



 Comments   
Comment by Alice Sherepa [ 2021-07-16 ]

Thank you!
I repeated on 10.2-10.6. On debug builds: spatial.cc:2361: int Gis_multi_point::spherical_distance_multipoints(Geometry*, double, double*, int*): Assertion `temp' failed.

10.2 fb0b28932ce82903f2fcf

 
#0  __pthread_kill (threadid=<optimized out>, signo=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:56
#1  0x00005599ffbe62c3 in my_write_core (sig=6) at /10.2/src/mysys/stacktrace.c:382
#2  0x00005599ff48a3eb in handle_fatal_signal (sig=6) at /10.2/src/sql/signal_handler.cc:355
#3  <signal handler called>
#4  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#5  0x00007f1bf0efc859 in __GI_abort () at abort.c:79
#6  0x00007f1bf0efc729 in __assert_fail_base (fmt=0x7f1bf1092588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x5599ffdb4154 "temp", file=0x5599ffdb3d38 "/10.2/src/sql/spatial.cc", line=2337, function=<optimized out>) at assert.c:92
#7  0x00007f1bf0f0df36 in __GI___assert_fail (assertion=0x5599ffdb4154 "temp", file=0x5599ffdb3d38 "/10.2/src/sql/spatial.cc", line=2337, function=0x5599ffdb4288 "int Gis_multi_point::spherical_distance_multipoints(Geometry*, double, double*, int*)") at assert.c:101
#8  0x00005599ff612d51 in Gis_multi_point::spherical_distance_multipoints (this=0x7f1be0588530, g=0x7f1be0588550, r=3232164176, result=0x7f1be0588498, err=0x7f1be0588490) at /10.2/src/sql/spatial.cc:2337
#9  0x00005599ff5305a1 in Item_func_sphere_distance::spherical_distance_points (this=0x7f1b80014640, g1=0x7f1be0588530, g2=0x7f1be0588550, r=3232164176) at /10.2/src/sql/item_geofunc.cc:2656
#10 0x00005599ff53029e in Item_func_sphere_distance::val_real (this=0x7f1b80014640) at /10.2/src/sql/item_geofunc.cc:2588
#11 0x00005599ff12bc02 in Item::update_null_value (this=0x7f1b80014640) at /10.2/src/sql/item.h:1577
#12 0x00005599ff1ca53c in Item_func::is_null (this=0x7f1b80014640) at /10.2/src/sql/item_func.h:180
#13 0x00005599ff624bf3 in mysql_do (thd=0x7f1b80000d90, values=...) at /10.2/src/sql/sql_do.cc:35
#14 0x00005599ff206834 in mysql_execute_command (thd=0x7f1b80000d90) at /10.2/src/sql/sql_parse.cc:3611
#15 0x00005599ff213996 in mysql_parse (thd=0x7f1b80000d90, rawbuf=0x7f1b800114d8 "do st_distance_sphere(\nst_asbinary(\npolygon(\nlinestring(\npoint(-19655,-18908), \npoint(-10261,-7746), \npoint(31432,-18255), \npoint(-19655,-18908)\n),\nlinestring(\npoint(-10494,19004),\npoint(-18181,-24299"..., length=484, parser_state=0x7f1be0589560, is_com_multi=false, is_next_command=false) at /10.2/src/sql/sql_parse.cc:7793
#16 0x00005599ff201bf1 in dispatch_command (command=COM_QUERY, thd=0x7f1b80000d90, packet=0x7f1b80008c61 "do st_distance_sphere(\nst_asbinary(\npolygon(\nlinestring(\npoint(-19655,-18908), \npoint(-10261,-7746), \npoint(31432,-18255), \npoint(-19655,-18908)\n),\nlinestring(\npoint(-10494,19004),\npoint(-18181,-24299"..., packet_length=484, is_com_multi=false, is_next_command=false) at /10.2/src/sql/sql_parse.cc:1827
#17 0x00005599ff2006ec in do_command (thd=0x7f1b80000d90) at /10.2/src/sql/sql_parse.cc:1381
#18 0x00005599ff35c00d in do_handle_one_connection (connect=0x559a00f8c4b0) at /10.2/src/sql/sql_connect.cc:1336
#19 0x00005599ff35bd72 in handle_one_connection (arg=0x559a00f8c4b0) at /10.2/src/sql/sql_connect.cc:1241
#20 0x00005599ffb883e0 in pfs_spawn_thread (arg=0x559a00f8c7f0) at /10.2/src/storage/perfschema/pfs.cc:1869
#21 0x00007f1bf141e609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x00007f1bf0ff9293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Comment by Anel Husakovic [ 2021-07-17 ]

What do you expect to be the result here?
Tested with Mysql

Comment by Anel Husakovic [ 2021-07-17 ]

Geometries that are allowed to be used are point and multipoint - documentation

Comment by sbester1 [ 2021-07-17 ]

Closing this bug without fixing the crash is not the right thing to do IMHO. All functions need to be able to gracefully handle even incorrectly typed arguments.

Comment by Anel Husakovic [ 2021-07-17 ]

Agree, bug reopen.

Comment by Alexey Botchkov [ 2022-01-27 ]

The st_asbinary() function doesn't return the geometry feature, just the WKB - it's standard binary representation.
And that representation should be treated as an arbitraty binary string, not the spatial object.
So this

st_distance_sphere(
   st_asbinary(...)

just not supposed to work.
There's the 'st_geomfromwkb' function that produces the spatial object from it's WKB.
So this supposed to work:

st_distance_sphere(
 st_geomfromwkb(
 st_asbinary(

The solution i'd propose - just to test that the arg1 and arg2 of st_sphere_distance() are geometries.
could be done like

if (args[0]->field_type() != MSYQL_FIELD_TYPE_GEOMETRY ||
    args[2]->field_type() != MYSQL_FIELD_TYPE_GEOMETRY)
 {
    my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_Distance_Sphere");
    goto handle_errors;
  }

Comment by Anel Husakovic [ 2022-01-27 ]

Hi holyfoot,
I have applied the patch and tried to compare the results with MySQL
Patch:

+  if (args[0]->field_type() != MYSQL_TYPE_GEOMETRY ||
+      args[1]->field_type() != MYSQL_TYPE_GEOMETRY)
   {
+    my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_Distance_Sphere");
+    goto handle_errors;
   }

Here is what I got when compared to MySQL, please note difference in error message compared to NULLs:

1. SET @poly = ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))'); SELECT ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)')); # gis data
 
- MySQL
ERROR 3055 (HY000) at line 1: Geometry byte string must be little endian.
 
- MariaDB
ERROR 22023: Invalid GIS data provided to function ST_Distance_Sphere.
 
 
2. SELECT ST_DISTANCE_SPHERE(ST_AsBinary(polygon(point(0,0),point(0,1),point(1,1),point(1,0),point(0,0))), ST_GEOMFROMTEXT('POINT(2 0)'));
- MySQL
ERROR 1210 (HY000) at line 1: Incorrect arguments to polygon
 
- MariaDB
NULL
 
3. SET @poly = ST_GeomFromText('POLYGON(LINESTRING(0 0,0 1,1 1,1 0,0 0))'); SELECT ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)')); 
 
- MySQL
ERROR 3037 (22023) at line 1: Invalid GIS data provided to function st_geometryfromtext.
 
- MariaDB
NULL
 
4. SELECT ST_DISTANCE_SPHERE(ST_AsBinary(polygon(linestring(point(0,0),point(0,1),point(1,1),point(1,0),point(0,0)))), ST_GEOMFROMTEXT('POINT(2 0)')); # gis data
 
- MySQL
ERROR 3055 (HY000) at line 1: Geometry byte string must be little endian.
 
 
- MariaDB
ERROR 22023: Invalid GIS data provided to function ST_Distance_Sphere.
 
 
5. SET @poly = NULL; SELECT ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)'));
 
- MySQL:
+-----------------------------------------------------------------------+
| ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)')) |
+-----------------------------------------------------------------------+
|                                                                  NULL |
+-----------------------------------------------------------------------+
 
- MariaDB:
 
NULL

Maybe to handle this error message to be more descriptive as the specific task?

  • Note also that with this type of the patch `set @p = point` must be corrected what is not good.
    Here is the patch 2e2be73a1d54e497
  • Seems that suggested patch is blocked by MDEV-27666.
Comment by Alexey Botchkov [ 2022-02-11 ]

See my comment in the patch.
Otherwise looks fine, can be pushed after that fixed.

Comment by Anel Husakovic [ 2022-02-14 ]

holyfoot thanks for the comment.
However still this will not work:

ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)'))

Note that it works in MySQL:

  • MySQL (@poly =NULL and also for @poly !=NULL) :

    +-----------------------------------------------------------------------+
    | ST_DISTANCE_SPHERE(ST_AsBinary(@poly), ST_GEOMFROMTEXT('POINT(2 0)')) |
    +-----------------------------------------------------------------------+
    |                                                                  NULL |
    +-----------------------------------------------------------------------+
    

and suggested approach will not solve it.

When updated per your suggestion, I get the error ER_GIS_INVALID_DATA, since ST_ASBINARY is WKB -> Item_func_as_wkb::field_type() = MYSQL_TYPE_BLOB, but we want to get rid of MYSQL_TYPE_BLOB because of the current MDEV. Should MDEV-27666 be solved first? What do you suggest as an solution to implement ?

However here is the commit 3136b68d3be061dd99

Comment by Alexey Botchkov [ 2022-03-14 ]

ok to push.

Comment by Anel Husakovic [ 2022-05-03 ]

Hi holyfoot any update on this?

Comment by Michael Widenius [ 2022-05-10 ]

I increased priority to blocker as this is a crash that looks like anyone could get

Comment by Alexey Botchkov [ 2022-10-25 ]

The fix was pushed so the server doesn't crash, we get the BAD GEOMETRY error instead.
Still it'd be good to fix it properly so the types of the arguments are cheked to produce more meaningful error when non-geometry data is sent.

Generated at Thu Feb 08 09:43:12 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.