diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index 3e3249bd9..b902aff59 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -315,13 +315,15 @@ module Make (TaintSpec : TaintSpec.S) = struct | Sil.Call (ret, Const (Cfun called_pname), actuals, callee_loc, call_flags) -> let analyze_call astate_acc callee_pname = let call_site = CallSite.make callee_pname callee_loc in - let astate_with_sink = - match TraceDomain.Sink.get call_site actuals with + + let sinks = TraceDomain.Sink.get call_site actuals in + let astate_with_sink = match sinks with | [] -> astate | sinks -> add_sinks sinks actuals astate proc_data callee_loc in + let source = TraceDomain.Source.get call_site in let astate_with_source = - match TraceDomain.Source.get call_site, ret with + match source, ret with | Some source, Some (ret_id, ret_typ) -> let access_tree = add_source source ret_id ret_typ astate_with_sink.access_tree in { astate_with_sink with access_tree; } @@ -331,12 +333,19 @@ module Make (TaintSpec : TaintSpec.S) = struct | None, _ -> astate_with_sink in - let summary = - match Summary.read_summary proc_data.tenv proc_data.pdesc callee_pname with - | Some summary -> summary - | None -> TaintSpec.handle_unknown_call call_site (Option.map snd ret) in - apply_summary ret actuals summary astate_with_source proc_data call_site - |> Domain.join astate_acc in + let astate_with_summary = + if sinks <> [] || Option.is_some source + then + (* don't use a summary for a procedure that is a direct source or sink *) + astate_with_source + else + let summary = + match Summary.read_summary proc_data.tenv proc_data.pdesc callee_pname with + | Some summary -> summary + | None -> TaintSpec.handle_unknown_call call_site (Option.map snd ret) in + apply_summary ret actuals summary astate_with_source proc_data call_site in + + Domain.join astate_acc astate_with_summary in (* for each possible target of the call, apply the summary. join all results together *) IList.fold_left analyze_call Domain.initial (called_pname :: call_flags.cf_targets)