Bug 877 - HUSH: parse error in "echo a | if true; then cat ; fi" leads to out of memory
Summary: HUSH: parse error in "echo a | if true; then cat ; fi" leads to out of memory
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.15.x
Hardware: Other Linux
: P5 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-12 11:37 UTC by Mikel Garai
Modified: 2010-01-30 23:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikel Garai 2010-01-12 11:37:09 UTC
Architecture: blackfin (i think it just happens with NOMMU)

NOTE: this error does not happen with MMU compilations. But it can be forced even in pc compilation by defining the constant BUILD_AS_NOMMU to 1, at least It happens to me consistently.

if you try to execute one of the following example commands (i guess it happens with every command that have an [if|while|..] after a pipe) hush uses all the system's memory:

echo echo | while read a ; do true ; done
echo echo | while test `date +%s` -lt 9739378 ; do true; done
echo echo | while test 1 -gt 2 ; do true; done
echo a | if true; then echo a ; fi

In those cases the workaround for scripts is very simple, putting brackets in the right part:

echo echo | ( while read a ; do true ; done )
echo echo | ( while test `date +%s` -lt 9739378 ; do true; done )
echo echo | ( while test 1 -gt 2 ; do true; done )
echo a | ( if true; then echo a ; fi )

I did try to find the bug myself and just couldn't, but I know at very high level what is the error that is happening. When parsing and executing list of commands hush (at least without MMU) executes itself again with -c argument and the command fragments to be executed, for example "(echo a; echo b) | cat" execute another hush process with "echo a; echo b" command. The issue here is that with "echo a | if true; then echo a; fi" style commands it executes infinite instances of hush with that entire command ("echo a | if true; then echo a; fi" in this case) instead of a subcommand (that in this case I'm guessing is "if true; then echo a; fi" )

Sorry for not finding the bug, and just tell me if you need more information.

thanks,

Mikel Garai
Comment 1 Denys Vlasenko 2010-01-12 12:34:25 UTC
Fix:

--- busybox.8/shell/hush.c      2010-01-12 11:56:36.000000000 +0100
+++ busybox.9/shell/hush.c      2010-01-12 13:33:46.540495850 +0100
@@ -6535,6 +6541,9 @@ static struct pipe *parse_stream(char **
                                 * with redirect_opt_num(), but bash doesn't do it.
                                 * "echo foo 2| cat" yields "foo 2". */
                                done_command(&ctx);
+#if !BB_MMU
+                               o_reset_to_empty_unquoted(&ctx.as_string);
+#endif
                        }
                        goto new_cmd;
                case '(':
Comment 2 Mikel Garai 2010-01-12 14:44:04 UTC
Tested and working!

Thank you very much!


Mikel Garai
Comment 3 Denys Vlasenko 2010-01-30 23:15:09 UTC
Fixed in 1.16.0