Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Sep 2007 04:13:15 -0700
From:      Darren Reed <darrenr@freebsd.org>
To:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: yacc bug in reader.c:end_rule()
Message-ID:  <46F64A4B.8000804@freebsd.org>
In-Reply-To: <46F6379B.9050000@freebsd.org>
References:  <46F6379B.9050000@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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.
>
> 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   <ptr>   test
%%

test:   | $$ = malloc(2);
        ;

%%

(The error here is that "test" has an undefined return.)

Darren




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?46F64A4B.8000804>