Buffer overruns, using string with unknown length

This commit is contained in:
Daniel Marjamäki 2007-07-18 06:12:16 +00:00
parent 7ea6e10f1f
commit 93b3e2e5aa
5 changed files with 151 additions and 1 deletions

View File

@ -9,6 +9,124 @@
//---------------------------------------------------------------------------
TOKEN *findfunction(TOKEN *tok)
{
int indentlevel = 0, parlevel = 0;
for (; tok; tok = tok->next)
{
if (tok->str[0] == '{')
indentlevel++;
else if (tok->str[0] == '}')
indentlevel--;
else if (tok->str[0] == '(')
parlevel++;
else if (tok->str[0] == ')')
parlevel--;
if (!tok->next)
break;
if (indentlevel==0 && parlevel==0 && IsName(tok->str) && tok->next->str[0]=='(')
{
for (TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next)
{
if (tok2->str[0] == ')')
{
if (tok2->next->str[0] == '{')
return tok;
break;
}
}
}
}
return 0;
}
//---------------------------------------------------------------------------
// Writing dynamic data in buffer without bounds checking
//---------------------------------------------------------------------------
static void _DynamicDataCheck(TOKEN *ftok, TOKEN *tok)
{
const char *var2 = tok->str;
bool decl = false;
unsigned int Var2Count = 0;
for ( TOKEN *tok2 = ftok; tok2; tok2 = tok2->next )
{
if (tok2 == tok)
break;
if (match(tok2,"char * var"))
{
decl |= (strcmp(getstr(tok2,2),var2)==0);
tok2 = gettok(tok2,3);
if ( strcmp(tok2->str, "=") == 0 )
{
Var2Count++;
break;
}
}
if (strcmp(tok2->str,var2)==0)
{
Var2Count++;
break;
}
}
// The size of Var2 isn't checked, is it?
if (decl && Var2Count == 0)
{
std::ostringstream ostr;
ostr << FileLine(tok) << ": A string with unknown length is copied to buffer.";
ReportErr(ostr.str());
}
}
static void _DynamicData()
{
for (TOKEN *ftok = findfunction(tokens); ftok; ftok = findfunction(ftok->next))
{
int indentlevel = 0;
for (TOKEN *tok = ftok; tok; tok = tok->next)
{
if (tok->str[0] == '{')
indentlevel++;
else if (tok->str[0] == '}')
{
indentlevel--;
if (indentlevel <= 0)
break;
}
if (match(tok,"strcpy ( var , var )") ||
match(tok,"strcat ( var , var )") )
{
_DynamicDataCheck(ftok,gettok(tok,4));
}
if (match(tok,"sprintf ( var"))
{
for ( TOKEN *tok2 = gettok(tok,3); tok2; tok2 = tok2->next )
{
if (tok2->str[0] == ')')
break;
if (match(tok2,", var ,") || match(tok2,", var )"))
{
_DynamicDataCheck(ftok,tok2->next);
}
}
}
}
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
@ -17,6 +135,8 @@
void CheckBufferOverrun()
{
_DynamicData();
int indentlevel = 0;
for (TOKEN *tok = tokens; tok; tok = tok->next)
{

View File

@ -4,6 +4,8 @@
#include <iostream>
#include <sstream>
//---------------------------------------------------------------------------
bool HasErrors;
//---------------------------------------------------------------------------
std::string FileLine(TOKEN *tok)
{
@ -16,6 +18,7 @@ std::string FileLine(TOKEN *tok)
void ReportErr(const std::string errmsg)
{
std::cerr << errmsg << std::endl;
HasErrors = true;
}
//---------------------------------------------------------------------------

View File

@ -65,8 +65,12 @@ int main(int argc, char* argv[])
// CppCheck - A function that checks a specified file
//---------------------------------------------------------------------------
extern bool HasErrors;
static void CppCheck(const char FileName[])
{
HasErrors = false;
// Tokenize the file
tokens = tokens_back = NULL;
Files.clear();
@ -74,7 +78,7 @@ static void CppCheck(const char FileName[])
// Check that the memsets are valid.
// This function can do dangerous things if used wrong.
// The 'memset' function can do dangerous things if used wrong.
// Important: The checking doesn't work on simplified tokens list.
CheckMemset();
@ -149,6 +153,10 @@ static void CppCheck(const char FileName[])
// Clean up tokens..
DeallocateTokens();
// Todo: How should this work? Activated by a command line switch?
//if ( ! HasErrors )
// std::cout << "No errors found\n";
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,3 @@
[testbufferoverrun7\testbufferoverrun7.cpp:5]: A string with unknown length is copied to buffer.
[testbufferoverrun7\testbufferoverrun7.cpp:10]: A string with unknown length is copied to buffer.
[testbufferoverrun7\testbufferoverrun7.cpp:15]: A string with unknown length is copied to buffer.

View File

@ -0,0 +1,16 @@
void f1(char *str)
{
strcpy(buf,str);
}
void f2(char *str)
{
strcat(buf,str);
}
void f3(char *str)
{
sprintf(buf,"%s",str);
}