freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service
- From: Frediano Ziglio <freddy77 AT gmail.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Subject: Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service
- Date: Wed, 21 Aug 2013 09:16:07 +0100
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 <cramm0 AT gmail.com>
> 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
> FreeTDS AT lists.ibiblio.org
> http://lists.ibiblio.org/mailman/listinfo/freetds
>
-
[freetds] Segmentation fault when trying to connect to a listening TCP port for another service,
Ramiro Morales, 08/20/2013
- Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service, Frediano Ziglio, 08/21/2013
-
Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service,
Frediano Ziglio, 08/21/2013
- Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service, Frediano Ziglio, 08/21/2013
- Re: [freetds] Segmentation fault when trying to connect to a listening TCP port for another service, Ramiro Morales, 08/22/2013
Archive powered by MHonArc 2.6.24.