From stefan@fafoe.dyndns.org  Wed Dec 11 17:49:23 2002
Return-Path: <stefan@fafoe.dyndns.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id A557037B401
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 11 Dec 2002 17:49:23 -0800 (PST)
Received: from fafoe.dyndns.org (chello212186121237.14.vie.surfer.at [212.186.121.237])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 1394E43ED1
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 11 Dec 2002 17:49:23 -0800 (PST)
	(envelope-from stefan@fafoe.dyndns.org)
Received: from frog.fafoe (frog.fafoe [192.168.2.101])
	by fafoe.dyndns.org (Postfix) with ESMTP
	id 3388A40AA; Thu, 12 Dec 2002 02:49:16 +0100 (CET)
Received: by frog.fafoe (Postfix, from userid 1001)
	id CF16A78A; Thu, 12 Dec 2002 02:49:15 +0100 (CET)
Message-Id: <20021212014915.CF16A78A@frog.fafoe>
Date: Thu, 12 Dec 2002 02:49:15 +0100 (CET)
From: Stefan Farfeleder <stefan@fafoe.dyndns.org>
Reply-To: Stefan Farfeleder <stefan@fafoe.dyndns.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: e0026813@stud3.tuwien.ac.at
Subject: [patch] make(1) missing trailing '\0' and accessing junk memory if '$' is at the end of line
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         46203
>Category:       bin
>Synopsis:       [patch] make(1) missing trailing '\0' and accessing junk memory if '$' is at the end of line
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ru
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 11 17:50:01 PST 2002
>Closed-Date:    Mon Oct 06 10:38:24 PDT 2003
>Last-Modified:  Mon Oct 06 10:38:24 PDT 2003
>Originator:     Stefan Farfeleder
>Release:        FreeBSD 5.0-RC i386
>Organization:
>Environment:
System: FreeBSD frog.fafoe 5.0-RC FreeBSD 5.0-RC #5: Tue Dec 10 19:18:00 CET 2002 freebsd@frog.fafoe:/freebsd/current/obj/freebsd/current/src/sys/FROG i386


	
>Description:
The function Var_Subst() goes through every character in its argument
`str' and calls Var_Parse() if it finds a '$'.  The latter function
stores the number of characters occupied by the '$' and the variable
name into *lengthPtr, which is then added to `str' in Var_Subst().
However, if Var_Parse() fails to parse the variable name after the '$',
*lengthPtr is always assigned the value 2.  This causes `str' to be
pointing one behind the terminating '\0' if the '$' is immediately
followed by the '\0'.  IOW, before var.c:1759 is executed, str == "$"
and length == 2, afterwards str is pointing to garbage.
	
>How-To-Repeat:
If no '\0' is in the memory owned by make following `str', a
segmentation fault will occur.
	
>Fix:
I'm fixing things inside Var_Parse() because it seems to be cleaner to
set length to 1 if str == "$" than to deal with it in Var_Subst().

[patch survived a buildworld]
	

--- make.diff begins here ---
Index: src/usr.bin/make/var.c
===================================================================
RCS file: /usr/home/ncvs/src/usr.bin/make/var.c,v
retrieving revision 1.40
diff -u -c -r1.40 var.c
*** src/usr.bin/make/var.c	8 Nov 2002 16:59:11 -0000	1.40
--- src/usr.bin/make/var.c	12 Dec 2002 00:23:10 -0000
***************
*** 801,807 ****
   *	The (possibly-modified) value of the variable or var_Error if the
   *	specification is invalid. The length of the specification is
   *	placed in *lengthPtr (for invalid specifications, this is just
!  *	2...?).
   *	A Boolean in *freePtr telling whether the returned string should
   *	be freed by the caller.
   *
--- 801,808 ----
   *	The (possibly-modified) value of the variable or var_Error if the
   *	specification is invalid. The length of the specification is
   *	placed in *lengthPtr (for invalid specifications, this is just
!  *	2 to skip the '$' and the following letter, or 1 if '$' was the
!  *	last character in the string).
   *	A Boolean in *freePtr telling whether the returned string should
   *	be freed by the caller.
   *
***************
*** 850,856 ****
  
  	v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
  	if (v == (Var *)NULL) {
! 	    *lengthPtr = 2;
  
  	    if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
  		/*
--- 851,860 ----
  
  	v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
  	if (v == (Var *)NULL) {
! 	    if (str[1] != '\0')
! 		*lengthPtr = 2;
! 	    else
! 		*lengthPtr = 1;
  
  	    if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
  		/*
--- make.diff ends here ---


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: ru 
State-Changed-When: Mon Oct 6 10:37:55 PDT 2003 
State-Changed-Why:  
Committed, thanks! 


Responsible-Changed-From-To: freebsd-bugs->ru 
Responsible-Changed-By: ru 
Responsible-Changed-When: Mon Oct 6 10:37:55 PDT 2003 
Responsible-Changed-Why:  

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