From owner-freebsd-current@FreeBSD.ORG Mon Sep 24 14:50:46 2007 Return-Path: Delivered-To: freebsd-current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0971616A418; Mon, 24 Sep 2007 14:50:46 +0000 (UTC) (envelope-from rermilov@team.vega.ru) Received: from mail.vega.ru (mx1.vega.ru [87.242.77.163]) by mx1.freebsd.org (Postfix) with ESMTP id BDC1B13C448; Mon, 24 Sep 2007 14:50:45 +0000 (UTC) (envelope-from rermilov@team.vega.ru) Received: from [87.242.97.68] (port=57267 helo=edoofus.dev.vega.ru) by mail.vega.ru with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.68 (FreeBSD)) (envelope-from ) id 1IZpGm-000A30-Tn; Mon, 24 Sep 2007 14:50:44 +0000 Received: from edoofus.dev.vega.ru (localhost [127.0.0.1]) by edoofus.dev.vega.ru (8.14.1/8.14.1) with ESMTP id l8OEo7RU084693; Mon, 24 Sep 2007 18:50:07 +0400 (MSD) (envelope-from rermilov@team.vega.ru) Received: (from ru@localhost) by edoofus.dev.vega.ru (8.14.1/8.14.1/Submit) id l8OEo7G0084692; Mon, 24 Sep 2007 18:50:07 +0400 (MSD) (envelope-from rermilov@team.vega.ru) X-Authentication-Warning: edoofus.dev.vega.ru: ru set sender to rermilov@team.vega.ru using -f Date: Mon, 24 Sep 2007 18:50:07 +0400 From: Ruslan Ermilov To: Darren Reed Message-ID: <20070924145007.GB82735@team.vega.ru> References: <46F6379B.9050000@freebsd.org> <46F64A4B.8000804@freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <46F64A4B.8000804@freebsd.org> User-Agent: Mutt/1.5.16 (2007-06-09) Cc: FreeBSD Current Subject: Re: yacc bug in reader.c:end_rule() X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Sep 2007 14:50:46 -0000 On Sun, Sep 23, 2007 at 04:13:15AM -0700, Darren Reed wrote: > Darren Reed wrote: >> There's a fairly obvious bug in yacc's reader.c but I'm not sure what the >> right fix is. >> >> Witness: >> end_rule() >> { >> int i; >> >> if (!last_was_action && plhs[nrules]->tag) >> { >> for (i = nitems - 1; pitem[i]; --i) continue; >> if (pitem[i + 1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag) >> ... >> } >> >> ...clearly if pitem[nitems-1] == NULL (and nitems is the size of the >> array from [0,nitems-1]) then the if() will access beyond the bounds >> of the array. >> >> There's also the question of i being able to run below 0 too here. >> Not possible: first four pitem's are explicitly set to NULL in reader.c:initialize_grammar(). >> I don't know if the bug is here or if the bug is elsewhere in yacc, >> but I doubt that the "fix" is s/i + 1/i/. *Maybe* "i = nitems - 2;"? >> >> The bug can be masked by using calloc instead of malloc and similar >> other tricks, but there is something more fundamentaly wrong here. >> >> Has anyone else run into this? > > The following sample grammar will exercise the bug: > > %{ > %} > > %union { > char *ptr; > }; > > %type test > %% > > test: | $$ = malloc(2); It crashes even when written "correctly" as: test: | { $$ = malloc(2); } > ; > > %% > > (The error here is that "test" has an undefined return.) > Try this patch. It replaces a non-sense with a fix for the bug. %%% Index: reader.c =================================================================== RCS file: /home/ncvs/src/usr.bin/yacc/reader.c,v retrieving revision 1.19 diff -u -p -r1.19 reader.c --- reader.c 25 Aug 2002 13:23:09 -0000 1.19 +++ reader.c 24 Sep 2007 14:16:18 -0000 @@ -1257,7 +1257,7 @@ end_rule() if (!last_was_action && plhs[nrules]->tag) { for (i = nitems - 1; pitem[i]; --i) continue; - if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag) + if (i == nitems - 1 || pitem[i+1]->tag != plhs[nrules]->tag) default_action_warning(); } %%% Cheers, -- Ruslan Ermilov ru@FreeBSD.org FreeBSD committer