|
|
@ -315,13 +315,15 @@ module Make (TaintSpec : TaintSpec.S) = struct
|
|
|
|
| Sil.Call (ret, Const (Cfun called_pname), actuals, callee_loc, call_flags) ->
|
|
|
|
| Sil.Call (ret, Const (Cfun called_pname), actuals, callee_loc, call_flags) ->
|
|
|
|
let analyze_call astate_acc callee_pname =
|
|
|
|
let analyze_call astate_acc callee_pname =
|
|
|
|
let call_site = CallSite.make callee_pname callee_loc in
|
|
|
|
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
|
|
|
|
| [] -> astate
|
|
|
|
| sinks -> add_sinks sinks actuals astate proc_data callee_loc in
|
|
|
|
| sinks -> add_sinks sinks actuals astate proc_data callee_loc in
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let source = TraceDomain.Source.get call_site in
|
|
|
|
let astate_with_source =
|
|
|
|
let astate_with_source =
|
|
|
|
match TraceDomain.Source.get call_site, ret with
|
|
|
|
match source, ret with
|
|
|
|
| Some source, Some (ret_id, ret_typ) ->
|
|
|
|
| Some source, Some (ret_id, ret_typ) ->
|
|
|
|
let access_tree = add_source source ret_id ret_typ astate_with_sink.access_tree in
|
|
|
|
let access_tree = add_source source ret_id ret_typ astate_with_sink.access_tree in
|
|
|
|
{ astate_with_sink with access_tree; }
|
|
|
|
{ astate_with_sink with access_tree; }
|
|
|
@ -331,12 +333,19 @@ module Make (TaintSpec : TaintSpec.S) = struct
|
|
|
|
| None, _ ->
|
|
|
|
| None, _ ->
|
|
|
|
astate_with_sink in
|
|
|
|
astate_with_sink in
|
|
|
|
|
|
|
|
|
|
|
|
let summary =
|
|
|
|
let astate_with_summary =
|
|
|
|
match Summary.read_summary proc_data.tenv proc_data.pdesc callee_pname with
|
|
|
|
if sinks <> [] || Option.is_some source
|
|
|
|
| Some summary -> summary
|
|
|
|
then
|
|
|
|
| None -> TaintSpec.handle_unknown_call call_site (Option.map snd ret) in
|
|
|
|
(* don't use a summary for a procedure that is a direct source or sink *)
|
|
|
|
apply_summary ret actuals summary astate_with_source proc_data call_site
|
|
|
|
astate_with_source
|
|
|
|
|> Domain.join astate_acc in
|
|
|
|
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 *)
|
|
|
|
(* 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)
|
|
|
|
IList.fold_left analyze_call Domain.initial (called_pname :: call_flags.cf_targets)
|
|
|
|