https://bugs.openldap.org/show_bug.cgi?id=10162
Issue ID: 10162 Summary: Fix for binary attributes data corruption in back-sql Product: OpenLDAP Version: unspecified Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: backends Assignee: bugs@openldap.org Reporter: dex.tracers@gmail.com Target Milestone: ---
Created attachment 1006 --> https://bugs.openldap.org/attachment.cgi?id=1006&action=edit Fix for binary attributes corruption on backed-sql
I've configured slapd to use back-sql (mariadb through odbc) and observed issues with the BINARY data retrievals from the database. The length of the attributes was properly reported, but the correct data inside was always 16384 bytes and after that point - some junk (usually filled-up with AAAAAAAA and some other attributes data from memory).
During the debugging - I've noticed that: - The MAX_ATTR_LEN (16384 bytes) is used to set the length of the data for BINARY columns when SQLBindCol is done inside of the "backsql_BindRowAsStrings_x" function - After SQLFetch is done - data in row->cols[i] is fetched up to the specified MAX_ATTR_LEN - After SQLFetch is done - the correct data size (greater than MAX_ATTR_LEN) is represented inside of the row->value_len
I'm assuming that slapd allocates the pointer in memory (row->cols[i]), fills it with the specified amount of data (MAX_ATTR_LEN), but when forming the actual attribute data - uses the length from row->value_len and so everything from 16384 bytes position till row->value_len is just a junk from the memory (uninitialized, leftovers, data from other variables).
After an investigation, I've find-out that: - for BINARY or variable length fields - SQLGetData should be used - SQLGetData supports chunked mode (if length is unknown) or full-read mode if the length is known - it could be used in pair with SQLBindCol after SQLFetch (!)
Since we have the correct data length inside of row->value_len, I've just added the code to the backsql_get_attr_vals() function to overwrite the corrupted data with the correct data by issuing SQLGetData request. And it worked - binary data was properly retrieved and reported over LDAP!
My current concerns / help needed - I'm not very familiar with the memory allocation/deallocation mechanisms, so I'm afraid that mentioned change can lead to memory corruption (so far not observed).
Please review attached patch (testing was done on OPENLDAP_REL_ENG_2_5_13, and applied on the master branch for easier review/application).