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

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>
This commit is contained in:
Denys Vlasenko 2016-09-28 23:02:57 +02:00
parent 7ee7c6fc20
commit 8e2bc47d62

View File

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