From 67f791e9dfd457941c7b73607fdeec2262020154 Mon Sep 17 00:00:00 2001 From: divverent Date: Wed, 19 Aug 2009 06:19:36 +0000 Subject: [PATCH] bounds check function calls, and entity indexes in LOAD instructions git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9127 d7cf8633-e32d-0410-b094-e92efae38249 --- prvm_execprogram.h | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/prvm_execprogram.h b/prvm_execprogram.h index 86596615..43d04745 100644 --- a/prvm_execprogram.h +++ b/prvm_execprogram.h @@ -3,7 +3,7 @@ while (1) { - st++; // TODO bounds check + st++; #if PRVMTRACE PRVM_PrintStatement(st); @@ -207,6 +207,13 @@ case OP_LOAD_S: case OP_LOAD_FNC: #if PRVMBOUNDSCHECK + if (OPA->edict < 0 || OPA->edict >= prog->edictareasize) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME); + goto cleanup; + } if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields)) { prog->xfunction->profile += (st - startst); @@ -215,12 +222,19 @@ goto cleanup; } #endif - ed = PRVM_PROG_TO_EDICT(OPA->edict); // TODO bounds check entity number + ed = PRVM_PROG_TO_EDICT(OPA->edict); OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int; break; case OP_LOAD_V: #if PRVMBOUNDSCHECK + if (OPA->edict < 0 || OPA->edict >= prog->edictareasize) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; + PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME); + goto cleanup; + } if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields) { prog->xfunction->profile += (st - startst); @@ -229,7 +243,7 @@ goto cleanup; } #endif - ed = PRVM_PROG_TO_EDICT(OPA->edict); // TODO bounds check entity number + ed = PRVM_PROG_TO_EDICT(OPA->edict); OPC->ivector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->ivector[0]; OPC->ivector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->ivector[1]; OPC->ivector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->ivector[2]; @@ -246,6 +260,7 @@ prog->xfunction->profile += (st - startst); st += st->b - 1; // offset the s++ startst = st; + // no bounds check needed, it is done when loading progs #if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { @@ -266,6 +281,7 @@ prog->xfunction->profile += (st - startst); st += st->b - 1; // offset the s++ startst = st; + // no bounds check needed, it is done when loading progs #if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { @@ -281,6 +297,7 @@ prog->xfunction->profile += (st - startst); st += st->a - 1; // offset the s++ startst = st; + // no bounds check needed, it is done when loading progs #if PRVMRUNAWAYCHECK if (++jumpcount == 10000000) { @@ -306,7 +323,18 @@ prog->argc = st->op - OP_CALL0; if (!OPA->function) PRVM_ERROR("NULL function in %s", PRVM_NAME); - newf = &prog->functions[OPA->function]; // TODO bounds check function + +#if PRVMBOUNDSCHECK + if(!OPA->function || OPA->function >= (unsigned int)prog->progs->numfunctions) + { + prog->xfunction->profile += (st - startst); + prog->xstatement = st - prog->statements; // we better stay on the previously executed statement + PRVM_ERROR("%s CALL outside the program", PRVM_NAME); + goto cleanup; + } +#endif + + newf = &prog->functions[OPA->function]; newf->callcount++; if (newf->first_statement < 0) -- 2.39.2