From dan@kulesh.obluda.cz  Mon Aug  7 12:02:16 2006
Return-Path: <dan@kulesh.obluda.cz>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id E4C3D16A4DE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Aug 2006 12:02:16 +0000 (UTC)
	(envelope-from dan@kulesh.obluda.cz)
Received: from smtp1.kolej.mff.cuni.cz (smtp1.kolej.mff.cuni.cz [195.113.24.4])
	by mx1.FreeBSD.org (Postfix) with ESMTP id D462943D60
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Aug 2006 12:01:57 +0000 (GMT)
	(envelope-from dan@kulesh.obluda.cz)
Received: from kulesh.obluda.cz (openvpn.ms.mff.cuni.cz [195.113.20.87])
	by smtp1.kolej.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id k77C3Qha000178
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 7 Aug 2006 14:03:28 +0200 (CEST)
	(envelope-from dan@kulesh.obluda.cz)
Received: from kulesh.obluda.cz (localhost. [127.0.0.1])
	by kulesh.obluda.cz (8.13.6/8.13.6) with ESMTP id k77C1rQO026515
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 7 Aug 2006 14:01:53 +0200 (CEST)
	(envelope-from dan@kulesh.obluda.cz)
Received: (from root@localhost)
	by kulesh.obluda.cz (8.13.6/8.13.6/Submit) id k77C1qU0026514;
	Mon, 7 Aug 2006 14:01:52 +0200 (CEST)
	(envelope-from dan)
Message-Id: <200608071201.k77C1qU0026514@kulesh.obluda.cz>
Date: Mon, 7 Aug 2006 14:01:52 +0200 (CEST)
From: Dan Lukes <dan@obluda.cz>
Reply-To: Dan Lukes <dan@obluda.cz>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [ PATCH ] Memory overflow "off-by one" in hexdump
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         101575
>Category:       bin
>Synopsis:       [patch] Memory overflow "off-by one" in hexdump(1)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 07 12:10:17 GMT 2006
>Closed-Date:    Sun Aug 20 20:31:39 GMT 2006
>Last-Modified:  Sun Aug 20 20:31:39 GMT 2006
>Originator:     Dan Lukes
>Release:        FreeBSD 6.1-STABLE i386
>Organization:
Obludarium
>Environment:
System: FreeBSD 6.1-STABLE: Fri Aug 4 19:58:43 CEST 2006 i386
usr.bin/hexdump/parse.c,v 1.13 2004/07/22 13:14:42

but the same problem is in 

System: FreeBSD 4.11-RELEASE-p19
usr.bin/hexdump/parse.c,v 1.4.2.1 2002/07/23 14:27:06

	I'm almost sure the same problem is in all FreeBSD 5.X as well

>Description:
	The program use one byte more memory than allocated.

	The problem occur in strcat()

	The code want to concat two strings - the fmtp[] has variable length, 
the cs[] is two byte.

	Program calloc strlen(fmtp) + 2 bytes for it - forgetting the final '\0' 
of concatenated string

	I think this overflow is not exploitable by an attacker even if we run 
hexdump on specially prepared source file. But my assumptions may be wrong.

>How-To-Repeat:
	Use an memory usage analyzator (memcheck or so), then run hd with no arguments

>Fix:

	Please MFC it to RELENG-4 too

--- usr.bin/hexdump/parse.c.ORIG	Sun Aug  8 21:12:10 2004
+++ usr.bin/hexdump/parse.c	Mon Aug  7 13:41:57 2006
@@ -394,7 +394,7 @@
 			 */
 			savech = *p2;
 			p1[0] = '\0';
-			if ((pr->fmt = calloc(1, strlen(fmtp) + 2)) == NULL)
+			if ((pr->fmt = calloc(1, strlen(fmtp) + 3)) == NULL)
 				err(1, NULL);
 			(void)strcpy(pr->fmt, fmtp);
 			(void)strcat(pr->fmt, cs);
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Wed Aug 9 19:12:26 UTC 2006 
State-Changed-Why:  
Dan, 

I decided to go OpenBSD's way and committed their version. 

