I'm currently using the ODBC Client v3.1.3 in production to connect to MemSql databases on linux. It has a performance issue when retrieving large amounts of data, however, so I'm trying to upgrade to v3.1.7.
Unfortunately I'm seeing memory corruption when doing basic select queries returning multiple rows. I don't have the source code for 3.1.7, but based on the v3.1.9 code available in git, and some debugging with valgrind, it looks like the problem is in the new MoveNext function. Here's an analysis from a colleague:
- There are two data structures: Stmt->result and Stmt->stmt->bind. The flow is basically populate result and memcpy into bind.
- If your query is broken up into multiple chunks (e.g., the number of rows exceeds your buffer size), we free the previous statement before fetching the next result set.
- This frees Stmt->result. However, because of the memcpy, portions of that memory are still pointed to by Stmt->stmt->bind.
- In older versions this didn't appear to be a problem since we never wrote to it; we just memcpy'd over it (it's also not clear that length was initialized in the same way). However, in the new code there is an API called MoveNext that does a whole bunch of things. One of those things is adding the flag MADB_BIND_DUMMY.
- This flag causes the code to take a different branch where it tries to write to Stmt->stmt->bind[ 0 ]->length which is a pointer into memory we freed causing the heap corruption.
Stack trace just shows that it's crashing in libmaodbc.so, which is called from our linux driver manager: