Bug hunting; better handling of struct member assignment in for loop

This commit is contained in:
Daniel Marjamäki 2020-12-07 19:58:19 +01:00
parent a9f4a14c8d
commit 02bb14003b
2 changed files with 28 additions and 0 deletions

View File

@ -2453,6 +2453,16 @@ static std::string execute(const Token *start, const Token *end, Data &data)
lhs = lhs->astOperand1();
if (!lhs)
throw ExprEngineException(tok2, "Unhandled assignment in loop");
if (Token::Match(lhs, ". %name% =|[") && Token::simpleMatch(lhs->astOperand1(), ".")) {
const Token *structToken = lhs;
while (Token::Match(structToken, ".|["))
structToken = structToken->astOperand1();
if (Token::Match(structToken, "%var%")) {
data.assignValue(structToken, structToken->varId(), std::make_shared<ExprEngine::BailoutValue>());
changedVariables.insert(structToken->varId());
continue;
}
}
if (Token::Match(lhs, ". %name% =|[") && lhs->astOperand1() && lhs->astOperand1()->valueType()) {
const Token *structToken = lhs->astOperand1();
if (!structToken->valueType() || !structToken->varId())

View File

@ -40,6 +40,7 @@ private:
TEST_CASE(arrayIndexOutOfBounds2);
TEST_CASE(arrayIndexOutOfBounds3);
TEST_CASE(arrayIndexOutOfBounds4);
TEST_CASE(arrayIndexOutOfBounds5);
TEST_CASE(bufferOverflowMemCmp1);
TEST_CASE(bufferOverflowMemCmp2);
TEST_CASE(bufferOverflowStrcpy1);
@ -135,6 +136,23 @@ private:
errout.str());
}
void arrayIndexOutOfBounds5() {
check("struct {\n"
" struct { int z; } y;\n"
"} x;\n"
"\n"
"void foo(int i) {\n"
" for (int c = 0; c <= i; c++)\n"
" x.y.z = 13;\n"
" int buf[10];\n"
" if (buf[i] > 0) { }\n"
"}");
ASSERT_EQUALS("[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is less than 10\n"
"[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is not negative\n"
"[test.cpp:9]: (error) Cannot determine that 'buf[i]' is initialized\n",
errout.str());
}
void bufferOverflowMemCmp1() {
// CVE-2020-24265
check("void foo(const char *pktdata, int datalen) {\n"