FreeTDS / freetds

Official FreeTDS repository
http://www.freetds.org/
GNU General Public License v2.0
460 stars 159 forks source link

dblib crashed while calling the dbcmd after execute a invalid SQL #526

Open taozuhong opened 7 months ago

taozuhong commented 7 months ago

Enviroment

Vendor: SQL Server 2017 FreeTDS: 1.4.10

Reproduce step

  1. execute_model ALTER AUTHORIZATION ON SCHEMA::"abcd" TO "dbo"; ==> throw and capture error

  2. execute_model ALTER AUTHORIZATION ON SCHEMA::"abcd" TO "dbo"; ==> crashed, pls see stacktrace freetds.zip

Vala code tips cmd ==> dbcmd execute ==> dbsqlexec cancel ==> dbcancel results ==> dbresults can_query ==> dbcanquery

public TableModel execute_model(string statement, bool in_thread = false) throws Error
{
    lock(m_connection) {
        this.clear_results();
        this.raise_error(m_connection.cmd(statement));
        this.raise_error(m_connection.execute());

        var retval = m_connection.results();
        this.raise_error(retval);

        if ((ResultCode.NO_MORE_RESULTS != retval) && (0 < m_connection.column_count())) {
            return this.fill_model(statement);
        } else {
            throw new Error.literal(GLib.Quark.from_string("SQLServer"), -1, _("No data returned.")); 
        }
    }
}

private void clear_results() throws Error
{
    int retval = m_connection.sql_ok();
    this.raise_error(retval);

    // Pull else results and rows
    if (ResultCode.SUCCEED == retval) {
        /*
        This is to just process each result set. Commands such as backup and
        restore are not done when the first result set is returned, so we need to
        exhaust the result sets before it is complete.
        */
        while (ResultCode.NO_MORE_RESULTS != m_connection.results()) {
            /*
            If we don't loop through each row for calls to TinyTds::Result.do that
            actually do return result sets, we will trigger error 20019 about trying
            to execute a new command with pending results. Oh well.
            */
            while (ResultCode.NO_MORE_ROWS != m_connection.next_row());
        }
    }
    this.raise_error(m_connection.can_query());
    this.raise_error(m_connection.cancel());
    this.reset_error_data();
}
0x00007fff82f3c733 in ntdll!RtlIsZeroMemory () from C:\Windows\SYSTEM32\ntdll.dll
(gdb) bt
#0  0x00007fff82f3c733 in ntdll!RtlIsZeroMemory () from C:\Windows\SYSTEM32\ntdll.dll
#1  0x00007fff82f4580a in ntdll!.misaligned_access () from C:\Windows\SYSTEM32\ntdll.dll
#2  0x00007fff82f45aea in ntdll!.misaligned_access () from C:\Windows\SYSTEM32\ntdll.dll
#3  0x00007fff82f51ae5 in ntdll!.misaligned_access () from C:\Windows\SYSTEM32\ntdll.dll
#4  0x00007fff82e6becc in ntdll!RtlGetCurrentServiceSessionId () from C:\Windows\SYSTEM32\ntdll.dll
#5  0x00007fff82e6ab11 in ntdll!RtlFreeHeap () from C:\Windows\SYSTEM32\ntdll.dll
#6  0x00007fff802337eb in ucrtbase!_free_base () from C:\Windows\System32\ucrtbase.dll
#7  0x00007fff271d8908 in dbfreebuf (dbproc=0x1cb11210) at ../../../src/dblib/dblib.c:6092
#8  0x00007fff271d8a93 in dbcmd (dbproc=0x1cb11210,
    cmdstring=0x2610fe30 "ALTER AUTHORIZATION ON SCHEMA::\"abcd\" TO \"dbo\";")
    at ../../../src/dblib/dblib.c:1387
#9  0x00007fff2dceac42 in kangaroo_providers_supports_sql_server_provider_real_execute_statements (
    base=0x1ce4af50, statements=0x2610fe30 "ALTER AUTHORIZATION ON SCHEMA::\"abcd\" TO \"dbo\";",
    in_thread=1, result_length1=0x60ffd94, error=0x60ffd98)
    at ../Providers/Supports/SQLServer/provider.vala:157
#10 0x00007fff2dc92261 in kangaroo_providers_contracts_iprovider_execute_statements (
    self=0x1ce4af50, statements=0x2610fe30 "ALTER AUTHORIZATION ON SCHEMA::\"abcd\" TO \"dbo\";",
    in_thread=1, result_length1=0x60ffd94, error=0x60ffd98)
    at ../Providers/Contracts/face_provider.vala:22
freddy77 commented 7 months ago

Maybe a sequence of calls would be more helpful. A TDSDUMP with the last calls to DB-Library would be more helpful.

taozuhong commented 7 months ago

Thanks for your response, I have updated the execute sequence and TDSDUMP file to locate the issue.

BTW: while opening TDSDUMP switch, the crash location changed.

freddy77 commented 5 months ago

I cannot reproduce it. Did you solve it?

taozuhong commented 5 months ago

Not yet,

If it is fixed, PR will be created for it.