[PATCH] ash: fix SEGV in parsebackq on big buffers caused by alloca

Martin Lewis martin.lewis.x84 at gmail.com
Thu Nov 15 00:11:18 UTC 2018


Closes https://bugs.busybox.net/show_bug.cgi?id=10761

Before fix:
$ python -c "print 'echo \"' + ' ' * 3000000 + ' \`true\`' * 1000 + '\"'" > test.sh
$ bash test.sh | wc
      1       0 3001001
$ ./busybox ash test.sh
Segmentation fault (core dumped)

After fix:
$ python -c "print 'echo \"' + ' ' * 3000000 + ' \`true\`' * 1000 + '\"'" > test.sh
$ ./busybox ash test.sh | wc
      1       0 3001001

Signed-off-by: Martin Lewis <martin.lewis.x84 at gmail.com>
---
 shell/ash.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 90eaf6f..f1dbbb5 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12600,15 +12600,7 @@ parsebackq: {
 	str = NULL;
 	savelen = out - (char *)stackblock();
 	if (savelen > 0) {
-		/*
-		 * FIXME: this can allocate very large block on stack and SEGV.
-		 * Example:
-		 * echo "..<100kbytes>..`true` $(true) `true` ..."
-		 * allocates 100kb for every command subst. With about
-		 * a hundred command substitutions stack overflows.
-		 * With larger prepended string, SEGV happens sooner.
-		 */
-		str = alloca(savelen);
+		str = ckmalloc(savelen);
 		memcpy(str, stackblock(), savelen);
 	}
 
@@ -12697,6 +12689,7 @@ parsebackq: {
 	if (str) {
 		memcpy(out, str, savelen);
 		STADJUST(savelen, out);
+		free(str);
 	}
 	USTPUTC(CTLBACKQ, out);
 	if (oldstyle)
-- 
1.9.1



More information about the busybox mailing list