Fix #8295 FN (error) Buffer is accessed out of bounds (wcpncpy, wcsncpy) (#4412)

* Fix #8295 FN (error) Buffer is accessed out of bounds (wcpncpy, wcsncpy)

* Fix cfg, validation

* Fix validation
This commit is contained in:
chrchr-github 2022-08-29 12:24:58 +02:00 committed by GitHub
parent df704361f6
commit 1e14e360cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 9 deletions

View File

@ -283,7 +283,6 @@
<attribute name="type"> <attribute name="type">
<choice> <choice>
<value>strlen</value> <value>strlen</value>
<value>argvalue</value>
<value>sizeof</value> <value>sizeof</value>
<value>mul</value> <value>mul</value>
</choice> </choice>
@ -310,6 +309,24 @@
<attribute name="baseType"><text/></attribute> <attribute name="baseType"><text/></attribute>
</optional> </optional>
</element> </element>
<element name="minsize">
<attribute name="type">
<choice>
<value>argvalue</value>
</choice>
</attribute>
<attribute name="arg">
<ref name="ARGNO"/>
</attribute>
<optional>
<attribute name="arg2">
<ref name="ARGNO"/>
</attribute>
</optional>
<optional>
<attribute name="baseType"><text/></attribute>
</optional>
</element>
</choice> </choice>
</zeroOrMore> </zeroOrMore>
<optional> <optional>

View File

@ -5449,7 +5449,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s
<not-overlapping-data ptr1-arg="1" ptr2-arg="2" size-arg="3"/> <not-overlapping-data ptr1-arg="1" ptr2-arg="2" size-arg="3"/>
<arg nr="1" direction="out"> <arg nr="1" direction="out">
<not-null/> <not-null/>
<minsize type="argvalue" arg="3"/> <minsize type="argvalue" arg="3" baseType="wchar_t"/>
</arg> </arg>
<arg nr="2" direction="in"> <arg nr="2" direction="in">
<not-null/> <not-null/>

View File

@ -5359,7 +5359,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
<not-overlapping-data ptr1-arg="1" ptr2-arg="2" size-arg="3"/> <not-overlapping-data ptr1-arg="1" ptr2-arg="2" size-arg="3"/>
<arg nr="1"> <arg nr="1">
<not-null/> <not-null/>
<minsize type="argvalue" arg="3"/> <minsize type="argvalue" arg="3" baseType="wchar_t"/>
</arg> </arg>
<arg nr="2" direction="in"> <arg nr="2" direction="in">
<not-null/> <not-null/>

View File

@ -593,10 +593,16 @@ static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::Mi
return Token::getStrLength(strtoken) < bufferSize; return Token::getStrLength(strtoken) < bufferSize;
} }
break; break;
case Library::ArgumentChecks::MinSize::Type::ARGVALUE: case Library::ArgumentChecks::MinSize::Type::ARGVALUE: {
if (arg && arg->hasKnownIntValue()) if (arg && arg->hasKnownIntValue()) {
return arg->getKnownIntValue() <= bufferSize; MathLib::bigint myMinsize = arg->getKnownIntValue();
unsigned int baseSize = tokenizer->sizeOfType(minsize.baseType);
if (baseSize != 0)
myMinsize *= baseSize;
return myMinsize <= bufferSize;
}
break; break;
}
case Library::ArgumentChecks::MinSize::Type::SIZEOF: case Library::ArgumentChecks::MinSize::Type::SIZEOF:
// TODO // TODO
break; break;

View File

@ -783,9 +783,6 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, valueattr); return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, valueattr);
ac.minsizes.emplace_back(type, 0); ac.minsizes.emplace_back(type, 0);
ac.minsizes.back().value = minsizevalue; ac.minsizes.back().value = minsizevalue;
const char* baseTypeAttr = argnode->Attribute("baseType");
if (baseTypeAttr)
ac.minsizes.back().baseType = baseTypeAttr;
} else { } else {
const char *argattr = argnode->Attribute("arg"); const char *argattr = argnode->Attribute("arg");
if (!argattr) if (!argattr)
@ -804,6 +801,9 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
ac.minsizes.back().arg2 = arg2attr[0] - '0'; ac.minsizes.back().arg2 = arg2attr[0] - '0';
} }
} }
const char* baseTypeAttr = argnode->Attribute("baseType"); // used by VALUE, ARGVALUE
if (baseTypeAttr)
ac.minsizes.back().baseType = baseTypeAttr;
} }
else if (argnodename == "iterator") { else if (argnodename == "iterator") {

View File

@ -564,6 +564,14 @@ size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen)
return len; return len;
} }
void bufferAccessOutOfBounds_wcpncpy()
{
wchar_t s[16];
wcpncpy(s, L"abc", 16);
// cppcheck-suppress bufferAccessOutOfBounds
wcpncpy(s, L"abc", 17);
}
size_t nullPointer_strnlen(const char *s, size_t maxlen) size_t nullPointer_strnlen(const char *s, size_t maxlen)
{ {
// No warning shall be shown: // No warning shall be shown:

View File

@ -556,6 +556,14 @@ void bufferAccessOutOfBounds_wcsftime(wchar_t* ptr, size_t maxsize, const wchar_
(void)wcsftime(ptr, maxsize, format, timeptr); (void)wcsftime(ptr, maxsize, format, timeptr);
} }
void bufferAccessOutOfBounds_wcsncpy()
{
wchar_t s[16];
wcsncpy(s, L"abc", 16);
// cppcheck-suppress bufferAccessOutOfBounds
wcsncpy(s, L"abc", 17);
}
int nullPointer_wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n) int nullPointer_wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n)
{ {
// cppcheck-suppress nullPointer // cppcheck-suppress nullPointer