Bug 8055 - PATCH: cpp0 dies with SIG11 when building FreeBSD kernel
Summary: PATCH: cpp0 dies with SIG11 when building FreeBSD kernel
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 3.2.1
: P3 normal
Target Milestone: 3.1.x/3.2.x
Assignee: Zack Weinberg
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2002-09-26 08:26 UTC by ak03
Modified: 2005-04-20 02:10 UTC (History)
4 users (show)

See Also:
Host: i386-portbld-freebsd4.7
Target: i386-portbld-freebsd4.7
Build: i386-portbld-freebsd4.7
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ak03 2002-09-26 08:26:01 UTC
	Preprocessor cpp0 dumps core when used to create dependencies list 
	while building the FreeBSD kernel. The reason is the bug in gcc/cppmacro.cpp
	in function stringify_arg. If pfile->u_buff buffer is completely filled
	when the function is called (i.e.
	BUFF_FRONT (pfile->u_buff) == BUFF_LIMIT (pfile->u_buff) ), and the
        macro_arg passed to it as a second parameter has no tokens, that is
	arg->count is 0, then stringify_buffer will happily advance the
        BUFF_FRONT(pfile->u_buff) pointer past the BUFF_LIMIT (pfile->u_buff) 
	values, making comparisons like 
          (size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len
        useless. CPP0 will dump core shortly afterwards trying strchr/strcpy
	a string which it thinks is about 4G in size.

Release:
3.2.1 [FreeBSD] 20020916 (prerelease)

Environment:
System: FreeBSD kanpc.gte.com 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Mon Sep 16 10:44:41EDT 2002 root@kanpc.gte.com:/usr/obj/usr/src/sys/KANPC  i386
GCC 3.2.1 configured as system compiler

As well as:
System: FreeBSD ork.gte.com 4.7-PRERELEASE FreeBSD 4.7-PRERELEASE #0: Mon Sep 16 11:16:37 EDT 2002 root@ork.gte.com:/usr/src/sys/compile/KAN i386

GCC 3.2.1 built from ports:
host: i386-portbld-freebsd4.7
build: i386-portbld-freebsd4.7
target: i386-portbld-freebsd4.7
configured with: ./..//gcc-20020902/configure --disable-nls --with-gnu-as --with-gnu-ld --with-gxx-include-dir=/usr/local/lib/gcc-lib/i386-portbld-freebsd4.7/3.2.1/include/g++-v3 --with-system-zlib --includedir=/usr/local/lib/gcc-lib/i386-portbld-freebsd4.7/3.2.1/include/Java --disable-libgcj --disable-shared --prefix=/usr/local i386-portbld-freebsd4.7

How-To-Repeat:
	The test case is not exactly trivial to produce. The stringify_arg
	function should be called with an empty argument and completely
	filled buffer. The layout of system header files happend to 
	trigger exectly this condition.
Comment 1 ak03 2002-09-26 08:26:01 UTC
Fix:
	The patch below takes care of the problem.

Index: contrib/gcc/cppmacro.c
===================================================================
RCS file: /usr/ncvs/src/contrib/gcc/cppmacro.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 cppmacro.c
--- contrib/gcc/cppmacro.c	1 Sep 2002 20:37:29 -0000	1.1.1.4
+++ contrib/gcc/cppmacro.c	24 Sep 2002 15:40:54 -0000
@@ -349,6 +349,12 @@
 
   /* Commit the memory, including NUL, and return the token.  */
   len = dest - BUFF_FRONT (pfile->u_buff);
+  if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1)
+    {
+      size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+      _cpp_extend_buff (pfile, &pfile->u_buff, 1);
+      dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
+    }
   BUFF_FRONT (pfile->u_buff) = dest + 1;
   return new_string_token (pfile, dest - len, len);
 }
Comment 2 Zack Weinberg 2002-09-27 12:50:09 UTC
From: Zack Weinberg <zack@codesourcery.com>
To: ak03@gte.com, Mark Mitchell <mark@codesourcery.com>,
	Neil Booth <neil@daikokuya.co.uk>
