Bug #93646 mysqlx_session_valid() results in Segmentation fault
Submitted: 17 Dec 2018 19:25 Modified: 18 Nov 2019 18:45
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Closed 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] MySQL Verification Team
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.
[15 Nov 2019 13:22] Rafal Somla
Posted by developer:
 
Doxygen documentation for the relevant functions was updated to clearly inform that the functions invalidate handles which cannot be used afterwards.

Note: No functionality was changed - it is only a documentation update.
[18 Nov 2019 18:45] Paul DuBois
Posted by developer:
 
Documentation update only. No changelog entry required.