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
CPP: Add query for CWE-190: Integer Overflow or Wraparound when using transform after operation #8247
Conversation
Hi @ihsinme, Thanks for another contribution. I really like this one :) Will review it very soon! |
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
Outdated
Show resolved
Hide resolved
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
Outdated
Show resolved
Hide resolved
) | ||
} | ||
|
||
from MulExpr mexp, string msg |
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.
Can you add a comment around here that explains why this query catches things that cpp/integer-multiplication-cast-to-long
doesn't catch?
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.
how do you view this text?
// Search for an explicit conversion of the result of multiplication in the situation of multiplying types of a smaller size than the result
// or casting the result of multiplication of comparable types to signed ones.
// In these situations, it is necessary to use the conversion not of the result, but of the arguments.
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.
That still doesn't explain (at least not to me) what the difference between this query and cpp/integer-multiplication-cast-to-long
is. As far as I remember, the goal of cpp/integer-multiplication-cast-to-long
is also to detect cases like:
int i1 = ...;
int i2 = ...;
long j = i * i;
where there's an implicit cast on the result of the multiplication, but where the cast should really be on the arguments.
Is the difference just that this query requires the cast to be explicit, while cpp/integer-multiplication-cast-to-long
requires the cast to be implicit?
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.
yes, the idea of the request is that the developer uses an explicit override, which would have happened anyway, therefore, this is either stylistically incorrect or overflow.
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 see. Thanks for clearing that up. Could you extend the description you wrote here to say that this query finds cases similar to the ones found by cpp/integer-multiplication-cast-to-long
, but requires the cast to be explicit?
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
Outdated
Show resolved
Hide resolved
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
Outdated
Show resolved
Hide resolved
msg = "this transformation is applied after multiplication" | ||
or | ||
signSmallerWithEqualSizes(mexp, e1, e2) and | ||
msg = "possible signed overflow followed by offset of the pointer out of bounds" |
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.
We have a range analysis library that can rule out cases that obviously doesn't overflow. See how it's used here: https://github.com/github/codeql/blob/main/cpp/ql/src/Likely%20Bugs/Arithmetic/SignedOverflowCheck.ql#L30 (there's only a convertedExprMightOverflow
predicate that checks for both overflow and underflow at the same time). Would that be useful to rule out false positives in some cases?
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 am considering this idea.
in my experience of using Range
there are too many surprises of uncertainty.
in the first part, I hope for a difference in the sizes of the types of arguments and results, in the second time, that the signed result is 1 bit less than the arguments.
I propose to return to this point if other cleaning options are exhausted?
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.
in my experience of using Range there are too many surprises of uncertainty.
I'd be interested in hearing what you mean by this.
I propose to return to this point if other cleaning options are exhausted?
That's fine.
...imental/query-tests/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation/test.cpp
Show resolved
Hide resolved
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.qhelp
Outdated
Show resolved
Hide resolved
cpp/ql/src/experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
Outdated
Show resolved
Hide resolved
thanks for the comments. separately sorry for repeated mistakes. |
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
Here are the CI failures:
|
This query looks for integer overflow situations that are not covered by the
cpp/integer-multiplication-cast-to-long query
. the first part is belated and meaningless transformations likes=(size_t)(i*i)
, which would still happen according to the law of expression. It's possible that the developer didn't use the conversion location correctly. the second part is the conversion of types that are the same size but different in sign, and then use the result in pointer arithmetic.CVE-2021-43618
facebook/zstd#2424