Cc: gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 27 Sep 2002 12:50:09 -0700

 Thank you for this bug report.  I've reproduced the problem, and
 confirm your analysis.  I'm going to do a complete bootstrap+test
 cycle on a slight modification of your patch (see below) and will
 apply to mainline if successful.
 
 Mark, is this an acceptable patch for 3.2.1?  It's not clear whether
 it's a regression from earlier 3.x, but it has been seen in the wild,
 and the fix is small, self-contained, and obvious.
 
 zw
 
 	* cppmacro.c (stringify_arg): Do not overflow the buffer
 	with the terminating NUL when the argument to be stringified
 	has no tokens.
 	* gcc.dg/cpp/20020927-1.c: New test case.
 
 ===================================================================
 Index: cppmacro.c
 --- cppmacro.c	22 Sep 2002 02:03:17 -0000	1.124
 +++ cppmacro.c	27 Sep 2002 19:48:15 -0000
 @@ -409,6 +409,12 @@ stringify_arg (pfile, arg)
      }
  
    /* Commit the memory, including NUL, and return the token.  */
 +  if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1)
 +    {
 +      size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
 +      _cpp_extend_buff (pfile, &pfile->u_buff, 1);
 +      dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
 +    }
    len = dest - BUFF_FRONT (pfile->u_buff);
    BUFF_FRONT (pfile->u_buff) = dest + 1;
    return new_string_token (pfile, dest - len, len);
 ===================================================================
 Index: testsuite/gcc.dg/cpp/20020927-1.c
 --- testsuite/gcc.dg/cpp/20020927-1.c	1 Jan 1970 00:00:00 -0000
 +++ testsuite/gcc.dg/cpp/20020927-1.c	27 Sep 2002 19:47:37 -0000
 @@ -0,0 +1,91 @@
 +/* Test case for buffer overflow bug in token stringification.
 +   See PR preprocessor/8055 for details.
 +   Reported by Alexander N. Kabaev <ak03@gte.com>.
 +   Test case written by Zack Weinberg <zack@codesourcery.com>.  */
 +
 +/* { dg-do preprocess } */
 +
 +#define S(x) #x
 +
 +/* Fill up one internal buffer with data.  */
 +S(1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  1234567890123456789012345678901234567890123456789012345678901234567890
 +  12345678901234567890123456789012345678901234567890123456789012345)
 +
 +/* When stringify_arg() was called with an empty macro argument, it would
 +   advance the buffer pointer by one but fail to check for running past the
 +   end of the buffer.  We can only know where the end of the buffer is to
 +   within about eight bytes, so do this sixteen times to be sure of hitting
 +   it.  */
 +
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +S()
 +
 +/* Now allocate more memory in the buffer, which should provoke a crash.  */
 +
 +S(abcdefghijklmnopqrstuvwxyz)
 +S(abcdefghijklmnopqrstuvwxyz)
 

Comment 3 Mark Mitchell 2002-09-27 13:50:20 UTC
From: Mark Mitchell <mark@codesourcery.com>
To: Zack Weinberg <zack@codesourcery.com>, "ak03@gte.com" <ak03@gte.com>,
   Neil Booth <neil@daikokuya.co.uk>
Cc: "gcc-gnats@gcc.gnu.org" <gcc-gnats@gcc.gnu.org>,
   "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 27 Sep 2002 13:50:20 -0700

 --On Friday, September 27, 2002 12:50:09 PM -0700 Zack Weinberg 
 <zack@codesourcery.com> wrote:
 
 > Thank you for this bug report.  I've reproduced the problem, and
 > confirm your analysis.  I'm going to do a complete bootstrap+test
 > cycle on a slight modification of your patch (see below) and will
 > apply to mainline if successful.
 
 I think we need to figure out if this is a regression before applying
 it to the branch.  Just in case.  If it is a regression, it's fine.
 
 Thanks,
 
 -- 
 Mark Mitchell                mark@codesourcery.com
 CodeSourcery, LLC            http://www.codesourcery.com

Comment 4 Zack Weinberg 2002-09-27 15:11:28 UTC
From: Zack Weinberg <zack@codesourcery.com>
To: Mark Mitchell <mark@codesourcery.com>
Cc: "ak03@gte.com" <ak03@gte.com>, Neil Booth <neil@daikokuya.co.uk>,
	"gcc-gnats@gcc.gnu.org" <gcc-gnats@gcc.gnu.org>,
	"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 27 Sep 2002 15:11:28 -0700

 On Fri, Sep 27, 2002 at 01:50:20PM -0700, Mark Mitchell wrote:
 > 
 > 
 > --On Friday, September 27, 2002 12:50:09 PM -0700 Zack Weinberg 
 > <zack@codesourcery.com> wrote:
 > 
 > >Thank you for this bug report.  I've reproduced the problem, and
 > >confirm your analysis.  I'm going to do a complete bootstrap+test
 > >cycle on a slight modification of your patch (see below) and will
 > >apply to mainline if successful.
 > 
 > I think we need to figure out if this is a regression before applying
 > it to the branch.  Just in case.  If it is a regression, it's fine.
 
 Reproducing the bug is a bit tricky; I have to instrument the buggy
 routine and then adjust the filler text in the test case by hand.
 3.0, 3.2 (nee 3.1), and mainline all want different lengths of filler
 text.
 
 I can say that I reproduced the bug under laboratory conditions using
 top of trunk and top of 3.2 (nee 3.1) branch, and that the same
 procedure fails to provoke a bug using the top of the 3.0 branch,
 where the memory allocation code is different.  I can also say that
 2.95, being the last release to use cccp.c, handled stringification
 quite differently and is unlikely to have this bug.  I haven't managed
 to reproduce the bug "in the wild" - i.e. using compilers I didn't
 build myself, or without instrumentation and tweaking.  However, we
 have the original report from the FreeBSD people to say that it does
 occur in the wild.  Is that good enough to call this a regression?
 
 zw

Comment 5 Mark Mitchell 2002-09-27 15:45:49 UTC
From: Mark Mitchell <mark@codesourcery.com>
To: Zack Weinberg <zack@codesourcery.com>
Cc: "ak03@gte.com" <ak03@gte.com>, Neil Booth <neil@daikokuya.co.uk>,
   "gcc-gnats@gcc.gnu.org" <gcc-gnats@gcc.gnu.org>,
   "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 27 Sep 2002 15:45:49 -0700

 > I can say that I reproduced the bug under laboratory conditions using
 > top of trunk and top of 3.2 (nee 3.1) branch, and that the same
 > procedure fails to provoke a bug using the top of the 3.0 branch,
 > where the memory allocation code is different.
 
 I think that's good enough.  Check it in.
 
 Thanks,
 
 -- 
 Mark Mitchell                mark@codesourcery.com
 CodeSourcery, LLC            http://www.codesourcery.com
Comment 6 ak03 2002-09-27 16:06:46 UTC
From: Alexander Kabaev <ak03@gte.com>
To: Zack Weinberg <zack@codesourcery.com>
Cc: mark@codesourcery.com, neil@daikokuya.co.uk, gcc-gnats@gcc.gnu.org,
   gcc-patches@gcc.gnu.org
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 27 Sep 2002 16:06:46 -0400

 Thanks for a prompt reply!
 
 I would really like to see the bug fixed in 3.2.1. The problem is very
 repeatable on FreeBSD and is very annoying. At the moment I made a patch
 available from my home page, but I really want to keep the number of
 local changes at minimum for FreeBSD system compiler.
 
 -- 
 Alexander Kabaev

Comment 7 Zack Weinberg 2002-09-27 17:33:39 UTC
Responsible-Changed-From-To: unassigned->zack
Responsible-Changed-Why: Mine.
Comment 8 Zack Weinberg 2002-09-27 17:33:39 UTC
State-Changed-From-To: open->closed
State-Changed-Why: Patch checked into mainline and 3.2 branch.
Comment 9 Zack Weinberg 2002-09-28 00:30:38 UTC
From: zack@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: preprocessor/8055
Date: 28 Sep 2002 00:30:38 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Changes by:	zack@gcc.gnu.org	2002-09-27 17:30:38
 
 Modified files:
 	gcc            : ChangeLog cppmacro.c 
 	gcc/testsuite  : ChangeLog 
 Added files:
 	gcc/testsuite/gcc.dg/cpp: 20020927-1.c 
 
 Log message:
 	2002-09-27  Alexander N. Kabaev <ak03@gte.com>
 	
 	PR preprocessor/8055
 	* cppmacro.c (stringify_arg): Do not overflow the buffer
 	with the terminating NUL when the argument to be stringified
 	has no tokens.
 	* testsuite/gcc.dg/cpp/20020927-1.c: New.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.15563&r2=1.15564
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cppmacro.c.diff?cvsroot=gcc&r1=1.124&r2=1.125
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2103&r2=1.2104
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/cpp/20020927-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
 

Comment 10 Zack Weinberg 2002-09-28 00:32:16 UTC
From: zack@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: preprocessor/8055
Date: 28 Sep 2002 00:32:16 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Branch: 	gcc-3_2-branch
 Changes by:	zack@gcc.gnu.org	2002-09-27 17:32:16
 
 Modified files:
 	gcc            : ChangeLog cppmacro.c 
 	gcc/testsuite  : ChangeLog 
 Added files:
 	gcc/testsuite/gcc.dg/cpp: 20020927-1.c 
 
 Log message:
 	2002-09-27  Alexander N. Kabaev <ak03@gte.com>
 	
 	PR preprocessor/8055
 	* cppmacro.c (stringify_arg): Do not overflow the buffer
 	with the terminating NUL when the argument to be stringified
 	has no tokens.
 	* gcc.dg/cpp/20020927-1.c: New.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.58&r2=1.13152.2.657.2.59
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cppmacro.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.91.6.6.2.1&r2=1.91.6.6.2.2
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.1672.2.166.2.16&r2=1.1672.2.166.2.17
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/cpp/20020927-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=NONE&r2=1.1.2.1
 

Comment 11 Neil Booth 2002-10-04 19:42:00 UTC
From: Neil Booth <neil@daikokuya.co.uk>
To: Zack Weinberg <zack@codesourcery.com>
Cc: ak03@gte.com, Mark Mitchell <mark@codesourcery.com>,
	gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: preprocessor/8055: CPP0 segfault on FreeBSD + PATCH
Date: Fri, 4 Oct 2002 19:42:00 +0100

 Zack Weinberg wrote:-
 
 > Thank you for this bug report.  I've reproduced the problem, and
 > confirm your analysis.  I'm going to do a complete bootstrap+test
 > cycle on a slight modification of your patch (see below) and will
 > apply to mainline if successful.
 
 Thanks Zack.  Catching up on 5 figures of email...
 
 Neil.