From iseki@gongon.com  Tue Mar 26 01:01:01 2002
Return-Path: <iseki@gongon.com>
Received: from gongon1.gongon.com (gongon1.gongon.com [61.202.206.226])
	by hub.freebsd.org (Postfix) with ESMTP id BF31F37B427
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 26 Mar 2002 01:00:57 -0800 (PST)
Received: from gongon1.gongon.com (localhost [IPv6:::1])
	by gongon1.gongon.com (8.12.2/8.12.2) with ESMTP id g2Q90uKP056921
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 26 Mar 2002 18:00:56 +0900 (JST)
	(envelope-from iseki@gongon1.gongon.com)
Received: (from root@localhost)
	by gongon1.gongon.com (8.12.2/8.12.2/Submit) id g2Q90uEp056920;
	Tue, 26 Mar 2002 18:00:56 +0900 (JST)
	(envelope-from iseki)
Message-Id: <200203260900.g2Q90uEp056920@gongon1.gongon.com>
Date: Tue, 26 Mar 2002 18:00:56 +0900 (JST)
From: Isao SEKI <iseki@gongon.com>
Reply-To: Isao SEKI <iseki@gongon.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: quick patch for qpopper4.0.3_1 buffer overflow
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         36326
>Category:       ports
>Synopsis:       quick patch for qpopper4.0.3_1 buffer overflow
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    lioux
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar 26 01:10:00 PST 2002
>Closed-Date:    Sun Mar 31 00:22:27 PST 2002
>Last-Modified:  Sun Mar 31 00:22:27 PST 2002
>Originator:     Isao SEKI
>Release:        FreeBSD 4.5-RELEASE i386
>Organization:
personal
>Environment:
System: FreeBSD gongon1.gongon.com 4.5-RELEASE FreeBSD 4.5-RELEASE #1: Thu Jan 31 18:40:00 JST 2002 iseki@gongon6.gongon.com:/usr/src/sys/compile/GONGON_NOSTUN i386


>Description:
If a string of longer than approximately 2048 characters is sent to
the qpopper process, a denial of service condition will occur.

>How-To-Repeat:
Please see at the Description.

>Fix:
I have made a quick patch for qpopper4.0.3.


*** popper.c.dist	Sat Jun  2 11:24:36 2001
--- popper.c	Tue Mar 26 16:24:30 2002
***************
*** 483,489 ****
--- 483,501 ----
                  else
                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
                  if ( len <= 0 )
+ #if 0
                      break;
