mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
binpac: Fix potential out-of-bounds memory reads in generated code.
Field lengths derived from other data in the input could potentially lead to reading from outside the bounds of the input buffer. Reported by John Villamil and Chris Rohlf - Yahoo Paranoids
This commit is contained in:
parent
db1c70b32e
commit
8648820497
2 changed files with 44 additions and 2 deletions
|
@ -41,10 +41,13 @@ void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env,
|
||||||
ASSERT(id_);
|
ASSERT(id_);
|
||||||
|
|
||||||
out_cc->println("// Checking out-of-bound for \"%s\"", data_name);
|
out_cc->println("// Checking out-of-bound for \"%s\"", data_name);
|
||||||
out_cc->println("if ( %s + (%s) > %s )",
|
out_cc->println("if ( %s + (%s) > %s || %s + (%s) < %s )",
|
||||||
ptr_expr(),
|
ptr_expr(),
|
||||||
data_size,
|
data_size,
|
||||||
env->RValue(end_of_data));
|
env->RValue(end_of_data),
|
||||||
|
ptr_expr(),
|
||||||
|
data_size,
|
||||||
|
ptr_expr());
|
||||||
|
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
|
|
|
@ -602,10 +602,37 @@ void RecordPaddingField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& fi
|
||||||
switch ( ptype_ )
|
switch ( ptype_ )
|
||||||
{
|
{
|
||||||
case PAD_BY_LENGTH:
|
case PAD_BY_LENGTH:
|
||||||
|
out_cc->println("if ( (%s) < 0 ) // check for negative pad length",
|
||||||
|
expr_->EvalExpr(out_cc, env));
|
||||||
|
out_cc->inc_indent();
|
||||||
|
out_cc->println("{");
|
||||||
|
out_cc->println("throw binpac::ExceptionInvalidStringLength(\"%s\", %s);",
|
||||||
|
Location(), expr_->EvalExpr(out_cc, env));
|
||||||
|
out_cc->println("}");
|
||||||
|
out_cc->dec_indent();
|
||||||
|
out_cc->println("");
|
||||||
|
|
||||||
out_cc->println("const_byteptr const %s = %s + (%s);",
|
out_cc->println("const_byteptr const %s = %s + (%s);",
|
||||||
env->LValue(end_of_field_dataptr_var),
|
env->LValue(end_of_field_dataptr_var),
|
||||||
field_begin.ptr_expr(),
|
field_begin.ptr_expr(),
|
||||||
expr_->EvalExpr(out_cc, env));
|
expr_->EvalExpr(out_cc, env));
|
||||||
|
|
||||||
|
out_cc->println("// Checking out-of-bound padding for \"%s\"", field_id_str_.c_str());
|
||||||
|
out_cc->println("if ( %s > %s || %s < %s )",
|
||||||
|
env->LValue(end_of_field_dataptr_var),
|
||||||
|
env->RValue(end_of_data),
|
||||||
|
env->LValue(end_of_field_dataptr_var),
|
||||||
|
field_begin.ptr_expr());
|
||||||
|
out_cc->inc_indent();
|
||||||
|
out_cc->println("{");
|
||||||
|
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
|
||||||
|
out_cc->println(" (%s), ",
|
||||||
|
expr_->EvalExpr(out_cc, env));
|
||||||
|
out_cc->println(" (%s) - (%s));",
|
||||||
|
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
|
||||||
|
out_cc->println("}");
|
||||||
|
out_cc->dec_indent();
|
||||||
|
out_cc->println("");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_TO_OFFSET:
|
case PAD_TO_OFFSET:
|
||||||
|
@ -628,6 +655,18 @@ void RecordPaddingField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& fi
|
||||||
field_begin.ptr_expr());
|
field_begin.ptr_expr());
|
||||||
out_cc->println("}");
|
out_cc->println("}");
|
||||||
out_cc->dec_indent();
|
out_cc->dec_indent();
|
||||||
|
out_cc->println("if ( %s > %s )",
|
||||||
|
env->LValue(end_of_field_dataptr_var),
|
||||||
|
env->RValue(end_of_data));
|
||||||
|
out_cc->inc_indent();
|
||||||
|
out_cc->println("{");
|
||||||
|
out_cc->println("throw binpac::ExceptionOutOfBound(\"%s\",", field_id_str_.c_str());
|
||||||
|
out_cc->println(" (%s), ",
|
||||||
|
expr_->EvalExpr(out_cc, env));
|
||||||
|
out_cc->println(" (%s) - (%s));",
|
||||||
|
env->RValue(end_of_data), env->LValue(end_of_field_dataptr_var));
|
||||||
|
out_cc->println("}");
|
||||||
|
out_cc->dec_indent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_TO_NEXT_WORD:
|
case PAD_TO_NEXT_WORD:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue