Skip to content

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

Yonah125
Copy link

@Yonah125 Yonah125 commented May 7, 2022

This query finds memory that might no be freed in a loop.

For exemple :

for(int i = 0; i < 10; i++){
     char* notfree = malloc(0x100);
     if(i == 5){
         break;
         }
      free(notfree)
 }

A resultat was found in netcdf-c : Unidata/netcdf-c#2339

Supervised by @catenacyber

Copy link
Contributor

@geoffw0 geoffw0 left a 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.

e.(ConstructorFieldInit).getExpr() = v.getAnAccess()
}

predicate allocCallOrIndirect(Expr e) {
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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...)?

@geoffw0
Copy link
Contributor

geoffw0 commented May 12, 2022

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.

Error: ql/cpp/ql/src/experimental/Critical/MemoryMayNotBeFreedOnLoop.ql would change by autoformatting.

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.

Comment on lines 37 to 40
is.getAChild() = b or
is.getThen().getAChild() = b or
is.getAChild() = rt or
is.getThen().getAChild() = rt

Check warning

Code scanning / CodeQL

Var only used in one side of disjunct.

The variable rt is only used in one side of disjunct.
Copy link
Contributor

@geoffw0 geoffw0 left a 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).

@catenacyber
Copy link
Contributor

Hi @geoffw0, I think @Yonah125 is done with this after his latest push. How does this look ?

@geoffw0
Copy link
Contributor

geoffw0 commented Aug 8, 2022

I think @Yonah125 is done with this after his latest push. How does this look ?

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.

Copy link
Contributor

@geoffw0 geoffw0 left a 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
is.getThen().getAChild() = b or
is.getThen().getAChild() = b

Copy link
Contributor

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 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants