Skip to content

Conversation

@jerhard
Copy link
Member

@jerhard jerhard commented Nov 4, 2025

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

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 lval that are dereferenced 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; 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_freed that is mutually recursive with warn_lval_might_contain_freed.

Fixes #1861

jerhard and others added 4 commits November 4, 2025 13:31
…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`.
@sim642 sim642 added bug unsound sv-comp SV-COMP (analyses, results), witnesses labels Nov 4, 2025
@sim642 sim642 added this to the SV-COMP 2026 milestone Nov 4, 2025
@sim642 sim642 self-requested a review November 4, 2025 13:41
@DrMichaelPetter
Copy link
Collaborator

I started an svcomp run a minute ago, I will test svcomp25 and branchset-pathsensitive

Copy link
Member

@sim642 sim642 left a 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 =
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let check_adress adresses =
let check_address addresses =

Also usages of both below.

Comment on lines +121 to +126
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
Copy link
Member

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?

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

Labels

bug sv-comp SV-COMP (analyses, results), witnesses unsound

Projects

None yet

Development

Successfully merging this pull request may close these issues.

double free not detected in SV-COMP 25/26

4 participants