Re: Segmentation fault when trying to connect to a listening TCP port for another service

Frediano Ziglio <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <CAHt6W4du6Uq+5Ct13ei-CY5phwX1CDbJxJMd3UTho=26B9S3SA@mail.gmail.com>
Yes, could work.

The problem is that in 0.91 in_buf_max is initialized with 0 while in_buf
is NULL. This means that trying to receive any packet should trigger an
allocation. This does not happen if header contains a length of  0. In this
case nothing is allocated but libTDS assume in_buf is sufficient to
contains an header (which is 8 bytes). Another solution is to check if len
is <8 and close connection and return error. This cause length has to be at
least 8. The issue with your solution is that code continue and assume in
case len == 0 that an empty packet was read. In this case it leads in_len
and in_pos to 8 which could lead to future problems (in_len and in_pos are
offset in in_buf but in this case in_buf is NULL). 0.92 (where this code is
completely different) test for len, in src/tds/packet.c:

...
        /* normal packet */
        if (packet->pos >= 8) {
                len = TDS_GET_A2BE(&packet->buf[2]);
                if (len < 8)
                        goto Severe_Error;
                if (packet->len < len) {
...

As buffer is always NULL in this case I don't see any security escalation
(only a DoS which is still security problem!).

Frediano


2013/8/21 Ramiro Morales <[email protected]>

> Hi all,
>
> As reported on pymssql issue 108
> (https://code.google.com/p/pymssql/issues/detail?id=108)
>
> The original reported experienced it under Windows. IT also kills the
> Python interpreter process under Linux.
>
> Taking pymssql/Python and Windows out of the picture. With tsql:
>
> $ tsql -H <MySQL server IP address> -p 3306
> Segmentation fault
>
> Running tsql under gdb to get the location:
>
> $ TDVER=7.1 gdb --args tsql -H <MySQL server IP address> -p 3306
> GNU gdb (GDB) 7.4.1-debian
> Copyright (C) 2012 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <
> http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Reading symbols from tsql...done.
> (gdb) run
> Starting program: tsql -H 172.17.2.15 -p 3306
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
> locale is "en_US.UTF-8"
> locale charset is "UTF-8"
> using default charset "UTF-8"
>
> Program received signal SIGSEGV, Segmentation fault.
> tds_read_packet (tds=tds@entry=0x63e3e0) at net.c:584
> 584             memcpy(tds->in_buf, header, 8);
>
> (gdb) bt
> #0  tds_read_packet (tds=tds@entry=0x63e3e0) at net.c:584
> #1  0x000000000040f651 in tds8_do_login (connection=0x63e860,
> tds=0x63e3e0) at login.c:1024
> #2  tds_connect (tds=tds@entry=0x63e3e0,
> connection=connection@entry=0x63e860,
> p_oserr=p_oserr@entry=0x7fffffffddec) at login.c:456
> #3  0x000000000040ffa6 in tds_connect_and_login
> (tds=tds@entry=0x63e3e0, connection=connection@entry=0x63e860) at
> login.c:506
> #4  0x0000000000403858 in main (argc=<optimized out>, argv=<optimized
> out>) at tsql.c:771
>
> (gdb) print tds->in_buf
> $1 = (unsigned char *) 0x0
>
> (gdb) print header
> $1 = "?\000\000\000\n5.0"
>
> It doesn't happen with every remote service (e.g. with SSH it simply times
> out).
>
> A patch (for the 0.91 branch):
>
> diff --git a/src/tds/net.c b/src/tds/net.c
> index 48426bb..1281613 100644
> --- a/src/tds/net.c
> +++ b/src/tds/net.c
> @@ -579,9 +579,11 @@ tds_read_packet(TDSSOCKET * tds)
>                 tds->in_buf_max = len;
>         }
>
> -       /* Clean out the in_buf so we don't use old stuff by mistake */
> -       memset(tds->in_buf, 0, tds->in_buf_max);
> -       memcpy(tds->in_buf, header, 8);
> +       if (tds->in_buf) {
> +               /* Clean out the in_buf so we don't use old stuff by
> mistake */
> +               memset(tds->in_buf, 0, tds->in_buf_max);
> +               memcpy(tds->in_buf, header, 8);
> +       }
>
>         /* Now get exactly how many bytes the server told us to get */
>         have = 8;
>
>
> With it I now get:
>
> $ tsql -H <MySQL server IP address> -p 3306
> locale is "en_US.UTF-8"
> locale charset is "UTF-8"
> using default charset "UTF-8"
> Error 20002 (severity 9):
>         Adaptive Server connection failed
> There was a problem connecting to the server
> $
>
> Regards,
>
> --
> Ramiro Morales
> @ramiromorales
> _______________________________________________
> FreeTDS mailing list
> [email protected]
> http://lists.ibiblio.org/mailman/listinfo/freetds
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.