From 45fb90de7b60dc621d2165c841c7df1d72e7e4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 29 Jun 2021 14:38:39 +0200 Subject: [PATCH] [Eva] Taint domain: better evaluation of "taints" extension in behaviors. Uses the logic environment to properly evaluates \result and values from the pre-state when using Eval_terms. --- src/plugins/value/domains/taint_domain.ml | 71 ++++++++++++----------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/plugins/value/domains/taint_domain.ml b/src/plugins/value/domains/taint_domain.ml index d0ef3151485..05a914e0b1a 100644 --- a/src/plugins/value/domains/taint_domain.ml +++ b/src/plugins/value/domains/taint_domain.ml @@ -378,66 +378,65 @@ let () = (* Interpretation of logic by the taint domain, using the cvalue domain. *) module TaintLogic = struct - let eval_tlval_zone cvalue_state term = - let env = Eval_terms.env_only_here cvalue_state in + let eval_tlval_zone cvalue_env term = let alarm_mode = Eval_terms.Fail in try let access = Locations.Read in - Some (Eval_terms.eval_tlval_as_zone_under_over ~alarm_mode access env term) + Some (Eval_terms.eval_tlval_as_zone_under_over + ~alarm_mode access cvalue_env term) with Eval_terms.LogicEvalError _ -> None - let eval_term_deps cvalue_state term = - let env = Eval_terms.env_only_here cvalue_state in + let eval_term_deps cvalue_env term = let alarm_mode = Eval_terms.Fail in try - let result = Eval_terms.eval_term ~alarm_mode env term in + let result = Eval_terms.eval_term ~alarm_mode cvalue_env term in match Logic_label.Map.bindings result.ldeps with | [ BuiltinLabel Here, zone ] -> Some (Zone.bottom, zone) | _ -> None with Eval_terms.LogicEvalError _ -> None - let eval_term_zone cvalue_state term = - match eval_tlval_zone cvalue_state term with + let eval_term_zone cvalue_env term = + match eval_tlval_zone cvalue_env term with | Some _ as x -> x - | None -> eval_term_deps cvalue_state term + | None -> eval_term_deps cvalue_env term - let reduce_by_taint_predicate cvalue_state state term positive = - match eval_term_zone cvalue_state term with + let reduce_by_taint_predicate cvalue_env state term positive = + match eval_term_zone cvalue_env term with | None -> state | Some (under, _over) -> if positive then { state with locs_data = Zone.join state.locs_data under } else { state with locs_data = Zone.diff state.locs_data under } - let rec reduce_by_predicate cvalue_state state predicate positive = + let rec reduce_by_predicate cvalue_env state predicate positive = match positive, predicate.pred_content with | true, Pand (p1, p2) | false, Por (p1, p2) -> - let state = reduce_by_predicate cvalue_state state p1 positive in - reduce_by_predicate cvalue_state state p2 positive + let state = reduce_by_predicate cvalue_env state p1 positive in + reduce_by_predicate cvalue_env state p2 positive | true,Por (p1,p2 ) | false,Pand (p1, p2) -> - let state1 = reduce_by_predicate cvalue_state state p1 positive in - let state2 = reduce_by_predicate cvalue_state state p2 positive in + let state1 = reduce_by_predicate cvalue_env state p1 positive in + let state2 = reduce_by_predicate cvalue_env state p2 positive in join state1 state2 - | _, Pnot p -> reduce_by_predicate cvalue_state state p (not positive) + | _, Pnot p -> reduce_by_predicate cvalue_env state p (not positive) | _, Papp ( {l_var_info = {lv_name = "\\tainted"}}, _labels, [arg]) -> - reduce_by_taint_predicate cvalue_state state arg positive + reduce_by_taint_predicate cvalue_env state arg positive | _ -> state - let evaluate_taint_predicate cvalue_state state term = - match eval_term_zone cvalue_state term with + let evaluate_taint_predicate cvalue_env state term = + match eval_term_zone cvalue_env term with | None -> Alarmset.Unknown | Some (_under, over) -> if Zone.intersects over state.locs_data then Alarmset.Unknown else Alarmset.False - let evaluate_predicate cvalue_state state predicate = + let evaluate_predicate cvalue_env state predicate = let rec evaluate predicate = match predicate.pred_content with | Papp ( {l_var_info = {lv_name = "\\tainted"}}, _labels, [arg]) -> - evaluate_taint_predicate cvalue_state state arg + evaluate_taint_predicate cvalue_env state arg | Ptrue -> True | Pfalse -> False | Pand (p1, p2) -> @@ -465,9 +464,9 @@ module TaintLogic = struct in evaluate predicate - let interpret_taint_extension cvalue_state taint terms = + let interpret_taint_extension cvalue_env taint terms = let taint_term taint term = - match eval_tlval_zone cvalue_state term with + match eval_tlval_zone cvalue_env term with | None -> Value_parameters.warning ~wkey ~current:true ~once:true "Cannot evaluate term %a in taint annotation; ignoring." @@ -493,35 +492,39 @@ let interpret_taint_logic (module Abstract: Abstractions.S) : (module Abstractio let module Dom = struct include Abstract.Dom + let get_states env state = + let taint = get_taint_state state in + let get_cvalue state = fst (get_cvalue_state state) in + let states label = get_cvalue (env.Abstract_domain.states label) in + let cvalue_env = Abstract_domain.{ env with states = states } in + Eval_terms.make_env cvalue_env (get_cvalue state), taint + let evaluate_predicate env state predicate = match evaluate_predicate env state predicate with | Unknown -> - let cvalue = fst (get_cvalue_state state) - and taint = get_taint_state state in - TaintLogic.evaluate_predicate cvalue taint predicate + let cvalue_env, taint = get_states env state in + TaintLogic.evaluate_predicate cvalue_env taint predicate | x -> x let reduce_by_predicate env state predicate positive = match reduce_by_predicate env state predicate positive with | `Bottom -> `Bottom | `Value state -> - let cvalue = fst (get_cvalue_state state) - and taint = get_taint_state state in + let cvalue_env, taint = get_states env state in let taint = - TaintLogic.reduce_by_predicate cvalue taint predicate positive + TaintLogic.reduce_by_predicate cvalue_env taint predicate positive in `Value (Abstract.Dom.set key taint state) - let interpret_acsl_extension extension _env state = + let interpret_acsl_extension extension env state = if String.equal extension.ext_name "taint" || String.equal extension.ext_name "taints" then match extension.ext_kind with | Ext_terms terms -> - let cvalue = fst (get_cvalue_state state) - and taint = get_taint_state state in + let cvalue_env, taint = get_states env state in let taint = - TaintLogic.interpret_taint_extension cvalue taint terms + TaintLogic.interpret_taint_extension cvalue_env taint terms in Abstract.Dom.set key taint state | _ -> -- GitLab