Potential false positive entry for C++ std::ranges::equal
Finds vulnerabilities in C/C++ source code
Brought to you by:
dwheeler
Hello,
I have switched from the old std::equal functions with iterators to the newer C++ std::ranges functions. After doing so, Flawfinder displayed the following message:
../src/nodecontainer.cpp:222: [1] (buffer) equal:
Function does not check the second iterator for over-read conditions
(CWE-126). This function is often discouraged by most C++ coding standards
in favor of its safer alternatives provided since C++14. Consider using a
form of this function that checks the second iterator before potentially
overflowing it.
../src/nodeinfo.cpp:126: [1] (buffer) equal:
Function does not check the second iterator for over-read conditions
(CWE-126). This function is often discouraged by most C++ coding standards
in favor of its safer alternatives provided since C++14. Consider using a
form of this function that checks the second iterator before potentially
overflowing it.
bool NodeContainer::operator==(const NodeContainer& other) const
{
return std::ranges::equal(this->_nodes,
other._nodes,
[](const auto& a, const auto& b)
{
return *a == *b;
});
}
bool NodeInfo::operator==(const NodeInfo& other) const
{
return this->_addresses == other._addresses &&
this->_mac_address == other._mac_address &&
this->_hoplimit == other._hoplimit &&
std::ranges::equal(this->_nodes,
other._nodes,
[](const auto& a, const auto& b)
{
return *a == *b;
});
}
I think this is a false positive. First, no warning was displayed beforehand. Second, according to the documentation, the equal function terminates (and returns false) if the lengths are different. This means that the elements are not read in the first place, so there is no over-read. Am I overlooking something here?
The false positive occurs because flawfinder matches function names lexically and cannot really resolve C++ namespaces without a full parser. The legacy std::equal, std::mismatch, and std::is_permutation taking three iterators are genuinely risky, but the C++20 std::ranges:: versions check both range lengths automatically and are safe.
We have fixed this (sort-of) through a heuristic, by checking whether ranges:: appears immediately before the function name in the source line. If so, the warning is suppressed. The fix covers all three affected functions (equal, mismatch, is_permutation) and is precise; it checks that ranges:: directly precedes the matched name, not merely that it appears somewhere on the same line.
Actual calls to the legacy iterator-based forms continue to be flagged as before. This fix will be included in the next release.
It's a messy heuristic, but I hope this helps!!
Fixed in master (main branch), will be in next release.
Thanks for fixing the bugs!
There's another false-positive bug. The annotation [[gnu::access(...)]] is being interpreted as the function access(...). Maybe you could fix that too? Should I create a new issue for this? Example code: https://codeberg.org/mark22k/resonancekey/src/commit/abb3c21c017c8e2da7dbe3cdeab56ee68fc5109f8d36adce37db9db390cdab6a/src/crypto.h