Thanks for the submission! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=101575 
Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Wed Aug 9 19:14:15 UTC 2006 
Responsible-Changed-Why:  
MFC reminder (for RELENG_4 as well). 

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

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dan Lukes <dan@obluda.cz>
Cc: bug-followup@freebsd.org
Subject: Re: bin/101575: [patch] Memory overflow "off-by one" in hexdump(1)
Date: Thu, 10 Aug 2006 00:07:24 +0400 (MSD)

 On Wed, 9 Aug 2006, 21:43+0200, Dan Lukes wrote:
 
 >
 > 	I didn't understand why OpenBSD didn't use this way:
 >
 > --- current code ---
 > size_t len;
 > ...
 > len = strlen(fmtp) + strlen(cs) + 1;
 > if ((pr->fmt = calloc(1, len)) == NULL)
 > 	err(1, NULL);
 > snprintf(pr->fmt, len, "%s%s", fmtp, cs);
 > --- better code ---
 > asprintf(&pr->fmt, "%s%s", fmtp, cs);
 > if (pr->fmt == NULL)
 > 	err(1, NULL);
 > -------------------
 >
 > 	The implementatin of asprintf on FreeBSD come from OpenBSD, so
 > it's sure the OpenBSD has this function. This situation is exactly
 > what the asprintf is for. In advance, we need no additional
 > variable.
 >
 > 	I think we should wrote nice effective code and allow the
 > OpenBSD learn from FreeBSD code. At least sometime. At least when we
 > can wrote better code ...
 
 I see no problem in code improvement over OpenBSD's one but personally
 I see no improvements in calloc()+snprintf() replacement by asprintf().
 What are they?
 
 On the other hand OpenBSD rev.1.11 is better than ours because it
 doesn't use hardcode constant and doesn't have the bug you found.
 
 I didn't study asprintf() implementation but suspect it uses malloc()
 for memory allocation.  calloc() zeroes allocated memory and this can
 be safe in some cases.  Not sure it is relevant for hexdump :-)
 
 > 	But, I'm not sure if you are asking me for this kind of opinion.
 >
 > 	Well. Your patch close the reported hole, so it's OK.
 >
 > 						Dan
 >
 >
 >
 
 -- 
 Maxim Konovalov

From: Dan Lukes <dan@obluda.cz>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/101575: [patch] Memory overflow "off-by one" in hexdump(1)
Date: Wed, 09 Aug 2006 22:42:54 +0200

 Maxim Konovalov napsal/wrote, On 08/09/06 22:07:
 > I see no problem in code improvement over OpenBSD's one but personally
 > I see no improvements in calloc()+snprintf() replacement by asprintf().
 > What are they?
 
 	I don't know why the asprintf has been implemented in OpenBSD and then 
 adopted by FreeBSD. But it has been implemented for some reason unknown 
 to us. I think it's internally implemented as either
 
 1. calloc+snprintf - then we can use it as it isn't worse.
 2. use an internal optimization (I know nothing about it) and is better 
 than calloc+snprintf - then we should use it as it is better
 
 	So - posibilities are - we CAN use it or we SHOULD use it. I 
 recommended to use it as it may be better or same but no worse (unless 
 the asprintf implementation is bad and should be corrected).
 
 > I didn't study asprintf() implementation but suspect it uses malloc()
 > for memory allocation.  calloc() zeroes allocated memory and this can
 > be safe in some cases.  Not sure it is relevant for hexdump :-)
 
 	I'm sure it isn't. The calloc on this place is waste of CPU cycles. If 
 we accept it's safest to use calloc there, then we can replace all 
 occurences of malloc with calloc with the same argument ...
 
 	Well, it's an sort of advocacy discussion and there is not appropriate 
 place for it.
 
 	Let's close the case ...
 
 					Dan
 
 
 -- 
 Dan Lukes                                   SISAL MFF UK
 AKA: dan@obluda.cz, dan@freebsd.cz,dan@kolej.mff.cuni.cz

From: Yar Tikhiy <yar@comp.chem.msu.su>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: Dan Lukes <dan@obluda.cz>, bug-followup@freebsd.org
Subject: Re: bin/101575: [patch] Memory overflow "off-by one" in hexdump(1)
Date: Sat, 12 Aug 2006 20:43:26 +0400

 > I see no problem in code improvement over OpenBSD's one but personally
 > I see no improvements in calloc()+snprintf() replacement by asprintf().
 > What are they?
 
 asprintf() is a single call that does almost the same and even more:
 asprintf() will allocate the amount of heap needed for the resulting
 string to fit; not more, not less.  Of course, the caller should free()
 the chunk returned by asprintf() later.
  
 -- 
 Yar
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Sun Aug 20 20:28:03 UTC 2006 
State-Changed-Why:  
Merged to RELENG_4,5,6. 

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