Bug #89543 stack-overflow on gis.geojson_functions / json.json_functions_innodb
Submitted: 6 Feb 2018 4:08 Modified: 21 Mar 2018 8:57
Reporter: Laurynas Biveinis (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: JSON Severity:S3 (Non-critical)
Version:8.0.4 OS:Any
Assigned to: CPU Architecture:Any
Tags: asan, json

[6 Feb 2018 4:08] Laurynas Biveinis
Description:
On a debug build with ASan and UBSan enabled:

gis.geojson_functions                    [ fail ]
        Test ended at 2018-02-06 06:05:24

CURRENT_TEST: gis.geojson_functions
mysqltest: At line 3854: query 'SELECT ST_GeomFromGeoJSON(REPEAT('[', 1000))' failed with wrong errno 2013: 'Lost connection to MySQL server during query', instead of 3157...
...
ASAN:DEADLYSIGNAL
=================================================================
==1455==ERROR: AddressSanitizer: stack-overflow on address 0x7f7b427bac98 (pc 0x7f7b637afad0 bp 0x7f7b427bb4e0 sp 0x7f7b427bac80 T30)
    #0 0x7f7b637afacf in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeacf)
    #1 0x55dba229e940 in my_raw_malloc /home/laurynas/mysql-8.0.4/mysys/my_malloc.cc:219
    #2 0x55dba229e940 in my_malloc /home/laurynas/mysql-8.0.4/mysys/my_malloc.cc:84
    #3 0x55db9c367a66 in Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > >::allocate(unsigned long, std::unique_ptr<Json_dom, std::default_delete<Json_dom> > const*) /home/laurynas/mysql-8.0.4/sql/malloc_allocator.h:105
    #4 0x55db9c367a66 in std::allocator_traits<Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::allocate(Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > >&, unsigned long) /usr/include/c++/7/bits/alloc_traits.h:301
    #5 0x55db9c367a66 in std::_Vector_base<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::_M_allocate(unsigned long) /usr/include/c++/7/bits/stl_vector.h:172
    #6 0x55db9c367a66 in void std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::_M_realloc_insert<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > >(__gnu_cxx::__normal_iterator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >*, std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > > >, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >&&) /usr/include/c++/7/bits/vector.tcc:406
    #7 0x55db9c310a89 in std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::_M_insert_rval(__gnu_cxx::__normal_iterator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > const*, std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > > >, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >&&) /usr/include/c++/7/bits/vector.tcc:327
    #8 0x55db9c310a89 in std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::_M_emplace_aux(__gnu_cxx::__normal_iterator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > const*, std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > > >, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >&&) /usr/include/c++/7/bits/stl_vector.h:1492
    #9 0x55db9c310a89 in __gnu_cxx::__normal_iterator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >*, std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > > > std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > >::emplace<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > >(__gnu_cxx::__normal_iterator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > const*, std::vector<std::unique_ptr<Json_dom, std::default_delete<Json_dom> >, Malloc_allocator<std::unique_ptr<Json_dom, std::default_delete<Json_dom> > > > >, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >&&) /usr/include/c++/7/bits/stl_vector.h:998
    #10 0x55db9c310a89 in Json_array::insert_alias(unsigned long, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >) /home/laurynas/mysql-8.0.4/sql/json_dom.cc:1285
    #11 0x55db9c312478 in Json_array::append_alias(std::unique_ptr<Json_dom, std::default_delete<Json_dom> >) /home/laurynas/mysql-8.0.4/sql/json_dom.h:584
    #12 0x55db9c312478 in seeing_value /home/laurynas/mysql-8.0.4/sql/json_dom.cc:515
    #13 0x55db9c34c18d in StartArray /home/laurynas/mysql-8.0.4/sql/json_dom.cc:623
    #14 0x55db9c34c18d in ParseArray<0, rapidjson::MemoryStream, (anonymous namespace)::Rapid_json_handler> /home/laurynas/mysql-8.0.4/extra/rapidjson/include/rapidjson/reader.h:661
...
    #172 0x55db9c354c64 in ParseArray<0, rapidjson::MemoryStream, (anonymous namespace)::Rapid_json_handler> /home/laurynas/mysql-8.0.4/extra/rapidjson/include/rapidjson/reader.h:674
    #173 0x55db9c354c64 in ParseValue<0, rapidjson::MemoryStream, (anonymous namespace)::Rapid_json_handler> /home/laurynas/mysql-8.0.4/extra/rapidjson/include/rapidjson/reader.h:1399
    #174 0x55db9c357bbf in Parse<0, rapidjson::MemoryStream, (anonymous namespace)::Rapid_json_handler> /home/laurynas/mysql-8.0.4/extra/rapidjson/include/rapidjson/reader.h:501
    #175 0x55db9c357bbf in Json_dom::parse(char const*, unsigned long, char const**, unsigned long*) /home/laurynas/mysql-8.0.4/sql/json_dom.cc:679
    #176 0x55db9bdaa7fd in parse_json(String const&, unsigned int, char const*, std::unique_ptr<Json_dom, std::default_delete<Json_dom> >*, bool, bool*) /home/laurynas/mysql-8.0.4/sql/item_json_func.cc:153
    #177 0x55db9bdb5973 in json_is_valid /home/laurynas/mysql-8.0.4/sql/item_json_func.cc:315
    #178 0x55db9bdb6a11 in get_json_wrapper(Item**, unsigned int, String*, char const*, Json_wrapper*) /home/laurynas/mysql-8.0.4/sql/item_json_func.cc:1009
    #179 0x55db9cff7d9a in Item_func_geomfromgeojson::val_str(String*) /home/laurynas/mysql-8.0.4/sql/item_geofunc.cc:1033
    #180 0x55db9b776fad in Item::send(Protocol*, String*) /home/laurynas/mysql-8.0.4/sql/item.cc:7540
    #181 0x55db988f3243 in THD::send_result_set_row(List<Item>*) /home/laurynas/mysql-8.0.4/sql/sql_class.cc:2883
    #182 0x55db9c611fb1 in Query_result_send::send_data(List<Item>&) /home/laurynas/mysql-8.0.4/sql/query_result.cc:103
    #183 0x55db98a0a8fc in JOIN::exec() /home/laurynas/mysql-8.0.4/sql/sql_executor.cc:263
    #184 0x55db98e49ae9 in Sql_cmd_dml::execute_inner(THD*) /home/laurynas/mysql-8.0.4/sql/sql_select.cc:736
    #185 0x55db98eabd2e in Sql_cmd_dml::execute(THD*) /home/laurynas/mysql-8.0.4/sql/sql_select.cc:616
    #186 0x55db98c3905d in mysql_execute_command(THD*, bool) /home/laurynas/mysql-8.0.4/sql/sql_parse.cc:4644
    #187 0x55db98c416fa in mysql_parse(THD*, Parser_state*) /home/laurynas/mysql-8.0.4/sql/sql_parse.cc:5440
    #188 0x55db98c50be9 in dispatch_command(THD*, COM_DATA const*, enum_server_command) /home/laurynas/mysql-8.0.4/sql/sql_parse.cc:1730
    #189 0x55db98c62de6 in do_command(THD*) /home/laurynas/mysql-8.0.4/sql/sql_parse.cc:1310
    #190 0x55db9ac0dbcb in handle_connection /home/laurynas/mysql-8.0.4/sql/conn_handler/connection_handler_per_thread.cc:335
    #191 0x55dba41c7a28 in pfs_spawn_thread /home/laurynas/mysql-8.0.4/storage/perfschema/pfs.cc:2994
    #192 0x7f7b634b97fb in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x77fb)
    #193 0x7f7b60af8b5e in clone (/lib/x86_64-linux-gnu/libc.so.6+0x114b5e)

How to repeat:
-DWITH_DEBUG=ON -DWITH_ASAN=ON -DWITH_UBSAN=ON
./mtr geojson_functions
 I have not tried checking whether the last CMake option for UBSan is required.
[6 Feb 2018 4:19] Laurynas Biveinis
Same seen on json.json_functions_innodb
[6 Feb 2018 5:17] MySQL Verification Team
Hello Laurynas,

Thank you for the report and feedback.

Thanks,
Umesh
[6 Feb 2018 5:21] MySQL Verification Team
test results

Attachment: 89543.results (application/octet-stream, text), 99.06 KiB.

[7 Feb 2018 9:06] Knut Anders Hatlen
I wasn't able to reproduce this with GCC 6.3. I was however able to reproduce it with GCC 7.3, but only when combining WITH_ASAN=ON and WITH_UBSAN=ON. I couldn't reproduce it with WITH_ASAN=ON alone. So it seems like UBSAN adds extra stack usage which makes parsing of some deeply nested JSON documents run out of stack space.
[21 Mar 2018 8:57] Knut Anders Hatlen
The two tests pass after the fix for bug#89961.