Skip to content

Commit

Permalink
Fix test main.bug12969156 when WITH_ASAN=ON
Browse files Browse the repository at this point in the history
*Problem:*

ASAN complains about stack-buffer-overflow on function `mysql_heartbeat`:

```
==90890==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fe746d06d14 at pc 0x7fe760f5b017 bp 0x7fe746d06cd0 sp 0x7fe746d06478
WRITE of size 24 at 0x7fe746d06d14 thread T16777215

Address 0x7fe746d06d14 is located in stack of thread T26 at offset 340 in frame
    #0 0x7fe746d0a55c in mysql_heartbeat(void*) /home/yura/ws/percona-server/plugin/daemon_example/daemon_example.cc:62

  This frame has 4 object(s):
    [48, 56) 'result' (line 66)
    [80, 112) '_db_stack_frame_' (line 63)
    [144, 200) 'tm_tmp' (line 67)
    [240, 340) 'buffer' (line 65) <== Memory access at offset 340 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
Thread T26 created by T25 here:
    #0 0x7fe760f5f6d5 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:216
    #1 0x557ccbbcb857 in my_thread_create /home/yura/ws/percona-server/mysys/my_thread.c:104
    #2 0x7fe746d0b21a in daemon_example_plugin_init /home/yura/ws/percona-server/plugin/daemon_example/daemon_example.cc:148
    #3 0x557ccb4c69c7 in plugin_initialize /home/yura/ws/percona-server/sql/sql_plugin.cc:1279
    #4 0x557ccb4d19cd in mysql_install_plugin /home/yura/ws/percona-server/sql/sql_plugin.cc:2279
    #5 0x557ccb4d218f in Sql_cmd_install_plugin::execute(THD*) /home/yura/ws/percona-server/sql/sql_plugin.cc:4664
    #6 0x557ccb47695e in mysql_execute_command(THD*, bool) /home/yura/ws/percona-server/sql/sql_parse.cc:5160
    #7 0x557ccb47977c in mysql_parse(THD*, Parser_state*, bool) /home/yura/ws/percona-server/sql/sql_parse.cc:5952
    percona#8 0x557ccb47b6c2 in dispatch_command(THD*, COM_DATA const*, enum_server_command) /home/yura/ws/percona-server/sql/sql_parse.cc:1544
    percona#9 0x557ccb47de1d in do_command(THD*) /home/yura/ws/percona-server/sql/sql_parse.cc:1065
    percona#10 0x557ccb6ac294 in handle_connection /home/yura/ws/percona-server/sql/conn_handler/connection_handler_per_thread.cc:325
    percona#11 0x557ccbbfabb0 in pfs_spawn_thread /home/yura/ws/percona-server/storage/perfschema/pfs.cc:2198
    percona#12 0x7fe760ab544f in start_thread nptl/pthread_create.c:473
```

The reason is that `my_thread_cancel` is used to finish the daemon thread. This is not and orderly way of finishing the thread. ASAN does not register the stack variables are not used anymore which generates the error above.

This is a benign error as all the variables are on the stack.

*Solution*:

Finish the thread in orderly way by using a signalling variable.
  • Loading branch information
Luis Donoso committed Apr 4, 2022
1 parent fe7b7ad commit 52732c4
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions plugin/daemon_example/daemon_example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <mysql/plugin.h>
#include <my_dir.h>
#include "my_thread.h"
#include "my_atomic.h"
#include "my_sys.h" // my_write, my_malloc
#include "m_string.h" // strlen
#include "sql_plugin.h" // st_plugin_int
Expand Down Expand Up @@ -56,6 +57,7 @@ struct mysql_heartbeat_context
{
my_thread_handle heartbeat_thread;
File heartbeat_file;
int32 done;
};

void *mysql_heartbeat(void *p)
Expand All @@ -66,7 +68,7 @@ void *mysql_heartbeat(void *p)
time_t result;
struct tm tm_tmp;

while(1)
while(my_atomic_load32(&con->done) != 1)
{
sleep(5);

Expand Down Expand Up @@ -125,6 +127,7 @@ static int daemon_example_plugin_init(void *p)
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
unlink(heartbeat_filename);
con->heartbeat_file= my_open(heartbeat_filename, O_CREAT|O_RDWR, MYF(0));
con->done= 0;

/*
No threads exist at this point in time, so this is thread safe.
Expand All @@ -143,7 +146,6 @@ static int daemon_example_plugin_init(void *p)
my_thread_attr_init(&attr);
my_thread_attr_setdetachstate(&attr, MY_THREAD_CREATE_JOINABLE);


/* now create the thread */
if (my_thread_create(&con->heartbeat_thread, &attr, mysql_heartbeat,
(void *)con) != 0)
Expand Down Expand Up @@ -181,7 +183,7 @@ static int daemon_example_plugin_deinit(void *p)
struct tm tm_tmp;
void *dummy_retval;

my_thread_cancel(&con->heartbeat_thread);
my_atomic_store32(&con->done, 1);

localtime_r(&result, &tm_tmp);
my_snprintf(buffer, sizeof(buffer),
Expand Down

0 comments on commit 52732c4

Please sign in to comment.