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;
}