Bug #112666 SQLDriverConnect() may cause memory leak (because of a bug in class `optionStr`)
Submitted: 9 Oct 2023 11:56 Modified: 11 Jul 2024 6:43
Reporter: Zixuan Fu (OCA) Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / ODBC Severity:S3 (Non-critical)
Version:8.1.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: bug, Contribution, memory leak

[9 Oct 2023 11:56] Zixuan Fu
Description:
SQLDriverConnect() may cause memory leak.

================= asan report =================

Direct leak of 160 byte(s) in 8 object(s) allocated from:
    #0 0x7ff87b2b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7ff876bdf9fe in sqlchar_as_sqlwchar mysql-connector-odbc/util/stringutil.cc:150
    #2 0x7ff876be6c92 in optionStr::set(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) mysql-connector-odbc/util/installer.cc:324
    #3 0x7ff876be6e89 in optionStr::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) mysql-connector-odbc/util/installer.cc:346
    #4 0x7ff876b152c2 in operator() mysql-connector-odbc/driver/connect.cc:817
    #5 0x7ff876b16c7a in DBC::connect(DataSource*) mysql-connector-odbc/driver/connect.cc:889
    #6 0x7ff876b184c4 in MySQLDriverConnect(void*, void*, unsigned short*, short, unsigned short*, short, short*, unsigned short) mysql-connector-odbc/driver/connect.cc:1395
    #7 0x7ff876b6090b in SQLDriverConnect mysql-connector-odbc/driver/ansi.cc:275
    #8 0x7ff87bc5e36f in SQLDriverConnect (/lib/x86_64-linux-gnu/libodbc.so.2+0x1a36f)
=================================================

void optionStr::set(const std::string &val, bool is_default = false) in util/installer.cc:

```
  SQLWCHAR *converted = sqlchar_as_sqlwchar(default_charset_info, (SQLCHAR*)val.c_str(), &len, nullptr);
  m_wstr = SQLWSTRING(converted, len);
```

`converted` is allocated by sqlchar_as_sqlwchar(), and SQLWSTRING copies data from it, and the variable `converted` is then dropped without being freed.

How to repeat:
build the client with ASAN, and connect to any mysql server with SQLDriverConnect().

Suggested fix:
add 
```
x_free(converted);
```
after
```
m_wstr = SQLWSTRING(converted, len);
```
[13 Oct 2023 12:06] MySQL Verification Team
Hello Zixuan,

Thank you for the bug report.
Could you please provide repeatable test case (sample project, etc. - please make it as private if you prefer) to confirm this issue at our end?

Regards,
Ashwini Patil
[5 Jul 2024 8:25] MySQL Verification Team
Thank you for the report and contribution.
[5 Jul 2024 16:04] Rafal Somla
Posted by developer:
 
Note: We can probably pull it off without a "repeatable test case". Provided description and analysis look solid enough.
[11 Jul 2024 6:43] Bogdan Degtyariov
Posted by developer:
 
The version 8.1 did not have x_free(converted), but it was added in 8.2.0 in commit 21066ea72fd22fe1c51f001ffae9de82e9a4abf7 (Fixes for unit tests and memory allocation).
The freeing of memory is present from 8.2.0 on.