aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-02-25 08:29:38 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2019-02-25 18:57:59 +0100
commitf55161ad27b641f6e09c6c498fa8a2bdb1112b0a (patch)
tree8ea2b3a9922ffd0b3fc8b47b7a997130e80bb7ce /shell
parente563f9e851c78f5c13cb9828ddb11ca981fd6331 (diff)
downloadbusybox-w32-f55161ad27b641f6e09c6c498fa8a2bdb1112b0a.tar.gz
busybox-w32-f55161ad27b641f6e09c6c498fa8a2bdb1112b0a.tar.bz2
busybox-w32-f55161ad27b641f6e09c6c498fa8a2bdb1112b0a.zip
ash: eval: avoid leaking memory associated with redirections. Closes 7748
The following constructs result in ever-increasing memory usage: while true; do { true; } </dev/null; done while true; do ( true; ) </dev/null; done For comparison, bash displays static memory usage in both cases. This has been fixed in dash by commit 2bc6caa. The maintainer writes: I have simplified evaltree so that it simply sets the stack mark unconditionally. This allows us to remove the stack marks in the functions called by evaltree. Closes BusyBox bug 7748. function old new delta evaltree 606 632 +26 evalcommand 1724 1696 -28 evalcase 382 351 -31 evalfor 230 196 -34 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 26/-93) Total: -67 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/shell/ash.c b/shell/ash.c
index a284b084d..a4394d756 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9034,8 +9034,11 @@ evaltree(union node *n, int flags)
9034{ 9034{
9035 int checkexit = 0; 9035 int checkexit = 0;
9036 int (*evalfn)(union node *, int); 9036 int (*evalfn)(union node *, int);
9037 struct stackmark smark;
9037 int status = 0; 9038 int status = 0;
9038 9039
9040 setstackmark(&smark);
9041
9039 if (n == NULL) { 9042 if (n == NULL) {
9040 TRACE(("evaltree(NULL) called\n")); 9043 TRACE(("evaltree(NULL) called\n"));
9041 goto out; 9044 goto out;
@@ -9149,6 +9152,7 @@ evaltree(union node *n, int flags)
9149 if (flags & EV_EXIT) 9152 if (flags & EV_EXIT)
9150 raise_exception(EXEXIT); 9153 raise_exception(EXEXIT);
9151 9154
9155 popstackmark(&smark);
9152 TRACE(("leaving evaltree (no interrupts)\n")); 9156 TRACE(("leaving evaltree (no interrupts)\n"));
9153 return exitstatus; 9157 return exitstatus;
9154} 9158}
@@ -9209,14 +9213,12 @@ evalfor(union node *n, int flags)
9209 struct arglist arglist; 9213 struct arglist arglist;
9210 union node *argp; 9214 union node *argp;
9211 struct strlist *sp; 9215 struct strlist *sp;
9212 struct stackmark smark;
9213 int status = 0; 9216 int status = 0;
9214 9217
9215 errlinno = lineno = n->ncase.linno; 9218 errlinno = lineno = n->ncase.linno;
9216 if (funcline) 9219 if (funcline)
9217 lineno -= funcline - 1; 9220 lineno -= funcline - 1;
9218 9221
9219 setstackmark(&smark);
9220 arglist.list = NULL; 9222 arglist.list = NULL;
9221 arglist.lastp = &arglist.list; 9223 arglist.lastp = &arglist.list;
9222 for (argp = n->nfor.args; argp; argp = argp->narg.next) { 9224 for (argp = n->nfor.args; argp; argp = argp->narg.next) {
@@ -9233,7 +9235,6 @@ evalfor(union node *n, int flags)
9233 break; 9235 break;
9234 } 9236 }
9235 loopnest--; 9237 loopnest--;
9236 popstackmark(&smark);
9237 9238
9238 return status; 9239 return status;
9239} 9240}
@@ -9244,14 +9245,12 @@ evalcase(union node *n, int flags)
9244 union node *cp; 9245 union node *cp;
9245 union node *patp; 9246 union node *patp;
9246 struct arglist arglist; 9247 struct arglist arglist;
9247 struct stackmark smark;
9248 int status = 0; 9248 int status = 0;
9249 9249
9250 errlinno = lineno = n->ncase.linno; 9250 errlinno = lineno = n->ncase.linno;
9251 if (funcline) 9251 if (funcline)
9252 lineno -= funcline - 1; 9252 lineno -= funcline - 1;
9253 9253
9254 setstackmark(&smark);
9255 arglist.list = NULL; 9254 arglist.list = NULL;
9256 arglist.lastp = &arglist.list; 9255 arglist.lastp = &arglist.list;
9257 expandarg(n->ncase.expr, &arglist, EXP_TILDE); 9256 expandarg(n->ncase.expr, &arglist, EXP_TILDE);
@@ -9270,8 +9269,6 @@ evalcase(union node *n, int flags)
9270 } 9269 }
9271 } 9270 }
9272 out: 9271 out:
9273 popstackmark(&smark);
9274
9275 return status; 9272 return status;
9276} 9273}
9277 9274
@@ -9970,7 +9967,6 @@ evalcommand(union node *cmd, int flags)
9970 struct localvar_list *localvar_stop; 9967 struct localvar_list *localvar_stop;
9971 struct parsefile *file_stop; 9968 struct parsefile *file_stop;
9972 struct redirtab *redir_stop; 9969 struct redirtab *redir_stop;
9973 struct stackmark smark;
9974 union node *argp; 9970 union node *argp;
9975 struct arglist arglist; 9971 struct arglist arglist;
9976 struct arglist varlist; 9972 struct arglist varlist;
@@ -9992,7 +9988,6 @@ evalcommand(union node *cmd, int flags)
9992 9988
9993 /* First expand the arguments. */ 9989 /* First expand the arguments. */
9994 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); 9990 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
9995 setstackmark(&smark);
9996 localvar_stop = pushlocalvars(); 9991 localvar_stop = pushlocalvars();
9997 file_stop = g_parsefile; 9992 file_stop = g_parsefile;
9998 back_exitstatus = 0; 9993 back_exitstatus = 0;
@@ -10275,7 +10270,6 @@ evalcommand(union node *cmd, int flags)
10275 */ 10270 */
10276 setvar0("_", lastarg); 10271 setvar0("_", lastarg);
10277 } 10272 }
10278 popstackmark(&smark);
10279 10273
10280 return status; 10274 return status;
10281} 10275}