Bug hunting; Diagnose array index out of bounds when struct member is accessed

This commit is contained in:
Daniel Marjamäki 2020-12-06 17:44:07 +01:00
parent 5e15a7fac7
commit d12732adfb
2 changed files with 17 additions and 4 deletions

View File

@ -2011,12 +2011,12 @@ static ExprEngine::ValuePtr executeCast(const Token *tok, Data &data)
static ExprEngine::ValuePtr executeDot(const Token *tok, Data &data)
{
if (!tok->astOperand1() || !tok->astOperand1()->varId()) {
auto v = getValueRangeFromValueType(tok->valueType(), data);
if (!tok->astOperand1()) {
auto v = std::make_shared<ExprEngine::BailoutValue>();
call(data.callbacks, tok, v, &data);
return v;
}
std::shared_ptr<ExprEngine::StructValue> structValue = std::dynamic_pointer_cast<ExprEngine::StructValue>(data.getValue(tok->astOperand1()->varId(), nullptr, nullptr));
std::shared_ptr<ExprEngine::StructValue> structValue = std::dynamic_pointer_cast<ExprEngine::StructValue>(executeExpression(tok->astOperand1(), data));
if (!structValue) {
if (tok->originalName() == "->") {
std::shared_ptr<ExprEngine::ArrayValue> pointerValue = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(data.getValue(tok->astOperand1()->varId(), nullptr, nullptr));

View File

@ -38,6 +38,7 @@ private:
TEST_CASE(checkAssignment);
TEST_CASE(arrayIndexOutOfBounds1);
TEST_CASE(arrayIndexOutOfBounds2);
TEST_CASE(arrayIndexOutOfBounds3);
TEST_CASE(bufferOverflowMemCmp1);
TEST_CASE(bufferOverflowMemCmp2);
TEST_CASE(bufferOverflowStrcpy1);
@ -83,7 +84,7 @@ private:
errout.str());
}
void arrayIndexOutOfBounds2() {
void arrayIndexOutOfBounds2() { // loop
check("void foo(int n) {\n"
" int p[8];\n"
" for (int i = 0; i < n; i++)\n"
@ -106,6 +107,18 @@ private:
errout.str());
}
void arrayIndexOutOfBounds3() { // struct
check("struct S { int x; };\n"
"void foo(short i) {\n"
" S s[8];\n"
" if (s[i].x == 0) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is less than 8\n"
"[test.cpp:4]: (error) Array index out of bounds, cannot determine that i is not negative\n"
"[test.cpp:4]: (error) Cannot determine that 's[i]' is initialized\n",
errout.str());
}
void bufferOverflowMemCmp1() {
// CVE-2020-24265
check("void foo(const char *pktdata, int datalen) {\n"