Ron Yorston
2018-11-11 10:33:52 UTC
This bug:
https://bugs.busybox.net/show_bug.cgi?id=9246
demonstrates a test case where BusyBox ash segfaults due to a stack
overflow.
Instead of using alloca() to preserve characters keep them on the
shell's heap-based stack. With this change the test case returns:
$ busybox sh test_case
test_case: line 3141: syntax error: unterminated quoted string
That is, the test runs to completion. If the heap is reduced to 8MB:
$ ulimit -S -d 8192
$ busybox sh test_case
sh: out of memory
Heap exhaustion is detected and the shell continues to run.
function old new delta
readtoken1 3265 3203 -62
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-62) Total: -62 bytes
Signed-off-by: Ron Yorston <***@pobox.com>
---
shell/ash.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/shell/ash.c b/shell/ash.c
index 90eaf6faf..5ee36db93 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12599,18 +12599,8 @@ 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);
- memcpy(str, stackblock(), savelen);
- }
+ if (savelen > 0)
+ str = grabstackstr(out);
if (oldstyle) {
/* We must read until the closing backquote, giving special
https://bugs.busybox.net/show_bug.cgi?id=9246
demonstrates a test case where BusyBox ash segfaults due to a stack
overflow.
Instead of using alloca() to preserve characters keep them on the
shell's heap-based stack. With this change the test case returns:
$ busybox sh test_case
test_case: line 3141: syntax error: unterminated quoted string
That is, the test runs to completion. If the heap is reduced to 8MB:
$ ulimit -S -d 8192
$ busybox sh test_case
sh: out of memory
Heap exhaustion is detected and the shell continues to run.
function old new delta
readtoken1 3265 3203 -62
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-62) Total: -62 bytes
Signed-off-by: Ron Yorston <***@pobox.com>
---
shell/ash.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/shell/ash.c b/shell/ash.c
index 90eaf6faf..5ee36db93 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12599,18 +12599,8 @@ 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);
- memcpy(str, stackblock(), savelen);
- }
+ if (savelen > 0)
+ str = grabstackstr(out);
if (oldstyle) {
/* We must read until the closing backquote, giving special
--
2.19.1
2.19.1