prevent more access to invalid memories (Debian #700604)

This commit is contained in:
tg 2013-02-15 18:36:48 +00:00
parent 2c76875ea3
commit 12f0ff60d2
1 changed files with 23 additions and 18 deletions

41
expr.c
View File

@ -2,7 +2,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012 * 2011, 2012, 2013
* Thorsten Glaser <tg@mirbsd.org> * Thorsten Glaser <tg@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.60 2012/10/03 17:24:19 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.61 2013/02/15 18:36:48 tg Exp $");
#if !HAVE_SILENT_IDIVWRAPV #if !HAVE_SILENT_IDIVWRAPV
#if !defined(MKSH_LEGACY_MODE) || HAVE_LONG_32BIT #if !defined(MKSH_LEGACY_MODE) || HAVE_LONG_32BIT
@ -139,18 +139,24 @@ static const struct opinfo opinfo[] = {
{ "", 0, P_PRIMARY } { "", 0, P_PRIMARY }
}; };
typedef struct expr_state Expr_state; typedef struct expr_state {
struct expr_state { /* expression being evaluated */
const char *expression; /* expression being evaluated */ const char *expression;
const char *tokp; /* lexical position */ /* lexical position */
struct tbl *val; /* value from token() */ const char *tokp;
struct tbl *evaling; /* variable that is being recursively /* value from token() */
* expanded (EXPRINEVAL flag set) */ struct tbl *val;
int noassign; /* don't do assigns (for ?:,&&,||) */ /* variable that is being recursively expanded (EXPRINEVAL flag set) */
enum token tok; /* token from token() */ struct tbl *evaling;
bool arith; /* evaluating an $(()) expression? */ /* token from token() */
bool natural; /* unsigned arithmetic calculation */ enum token tok;
}; /* don't do assignments (for ?:, &&, ||) */
short noassign;
/* evaluating an $(()) expression? */
bool arith;
/* unsigned arithmetic calculation */
bool natural;
} Expr_state;
#define bivui(x, op, y) (es->natural ? \ #define bivui(x, op, y) (es->natural ? \
(mksh_uari_t)((x)->val.u op (y)->val.u) : \ (mksh_uari_t)((x)->val.u op (y)->val.u) : \
@ -199,11 +205,10 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
int i; int i;
/* save state to allow recursive calls */ /* save state to allow recursive calls */
memset(&curstate, 0, sizeof(curstate));
curstate.expression = curstate.tokp = expr; curstate.expression = curstate.tokp = expr;
curstate.noassign = 0; curstate.tok = BAD;
curstate.arith = arith; curstate.arith = arith;
curstate.evaling = NULL;
curstate.natural = false;
newenv(E_ERRH); newenv(E_ERRH);
if ((i = kshsetjmp(e->jbuf))) { if ((i = kshsetjmp(e->jbuf))) {
@ -641,7 +646,7 @@ do_ppmm(Expr_state *es, enum token op, struct tbl *vasn, bool is_prefix)
static void static void
assign_check(Expr_state *es, enum token op, struct tbl *vasn) assign_check(Expr_state *es, enum token op, struct tbl *vasn)
{ {
if (es->tok == END || if (es->tok == END || !vasn ||
(vasn->name[0] == '\0' && !(vasn->flag & EXPRLVALUE))) (vasn->name[0] == '\0' && !(vasn->flag & EXPRLVALUE)))
evalerr(es, ET_LVALUE, opinfo[(int)op].name); evalerr(es, ET_LVALUE, opinfo[(int)op].name);
else if (vasn->flag & RDONLY) else if (vasn->flag & RDONLY)