mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
implement bounds checking on all opcodes
This commit is contained in:
parent
c3f47efb07
commit
5d6977288f
2 changed files with 95 additions and 20 deletions
|
@ -257,6 +257,21 @@ PR_LeaveFunction (progs_t *pr)
|
|||
&pr->localstack[pr->localstack_used], sizeof (pr_type_t) * c);
|
||||
}
|
||||
|
||||
static void
|
||||
PR_BoundsCheckSize (progs_t *pr, int addr, unsigned size)
|
||||
{
|
||||
if (addr < 0 || addr >= pr->globals_size
|
||||
|| size > (unsigned) (pr->globals_size - addr))
|
||||
PR_RunError (pr, "invalid memory access: %d (0 to %d-%d)", addr,
|
||||
pr->globals_size, size);
|
||||
}
|
||||
|
||||
static void
|
||||
PR_BoundsCheck (progs_t *pr, int addr, etype_t type)
|
||||
{
|
||||
PR_BoundsCheckSize (pr, addr, pr_type_size[type]);
|
||||
}
|
||||
|
||||
#define OPA (*op_a)
|
||||
#define OPB (*op_b)
|
||||
#define OPC (*op_c)
|
||||
|
@ -576,18 +591,27 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_STOREP_I:
|
||||
case OP_STOREP_U:
|
||||
case OP_STOREP_P:
|
||||
//FIXME put bounds checking back
|
||||
ptr = pr->pr_globals + OPB.integer_var;
|
||||
pointer = OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
ptr->integer_var = OPA.integer_var;
|
||||
break;
|
||||
case OP_STOREP_V:
|
||||
//FIXME put bounds checking back
|
||||
ptr = pr->pr_globals + OPB.integer_var;
|
||||
pointer = OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
VectorCopy (OPA.vector_var, ptr->vector_var);
|
||||
break;
|
||||
case OP_STOREP_Q:
|
||||
//FIXME put bounds checking back
|
||||
ptr = pr->pr_globals + OPB.integer_var;
|
||||
pointer = OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quat);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
QuatCopy (OPA.quat_var, ptr->quat_var);
|
||||
break;
|
||||
|
||||
|
@ -674,20 +698,26 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_LOADB_I:
|
||||
case OP_LOADB_U:
|
||||
case OP_LOADB_P:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
OPC.integer_var = ptr->integer_var;
|
||||
break;
|
||||
case OP_LOADB_V:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
VectorCopy (ptr->vector_var, OPC.vector_var);
|
||||
break;
|
||||
case OP_LOADB_Q:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quat);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
QuatCopy (ptr->quat_var, OPC.quat_var);
|
||||
break;
|
||||
|
@ -700,20 +730,26 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_LOADBI_I:
|
||||
case OP_LOADBI_U:
|
||||
case OP_LOADBI_P:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + (short) st->b;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
OPC.integer_var = ptr->integer_var;
|
||||
break;
|
||||
case OP_LOADBI_V:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + (short) st->b;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
VectorCopy (ptr->vector_var, OPC.vector_var);
|
||||
break;
|
||||
case OP_LOADBI_Q:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPA.integer_var + (short) st->b;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quat);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
QuatCopy (ptr->quat_var, OPC.quat_var);
|
||||
break;
|
||||
|
@ -736,20 +772,26 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_STOREB_I:
|
||||
case OP_STOREB_U:
|
||||
case OP_STOREB_P:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + OPC.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
ptr->integer_var = OPA.integer_var;
|
||||
break;
|
||||
case OP_STOREB_V:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + OPC.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
VectorCopy (OPA.vector_var, ptr->vector_var);
|
||||
break;
|
||||
case OP_STOREB_Q:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + OPC.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quat);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
QuatCopy (OPA.quat_var, ptr->quat_var);
|
||||
break;
|
||||
|
@ -762,20 +804,26 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_STOREBI_I:
|
||||
case OP_STOREBI_U:
|
||||
case OP_STOREBI_P:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + (short) st->c;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
ptr->integer_var = OPA.integer_var;
|
||||
break;
|
||||
case OP_STOREBI_V:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + (short) st->c;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
VectorCopy (OPA.vector_var, ptr->vector_var);
|
||||
break;
|
||||
case OP_STOREBI_Q:
|
||||
//FIXME put bounds checking in
|
||||
pointer = OPB.integer_var + (short) st->c;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quat);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
QuatCopy (OPA.quat_var, ptr->quat_var);
|
||||
break;
|
||||
|
@ -830,8 +878,10 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
break;
|
||||
case OP_JUMPB:
|
||||
//FIXME put bounds checking in
|
||||
pointer = st->a + OPB.integer_var;
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheck (pr, pointer, ev_integer);
|
||||
}
|
||||
ptr = pr->pr_globals + pointer;
|
||||
pointer = ptr->integer_var;
|
||||
if (pr_boundscheck->int_val
|
||||
|
@ -1035,6 +1085,10 @@ op_call:
|
|||
memmove (&OPC, &OPA, st->b * 4);
|
||||
break;
|
||||
case OP_MOVEP:
|
||||
if (pr_boundscheck->int_val) {
|
||||
PR_BoundsCheckSize (pr, OPC.integer_var, OPB.uinteger_var);
|
||||
PR_BoundsCheckSize (pr, OPA.integer_var, OPB.uinteger_var);
|
||||
}
|
||||
memmove (pr->pr_globals + OPC.integer_var,
|
||||
pr->pr_globals + OPA.integer_var,
|
||||
OPB.uinteger_var * 4);
|
||||
|
|
|
@ -1213,7 +1213,8 @@ check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (operand >= pr->progs->numglobals) {
|
||||
if (operand + (unsigned) pr_type_size[type]
|
||||
> pr->progs->numglobals) {
|
||||
msg = "out of bounds global index";
|
||||
goto error;
|
||||
}
|
||||
|
@ -1226,6 +1227,22 @@ error:
|
|||
(long)(st - pr->pr_statements), op->opname);
|
||||
}
|
||||
|
||||
static inline void
|
||||
check_global_size (progs_t *pr, dstatement_t *st, opcode_t *op,
|
||||
unsigned short size, unsigned short operand)
|
||||
{
|
||||
const char *msg;
|
||||
if (operand + size > pr->progs->numglobals) {
|
||||
msg = "out of bounds global index";
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
PR_PrintStatement (pr, st, 0);
|
||||
PR_Error (pr, "PR_Check_Opcodes: %s (statement %ld: %s)", msg,
|
||||
(long)(st - pr->pr_statements), op->opname);
|
||||
}
|
||||
|
||||
int
|
||||
PR_Check_Opcodes (progs_t *pr)
|
||||
{
|
||||
|
@ -1300,6 +1317,10 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
check_global (pr, st, op, op->type_b, st->b);
|
||||
check_global (pr, st, op, op->type_c, st->c);
|
||||
break;
|
||||
case OP_MOVE:
|
||||
check_global_size (pr, st, op, st->b, st->a);
|
||||
check_global_size (pr, st, op, st->b, st->c);
|
||||
break;
|
||||
default:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
|
|
Loading…
Reference in a new issue