-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Fix missing results in cpp/unbounded-write
#14771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++: Fix missing results in cpp/unbounded-write
#14771
Conversation
cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp
Outdated
Show resolved
Hide resolved
jketema
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with these changes if DCA is happy.
I'm wondering if we should also do a MRVA experiment comparing the results before and after?
Yeah, I can start such a run as well 👍 |
|
With the latest accepted test changes, do I see correctly that there's some result duplication now? Or am I reading that totally wrong? |
|
You're reading that correctly. The problem happens in a test that looks like: int main(int argc, char* argv[]) {
// ...
sprintf(buffer100, "%s", argv[0]);
scanf("%s", buffer100);
}where we now report a path from Thinking more about this, I think a better way to fix this is to simply block flow out of the sinks that are not qualifiers. i.e., don't block flow out of S* s = tainted_struct();
strcpy(buffer, s->field);but block flow out of char* s = ...;
strcpy(buffer, s); |
…w result duplication and keeps the new result.
|
I've done ^ in 967bbbc. Let me run a new DCA and MRVA run and see what happens now 🤞 |
|
DCA LGTM! The new results are all field-related (as expected), and were present in the old DTT-based query |
I had missed this issue in #14669.
The problem was that every sink was marked as an out barrier. I did this to avoid path duplication when the outgoing argument was marked as a sink to continue to flag up cases such as:
However, marking all sinks are out barriers was slightly too aggressive (as seen in the first commit). This is because the query also flags up writes fields when the qualifier of the field is tainted. That is, this is also flagged up:
S* s = tainted_struct(); strcpy(buffer, s->field);so both
structands->fieldare marked as sinks. But since we mark every sink as an out barrier we'd marksas a barrier, and thus we'd never get a to the read step required to catch something like:S* s; s->field = tainted(); strcpy(buffer, s->field);This PR fixes the problem by only marking
gets(and friends) functions as out barriers.