oracle / odpi

ODPI-C: Oracle Database Programming Interface for Drivers and Applications
https://oracle.github.io/odpi/
Other
264 stars 75 forks source link

double free or corruption in dpiStmt_release #141

Closed protamail closed 4 years ago

protamail commented 4 years ago

If non-existing variable is bound, subsequent stmt close causes corruption.

  1. Latest git pull (4.1)

  2. Redhat 6

  3. gcc 7.3

  4. What is your version of the Oracle Client (e.g. Instant Client)? How was it installed? Where it is installed?

  5. 11.2.0.4

  6. LD_LIBRARY_PATH=/path/to/libodpic.so.4.1.0

  7. No

  8. When dpiStmt_release is called, the following error appears

    ERROR: ORA-01036: illegal variable name/number (dpiStmt_bindValueByPos: bind by position), offset: 0
    *** glibc detected *** ./build/DemoFetch: double free or corruption (top): 0x00000000017cecb0 ***
    ======= Backtrace: =========
    /lib64/libc.so.6[0x39dd275e5e]
    /lib64/libc.so.6[0x39dd278cf0]
    /opt/app/workload/odpi/lib/libodpic.so.4(dpiStmt__close+0xa9)[0x7f7a874d4359]
    /opt/app/workload/odpi/lib/libodpic.so.4(dpiStmt__free+0x1a)[0x7f7a874d45aa]
    /opt/app/workload/odpi/lib/libodpic.so.4(dpiGen__release+0x28)[0x7f7a874cdfc8]
    ./build/DemoFetch[0x401279]
    /lib64/libc.so.6(__libc_start_main+0x100)[0x39dd21ed20]
    ./build/DemoFetch[0x401341]
    ======= Memory map: ========
  9. #include "SampleLib.h"
    int main(void)
    {
    dpiData *intColValue;
    uint32_t numQueryColumns, bufferRowIndex;
    dpiData bindValue;
    dpiNativeTypeNum nativeTypeNum;
    dpiStmt *stmt = NULL;
    dpiConn *conn = NULL;
    int found;
    
    conn = dpiSamples_getConn(1, NULL);
    bindValue.value.asInt64 = 10;
    bindValue.isNull = 0;
    
    #define SQL "select 1 from dual where 10=:a"
    if (dpiConn_prepareStmt(conn, 0, SQL, strlen(SQL), NULL, 0, &stmt) < 0)
        goto fail;
    if (dpiStmt_bindValueByPos(stmt, 1, DPI_NATIVE_TYPE_INT64, &bindValue) < 0)
        goto fail;
    if (dpiStmt_bindValueByPos(stmt, 2, DPI_NATIVE_TYPE_INT64, &bindValue) < 0)
        goto fail;
    if (dpiStmt_execute(stmt, 0, &numQueryColumns) < 0)
        goto fail;
    
    while (1) {
        if (dpiStmt_fetch(stmt, &found, &bufferRowIndex) < 0)
            goto fail;
        if (!found)
            break;
        if (dpiStmt_getQueryValue(stmt, 1, &nativeTypeNum, &intColValue) < 0)
            goto fail;
        printf("Row: Int = %" PRId64 "\n", intColValue->value.asInt64);
    }
    done:
    if (stmt)
        dpiStmt_release(stmt);
    if (conn)
        dpiConn_release(conn);
    return 0;
    fail:
    dpiSamples_showError();
    goto done;
    }

    -->

anthony-tuininga commented 4 years ago

Thanks. I can replicate the issue. I'll get back to you on the fix shortly, I hope!

anthony-tuininga commented 4 years ago

Problem solved, I believe. Let me know if you agree! I found some duplicated code which I removed at the same time.

protamail commented 4 years ago

Works fine for me. Thanks!