On Mon, Jan 30, 2012 at 03:18:04PM +0100, Michael Niedermayer wrote:

> Hi
> 
> Our automated tests for FFmpeg (http://fate.ffmpeg.org/) have yesterday
> found a segfault in openbsds /bin/sh.
> 
> Analysis revealed that it was triggered by too many variables
> That is something like
> 
> #!/bin/sh
> 
> i=0
> while true ; do
>     eval X${i}=yes
>     i=$(($i+1))
>     test $i -gt 17000 && break
> done
> 
> will segfault.
> 
> The following patch fixes it: (which we are currently using on our
> openbsd fate client)
> 
> Index: table.h
> ===================================================================
> RCS file: /cvs/src/bin/ksh/table.h,v
> retrieving revision 1.7
> diff -u -r1.7 table.h
> --- table.h     11 Dec 2005 20:31:21 -0000      1.7
> +++ table.h     30 Jan 2012 14:13:30 -0000
> @@ -8,7 +8,7 @@
> 
>  struct table {
>         Area   *areap;          /* area to allocate entries */
> -       short   size, nfree;    /* hash size (always 2^^n), free entries */
> +       int     size, nfree;    /* hash size (always 2^^n), free entries */
>         struct  tbl **tbls;     /* hashed table items */
>  };
> 
> 

Thanks for the report.

I could reproduce the bug, but I'm not 100% happy with your fix since
it just pushes the failure to a bigger number of vars.

It's better to check for the case like below,

        -Otto

Index: table.c
===================================================================
RCS file: /cvs/src/bin/ksh/table.c,v
retrieving revision 1.13
diff -u -p -r1.13 table.c
--- table.c     17 Jan 2009 22:06:44 -0000      1.13
+++ table.c     31 Jan 2012 12:07:20 -0000
@@ -108,7 +108,10 @@ ktenter(struct table *tp, const char *n,
        }
 
        if (tp->nfree <= 0) {   /* too full */
-               texpand(tp, 2*tp->size);
+               if (tp->size <= SHRT_MAX/2)
+                       texpand(tp, 2*tp->size);
+               else
+                       internal_errorf(1, "too many vars");
                goto Search;
        }

Reply via email to