Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
9e7becf1
Commit
9e7becf1
authored
3 years ago
by
David Bühler
Browse files
Options
Downloads
Patches
Plain Diff
[Eva] Taint domain: implements [filter] and [reuse] for the memexec cache.
Improves significantly the domain performance.
parent
f8ef4515
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/plugins/value/domains/taint_domain.ml
+47
-24
47 additions, 24 deletions
src/plugins/value/domains/taint_domain.ml
with
47 additions
and
24 deletions
src/plugins/value/domains/taint_domain.ml
+
47
−
24
View file @
9e7becf1
...
@@ -34,8 +34,11 @@ type taint = {
...
@@ -34,8 +34,11 @@ type taint = {
(* Set of assume statements over a tainted expression. This set is needed to
(* Set of assume statements over a tainted expression. This set is needed to
implement control-dependency: all left-values appearing in statements whose
implement control-dependency: all left-values appearing in statements whose
evaluation depends on at least one of the assume expressions is to be
evaluation depends on at least one of the assume expressions is to be
tainted. *)
tainted.
This set is restricted to statements of the current function.
*)
assume_stmts
:
Stmt
.
Set
.
t
;
assume_stmts
:
Stmt
.
Set
.
t
;
(* Whether the current call depends on a tainted assume statement: if true,
all assignments in the current call should be control tainted. *)
dependent_call
:
bool
;
}
}
let
dkey
=
Value_parameters
.
register_category
"d-taint"
let
dkey
=
Value_parameters
.
register_category
"d-taint"
...
@@ -59,10 +62,12 @@ module LatticeTaint = struct
...
@@ -59,10 +62,12 @@ module LatticeTaint = struct
Format
.
fprintf
fmt
Format
.
fprintf
fmt
"@[<v 2>Locations (data):@ @[<hov>%a@]@]@
\n
\
"@[<v 2>Locations (data):@ @[<hov>%a@]@]@
\n
\
@[<v 2>Locations (control):@ @[<hov>%a@]@]@
\n
\
@[<v 2>Locations (control):@ @[<hov>%a@]@]@
\n
\
@[<v 2>Assume statements:@ @[<hov>%a@]@]"
@[<v 2>Assume statements:@ @[<hov>%a@]@
\n
\
@[<v 2>Dependent call:@ %b@]"
Zone
.
pretty
t
.
locs_data
Zone
.
pretty
t
.
locs_data
Zone
.
pretty
t
.
locs_control
Zone
.
pretty
t
.
locs_control
Stmt
.
Set
.
pretty
t
.
assume_stmts
Stmt
.
Set
.
pretty
t
.
assume_stmts
t
.
dependent_call
(* Frama-C "datatype" for type [taint]. *)
(* Frama-C "datatype" for type [taint]. *)
include
Datatype
.
Make_with_collections
(
struct
include
Datatype
.
Make_with_collections
(
struct
...
@@ -75,20 +80,18 @@ module LatticeTaint = struct
...
@@ -75,20 +80,18 @@ module LatticeTaint = struct
let
reprs
=
let
reprs
=
[
{
locs_data
=
List
.
hd
Zone
.
reprs
;
[
{
locs_data
=
List
.
hd
Zone
.
reprs
;
locs_control
=
List
.
hd
Zone
.
reprs
;
locs_control
=
List
.
hd
Zone
.
reprs
;
assume_stmts
=
Stmt
.
Set
.
empty
;
}
]
assume_stmts
=
Stmt
.
Set
.
empty
;
dependent_call
=
false
;
}
]
let
structural_descr
=
let
structural_descr
=
Structural_descr
.
t_abstract
(* TODO *)
Structural_descr
.
t_abstract
(* TODO *)
let
compare
t1
t2
=
let
compare
t1
t2
=
let
c
=
Zone
.
compare
t1
.
locs_data
t2
.
locs_data
in
let
(
<?>
)
c
(
cmp
,
x
,
y
)
=
if
c
=
0
then
cmp
x
y
else
c
in
if
c
<>
0
Zone
.
compare
t1
.
locs_data
t2
.
locs_data
then
c
<?>
(
Zone
.
compare
,
t1
.
locs_control
,
t2
.
locs_control
)
else
<?>
(
Stmt
.
Set
.
compare
,
t1
.
assume_stmts
,
t2
.
assume_stmts
)
let
c
=
Zone
.
compare
t1
.
locs_data
t2
.
locs_data
in
<?>
(
Datatype
.
Bool
.
compare
,
t1
.
dependent_call
,
t2
.
dependent_call
)
if
c
<>
0
then
c
else
Stmt
.
Set
.
compare
t1
.
assume_stmts
t2
.
assume_stmts
let
equal
=
Datatype
.
from_compare
let
equal
=
Datatype
.
from_compare
...
@@ -101,7 +104,8 @@ module LatticeTaint = struct
...
@@ -101,7 +104,8 @@ module LatticeTaint = struct
Hashtbl
.
hash
Hashtbl
.
hash
(
Zone
.
hash
t
.
locs_data
,
(
Zone
.
hash
t
.
locs_data
,
Zone
.
hash
t
.
locs_control
,
Zone
.
hash
t
.
locs_control
,
Stmt
.
Set
.
hash
t
.
assume_stmts
)
Stmt
.
Set
.
hash
t
.
assume_stmts
,
t
.
dependent_call
)
let
copy
c
=
c
let
copy
c
=
c
...
@@ -112,6 +116,7 @@ module LatticeTaint = struct
...
@@ -112,6 +116,7 @@ module LatticeTaint = struct
locs_data
=
Zone
.
bottom
;
locs_data
=
Zone
.
bottom
;
locs_control
=
Zone
.
bottom
;
locs_control
=
Zone
.
bottom
;
assume_stmts
=
Stmt
.
Set
.
empty
;
assume_stmts
=
Stmt
.
Set
.
empty
;
dependent_call
=
false
;
}
}
(* Top state: everything is tainted. *)
(* Top state: everything is tainted. *)
...
@@ -119,13 +124,15 @@ module LatticeTaint = struct
...
@@ -119,13 +124,15 @@ module LatticeTaint = struct
locs_data
=
Zone
.
top
;
locs_data
=
Zone
.
top
;
locs_control
=
Zone
.
top
;
locs_control
=
Zone
.
top
;
assume_stmts
=
Stmt
.
Set
.
empty
;
assume_stmts
=
Stmt
.
Set
.
empty
;
dependent_call
=
false
;
}
}
(* Join: keep pointwise over-approximation. *)
(* Join: keep pointwise over-approximation. *)
let
join
t1
t2
=
let
join
t1
t2
=
{
locs_data
=
Zone
.
join
t1
.
locs_data
t2
.
locs_data
;
{
locs_data
=
Zone
.
join
t1
.
locs_data
t2
.
locs_data
;
locs_control
=
Zone
.
join
t1
.
locs_control
t2
.
locs_control
;
locs_control
=
Zone
.
join
t1
.
locs_control
t2
.
locs_control
;
assume_stmts
=
Stmt
.
Set
.
union
t1
.
assume_stmts
t2
.
assume_stmts
;
}
assume_stmts
=
Stmt
.
Set
.
union
t1
.
assume_stmts
t2
.
assume_stmts
;
dependent_call
=
t1
.
dependent_call
||
t2
.
dependent_call
;
}
(* The memory locations are finite, so the ascending chain property is
(* The memory locations are finite, so the ascending chain property is
already verified. We simply use a join. *)
already verified. We simply use a join. *)
...
@@ -136,6 +143,7 @@ module LatticeTaint = struct
...
@@ -136,6 +143,7 @@ module LatticeTaint = struct
locs_data
=
Zone
.
narrow
t1
.
locs_data
t2
.
locs_data
;
locs_data
=
Zone
.
narrow
t1
.
locs_data
t2
.
locs_data
;
locs_control
=
Zone
.
narrow
t1
.
locs_control
t2
.
locs_control
;
locs_control
=
Zone
.
narrow
t1
.
locs_control
t2
.
locs_control
;
assume_stmts
=
Stmt
.
Set
.
inter
t1
.
assume_stmts
t2
.
assume_stmts
;
assume_stmts
=
Stmt
.
Set
.
inter
t1
.
assume_stmts
t2
.
assume_stmts
;
dependent_call
=
t1
.
dependent_call
&&
t2
.
dependent_call
;
}
}
(* Inclusion testing: pointwise, on locs only. *)
(* Inclusion testing: pointwise, on locs only. *)
...
@@ -192,7 +200,7 @@ module TransferTaint = struct
...
@@ -192,7 +200,7 @@ module TransferTaint = struct
(* Control-dependency: taint the left-value of an assign statement whose
(* Control-dependency: taint the left-value of an assign statement whose
execution depends on the value of a tainted assume statement. *)
execution depends on the value of a tainted assume statement. *)
let
state
=
let
state
=
if
Stmt
.
Set
.
is_empty
state
.
assume_stmts
if
not
state
.
dependent_call
&&
Stmt
.
Set
.
is_empty
state
.
assume_stmts
then
then
(* No active tainted assume statement means that there is no
(* No active tainted assume statement means that there is no
control-dependecy that applies on [lv]. *)
control-dependecy that applies on [lv]. *)
...
@@ -225,7 +233,7 @@ module TransferTaint = struct
...
@@ -225,7 +233,7 @@ module TransferTaint = struct
let
to_loc
=
loc_of_lval
valuation
in
let
to_loc
=
loc_of_lval
valuation
in
let
exp_zone
=
Value_util
.
zone_of_expr
to_loc
exp
in
let
exp_zone
=
Value_util
.
zone_of_expr
to_loc
exp
in
let
state
=
let
state
=
if
LatticeTaint
.
intersects
state
exp_zone
if
not
state
.
dependent_call
&&
LatticeTaint
.
intersects
state
exp_zone
then
{
state
with
assume_stmts
=
Stmt
.
Set
.
add
stmt
state
.
assume_stmts
;
}
then
{
state
with
assume_stmts
=
Stmt
.
Set
.
add
stmt
state
.
assume_stmts
;
}
else
state
else
state
in
in
...
@@ -233,6 +241,10 @@ module TransferTaint = struct
...
@@ -233,6 +241,10 @@ module TransferTaint = struct
let
start_call
stmt
call
_recursion
valuation
state
=
let
start_call
stmt
call
_recursion
valuation
state
=
let
state
=
filter_active_tainted_assumes
stmt
state
in
let
state
=
filter_active_tainted_assumes
stmt
state
in
let
dependent_call
=
state
.
dependent_call
||
not
(
Stmt
.
Set
.
is_empty
state
.
assume_stmts
)
in
let
state
=
{
state
with
assume_stmts
=
Stmt
.
Set
.
empty
;
dependent_call
}
in
let
state
=
let
state
=
(* Add tainted actual parameters in [state]. *)
(* Add tainted actual parameters in [state]. *)
let
to_loc
=
loc_of_lval
valuation
in
let
to_loc
=
loc_of_lval
valuation
in
...
@@ -251,7 +263,8 @@ module TransferTaint = struct
...
@@ -251,7 +263,8 @@ module TransferTaint = struct
let
finalize_call
_stmt
_call
_recursion
~
pre
~
post
=
let
finalize_call
_stmt
_call
_recursion
~
pre
~
post
=
(* Recover assume statements from the [pre] abstract state: we assume the
(* Recover assume statements from the [pre] abstract state: we assume the
control-dependency does not extended beyond the function scope. *)
control-dependency does not extended beyond the function scope. *)
`Value
{
post
with
assume_stmts
=
pre
.
assume_stmts
;
}
`Value
{
post
with
assume_stmts
=
pre
.
assume_stmts
;
dependent_call
=
pre
.
dependent_call
;
}
let
show_expr
valuation
state
fmt
exp
=
let
show_expr
valuation
state
fmt
exp
=
let
to_loc
=
loc_of_lval
valuation
in
let
to_loc
=
loc_of_lval
valuation
in
...
@@ -326,14 +339,14 @@ module TaintDomain = struct
...
@@ -326,14 +339,14 @@ module TaintDomain = struct
let
enter_scope
_kind
_vars
state
=
state
let
enter_scope
_kind
_vars
state
=
state
let
remove_bases
bases
state
=
let
remove
=
Zone
.
filter_base
(
fun
b
->
not
(
Base
.
Hptset
.
mem
b
bases
))
in
{
state
with
locs_data
=
remove
state
.
locs_data
;
locs_control
=
remove
state
.
locs_control
;
}
let
leave_scope
_kf
vars
state
=
let
leave_scope
_kf
vars
state
=
let
remove_unscoped_bases
=
let
bases
=
Base
.
Hptset
.
of_list
(
List
.
map
Base
.
of_varinfo
vars
)
in
let
bases
=
Base
.
Set
.
of_list
(
List
.
map
Base
.
of_varinfo
vars
)
in
remove_bases
bases
state
Zone
.
filter_base
(
fun
b
->
not
(
Base
.
Set
.
mem
b
bases
))
in
{
state
with
locs_data
=
remove_unscoped_bases
state
.
locs_data
;
locs_control
=
remove_unscoped_bases
state
.
locs_control
;
}
(* Initial state: initializers are singletons, so we store nothing. *)
(* Initial state: initializers are singletons, so we store nothing. *)
...
@@ -342,8 +355,18 @@ module TaintDomain = struct
...
@@ -342,8 +355,18 @@ module TaintDomain = struct
let
initialize_variable_using_type
_
_
state
=
state
let
initialize_variable_using_type
_
_
state
=
state
(* M
isc
. *)
(* M
emExec cache
. *)
let
relate
_kf
_bases
_state
=
Base
.
SetLattice
.
empty
let
relate
_kf
_bases
_state
=
Base
.
SetLattice
.
empty
let
filter
_kf
_kind
bases
state
=
let
filter_base
=
Zone
.
filter_base
(
fun
b
->
Base
.
Hptset
.
mem
b
bases
)
in
{
state
with
locs_data
=
filter_base
state
.
locs_data
;
locs_control
=
filter_base
state
.
locs_control
;
assume_stmts
=
Stmt
.
Set
.
empty
;
}
let
reuse
_kf
bases
~
current_input
~
previous_output
=
let
state
=
remove_bases
bases
current_input
in
join
state
previous_output
end
end
include
TaintDomain
include
TaintDomain
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment