Bug 767850

Summary: xchat server connect DoS
Product: [Other] Security Response Reporter: Kurt Seifried <kseifried>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: fedora, jrb, kevin
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-04-03 01:20:35 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 767851    

Description Kurt Seifried 2011-12-15 01:05:54 UTC
http://packetstormsecurity.org/files/107312/xchat-dos.txt

Long buffer (>1537 of ascii 20) sent to xchat client triggers crash. PoC author
claims it works for xchat on KDE.

tested on RHEL/Fedora 16 x86_64, no crash but it does print a warning:

*** XCHAT WARNING: Buffer overflow - shit server!

which is from src/common/server.c:

default:
        serv->linebuf[serv->pos] = lbuf[i];
        if (serv->pos >= (sizeof (serv->linebuf) - 1))
                fprintf (stderr,
"*** XCHAT WARNING: Buffer overflow - shit server!\n");

Comment 1 Huzaifa S. Sidhpurwala 2011-12-15 05:59:35 UTC
Analysis:
=========

In server.c::server_read()

409         char lbuf[2050];

This is a temporary buffer used to read data from the network, after sanitizing the data it will be transferred to "server *serv" structure.

At:
416                         len = recv (sok, lbuf, sizeof (lbuf) - 2, 0);

it reads data of size 2048 bytes from the network, and is stored in the lbuf buffer.

Further down at:
421                 if (len < 1)
if no data is read from the network, either it autoconnects or cycles to the next server in the list or throws an error and exits.

If data is read from the network, it is transferred to the serv->linebuf buffer

Relevant code is:



 450                 lbuf[len] = 0;
 451 
 452                 while (i < len)
 453                 {
 454                         switch (lbuf[i])
..
..

 465                         default:
 466                                 serv->linebuf[serv->pos] = lbuf[i];
 467                                 if (serv->pos >= (sizeof (serv->linebuf) - 1))
 468                                         fprintf (stderr,
 469                                                                 "*** XCHAT WARNING: Buffer overflow - shit server!\n");
 470                                 else
 471                                         serv->pos++;
 472                         }
 473                         i++;
 474                 }

When the loop starts len <= 2048, serv->pos may not be essentially zero depending on the previous state.

When the default condition is hit, sequentially data is transferred from lbuf to serv->linebuf. However if serv->pos is not at zero initially incrementing serv->pos would result in serv->pos >= size-of the serv->linebuf buffer

If more data is transferred into serv->linebuf buffer using serv->pos as the index, it would result in buffer overflow.

However line 467 will stop this from happening. It detects that serv->pos is equal to size of serv->linebuf and any more copying data could result in an overflow, and therefore does not increment serv->pos at all.

In future iterations, values from linebuf are copied at the last legal place in serv->linebuf, and an overflow is avoided.

So no buffer overflow as such.

Comment 2 Kurt Seifried 2012-04-03 01:20:35 UTC
Closed as NOTABUG, this doesn't appear to trigger any buffer overflow or cause a denial of service in testing.