-
Notifications
You must be signed in to change notification settings - Fork 277
Function contracts: check target validity, simplify snapshot instrumentation #6564
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
Merged
tautschnig
merged 1 commit into
diffblue:develop
from
remi-delmas-3000:check-target-validity-simplify-snapshots
Jan 12, 2022
Merged
Function contracts: check target validity, simplify snapshot instrumentation #6564
tautschnig
merged 1 commit into
diffblue:develop
from
remi-delmas-3000:check-target-validity-simplify-snapshots
Jan 12, 2022
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ba0480f
to
0a237bf
Compare
Codecov Report
@@ Coverage Diff @@
## develop #6564 +/- ##
===========================================
- Coverage 76.01% 76.01% -0.01%
===========================================
Files 1579 1579
Lines 181304 181303 -1
===========================================
- Hits 137819 137817 -2
- Misses 43485 43486 +1
Continue to review full report at Codecov.
|
2c801bf
to
a9d3343
Compare
tautschnig
approved these changes
Jan 11, 2022
2725ffa
to
76178f8
Compare
tautschnig
reviewed
Jan 12, 2022
tautschnig
reviewed
Jan 12, 2022
76178f8
to
9484910
Compare
Changes: - Generate assertions to check that user-specified conditional targets point to null or valid locations when the condition is true. - Replace the all_dereferences_valid and w_ok condition by a single not NULL-check in the CAR validity condition. - Initialise lower and upper address bounds for a CAR unconditionally - Skip target validation for malloc (always returns NULL or a good object) - Skip target validity checks DECL symbols (always backed by a good object) - Forbid NULL targets for assignments lhs and havoc parameters - Accept NULL targets for `free` arguments (accept null) Benefits: better performance better user feedback.
9484910
to
ec3902c
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In assigns clause checking, for better usability and performance with conditional targets:
all_dereferences_valid
with a simplernot_null
check in the validity condition, remove conditional jumpsBenefits:
s2n-tls
benchmarks)Details
Problem
We now support conditional assigns targets of the form
condition: target
.The
condition
lets the user specify when the target expression is assignable by the function.We also need to make sure the target expression denotes a valid memory location when the condition holds.
Today this is achieved using this instrumentation code:
Inclusion checks are performed using:
With this encoding, if the target expression happens to be invalid when the user-provided condition is true, we silently compute an empty conditional address range and we will reject assignments to this invalid target location (as expected),
The results can however be hard to interpret from the user's perspective since he does not know that the target is invalid when he specified it should be assignable. It is most likely the sign of an involuntary error in the target condition
Moreover, the use of
all_dereferences_valid
andw_ok
predicates creates large formulas and causes long runtimes.Proposed Fix
We distinguish the following uses for an address range snaphsot
(__car_valid, __car_lb, __car_ub)
:a. when the condition holds, the
target_start_address
pointer shall be eitherNULL
or writable with the expected size. We allowNULL
because it can be passed as a valid argument to functions such asfree()
, and the user code might attempt to do this.b. we forbid invalid
target_start_address
pointers because they are not accepted in any meaningful operation.free()
. The pointer must either be aNULL
pointer or a pointer to the start address of a valid object (with offset 0, but we will not check that sincefree
checks it itself).havoc
function, in order to perform an inclusion check against a set of allowed target locations (themselves derived from cases 1 and 4). In that case:a. we want to check that the
target_start_address
is neitherNULL
norINVALID
when its condition holds.DECL
or a pointer returned bymalloc
. Conditions 1.a. and 1.b. would apply here, but they are always satisfied by construction (a stack allocated var is always backed by an object of the right size for its type, and CBMC'smalloc
either returns aNULL
pointer or a pointer backed by an object of the right size).So, in order to check for target validity in cases 1. and 2. (user specified targets and parameters to free), we use:
To check for target validity in case 3. (assignment LHS), we use:
These assertions will be falsified if
target_start_address
is an invalid pointer.As explained above, in case 4 the target is valid by construction, so we do not generate an assertion.
In cases 1, 2, 3 and 4 the snapshot is rid of conditional jumps and becomes:
Assuming the "target validity" assertion was proved, if
condition & not_null(target_start_address)
holds thenw_ok(target_start_address, target_size)
holds and the computed__car_lb
and__car_ub
are meaningful.If the target happens to be
NULL
,__car_valid
will be false and__car_lb
and__car_ub
will contain garbage values but will never be used in inclusion checks, which are guarded by__car_valid
.If the target happens to be invalid, then all snapshot variables can take arbitrary and incoherent values which may or may not fail the inclusion checks. In all cases, since the target validity assertions will surely fail, the assigns clause checking analysis as a whole will not succeed.
Inclusion checks
The inclusion check for assignments and havoc parameters is written as:
An for parameters to
free
we allow NULL as a special case:Summary
With this new encoding,
For a full assigns clause check to be considered successful:
havoc
orfree
must pass the inclusion check