Buffer overrun: UB when pointer arithmetic result points out of bounds. Ticket #1774

This commit is contained in:
Daniel Marjamäki 2010-12-26 21:23:28 +01:00
parent 6178459c15
commit 6aa400fd80
3 changed files with 34 additions and 0 deletions

View File

@ -125,6 +125,12 @@ void CheckBufferOverrun::outOfBounds(const Token *tok, const std::string &what)
reportError(tok, Severity::error, "outOfBounds", what + " is out of bounds");
}
void CheckBufferOverrun::pointerOutOfBounds(const Token *tok)
{
reportError(tok, Severity::portability, "pointerOutOfBounds", "Undefined behaviour: pointer arithmetic result does not point into or just past the end of the array\n"
"Undefined behaviour: Using pointer arithmetic so that the result does not point into or just past the end of the same object. Further information: https://www.securecoding.cert.org/confluence/display/seccode/ARR30-C.+Do+not+form+or+use+out+of+bounds+pointers+or+array+subscripts");
}
void CheckBufferOverrun::sizeArgumentAsChar(const Token *tok)
{
if (_settings && !_settings->_checkCodingStyle)
@ -1078,6 +1084,16 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
if (static_cast<unsigned long>(n) > total_size)
outOfBounds(tok->tokAt(4), "snprintf size");
}
// undefined behaviour: result of pointer arithmetic is out of bounds
if (_settings->_checkCodingStyle && Token::Match(tok, "= %varid% + %num% ;", arrayInfo.varid))
{
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3));
if (index < 0 || index > arrayInfo.num[0])
{
pointerOutOfBounds(tok->next());
}
}
}
}

View File

@ -186,6 +186,7 @@ public:
void terminateStrncpyError(const Token *tok);
void negativeIndexError(const Token *tok, MathLib::bigint index);
void cmdLineArgsError(const Token *tok);
void pointerOutOfBounds(const Token *tok); // UB when result of calculation is out of bounds
void getErrorMessages()
{
@ -197,6 +198,7 @@ public:
terminateStrncpyError(0);
negativeIndexError(0, -1);
cmdLineArgsError(0);
pointerOutOfBounds(0);
}
std::string name() const

View File

@ -131,6 +131,13 @@ private:
TEST_CASE(buffer_overrun_15); // ticket #1787
TEST_CASE(buffer_overrun_16);
// It is undefined behaviour to point out of bounds of an array
// the address beyond the last element is in bounds
// char a[10];
// char *p1 = a + 10; // OK
// char *p2 = a + 11 // UB
TEST_CASE(pointer_out_of_bounds_1);
TEST_CASE(sprintf1);
TEST_CASE(sprintf2);
TEST_CASE(sprintf3);
@ -1800,6 +1807,15 @@ private:
ASSERT_EQUALS("", errout.str());
}
void pointer_out_of_bounds_1()
{
check("void f() {\n"
" char a[10];\n"
" char *p = a + 100;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour: pointer arithmetic result does not point into or just past the end of the array\n", errout.str());
}
void sprintf1()
{
check("void f()\n"