Skip to content
Snippets Groups Projects
Commit 30834c32 authored by David Bühler's avatar David Bühler
Browse files

[Eva] Taint domain: interprets taint extension with the cvalue domain.

parent 27dba68b
No related branches found
No related tags found
No related merge requests found
...@@ -44,6 +44,8 @@ let dkey = Value_parameters.register_category "d-taint" ...@@ -44,6 +44,8 @@ let dkey = Value_parameters.register_category "d-taint"
Frama_C_domain_show_each directive. *) Frama_C_domain_show_each directive. *)
let dkey_debug = Value_parameters.register_category "d-taint-debug" let dkey_debug = Value_parameters.register_category "d-taint-debug"
let wkey = Value_parameters.register_warn_category "taint"
module LatticeTaint = struct module LatticeTaint = struct
let pp_locs_only fmt t = let pp_locs_only fmt t =
...@@ -151,28 +153,6 @@ end ...@@ -151,28 +153,6 @@ end
module TransferTaint = struct module TransferTaint = struct
let zone_of_taint_annot stmt =
let zone_of_term t =
match t.term_node with
| TLval (TVar { lv_origin = Some vi }, TNoOffset) ->
Locations.zone_of_varinfo vi
| _ ->
(* TODO: Better message. *)
Value_parameters.not_yet_implemented ~current:true
"@[The taint domain currently supports only variables.@]"
in
match Eva_annotations.get_taint_annot stmt with
| [] ->
Zone.bottom
| [ tt ] ->
List.fold_left
(fun zones t -> Zone.join zones (zone_of_term t))
Zone.bottom
tt
| _ ->
(* No more than one annotation at time. *)
assert false
let loc_of_lval valuation lv = let loc_of_lval valuation lv =
match valuation.Abstract_domain.find_loc lv with match valuation.Abstract_domain.find_loc lv with
| `Value loc -> loc.Eval.loc | `Value loc -> loc.Eval.loc
...@@ -208,12 +188,6 @@ module TransferTaint = struct ...@@ -208,12 +188,6 @@ module TransferTaint = struct
let loc = Precise_locs.imprecise_location ploc in let loc = Precise_locs.imprecise_location ploc in
Locations.enumerate_valid_bits Write loc Locations.enumerate_valid_bits Write loc
in in
(* Update [state] by considering as tainted the left-values appearing in
taint annotation, and by keeping only the active tainted assumes. *)
let annot_zone = zone_of_taint_annot stmt in
let state =
{ state with locs_data = Zone.join state.locs_data annot_zone }
in
let state = filter_active_tainted_assumes stmt state in let state = filter_active_tainted_assumes stmt state in
(* 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. *)
...@@ -226,40 +200,27 @@ module TransferTaint = struct ...@@ -226,40 +200,27 @@ module TransferTaint = struct
else else
{ state with locs_control = Zone.join state.locs_control lv_zone } { state with locs_control = Zone.join state.locs_control lv_zone }
in in
(* Data-dependecy: taint the left-value of an assign statement if (* Compute data-dependency with [state]: whenever [exp] (or its
tainted locations are involved in either the offset part of the sub-expressions) is tainted, or [lv] is indexed by a tainted memory
left-value or the assigned expression. As a special case, a location. *)
left-value is tainted as soon as it appears in a taint annotation. *) let exp_zone = Value_util.zone_of_expr to_loc exp in
let is_taint_annotated = Zone.is_included lv_zone annot_zone in let lv_indirect_zone =
if is_taint_annotated Value_util.indirect_zone_of_lval to_loc lv.Eval.lval
then in
state let intersect_state =
else LatticeTaint.intersects state exp_zone ||
(* Compute data-dependency with [state]: whenever [exp] (or its LatticeTaint.intersects state lv_indirect_zone
sub-expressions) is tainted, or [lv] is indexed by a tainted memory in
location. *) if intersect_state
let exp_zone = Value_util.zone_of_expr to_loc exp in then { state with locs_data = Zone.join state.locs_data lv_zone }
let lv_indirect_zone = else if Precise_locs.cardinal_zero_or_one ploc
Value_util.indirect_zone_of_lval to_loc lv.Eval.lval then { state with locs_data = Zone.diff state.locs_data lv_zone }
in else state
let intersect_state =
LatticeTaint.intersects state exp_zone ||
LatticeTaint.intersects state lv_indirect_zone
in
if intersect_state
then { state with locs_data = Zone.join state.locs_data lv_zone }
else if Precise_locs.cardinal_zero_or_one ploc
then { state with locs_data = Zone.diff state.locs_data lv_zone }
else state
in in
`Value state `Value state
let assume stmt exp _b valuation state = let assume stmt exp _b valuation state =
let state = filter_active_tainted_assumes stmt state in let state = filter_active_tainted_assumes stmt state in
let state =
let annot_zone = zone_of_taint_annot stmt in
{ state with locs_data = Zone.join state.locs_data annot_zone }
in
(* Add [stmt] as assume statement in [state] as soon as [exp] is tainted. *) (* Add [stmt] as assume statement in [state] as soon as [exp] is tainted. *)
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
...@@ -272,10 +233,6 @@ module TransferTaint = struct ...@@ -272,10 +233,6 @@ 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 state =
let annot_zone = zone_of_taint_annot stmt in
{ state with locs_data = Zone.join state.locs_data annot_zone }
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
...@@ -495,6 +452,25 @@ module TaintLogic = struct ...@@ -495,6 +452,25 @@ module TaintLogic = struct
| _ -> Unknown | _ -> Unknown
in in
evaluate predicate evaluate predicate
let interpret_taint_extension cvalue_state taint terms =
let taint_term taint term =
match eval_tlval_zone cvalue_state term with
| None ->
Value_parameters.warning ~wkey ~current:true ~once:true
"Cannot evaluate term %a in taint annotation; ignoring."
Printer.pp_term term;
taint
| Some (under, over) ->
if not (Zone.equal under over)
then
Value_parameters.warning ~wkey ~current:true ~once:true
"Cannot precisely evaluate term %a in taint annotation; \
over-approximating."
Printer.pp_term term;
{ taint with locs_data = Zone.join taint.locs_data over }
in
List.fold_left taint_term taint terms
end end
let interpret_taint_logic (module Abstract: Abstractions.S) : (module Abstractions.S) = let interpret_taint_logic (module Abstract: Abstractions.S) : (module Abstractions.S) =
...@@ -523,6 +499,24 @@ let interpret_taint_logic (module Abstract: Abstractions.S) : (module Abstractio ...@@ -523,6 +499,24 @@ let interpret_taint_logic (module Abstract: Abstractions.S) : (module Abstractio
TaintLogic.reduce_by_predicate cvalue taint predicate positive TaintLogic.reduce_by_predicate cvalue taint predicate positive
in in
`Value (Abstract.Dom.set key taint state) `Value (Abstract.Dom.set key taint state)
let interpret_acsl_extension extension state =
if String.equal extension.ext_name "taint"
then
match extension.ext_kind with
| Ext_terms terms ->
let cvalue = fst (get_cvalue_state state)
and taint = get_taint_state state in
let taint =
TaintLogic.interpret_taint_extension cvalue taint terms
in
Abstract.Dom.set key taint state
| _ ->
Value_parameters.warning ~wkey ~current:true ~once:true
"Invalid taint annotation %a; ignoring."
Printer.pp_extended extension;
state
else state
end end
in in
(module struct (module struct
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment