ash: [EVAL] Fix use-after-free in dotrap/evalstring
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 28 Sep 2016 21:02:57 +0000 (23:02 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 28 Sep 2016 21:02:57 +0000 (23:02 +0200)
From upstream:

    [EVAL] Fix use-after-free in dotrap/evalstring

    The function dotrap calls evalstring using the stored trap string.
    If evalstring then unsets that exact trap string then we will end
    up using freed memory.

    This patch fixes it by making evalstring always duplicate the string
    before using it.

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

index f395a16a964137a75cf49fea8a295fd359e1f63e..7a7ea18964d8f7189531d880f44c0edd291a75d3 100644 (file)
@@ -1459,7 +1459,7 @@ stunalloc(void *p)
  * Like strdup but works with the ash stack.
  */
 static char *
-ststrdup(const char *p)
+sstrdup(const char *p)
 {
        size_t len = strlen(p) + 1;
        return memcpy(stalloc(len), p, len);
@@ -2514,7 +2514,7 @@ updatepwd(const char *dir)
        char *cdcomppath;
        const char *lim;
 
-       cdcomppath = ststrdup(dir);
+       cdcomppath = sstrdup(dir);
        STARTSTACKSTR(new);
        if (*dir != '/') {
                if (curdir == nullstr)
@@ -6993,7 +6993,7 @@ addfname(const char *name)
        struct strlist *sp;
 
        sp = stzalloc(sizeof(*sp));
-       sp->text = ststrdup(name);
+       sp->text = sstrdup(name);
        *exparg.lastp = sp;
        exparg.lastp = &sp->next;
 }
@@ -12221,10 +12221,12 @@ evalstring(char *s, int mask)
        int skip;
 //     int status;
 
+       s = sstrdup(s);
        setinputstring(s);
        setstackmark(&smark);
 
        skip = 0;
+//     status = 0;
        while ((n = parsecmd(0)) != NODE_EOF) {
                int i;
 
@@ -12236,7 +12238,9 @@ evalstring(char *s, int mask)
                if (skip)
                        break;
        }
+       popstackmark(&smark);
        popfile();
+       stunalloc(s);
 
        skip &= mask;
        evalskip = skip;