[Libreoffice] [Bug 42865] New: MySQL native driver: free() on non-heap pointer; in debug mode abort()

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Sat Nov 12 16:40:09 PST 2011


https://bugs.freedesktop.org/show_bug.cgi?id=42865

             Bug #: 42865
           Summary: MySQL native driver: free() on non-heap pointer; in
                    debug mode abort()
    Classification: Unclassified
           Product: LibreOffice
           Version: LibO Master
          Platform: All
        OS/Version: All
            Status: ASSIGNED
          Severity: major
          Priority: medium
         Component: Database
        AssignedTo: lionel at mamane.lu
        ReportedBy: lionel at mamane.lu
                CC: mstahl at redhat.com


Open a .odb file that uses the native MySQL driver. Click on "tables" in the
left column to see the list of available tables.

free() is called on a pointer that was not malloc()ed; on a dbgutil build, this
leads to an immediate abort() since commit
e0c72547ce57c25db61ec3da6c2f2f2792348c7d, which enables libstdc++ debug mode in
dbgutil build.

The root cause is the interplay of how libstdc++ handles empty std::string and
mysqlc.uno.so's version script:

libstdc++ does not allocate heap memory for an empty std::string, but makes the
data pointer point to a constant, the symbol _S_empty_rep_storage (initialised
by the linker). The std::string destructor does something along the lines of:

if (the_string.pData != &_S_empty_rep_storage)
   free(the_string.pData)

Normally, the symbol _S_empty_rep_storage is unique global across the whole
process (GNU extension to ELF), so this works well. But the "local: *;" in
mysqlc.uno.so's version link script overrides that and makes the
_S_empty_rep_storage of mysqlc.uno.so different from the _S_empty_rep_storage
of libmysqlcppconn.so. But mysqlc.uno.so's getTables calls libmysqlcppconn.so's
getTables, and gets (among others) empty strings as result (wrapped in a
SQLString); the first occurrence is the name of the catalog of the table (MySQL
does not support catalogs).

When that empty string is destructed within mysqlc.uno.so, the destructor calls
free() on libmysqlcppconn.so's _S_empty_rep_storage, and boum!


The best fix would be to add

{
    global:
        _ZNSs4_Rep20_S_empty_rep_storageE;
};

to all version link scripts (to get rid of that problem *everywhere*), but that
is not allowed. I filed a request to allow that in GNU ld
(http://sourceware.org/bugzilla/show_bug.cgi?id=13406), but even if we get my
wish, we need another solution until that version of ld can become our
baseline... years away.

Note that exporting that symbol in UDK_3_0_0 (or any other named version) does
*not* work, it needs to be the anonymous version to be compatible with system
DSOs such as mysqlcppconn.so.


Removing the "local: *;" from all link scripts would lead to massive symbol
leak, defeating the purpose of link version scripts. Unless we do something
like *automatically* adding each and every symbol there, except for
"_ZNSs4_Rep20_S_empty_rep_storageE", e.g. with a script that does:

1) Link a first time without .map file
2) use nm/"objdump -T" to get symbols
3) add to .map file every symbol not already mentioned in another section,
except for _ZNSs4_Rep20_S_empty_rep_storageE.
4) Link again with .map file


Anybody got a better idea?


Note that this problem is probably not MySQL-specific, nor Base-specifing; it
will crop up with any external C++ lib that provides us with (potentially
empty) std::string.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
You reported the bug.



More information about the LibreOffice mailing list