Bug #93646 mysqlx_session_valid() results in Segmentation fault
Submitted: 17 Dec 2018 19:25 Modified: 20 Dec 2018 20:10
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:Connector / C++ Severity:S3 (Non-critical)
Version:8.0.13 OS:Any
Assigned to: CPU Architecture:Any

[17 Dec 2018 19:25] Daniël van Eeden
Description:
Docs: https://dev.mysql.com/doc/dev/connector-cpp/8.0/group__xapi__sess.html#gadb96260c0499a1563...

Calling mysqlx_session_valid(sess) after calling mysqlx_session_close(sess) results in a SIGSEGV.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7d7bb69 in cdk::foundation::api::Async_op_base::wait (this=0x4409e8)
    at /home/dvaneeden/dev/mysql-connector-cpp/cdk/include/mysql/cdk/foundation/async.h:77
77	    if (is_completed()) return;
(gdb) bt
#0  0x00007ffff7d7bb69 in cdk::foundation::api::Async_op_base::wait (this=0x4409e8)
    at /home/dvaneeden/dev/mysql-connector-cpp/cdk/include/mysql/cdk/foundation/async.h:77
#1  0x00007ffff7e2a7a6 in cdk::mysqlx::Session::is_valid (this=0x4409e0) at /home/dvaneeden/dev/mysql-connector-cpp/cdk/mysqlx/session.cc:447
#2  0x00007ffff7daa780 in cdk::Session::is_valid (this=0x41b178) at /home/dvaneeden/dev/mysql-connector-cpp/cdk/include/mysql/cdk/session.h:82
#3  0x00007ffff7db3008 in mysqlx_session_struct::is_valid (this=0x41a6a0) at /home/dvaneeden/dev/mysql-connector-cpp/xapi/mysqlx_cc_internal.h:207
#4  0x00007ffff7da6523 in mysqlx_session_valid (sess=0x41a6a0) at /home/dvaneeden/dev/mysql-connector-cpp/xapi/mysqlx.cc:1672
#5  0x000000000040118a in main ()

How to repeat:
#include <mysqlx/xapi.h>

int main() {
  mysqlx_session_t *sess = mysqlx_get_session_from_url("mysqlx://msandbox:msandbox@localhost/test", NULL, NULL);
  mysqlx_session_valid(sess);
  mysqlx_session_close(sess);
  mysqlx_session_valid(sess);
}

Suggested fix:
1. Make mysqlx_session_valid() return 0 if the session is closed

OR

2. Update the documentation if one must never call mysqlx_session_valid() on a closed session.
[18 Dec 2018 11:36] Bogdan Kecman
Hi Daniel,

Session handle becomes invalid after close as the memory is freed hence the crash. Our team will decide how to proceed.

Thanks for the report
Bogdan
[18 Dec 2018 13:26] Daniël van Eeden
Setting sess to NULL seems to work. Not sure if that's the best solution. 

-----
#include <mysqlx/xapi.h>

int main() {
  mysqlx_session_t *sess = mysqlx_get_session_from_url("mysqlx://msandbox:msandbox@localhost/test", NULL, NULL);
  mysqlx_session_valid(sess);

  mysqlx_session_close(sess);
  sess = NULL;

  mysqlx_session_valid(sess);
}
[20 Dec 2018 9:54] Rafal Somla
To be precise, after closing a session, the session is simply destroyed and no longer exists. The handle to the session (the mysqlx_session_t* pointer) becomes invalid or "dangling", similar like a pointer after a call to free(). Function mysqlx_session_valid() function does not check validity of the session handle, but of the session itself - it assumes that session handle you pass to it is valid. From that perspective, your second call to mysqlx_session_valid() is trying to check validity of a session that does not exist any more... Since it is plain C, we don't think we can detect if pointer is dangling or not - the best we can do is "undefined behavior", i.e., crash in this case.
[20 Dec 2018 20:10] Daniël van Eeden
In that case the second option I suggested seems to be the correct one: Update the documentation to say that mysqlx_session_close() invalidates the session and that it must not be used afterwards.

I think mysqlx_session_close() should have been called mysqlx_session_free() to be more explicit about what it does. But I guess it's too late to change that now.