-
Notifications
You must be signed in to change notification settings - Fork 84
Use-after-free Analysis: Fix warning generation for lvalues #1862
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: master
Are you sure you want to change the base?
Conversation
…analysis. This test case was minimized from a larger example by Michael Schwarz. Co-authored-by: Michael Schwarz <[email protected]>
Given, e.g., a statement lval = rval; There may be two types of use-after-free errors that can occur for the lval: 1. The memory location to which lval evaluates has been freed already. 2. The memory location(s) inside rval that are dereferenced to evaluate rval have been freed already. Previously, the check implemented for lvals did not consistently check for both types of errors. In case a dereference was at the top-level of the lval, only the second type of error was checked, but not recursively for sub-lvals. This is changed with this PR. The 1. check is now performed, whether the lhost is a variable or a memory dereference. The second check is performed using a recursive call of the mutually recursive function `warn_exp_might_contain_freed`.
|
I started an svcomp run a minute ago, I will test svcomp25 and branchset-pathsensitive |
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.
One of the spurious warnings on sv-benchmarks this causes is
[Warning][Behavior > Undefined > UseAfterFree][CWE-416] lval ((alloc@sid:145@tid:[main](#0))) in "assign" points to a maybe freed memory region (../sv-benchmarks/c/Juliet_Test/CWE415_Double_Free---s01---CWE415_Double_Free__malloc_free_char_32_good.i:695:10-695:29)
which is
char *data_1 = *dataPtr2;which actually is the initialization assignment
data_1 = *dataPtr2;It seems to me that here there are also extra warnings from the right-hand side now. Here *dataPtr2 is a points-to set which contains a free-d pointer, but that's irrelevant. It would only be a problem if it was **dataPtr2.
Maybe this is now overly aggressive at checking dereferences recursively?
| let undefined_behavior = if is_free then Undefined DoubleFree else Undefined UseAfterFree in | ||
| let cwe_number = if is_free then 415 else 416 in | ||
|
|
||
| let check_adress adresses = |
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.
| let check_adress adresses = | |
| let check_address addresses = |
Also usages of both below.
| match addr with | ||
| | Queries.AD.Addr.Addr (v,_) when man.ask (Queries.IsAllocVar v) -> v :: vars | ||
| | _ -> vars | ||
| ) adresses [] | ||
| in | ||
| if not (Queries.AD.is_top adresses) then begin |
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.
The pointed_to_heap_vars above could be moved into this if, right?
This fixes the handling of lvals in the warning generation of the use-after-free analysis in
warn_lval_might_contain_freed.Background
Given, e.g., a statement
There may be two types of use-after-free errors that can occur for the lval:
Previously, the check implemented for lvals did not consistently check for both types of errors.
In case a dereference was at the top-level of the lval, only the second type of error was checked; also this was not check recursively for sub-lvals.
Changes
This is changed with this PR.
The check for (1.) is now performed whether the lhost is a variable or a memory dereference.
The check for (2.) is performed, in case that the lhost is a dereference, and uses a recursive call of the function
warn_exp_might_contain_freedthat is mutually recursive withwarn_lval_might_contain_freed.Fixes #1861