-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C/C++ : memory may not be freed on loop #9053
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
base: main
Are you sure you want to change the base?
Conversation
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.
This is a promising idea for a query, thank you for your contribution!
I think we should clean up the QL a bit - I've made some initial suggestions. In general adding \\
comments to blocks of code explaining what they do would help make the QL more readable and maintainable.
cpp/ql/src/experimental/Critical/MemoryMayNotBeFreedOnLoop.qhelp
Outdated
Show resolved
Hide resolved
cpp/ql/src/experimental/Critical/MemoryMayNotBeFreedOnLoop.qhelp
Outdated
Show resolved
Hide resolved
e.(ConstructorFieldInit).getExpr() = v.getAnAccess() | ||
} | ||
|
||
predicate allocCallOrIndirect(Expr e) { |
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.
Again it may be worth calling out the predicates that are copies, as ideally at some point we would want to clean this up to have a single version of each in a .qll
library somewhere.
from StackVariable v, Expr def, JumpStmt b, BlockStmt bs, IfStmt is | ||
where | ||
allocationDefinition(v, def) and | ||
(b instanceof BreakStmt or b instanceof ContinueStmt) and |
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.
Do you think we'd get good results if we included ReturnStmt
as well?
(bs.getChild(y) = is or bs.getChild(y).(IfStmt).getAChild*() = is) and | ||
sameLoop(bs, is) and | ||
(is.getAChild() = b or is.getThen().getAChild() = b) and | ||
not is.getCondition().getAChild*() = v.getAnAccess() and |
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 think this line is redundant, given the line below.
) and | ||
exists(int y | y in [i .. bs.getNumStmt() - 1] | | ||
(bs.getChild(y) = is or bs.getChild(y).(IfStmt).getAChild*() = is) and | ||
sameLoop(bs, is) and |
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.
Is checking sameLoop
here redundant (given the previous line bs.getChild(y) = is or
...)?
I've run the tests on this PR, and it looks like you need to autoformat the QL file. Let me know if you don't know how to do this.
I also started an LGTM run to see what kinds of real world results we get from this query: https://lgtm.com/query/7023328987326235286/ . It looks like there are some good results, but sometimes a very large number of locations are reported. |
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.
Hi @Yonah125, please could you let us know if you intend to do any more work on this PR? I'm OK with merging this into experimental
as it is - but there are some unaddressed comments, in particular the real world results that reference very large numbers of locations. I think this query would also benefit greatly from a good test (in cpp/ql/test/experimental
).
cpp/ql/src/experimental/Critical/MemoryMayNotBeFreedOnLoop.qhelp
Outdated
Show resolved
Hide resolved
Yes I think you're right. Its looks promising but a little unfinished to me. But for merging into experimental that's OK, it can potentially be built upon in future. I've started the checks, will merge if they pass. |
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.
AllocAndFree.qll
needs autoformatting.
sameLoop(bs, is) and | ||
( | ||
is.getAChild() = b or | ||
is.getThen().getAChild() = b or |
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.
is.getThen().getAChild() = b or | |
is.getThen().getAChild() = b |
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.
Friendly ping @Yonah125 could you do these changes ?
This query finds memory that might no be freed in a loop.
For exemple :
A resultat was found in netcdf-c : Unidata/netcdf-c#2339
Supervised by @catenacyber