+ #else
+                 {
+                     /*
+                      * patch by Isao SEKI <iseki@gongon.com>
+                      * return 0 is meaningless after buffer overflow
+                      */
+                     pop_log (pPOP, POP_NOTICE, HERE,
+                               "read 0 byte after buffer overflow\n");
+                     return(NULL);
+                 }
+ #endif
                  q = strchr ( junk, '\n' );
                  if ( q == NULL ) {
                      disc += len;
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-ports->lioux 
Responsible-Changed-By: pat 
Responsible-Changed-When: Tue Mar 26 09:33:14 PST 2002 
Responsible-Changed-Why:  
Over to maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=36326 

From: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
To: Isao SEKI <iseki@gongon.com>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Wed, 27 Mar 2002 14:08:58 -0300

 Hi,
 
 > >Description:
 > If a string of longer than approximately 2048 characters is sent to
 > the qpopper process, a denial of service condition will occur.
 
 	Close inspection lead me to believe that the problem is
 inherent to the way qpopper was designed. It ALWAYS believe that
 str (string which is sent as a buffer to getline) returned from
 getline is true. However, str is only updated IF getline works.
 When it does not, getline returns str untouched, with the same value
 as before. Therefore, it is possible to make it infinitly loops
 under extreme circunstances. Exercise cases are up to the reader. :)
 
 	Your patch addresses the correct problem source but it
 loses the buffer.
 
 > *** popper.c.dist	Sat Jun  2 11:24:36 2001
 > --- popper.c	Tue Mar 26 16:24:30 2002
 > ***************
 > *** 483,489 ****
 > --- 483,501 ----
 >                   else
 >                       len = read ( pPOP->input_fd, junk, sizeof(junk) );
 >                   if ( len <= 0 )
 > + #if 0
 >                       break;
 > + #else
 > +                 {
 > +                     /*
 > +                      * patch by Isao SEKI <iseki@gongon.com>
 > +                      * return 0 is meaningless after buffer overflow
 > +                      */
 > +                     pop_log (pPOP, POP_NOTICE, HERE,
 > +                               "read 0 byte after buffer overflow\n");
 > +                     return(NULL);
 > +                 }
 > + #endif
 >                   q = strchr ( junk, '\n' );
 >                   if ( q == NULL ) {
 >                       disc += len;
 
 	Could you try the following patch? Let me know how this turns out.
 If it is good, I'll commit it ASAP. I did not reproduce the 2048 bug so
 I am relying on you for feedback.
 
 --- popper/popper.c.orig	Wed Mar 27 13:09:15 2002
 +++ popper/popper.c	Wed Mar 27 14:01:30 2002
 @@ -483,7 +483,21 @@
                  else
                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
                  if ( len <= 0 )
 +		{
 +		    /*
 +		     * patch by Isao SEKI <iseki@gongon.com> and
 +		     * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 +		     * return 0 is meaningless after buffer overflow
 +		     */
 +
 +		    str[0]='\0'; /* empty buffer before returning
 +				    since it seems that qpopper
 +				    believes in the contents
 +				    of str */
 +                    pop_log (pPOP, POP_NOTICE, HERE,
 +		 	    "read 0 byte after buffer overflow\n");
                      break;
 +		}
                  q = strchr ( junk, '\n' );
                  if ( q == NULL ) {
                      disc += len;
 
 -- 
 Mario S F Ferreira - DF - Brazil - "I guess this is a signature."
 Computer Science Undergraduate | FreeBSD Committer | CS Developer
 flames to beloved devnull@someotherworldbeloworabove.org
 feature, n: a documented bug | bug, n: an undocumented feature

From: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
To: Isao SEKI <iseki@gongon.com>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Wed, 27 Mar 2002 14:08:58 -0300

 Hi,
 
 > >Description:
 > If a string of longer than approximately 2048 characters is sent to
 > the qpopper process, a denial of service condition will occur.
 
 	Close inspection lead me to believe that the problem is
 inherent to the way qpopper was designed. It ALWAYS believe that
 str (string which is sent as a buffer to getline) returned from
 getline is true. However, str is only updated IF getline works.
 When it does not, getline returns str untouched, with the same value
 as before. Therefore, it is possible to make it infinitly loops
 under extreme circunstances. Exercise cases are up to the reader. :)
 
 	Your patch addresses the correct problem source but it
 loses the buffer.
 
 > *** popper.c.dist	Sat Jun  2 11:24:36 2001
 > --- popper.c	Tue Mar 26 16:24:30 2002
 > ***************
 > *** 483,489 ****
 > --- 483,501 ----
 >                   else
 >                       len = read ( pPOP->input_fd, junk, sizeof(junk) );
 >                   if ( len <= 0 )
 > + #if 0
 >                       break;
 > + #else
 > +                 {
 > +                     /*
 > +                      * patch by Isao SEKI <iseki@gongon.com>
 > +                      * return 0 is meaningless after buffer overflow
 > +                      */
 > +                     pop_log (pPOP, POP_NOTICE, HERE,
 > +                               "read 0 byte after buffer overflow\n");
 > +                     return(NULL);
 > +                 }
 > + #endif
 >                   q = strchr ( junk, '\n' );
 >                   if ( q == NULL ) {
 >                       disc += len;
 
 	Could you try the following patch? Let me know how this turns out.
 If it is good, I'll commit it ASAP. I did not reproduce the 2048 bug so
 I am relying on you for feedback.
 
 --- popper/popper.c.orig	Wed Mar 27 13:09:15 2002
 +++ popper/popper.c	Wed Mar 27 14:01:30 2002
 @@ -483,7 +483,21 @@
                  else
                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
                  if ( len <= 0 )
 +		{
 +		    /*
 +		     * patch by Isao SEKI <iseki@gongon.com> and
 +		     * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 +		     * return 0 is meaningless after buffer overflow
 +		     */
 +
 +		    str[0]='\0'; /* empty buffer before returning
 +				    since it seems that qpopper
 +				    believes in the contents
 +				    of str */
 +                    pop_log (pPOP, POP_NOTICE, HERE,
 +		 	    "read 0 byte after buffer overflow\n");
                      break;
 +		}
                  q = strchr ( junk, '\n' );
                  if ( q == NULL ) {
                      disc += len;
 
 -- 
 Mario S F Ferreira - DF - Brazil - "I guess this is a signature."
 Computer Science Undergraduate | FreeBSD Committer | CS Developer
 flames to beloved devnull@someotherworldbeloworabove.org
 feature, n: a documented bug | bug, n: an undocumented feature

From: David Rufino <dr@soniq.net>
To: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
Cc: Isao SEKI <iseki@gongon.com>, FreeBSD-gnats-submit@FreeBSD.ORG,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Wed, 27 Mar 2002 18:40:04 +0100

 The comment of the function indicates that it should try and copy as much
 data as possible into 'str', ignoring the rest. I think the correct fix
 is to copy as much as is possible into str, even if it isn't terminated
 with a newline, and null-terminate it. Note this happens in any case
 if len > 0, so it shouldn't require a great alteration...
 
 On Wed, Mar 27, 2002 at 02:08:58PM -0300, Mario Sergio Fujikawa Ferreira wrote:
 > Hi,
 > 
 > > >Description:
 > > If a string of longer than approximately 2048 characters is sent to
 > > the qpopper process, a denial of service condition will occur.
 > 
 > 	Close inspection lead me to believe that the problem is
 > inherent to the way qpopper was designed. It ALWAYS believe that
 > str (string which is sent as a buffer to getline) returned from
 > getline is true. However, str is only updated IF getline works.
 > When it does not, getline returns str untouched, with the same value
 > as before. Therefore, it is possible to make it infinitly loops
 > under extreme circunstances. Exercise cases are up to the reader. :)
 > 
 > 	Your patch addresses the correct problem source but it
 > loses the buffer.
 > 
 > > *** popper.c.dist	Sat Jun  2 11:24:36 2001
 > > --- popper.c	Tue Mar 26 16:24:30 2002
 > > ***************
 > > *** 483,489 ****
 > > --- 483,501 ----
 > >                   else
 > >                       len = read ( pPOP->input_fd, junk, sizeof(junk) );
 > >                   if ( len <= 0 )
 > > + #if 0
 > >                       break;
 > > + #else
 > > +                 {
 > > +                     /*
 > > +                      * patch by Isao SEKI <iseki@gongon.com>
 > > +                      * return 0 is meaningless after buffer overflow
 > > +                      */
 > > +                     pop_log (pPOP, POP_NOTICE, HERE,
 > > +                               "read 0 byte after buffer overflow\n");
 > > +                     return(NULL);
 > > +                 }
 > > + #endif
 > >                   q = strchr ( junk, '\n' );
 > >                   if ( q == NULL ) {
 > >                       disc += len;
 > 
 > 	Could you try the following patch? Let me know how this turns out.
 > If it is good, I'll commit it ASAP. I did not reproduce the 2048 bug so
 > I am relying on you for feedback.
 > 
 > --- popper/popper.c.orig	Wed Mar 27 13:09:15 2002
 > +++ popper/popper.c	Wed Mar 27 14:01:30 2002
 > @@ -483,7 +483,21 @@
 >                  else
 >                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
 >                  if ( len <= 0 )
 > +		{
 > +		    /*
 > +		     * patch by Isao SEKI <iseki@gongon.com> and
 > +		     * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 > +		     * return 0 is meaningless after buffer overflow
 > +		     */
 > +
 > +		    str[0]='\0'; /* empty buffer before returning
 > +				    since it seems that qpopper
 > +				    believes in the contents
 > +				    of str */
 > +                    pop_log (pPOP, POP_NOTICE, HERE,
 > +		 	    "read 0 byte after buffer overflow\n");
 >                      break;
 > +		}
 >                  q = strchr ( junk, '\n' );
 >                  if ( q == NULL ) {
 >                      disc += len;
 > 
 > -- 
 > Mario S F Ferreira - DF - Brazil - "I guess this is a signature."
 > Computer Science Undergraduate | FreeBSD Committer | CS Developer
 > flames to beloved devnull@someotherworldbeloworabove.org
 > feature, n: a documented bug | bug, n: an undocumented feature

From: Alessandro de Manzano <ale@unixmania.net>
To: David Rufino <dr@soniq.net>
Cc: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>,
	Isao SEKI <iseki@gongon.com>, FreeBSD-gnats-submit@FreeBSD.ORG,
	eivind@FreeBSD.org
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Wed, 27 Mar 2002 18:54:08 +0100

 On Wed, Mar 27, 2002 at 06:40:04PM +0100, David Rufino wrote:
 
 > 
 > The comment of the function indicates that it should try and copy as much
 > data as possible into 'str', ignoring the rest. I think the correct fix
 > is to copy as much as is possible into str, even if it isn't terminated
 > with a newline, and null-terminate it. Note this happens in any case
 > if len > 0, so it shouldn't require a great alteration...
 
 FWIW, I agree.
 
 btw, on Bugtraq site there is a trivial one-line Perl script that sends
 > 2048 "A"s to Qpopper via Netcat and someone on qpopper list reports
 that his machine also starts eating memory, not just 100% CPU (infinite
 loop).
 On my 4.4-stable box I can't reproduce the memory eating.
 
 Further, on the qpopper list has appeard a tiny un-official patch that
 seems to address the problem, IMHO, in another way.
 
 Sorry currently I've not access to that patch to discuss it more
 appropriately :(
 
 
 Anyway, many thanks to you all for your help to fix this bug! :-)
 
 
 > 
 > On Wed, Mar 27, 2002 at 02:08:58PM -0300, Mario Sergio Fujikawa Ferreira wrote:
 > > Hi,
 > > 
 > > > >Description:
 > > > If a string of longer than approximately 2048 characters is sent to
 > > > the qpopper process, a denial of service condition will occur.
 > > 
 > > 	Close inspection lead me to believe that the problem is
 > > inherent to the way qpopper was designed. It ALWAYS believe that
 > > str (string which is sent as a buffer to getline) returned from
 > > getline is true. However, str is only updated IF getline works.
 > > When it does not, getline returns str untouched, with the same value
 > > as before. Therefore, it is possible to make it infinitly loops
 > > under extreme circunstances. Exercise cases are up to the reader. :)
 > > 
 > > 	Your patch addresses the correct problem source but it
 > > loses the buffer.
 > > 
 > > > *** popper.c.dist	Sat Jun  2 11:24:36 2001
 > > > --- popper.c	Tue Mar 26 16:24:30 2002
 > > > ***************
 > > > *** 483,489 ****
 > > > --- 483,501 ----
 > > >                   else
 > > >                       len = read ( pPOP->input_fd, junk, sizeof(junk) );
 > > >                   if ( len <= 0 )
 > > > + #if 0
 > > >                       break;
 > > > + #else
 > > > +                 {
 > > > +                     /*
 > > > +                      * patch by Isao SEKI <iseki@gongon.com>
 > > > +                      * return 0 is meaningless after buffer overflow
 > > > +                      */
 > > > +                     pop_log (pPOP, POP_NOTICE, HERE,
 > > > +                               "read 0 byte after buffer overflow\n");
 > > > +                     return(NULL);
 > > > +                 }
 > > > + #endif
 > > >                   q = strchr ( junk, '\n' );
 > > >                   if ( q == NULL ) {
 > > >                       disc += len;
 > > 
 > > 	Could you try the following patch? Let me know how this turns out.
 > > If it is good, I'll commit it ASAP. I did not reproduce the 2048 bug so
 > > I am relying on you for feedback.
 > > 
 > > --- popper/popper.c.orig	Wed Mar 27 13:09:15 2002
 > > +++ popper/popper.c	Wed Mar 27 14:01:30 2002
 > > @@ -483,7 +483,21 @@
 > >                  else
 > >                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
 > >                  if ( len <= 0 )
 > > +		{
 > > +		    /*
 > > +		     * patch by Isao SEKI <iseki@gongon.com> and
 > > +		     * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 > > +		     * return 0 is meaningless after buffer overflow
 > > +		     */
 > > +
 > > +		    str[0]='\0'; /* empty buffer before returning
 > > +				    since it seems that qpopper
 > > +				    believes in the contents
 > > +				    of str */
 > > +                    pop_log (pPOP, POP_NOTICE, HERE,
 > > +		 	    "read 0 byte after buffer overflow\n");
 > >                      break;
 > > +		}
 > >                  q = strchr ( junk, '\n' );
 > >                  if ( q == NULL ) {
 > >                      disc += len;
 > > 
 > > -- 
 > > Mario S F Ferreira - DF - Brazil - "I guess this is a signature."
 > > Computer Science Undergraduate | FreeBSD Committer | CS Developer
 > > flames to beloved devnull@someotherworldbeloworabove.org
 > > feature, n: a documented bug | bug, n: an undocumented feature
 
 -- 
 
 bye!
 
 Ale
 
 ale@unixmania.net

From: Isao SEKI <iseki@gongon.com>
To: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
Cc: FreeBSD-gnats-submit@FreeBSD.org,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Thu, 28 Mar 2002 11:29:07 +0900

 --Multipart_Thu_Mar_28_11:29:06_2002-1
 Content-Type: text/plain; charset=US-ASCII
 
 Hi, 
 
 Unfortunately, high cpu usage problem was reproduced by your new
 patch. I think that my patch (return null immediately or str=NULL)
 is not best way however it is better in limited time.
 
 Btw, I wrote a small program to sent big data. It is worked on
 Mac OS X machine at my testing. Maybe it will work on FreeBSD.
 
 
 --Multipart_Thu_Mar_28_11:29:06_2002-1
 Content-Type: application/octet-stream; type=tar+gzip
 Content-Disposition: attachment; filename="v6-test.tgz"
 Content-Transfer-Encoding: base64
 
 H4sIAAAAAAAAA+1YbVPbOBDuV/wrVBhSO+TFdt7uSMMMQ8MNcxS4hn45ymSMLSeaOFZGlgNcJ//9
 VpKd2Emu5UND56Z+Plj2Snp2tdpdKZm3qxxH/M0uYZpNs9NqQWuanbZqAWmr3jvNltnsdBptG+SW
 1Wg13rR2alWCOOIOA5UkwhPyjXGPY4yD1zDodTFX+18/p+yvGZ3NMKvxpx8cDqZlmu1m8z/337Kb
 6/vftEX7Y83Yjl98/33KEMMzRr3YJeEIjclojNxZjOLIGWEEHQ8BntY0LaCuE4xpxIeHqFZPwgbd
 MTylHN/IyLlHEEENTfvZayrwcqT5P3VIWHN3o+M7+d9s2B2V/6ZtNi1L5L/dEv27MSePXzz/D0jo
 BrGH0fvoOarz5xmOauMTLS8GF/EtUupO8Jo8xNx7WBvKPUKFSBMxpjts5FYQPOeGRkIu3tyu5o4d
 hspCenff1b5qCCB6fa9XtSoowGEFka4UR5zFLkecTPHcCWRLY57r871hhEXDlFiyP8T+HcTXb8B/
 fnHZR2V/1tWysxzPYyT0KdTAkEcVVGY4eZoJDQ2h5ClTXSeOMOqhq8+XlwkN8ZFcHXrbQw0DqUUI
 zICW+/q+LKnH6DBCoo6GzhTqK2X8S7ivHHJn3hvd5Sz8RLiefC+0LA/YEWLhAiq4aoAVhSUo5Ogp
 noIT9FKyGrOCIvIPpr4uBUbCLD9qDhn6zpQEz7Cim/Ph56vBTf9MDaiXt4+5uOrftruoXM/TiKAQ
 UQSDBtdnfw4Ht5/6px8V1Qjz1Md6YmxitQ0vqaEl4fDEOuFS8Yl6ytM5r2LGKNP3M6z76+6zlv6T
 je+BWVVLycTJJ8hBJLdYPOVDCaonsJoQP/FtOykUHqOsOslGeuAR8t624Xl0lJ2YnXxo2k+wXXqq
 RJBVTyJn6DncuSP3Rsl88v0Md+oJctJGpZJQYIlW18mhbbztmYaRG5rVdZy1cbGxDoib7BqEe1RW
 L41TW15ZeiTd35UErgicujTIEAljgew9Mjd8kGya0rK/tkgIbE7CGG8zWXAmgQ/cK/XCe/kvKBbG
 t3QnLBvKAxphoF4T52LmJYY+MOxMujJx6MR5Ro8YjShHNMRpsiyWsb3ppHRncOgh6suahKMIBZRO
 4ploZvk9Wwtz8QTFPsN4mWoqn4TybVUEe4rwq3bgYZ+AlTcDqBMISuXv+eIp5ffdZW0mmTwiPVNE
 vhxyZKnwX3kEJpN7cOO703dqziMjHMtthL6K0pisIQownum2kVaf1bbItXZhGQs4XXxkrrR3u1kX
 JidCjc/hFHBBLZiWkcVKaImrx8qP5x+Gf/c/XeslODSMnHjQv5WWrvWI7YtwoMLxyFL9FVml0mcp
 0Wqgk81oFPOB/WKQ418flY7UIahlXXK8lduSeg7vhrE14pdBlUS+mL4e9lsDKYsFwgEcdcIKaURv
 V3o2JCpKrGS1Iq3zsxZr2QdxAWlDfAiQn32t+t8gvf9/dCaQ/QHehY7v/f632224/zfaVqNpNk3R
 bzXMVqe4/78Czs4vT/8YiCNuhKrXNjqoXtTjiNXlz/06Yx6nNKhaNbPWaNSTO72mJVFzjOTPRqrt
 uW5KUJ1hz4HTEQT+zcUZqlKU/lmgBqODL9re3kH1MqNn3q4H5AFVAzh/eFtzA+yEx9oemwIJKsOc
 cs2lDKdMRXoXKFCgQIECBQoUKFCgQIECBQoUKPAi/AsXk8CPACgAAA==
 
 --Multipart_Thu_Mar_28_11:29:06_2002-1
 Content-Type: text/plain; charset=US-ASCII
 
 
 Isao
 
 At 14:08 03/27/2002 -0300, Mario Sergio Fujikawa Ferreira wrote:
 > Hi,
 > 
 > > >Description:
 > > If a string of longer than approximately 2048 characters is sent to
 > > the qpopper process, a denial of service condition will occur.
 > 
 > 	Close inspection lead me to believe that the problem is
 > inherent to the way qpopper was designed. It ALWAYS believe that
 > str (string which is sent as a buffer to getline) returned from
 > getline is true. However, str is only updated IF getline works.
 > When it does not, getline returns str untouched, with the same value
 > as before. Therefore, it is possible to make it infinitly loops
 > under extreme circunstances. Exercise cases are up to the reader. :)
 > 
 > 	Your patch addresses the correct problem source but it
 > loses the buffer.
 > 
 > > *** popper.c.dist	Sat Jun  2 11:24:36 2001
 > > --- popper.c	Tue Mar 26 16:24:30 2002
 > > ***************
 > > *** 483,489 ****
 > > --- 483,501 ----
 > >                   else
 > >                       len = read ( pPOP->input_fd, junk, sizeof(junk) );
 > >                   if ( len <= 0 )
 > > + #if 0
 > >                       break;
 > > + #else
 > > +                 {
 > > +                     /*
 > > +                      * patch by Isao SEKI <iseki@gongon.com>
 > > +                      * return 0 is meaningless after buffer overflow
 > > +                      */
 > > +                     pop_log (pPOP, POP_NOTICE, HERE,
 > > +                               "read 0 byte after buffer overflow\n");
 > > +                     return(NULL);
 > > +                 }
 > > + #endif
 > >                   q = strchr ( junk, '\n' );
 > >                   if ( q == NULL ) {
 > >                       disc += len;
 > 
 > 	Could you try the following patch? Let me know how this turns out.
 > If it is good, I'll commit it ASAP. I did not reproduce the 2048 bug so
 > I am relying on you for feedback.
 > 
 > --- popper/popper.c.orig	Wed Mar 27 13:09:15 2002
 > +++ popper/popper.c	Wed Mar 27 14:01:30 2002
 > @@ -483,7 +483,21 @@
 >                  else
 >                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
 >                  if ( len <= 0 )
 > +		{
 > +		    /*
 > +		     * patch by Isao SEKI <iseki@gongon.com> and
 > +		     * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 > +		     * return 0 is meaningless after buffer overflow
 > +		     */
 > +
 > +		    str[0]='\0'; /* empty buffer before returning
 > +				    since it seems that qpopper
 > +				    believes in the contents
 > +				    of str */
 > +                    pop_log (pPOP, POP_NOTICE, HERE,
 > +		 	    "read 0 byte after buffer overflow\n");
 >                      break;
 > +		}
 >                  q = strchr ( junk, '\n' );
 >                  if ( q == NULL ) {
 >                      disc += len;
 
 --Multipart_Thu_Mar_28_11:29:06_2002-1--

From: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
To: Isao SEKI <iseki@gongon.com>
Cc: FreeBSD-gnats-submit@FreeBSD.org,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Sat, 30 Mar 2002 18:52:56 -0300

 Well, this last patch seems to work. I sort of I do not believe in
 losing pointer references so I changed the way getline, tgetline
 work. Just so that they resemble read return codes.
 
 1) if < 0 problem
 2) if >= 0 user typed something (enter without anything else is
    something)
 
 Anyway, here is the patch. It works against the test program
 supplied by Isao Seki. Could you test it against live systems?
 If it works, I'll commit it ASAP.
 
 
 diff -ruN qpopper4.0.3.orig/popper/popper.c qpopper4.0.3/popper/popper.c
 --- qpopper4.0.3.orig/popper/popper.c	Fri Jun  1 23:24:14 2001
 +++ qpopper4.0.3/popper/popper.c	Sat Mar 30 18:24:06 2002
 @@ -125,8 +125,8 @@
      state_table     *   s;
      char                message [ MAXLINELEN ];
      pop_result          rslt = POP_FAILURE;
 -    char            *   tgetline();
 -    char            *   getline();
 +    ssize_t		tgetline();
 +    ssize_t		getline();
      
      /*
       * seed random with the current time to nearest second 
 @@ -287,7 +287,7 @@
          if ( hangup ) {
              pop_exit ( &p, HANGUP );
          } 
 -        else if ( tgetline ( message, MAXLINELEN, &p, pop_timeout ) == NULL ) {
 +        else if ( tgetline ( message, MAXLINELEN, &p, pop_timeout ) < 0 ) {
              pop_exit ( &p, (poptimeout) ? TIMEOUT :  ABORT );
          } 
          else if ( StackSize ( &(p.InProcess) ) ) { 
 @@ -400,8 +400,8 @@
   *  the input is discarded.
   */
  
 -char
 -*getline ( char *str, int size, POP *pPOP )
 +ssize_t
 +getline ( char *str, int size, POP *pPOP )
  {
      char *p       = NULL;
      char *pEnd    = NULL;
 @@ -427,7 +427,7 @@
                p++ )
              if ( *p == '\n' )
                  break;
 -        if ( p != pPOP->pcInEnd && *p == '\n' ) {
 +            if ( p != pPOP->pcInEnd && *p == '\n' ) {
              /*
               * Got a line
               */
 @@ -451,7 +451,7 @@
              }
              _DEBUG_LOG3 ( pPOP, "getline() returning %d: '%.*s'",
                            strlen(str), MIN(25, (int) strlen(str)), str );
 -            return ( str );
 +            return ( strlen(str) );
          } /* got a line */
  
          nRoom = pPOP->pcInBuf + nBufSz - pPOP->pcInEnd;
 @@ -483,7 +483,22 @@
                  else
                      len = read ( pPOP->input_fd, junk, sizeof(junk) );
                  if ( len <= 0 )
 -                    break;
 +                {
 +                   /*
 +                    * patch by Isao SEKI <iseki@gongon.com> and
 +                    * Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
 +                    * return 0 is meaningless after buffer overflow
 +                    */
 +
 +                   /* do not touch buffer before returning
 +                    * since it seems that qpopper
 +                    * believes in the contents of str
 +                    */
 +                                   
 +                    pop_log (pPOP, POP_NOTICE, HERE,
 +                           "read 0 byte. Possible buffer overflow\n");
 +                    return (-1);
 +                }
                  q = strchr ( junk, '\n' );
                  if ( q == NULL ) {
                      disc += len;
 @@ -522,7 +537,7 @@
              } /* loop and discard until we see a '\n' */
  
              _DEBUG_LOG1 ( pPOP, "getline() returning %d", strlen(str) );
 -            return ( str );
 +            return ( strlen(str) );
          } /* nRoom == 0 */
  
          if ( pPOP->tls_started )
 @@ -544,7 +559,7 @@
      } /* main loop */
  
      _DEBUG_LOG0 ( pPOP, "getline() returning NULL" );
 -    return ( NULL );
 +    return ( -1 );
  }
  
  
 @@ -552,12 +567,12 @@
  /*
   * Get a line of input with a timeout.  This part does the timeout
   */
 -char *
 +ssize_t
  tgetline ( char *str, int size, POP *p, int timeout )
  {
      int ring();
 -
 -
 +    ssize_t result;
 +        
      (void) signal ( SIGALRM, VOIDSTAR ring );
      alarm ( timeout );
      if ( setjmp ( env ) ) {
 @@ -565,12 +580,13 @@
          pop_log ( p, POP_NOTICE, HERE, "(v%s) Timeout (%d secs) during "
                                         "nw read from %s at %s (%s)",
                    VERSION, timeout, p->user, p->client, p->ipaddr );
 +        result = 0;
      }
      else
 -        str = getline ( str, size, p );
 +        result = getline ( str, size, p );
      alarm  ( 0 );
      signal ( SIGALRM, SIG_DFL );
 -    return ( str );
 +    return ( result );
  }
  
  

From: Alessandro de Manzano <ale@unixmania.net>
To: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
Cc: Isao SEKI <iseki@gongon.com>, FreeBSD-gnats-submit@FreeBSD.org,
	eivind@FreeBSD.org, dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Sat, 30 Mar 2002 23:17:12 +0100

 On Sat, Mar 30, 2002 at 06:52:56PM -0300, Mario Sergio Fujikawa Ferreira wrote:
 
 > Well, this last patch seems to work. I sort of I do not believe in
 > losing pointer references so I changed the way getline, tgetline
 > work. Just so that they resemble read return codes.
 > 
 > 1) if < 0 problem
 > 2) if >= 0 user typed something (enter without anything else is
 >    something)
 > 
 > Anyway, here is the patch. It works against the test program
 > supplied by Isao Seki. Could you test it against live systems?
 > If it works, I'll commit it ASAP.
 
 Ok, however due to Easter holidays I can't test it until Tuesday April,
 2nd...
 
 I'll report to you all my results.
 
 
 Thanks a lot!
 
 
 -- 
 
 bye!
 
 Ale
 
 ale@unixmania.net

