ash: make popfile() anfter popallfiles() safe
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 30 Oct 2016 17:27:14 +0000 (18:27 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 30 Oct 2016 17:27:14 +0000 (18:27 +0100)
In this example:

ash -c 'readonly x; echo $(command eval x=2)'

evalstring() is called after forkchild(), which calls popallfiles().
On exception, evalstring() will popfile().

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index fc1b5d9275d54a5b8c532d9554439491616389b3..0c84805879488dd27cd1f9b08e6090d65aebb1f5 100644 (file)
@@ -10125,6 +10125,9 @@ popfile(void)
 {
        struct parsefile *pf = g_parsefile;
 
+       if (pf == &basepf)
+               return;
+
        INT_OFF;
        if (pf->pf_fd >= 0)
                close(pf->pf_fd);
@@ -12286,7 +12289,7 @@ expandstr(const char *ps)
 static int
 evalstring(char *s, int flags)
 {
-       struct jmploc *volatile savehandler = exception_handler;
+       struct jmploc *volatile savehandler;
        struct jmploc jmploc;
        int ex;
 
@@ -12307,10 +12310,10 @@ evalstring(char *s, int flags)
         * But if we skip popfile(), we hit EOF in eval's string, and exit.
         */
        savehandler = exception_handler;
-       exception_handler = &jmploc;
        ex = setjmp(jmploc.loc);
        if (ex)
                goto out;
+       exception_handler = &jmploc;
 
        while ((n = parsecmd(0)) != NODE_EOF) {
                int i;