From: Isao SEKI <iseki@gongon.com>
To: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
Cc: FreeBSD-gnats-submit@FreeBSD.org,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Sun, 31 Mar 2002 13:57:33 +0900

 Mario,
 
 Great! 
 I just have tested your last patch now and it is working fine.
 
 Isao
 
 At 18:52 03/30/2002 -0300, Mario Sergio Fujikawa Ferreira wrote:
 > Well, this last patch seems to work. I sort of I do not believe in
 > losing pointer references so I changed the way getline, tgetline
 > work. Just so that they resemble read return codes.
 > 
 > 1) if < 0 problem
 > 2) if >= 0 user typed something (enter without anything else is
 >    something)
 > 
 > Anyway, here is the patch. It works against the test program
 > supplied by Isao Seki. Could you test it against live systems?
 > If it works, I'll commit it ASAP.

From: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
To: Isao SEKI <iseki@gongon.com>
Cc: FreeBSD-gnats-submit@FreeBSD.org,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Sun, 31 Mar 2002 03:10:25 -0300

 On Sun, Mar 31, 2002 at 01:57:11PM +0900, Isao SEKI wrote:
 > 
 > Great! 
 > I just have tested your last patch now and it is working fine.
 
 	Real live system? Didn't I break anything else?

From: Isao SEKI <iseki@gongon.com>
To: Mario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>
Cc: FreeBSD-gnats-submit@FreeBSD.org,
	Alessandro de Manzano <ale@unixmania.net>, eivind@FreeBSD.org,
	dr@soniq.net
Subject: Re: ports/36326: quick patch for qpopper4.0.3_1 buffer overflow
Date: Sun, 31 Mar 2002 15:27:32 +0900

 At 03:10 03/31/2002 -0300, Mario Sergio Fujikawa Ferreira wrote:
 > > Great! 
 > > I just have tested your last patch now and it is working fine.
 > 	Real live system? Didn't I break anything else?
 
 I tested on our main server, "gongon.com".
 I did not find out any breaking.
 
 Isao
State-Changed-From-To: open->closed 
State-Changed-By: lioux 
State-Changed-When: Sun Mar 31 00:20:54 PST 2002 
State-Changed-Why:  
A consensual patch has been committed, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=36326 
>Unformatted:
