[infer][checkers] Prevent the race conditions between the summaries passed as parameter to the checkers and the summaries from the specs table

Summary:
This is step further simplify the code to avoid cases where the summary of the procedure being analyzed can exist in two different versions:
# one version is the summary passed as parameter to every checker
# the other is a copy of the summary in the in-memory specs table

This diff implements:
# the analysis always run through the `Ondemand` module (was already the case before)
# the summary of the procedure being analyzed is created at the beginning of the on-demand analysis call
# all the checkers run in sequence, update their respective part of the payload and log errors to the error table
# the summary is store at the end of the on-demand analysis call

Reviewed By: sblackshear

Differential Revision: D4787414

fbshipit-source-id: 2d115c9
master
Jeremy Dubreil 8 years ago committed by Facebook Github Bot
parent 1cd4b4cc38
commit f5adab59ec

@ -57,17 +57,8 @@ let get_procedure_definition exe_env proc_name =
let get_language proc_name = if Typ.Procname.is_java proc_name then Config.Java else Config.Clang let get_language proc_name = if Typ.Procname.is_java proc_name then Config.Java else Config.Clang
let reset_summary proc_name =
match Specs.get_summary proc_name with
| Some summary -> summary
| None ->
let attributes_opt =
Specs.proc_resolve_attributes proc_name in
Specs.reset_summary proc_name attributes_opt None
(** Invoke all registered procedure callbacks on the given procedure. *) (** Invoke all registered procedure callbacks on the given procedure. *)
let iterate_procedure_callbacks exe_env caller_pname = let iterate_procedure_callbacks exe_env summary caller_pname =
let procedure_language = get_language caller_pname in let procedure_language = get_language caller_pname in
Config.curr_language := procedure_language; Config.curr_language := procedure_language;
@ -81,12 +72,11 @@ let iterate_procedure_callbacks exe_env caller_pname =
| None -> | None ->
[] in [] in
let initial_summary = reset_summary caller_pname in
match get_procedure_definition exe_env caller_pname with match get_procedure_definition exe_env caller_pname with
| None -> initial_summary | None -> summary
| Some (idenv, tenv, _, proc_desc, _) -> | Some (idenv, tenv, _, proc_desc, _) ->
List.fold List.fold
~init:initial_summary ~init:summary
~f:(fun summary (language_opt, proc_callback) -> ~f:(fun summary (language_opt, proc_callback) ->
let language_matches = match language_opt with let language_matches = match language_opt with
| Some language -> Config.equal_language language procedure_language | Some language -> Config.equal_language language procedure_language
@ -140,12 +130,9 @@ let iterate_callbacks call_graph exe_env =
(* analyze all the currently defined procedures *) (* analyze all the currently defined procedures *)
Cg.get_defined_nodes call_graph in Cg.get_defined_nodes call_graph in
(* Make sure summaries exists. *) let analyze_ondemand _ summary proc_desc =
List.iter ~f:(fun p -> ignore (reset_summary p)) procs_to_analyze;
let analyze_ondemand _ proc_desc =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
iterate_procedure_callbacks exe_env proc_name in iterate_procedure_callbacks exe_env summary proc_name in
let callbacks = { let callbacks = {
Ondemand.analyze_ondemand; Ondemand.analyze_ondemand;
@ -193,10 +180,4 @@ let iterate_callbacks call_graph exe_env =
(* Unregister callbacks *) (* Unregister callbacks *)
Ondemand.unset_callbacks (); Ondemand.unset_callbacks ();
(* Store all the summaries to disk *)
List.iter
~f:(fun pname ->
Specs.store_summary (Specs.get_summary_unsafe "Checkers: store summaries" pname))
procs_to_analyze;
Config.curr_language := saved_language Config.curr_language := saved_language

@ -1430,7 +1430,7 @@ let do_analysis_closures exe_env : Tasks.closure list =
Option.bind (Specs.get_summary proc_name) Option.bind (Specs.get_summary proc_name)
(fun summary -> summary.Specs.proc_desc_option) (fun summary -> summary.Specs.proc_desc_option)
| None -> None in | None -> None in
let analyze_ondemand source proc_desc = let analyze_ondemand source _ proc_desc =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let tenv = Exe_env.get_tenv exe_env proc_name in let tenv = Exe_env.get_tenv exe_env proc_name in
if not (Config.eradicate || Config.checkers) && not (Procdesc.did_preanalysis proc_desc) if not (Config.eradicate || Config.checkers) && not (Procdesc.did_preanalysis proc_desc)

@ -27,7 +27,7 @@ let dirs_to_analyze =
changed_files String.Set.empty in changed_files String.Set.empty in
Option.map ~f:process_changed_files SourceFile.changed_files_set Option.map ~f:process_changed_files SourceFile.changed_files_set
type analyze_ondemand = SourceFile.t -> Procdesc.t -> Specs.summary type analyze_ondemand = SourceFile.t -> Specs.summary -> Procdesc.t -> Specs.summary
type get_proc_desc = Typ.Procname.t -> Procdesc.t option type get_proc_desc = Typ.Procname.t -> Procdesc.t option
@ -145,9 +145,9 @@ let run_proc_analysis ~propagate_exceptions analyze_proc curr_pdesc callee_pdesc
if Config.dynamic_dispatch = `Lazy if Config.dynamic_dispatch = `Lazy
then Some callee_pdesc then Some callee_pdesc
else None in else None in
ignore (Specs.reset_summary callee_pname attributes_opt callee_pdesc_option); let initial_summary = Specs.reset_summary callee_pname attributes_opt callee_pdesc_option in
Specs.set_status callee_pname Specs.Active; Specs.set_status callee_pname Specs.Active;
source in source, initial_summary in
let postprocess source summary = let postprocess source summary =
decr nesting; decr nesting;
@ -156,22 +156,22 @@ let run_proc_analysis ~propagate_exceptions analyze_proc curr_pdesc callee_pdesc
log_elapsed_time (); log_elapsed_time ();
summary in summary in
let log_error_and_continue exn kind = let log_error_and_continue exn summary kind =
Reporting.log_error callee_pname exn; Reporting.log_error_from_summary summary exn;
let prev_summary = Specs.get_summary_unsafe "Ondemand.do_analysis" callee_pname in let stats = { summary.Specs.stats with Specs.stats_failure = Some kind } in
let stats = { prev_summary.Specs.stats with Specs.stats_failure = Some kind } in
let payload = let payload =
{ prev_summary.Specs.payload with Specs.preposts = Some []; } in { summary.Specs.payload with Specs.preposts = Some []; } in
let new_summary = { prev_summary with Specs.stats; payload } in let new_summary = { summary with Specs.stats; payload } in
Specs.store_summary new_summary; Specs.store_summary new_summary;
log_elapsed_time (); log_elapsed_time ();
new_summary in new_summary in
let old_state = save_global_state () in let old_state = save_global_state () in
let source = preprocess () in let source, initial_summary = preprocess () in
try try
let summary = let summary =
analyze_proc source callee_pdesc |> postprocess source in analyze_proc source initial_summary callee_pdesc
|> postprocess source in
restore_global_state old_state; restore_global_state old_state;
summary summary
with exn -> with exn ->
@ -188,10 +188,10 @@ let run_proc_analysis ~propagate_exceptions analyze_proc curr_pdesc callee_pdesc
| SymOp.Analysis_failure_exe kind -> | SymOp.Analysis_failure_exe kind ->
(* in production mode, log the timeout/crash and continue with the summary we had before (* in production mode, log the timeout/crash and continue with the summary we had before
the failure occurred *) the failure occurred *)
log_error_and_continue exn kind log_error_and_continue exn initial_summary kind
| _ -> | _ ->
(* this happens with assert false or some other unrecognized exception *) (* this happens with assert false or some other unrecognized exception *)
log_error_and_continue exn (FKcrash (Exn.to_string exn)) log_error_and_continue exn initial_summary (FKcrash (Exn.to_string exn))
let analyze_proc_desc ~propagate_exceptions curr_pdesc callee_pdesc : Specs.summary option = let analyze_proc_desc ~propagate_exceptions curr_pdesc callee_pdesc : Specs.summary option =

@ -15,7 +15,7 @@ open! IStd
will be analyzed *) will be analyzed *)
val dirs_to_analyze : String.Set.t option val dirs_to_analyze : String.Set.t option
type analyze_ondemand = SourceFile.t -> Procdesc.t -> Specs.summary type analyze_ondemand = SourceFile.t -> Specs.summary -> Procdesc.t -> Specs.summary
type get_proc_desc = Typ.Procname.t -> Procdesc.t option type get_proc_desc = Typ.Procname.t -> Procdesc.t option

@ -56,7 +56,10 @@ let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters
let log_issue err_kind proc_name ?loc ?node_id ?session ?ltr ?linters_def_file exn = let log_issue err_kind proc_name ?loc ?node_id ?session ?ltr ?linters_def_file exn =
match Specs.get_summary proc_name with match Specs.get_summary proc_name with
| Some summary -> | Some summary ->
log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file exn log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file exn;
if Config.checkers then
(* TODO (#16348004): Remove this once Specs.get_summary_unsafe is entirely removed *)
Specs.store_summary summary
| None -> | None ->
failwithf failwithf
"Trying to report error on procedure %a, but cannot because no summary exists for this \ "Trying to report error on procedure %a, but cannot because no summary exists for this \

@ -18,13 +18,13 @@ module L = Logging
module Dom = BufferOverrunDomain module Dom = BufferOverrunDomain
module Summary = Summary.Make (struct module Summary = Summary.Make (struct
type summary = Dom.Summary.t type payload = Dom.Summary.t
let update_payload astate payload = let update_payload astate (summary : Specs.summary) =
{ payload with Specs.buffer_overrun = Some astate } { summary with payload = { summary.payload with buffer_overrun = Some astate }}
let read_from_payload payload = let read_payload (summary : Specs.summary) =
payload.Specs.buffer_overrun summary.payload.buffer_overrun
end) end)
module TransferFunctions (CFG : ProcCfg.S) = module TransferFunctions (CFG : ProcCfg.S) =
@ -319,7 +319,7 @@ struct
let instantiate_cond let instantiate_cond
: Tenv.t -> Typ.Procname.t -> Procdesc.t option -> (Exp.t * Typ.t) list : Tenv.t -> Typ.Procname.t -> Procdesc.t option -> (Exp.t * Typ.t) list
-> Dom.Mem.t -> Summary.summary -> Location.t -> Dom.ConditionSet.t -> Dom.Mem.t -> Summary.payload -> Location.t -> Dom.ConditionSet.t
= fun tenv caller_pname callee_pdesc params caller_mem summary loc -> = fun tenv caller_pname callee_pdesc params caller_mem summary loc ->
let callee_entry_mem = Dom.Summary.get_input summary in let callee_entry_mem = Dom.Summary.get_input summary in
let callee_cond = Dom.Summary.get_cond_set summary in let callee_cond = Dom.Summary.get_cond_set summary in
@ -415,7 +415,7 @@ struct
end end
let compute_post let compute_post
: Analyzer.TransferFunctions.extras ProcData.t -> Summary.summary option : Analyzer.TransferFunctions.extras ProcData.t -> Summary.payload option
= fun { pdesc; tenv; extras = get_pdesc } -> = fun { pdesc; tenv; extras = get_pdesc } ->
let cfg = CFG.from_pdesc pdesc in let cfg = CFG.from_pdesc pdesc in
let pdata = ProcData.make pdesc tenv get_pdesc in let pdata = ProcData.make pdesc tenv get_pdesc in
@ -446,15 +446,16 @@ let checker : Callbacks.proc_callback_args -> Specs.summary
= fun ({ summary } as callback) -> = fun ({ summary } as callback) ->
let proc_name = Specs.get_proc_name summary in let proc_name = Specs.get_proc_name summary in
let make_extras _ = callback.get_proc_desc in let make_extras _ = callback.get_proc_desc in
let post = let updated_summary : Specs.summary =
Interprocedural.compute_and_store_post Interprocedural.compute_and_store_post
~compute_post ~compute_post
~make_extras ~make_extras
callback callback in
in let post =
updated_summary.payload.buffer_overrun in
begin begin
match post with match post with
| Some s when Config.bo_debug >= 1 -> print_summary proc_name s | Some s when Config.bo_debug >= 1 -> print_summary proc_name s
| _ -> () | _ -> ()
end; end;
Specs.get_summary_unsafe "bufferOverrunChecker.checker" proc_name updated_summary

@ -159,13 +159,12 @@ end
module Interprocedural (Summ : Summary.S) = struct module Interprocedural (Summ : Summary.S) = struct
let compute_and_store_post let compute_and_store_post
~compute_post ~make_extras { Callbacks.proc_desc; tenv; } = ~compute_post ~make_extras { Callbacks.proc_desc; summary; tenv; } : Specs.summary =
match compute_post (ProcData.make proc_desc tenv (make_extras proc_desc)) with match compute_post (ProcData.make proc_desc tenv (make_extras proc_desc)) with
| Some post -> | Some post ->
Summ.write_summary (Procdesc.get_proc_name proc_desc) post; Summ.update_summary post summary
Some post
| None -> | None ->
None summary
end end

@ -66,8 +66,8 @@ module Interprocedural (Summary : Summary.S) : sig
(** compute and return the summary for the given procedure and store it on disk using (** compute and return the summary for the given procedure and store it on disk using
[compute_post]. *) [compute_post]. *)
val compute_and_store_post : val compute_and_store_post :
compute_post: ('a ProcData.t -> Summary.summary option) -> compute_post: ('a ProcData.t -> Summary.payload option) ->
make_extras : (Procdesc.t -> 'a) -> make_extras : (Procdesc.t -> 'a) ->
Callbacks.proc_callback_args -> Callbacks.proc_callback_args ->
Summary.summary option Specs.summary
end end

@ -23,13 +23,16 @@ module Domain = AbstractDomain.FiniteSet(ProcnameSet)
in the output directory as JSON files and *only* for those methods that in the output directory as JSON files and *only* for those methods that
will be part of the final crashcontext.json. *) will be part of the final crashcontext.json. *)
module SpecSummary = Summary.Make (struct module SpecSummary = Summary.Make (struct
type summary = Stacktree_j.stacktree option type payload = Stacktree_j.stacktree
let update_payload frame payload = let update_payload frame (summary : Specs.summary) =
{ payload with Specs.crashcontext_frame = frame } let payload =
{ summary.payload with Specs.crashcontext_frame = Some frame } in
{ summary with payload = payload }
let read_payload (summary : Specs.summary) =
summary.payload.crashcontext_frame
let read_from_payload payload =
Some payload.Specs.crashcontext_frame
end) end)
type extras_t = { type extras_t = {
@ -78,15 +81,16 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let callees = List.map let callees = List.map
~f:(fun pn -> ~f:(fun pn ->
match SpecSummary.read_summary pdesc pn with match SpecSummary.read_summary pdesc pn with
| None | Some None -> (match get_proc_desc pn with | None ->
| None -> stacktree_stub_of_procname pn (match get_proc_desc pn with
(* This can happen when the callee is in the same cluster/ buck | None -> stacktree_stub_of_procname pn
target, but it hasn't been checked yet. So we need both the (* This can happen when the callee is in the same cluster/ buck
inter-target lookup (SpecSummary) and the intra-target target, but it hasn't been checked yet. So we need both the
lookup (using get_proc_desc). *) inter-target lookup (SpecSummary) and the intra-target
| Some callee_pdesc -> lookup (using get_proc_desc). *)
stacktree_of_pdesc callee_pdesc "proc_start") | Some callee_pdesc ->
| Some (Some stracktree) -> stracktree ) stacktree_of_pdesc callee_pdesc "proc_start")
| Some stracktree -> stracktree )
procs in procs in
stacktree_of_pdesc pdesc ~loc ~callees location_type stacktree_of_pdesc pdesc ~loc ~callees location_type
@ -163,8 +167,7 @@ let loaded_stacktraces =
| None -> None | None -> None
| Some files -> Some (List.map ~f:Stacktrace.of_json_file files) | Some files -> Some (List.map ~f:Stacktrace.of_json_file files)
let checker { Callbacks.proc_desc; tenv; get_proc_desc } : Specs.summary = let checker { Callbacks.proc_desc; tenv; get_proc_desc; summary } : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in
begin begin
match loaded_stacktraces with match loaded_stacktraces with
| None -> failwith "Missing command line option. Either \ | None -> failwith "Missing command line option. Either \
@ -180,4 +183,4 @@ let checker { Callbacks.proc_desc; tenv; get_proc_desc } : Specs.summary =
ignore (Analyzer.exec_pdesc (ProcData.make proc_desc tenv extras) ~initial:Domain.empty) ignore (Analyzer.exec_pdesc (ProcData.make proc_desc tenv extras) ~initial:Domain.empty)
end end
end; end;
Specs.get_summary_unsafe "BoundedCallTree.checker" proc_name summary

@ -82,7 +82,7 @@ module Make (Spec : Spec) : S = struct
module Analyzer = AbstractInterpreter.Make (ProcCfg.Exceptional) (TransferFunctions) module Analyzer = AbstractInterpreter.Make (ProcCfg.Exceptional) (TransferFunctions)
let checker { Callbacks.proc_desc; tenv; } : Specs.summary = let checker { Callbacks.proc_desc; tenv; summary } : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let nodes = Procdesc.get_nodes proc_desc in let nodes = Procdesc.get_nodes proc_desc in
let do_reporting node_id state = let do_reporting node_id state =
@ -101,6 +101,6 @@ module Make (Spec : Spec) : S = struct
let inv_map = let inv_map =
Analyzer.exec_pdesc (ProcData.make_default proc_desc tenv) ~initial:Domain.empty in Analyzer.exec_pdesc (ProcData.make_default proc_desc tenv) ~initial:Domain.empty in
Analyzer.InvariantMap.iter do_reporting inv_map; Analyzer.InvariantMap.iter do_reporting inv_map;
Specs.get_summary_unsafe "checker" proc_name summary
end end

@ -46,13 +46,13 @@ let is_modelled =
|> QualifiedCppName.Match.match_qualifiers models_matcher |> QualifiedCppName.Match.match_qualifiers models_matcher
module Summary = Summary.Make (struct module Summary = Summary.Make (struct
type summary = SiofDomain.astate type payload = SiofDomain.astate
let update_payload astate payload = let update_payload astate (summary : Specs.summary) =
{ payload with Specs.siof = Some astate } { summary with payload = { summary.payload with siof = Some astate }}
let read_from_payload payload = let read_payload (summary : Specs.summary) =
payload.Specs.siof summary.payload.siof
end) end)
module TransferFunctions (CFG : ProcCfg.S) = struct module TransferFunctions (CFG : ProcCfg.S) = struct
@ -183,7 +183,7 @@ let is_foreign tu_opt (v, _) =
| None -> assert false in | None -> assert false in
Option.value_map ~f:(fun f -> not (is_orig_file f)) ~default:false (Pvar.get_source_file v) Option.value_map ~f:(fun f -> not (is_orig_file f)) ~default:false (Pvar.get_source_file v)
let report_siof trace pdesc gname loc = let report_siof summary trace pdesc gname loc =
let tu_opt = let tu_opt =
let attrs = Procdesc.get_attributes pdesc in let attrs = Procdesc.get_attributes pdesc in
attrs.ProcAttributes.translation_unit in attrs.ProcAttributes.translation_unit in
@ -208,10 +208,9 @@ let report_siof trace pdesc gname loc =
GlobalsAccesses.pp foreign_globals in GlobalsAccesses.pp foreign_globals in
description, (passthroughs, (final_sink', pt)::rest) in description, (passthroughs, (final_sink', pt)::rest) in
let ltr = SiofTrace.trace_of_error loc gname sink_path' in let ltr = SiofTrace.trace_of_error loc gname sink_path' in
let caller_pname = Procdesc.get_proc_name pdesc in
let msg = Localise.to_issue_id Localise.static_initialization_order_fiasco in let msg = Localise.to_issue_id Localise.static_initialization_order_fiasco in
let exn = Exceptions.Checkers (msg, Localise.verbatim_desc description) in let exn = Exceptions.Checkers (msg, Localise.verbatim_desc description) in
Reporting.log_error caller_pname ~loc ~ltr exn in Reporting.log_error_from_summary summary ~loc ~ltr exn in
let has_foreign_sink (_, path) = let has_foreign_sink (_, path) =
List.exists List.exists
@ -224,7 +223,8 @@ let report_siof trace pdesc gname loc =
|> List.filter ~f:has_foreign_sink |> List.filter ~f:has_foreign_sink
|> List.iter ~f:report_one_path |> List.iter ~f:report_one_path
let siof_check pdesc gname = function let siof_check pdesc gname (summary : Specs.summary) =
match summary.payload.siof with
| Some ((SiofDomain.BottomSiofTrace.NonBottom post, _)) -> | Some ((SiofDomain.BottomSiofTrace.NonBottom post, _)) ->
let attrs = Procdesc.get_attributes pdesc in let attrs = Procdesc.get_attributes pdesc in
let all_globals = SiofTrace.Sinks.fold let all_globals = SiofTrace.Sinks.fold
@ -234,7 +234,7 @@ let siof_check pdesc gname = function
let attrs = Procdesc.get_attributes pdesc in let attrs = Procdesc.get_attributes pdesc in
attrs.ProcAttributes.translation_unit in attrs.ProcAttributes.translation_unit in
if GlobalsAccesses.exists (is_foreign tu_opt) all_globals then if GlobalsAccesses.exists (is_foreign tu_opt) all_globals then
report_siof post pdesc gname attrs.ProcAttributes.loc; report_siof summary post pdesc gname attrs.ProcAttributes.loc;
| Some (SiofDomain.BottomSiofTrace.Bottom, _) | None -> | Some (SiofDomain.BottomSiofTrace.Bottom, _) | None ->
() ()
@ -244,7 +244,7 @@ let compute_post proc_data =
|> Option.map ~f:SiofDomain.normalize |> Option.map ~f:SiofDomain.normalize
let checker ({ Callbacks.proc_desc } as callback) : Specs.summary = let checker ({ Callbacks.proc_desc } as callback) : Specs.summary =
let post = let updated_summary =
Interprocedural.compute_and_store_post Interprocedural.compute_and_store_post
~compute_post ~compute_post
~make_extras:ProcData.make_empty_extras ~make_extras:ProcData.make_empty_extras
@ -253,8 +253,8 @@ let checker ({ Callbacks.proc_desc } as callback) : Specs.summary =
begin begin
match Typ.Procname.get_global_name_of_initializer pname with match Typ.Procname.get_global_name_of_initializer pname with
| Some gname -> | Some gname ->
siof_check proc_desc gname post siof_check proc_desc gname updated_summary
| None -> | None ->
() ()
end; end;
Specs.get_summary_unsafe "SIOF checker" pname updated_summary

@ -14,13 +14,13 @@ module L = Logging
module MF = MarkupFormatter module MF = MarkupFormatter
module Summary = Summary.Make (struct module Summary = Summary.Make (struct
type summary = ThreadSafetyDomain.summary type payload = ThreadSafetyDomain.summary
let update_payload summary payload = let update_payload post (summary : Specs.summary) =
{ payload with Specs.threadsafety = Some summary } { summary with payload = { summary.payload with threadsafety = Some post }}
let read_from_payload payload = let read_payload (summary : Specs.summary) =
payload.Specs.threadsafety summary.payload.threadsafety
end) end)
let is_owned access_path attribute_map = let is_owned access_path attribute_map =
@ -870,18 +870,10 @@ let analyze_procedure callback =
end end
else else
Some empty_post in Some empty_post in
match Interprocedural.compute_and_store_post
Interprocedural.compute_and_store_post ~compute_post
~compute_post ~make_extras:FormalMap.make
~make_extras:FormalMap.make callback
callback with
| Some post -> post
| None -> empty_post
let checker ({ Callbacks.summary } as callback_args) : Specs.summary =
let proc_name = Specs.get_proc_name summary in
ignore (analyze_procedure callback_args);
Specs.get_summary_unsafe "ThreadSafety.checker" proc_name
(* we assume two access paths can alias if their access parts are equal (we ignore the base). *) (* we assume two access paths can alias if their access parts are equal (we ignore the base). *)
let can_alias access_path1 access_path2 = let can_alias access_path1 access_path2 =

@ -9,4 +9,4 @@
val file_analysis : Callbacks.cluster_callback_t val file_analysis : Callbacks.cluster_callback_t
val checker : Callbacks.proc_callback_t val analyze_procedure : Callbacks.proc_callback_t

@ -73,13 +73,13 @@ module Domain = struct
end end
module Summary = Summary.Make (struct module Summary = Summary.Make (struct
type summary = CallsDomain.astate type payload = CallsDomain.astate
let update_payload call_map payload = let update_payload call_map (summary : Specs.summary) =
{ payload with Specs.calls = Some call_map } { summary with payload = { summary.payload with calls = Some call_map }}
let read_from_payload payload = let read_payload (summary : Specs.summary) =
payload.Specs.calls summary.payload.calls
end) end)
(* Warning name when a performance critical method directly or indirectly (* Warning name when a performance critical method directly or indirectly
@ -161,7 +161,8 @@ let string_of_pname =
Typ.Procname.to_simplified_string ~withclass:true Typ.Procname.to_simplified_string ~withclass:true
let report_allocation_stack let report_allocation_stack
src_annot pname fst_call_loc trace stack_str constructor_pname call_loc = src_annot summary fst_call_loc trace stack_str constructor_pname call_loc =
let pname = Specs.get_proc_name summary in
let final_trace = List.rev (update_trace call_loc trace) in let final_trace = List.rev (update_trace call_loc trace) in
let constr_str = string_of_pname constructor_pname in let constr_str = string_of_pname constructor_pname in
let description = let description =
@ -173,11 +174,12 @@ let report_allocation_stack
MF.pp_monospaced (stack_str ^ ("new "^constr_str)) in MF.pp_monospaced (stack_str ^ ("new "^constr_str)) in
let exn = let exn =
Exceptions.Checkers (allocates_memory, Localise.verbatim_desc description) in Exceptions.Checkers (allocates_memory, Localise.verbatim_desc description) in
Reporting.log_error pname ~loc:fst_call_loc ~ltr:final_trace exn Reporting.log_error_from_summary summary ~loc:fst_call_loc ~ltr:final_trace exn
let report_annotation_stack src_annot snk_annot src_pname loc trace stack_str snk_pname call_loc = let report_annotation_stack src_annot snk_annot src_summary loc trace stack_str snk_pname call_loc =
let src_pname = Specs.get_proc_name src_summary in
if String.equal snk_annot dummy_constructor_annot if String.equal snk_annot dummy_constructor_annot
then report_allocation_stack src_annot src_pname loc trace stack_str snk_pname call_loc then report_allocation_stack src_annot src_summary loc trace stack_str snk_pname call_loc
else else
let final_trace = List.rev (update_trace call_loc trace) in let final_trace = List.rev (update_trace call_loc trace) in
let exp_pname_str = string_of_pname snk_pname in let exp_pname_str = string_of_pname snk_pname in
@ -195,9 +197,9 @@ let report_annotation_stack src_annot snk_annot src_pname loc trace stack_str sn
else annotation_reachability_error in else annotation_reachability_error in
let exn = let exn =
Exceptions.Checkers (msg, Localise.verbatim_desc description) in Exceptions.Checkers (msg, Localise.verbatim_desc description) in
Reporting.log_error src_pname ~loc ~ltr:final_trace exn Reporting.log_error_from_summary src_summary ~loc ~ltr:final_trace exn
let report_call_stack end_of_stack lookup_next_calls report call_site calls = let report_call_stack summary end_of_stack lookup_next_calls report call_site calls =
(* TODO: stop using this; we can use the call site instead *) (* TODO: stop using this; we can use the call site instead *)
let lookup_location pname = let lookup_location pname =
match Specs.get_summary pname with match Specs.get_summary pname with
@ -205,7 +207,7 @@ let report_call_stack end_of_stack lookup_next_calls report call_site calls =
| Some summary -> summary.Specs.attributes.ProcAttributes.loc in | Some summary -> summary.Specs.attributes.ProcAttributes.loc in
let rec loop fst_call_loc visited_pnames (trace, stack_str) (callee_pname, call_loc) = let rec loop fst_call_loc visited_pnames (trace, stack_str) (callee_pname, call_loc) =
if end_of_stack callee_pname then if end_of_stack callee_pname then
report (CallSite.pname call_site) fst_call_loc trace stack_str callee_pname call_loc report summary fst_call_loc trace stack_str callee_pname call_loc
else else
let callee_def_loc = lookup_location callee_pname in let callee_def_loc = lookup_location callee_pname in
let next_calls = lookup_next_calls callee_pname in let next_calls = lookup_next_calls callee_pname in
@ -328,7 +330,7 @@ module Interprocedural = struct
let method_is_expensive tenv pname = let method_is_expensive tenv pname =
is_modeled_expensive tenv pname || is_expensive tenv pname is_modeled_expensive tenv pname || is_expensive tenv pname
let check_and_report ({ Callbacks.proc_desc; tenv; } as proc_data) : Specs.summary = let check_and_report ({ Callbacks.proc_desc; tenv; summary } as proc_data) : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let loc = Procdesc.get_loc proc_desc in let loc = Procdesc.get_loc proc_desc in
let expensive = is_expensive tenv proc_name in let expensive = is_expensive tenv proc_name in
@ -344,7 +346,7 @@ module Interprocedural = struct
let exn = let exn =
Exceptions.Checkers Exceptions.Checkers
(expensive_overrides_unexpensive, Localise.verbatim_desc description) in (expensive_overrides_unexpensive, Localise.verbatim_desc description) in
Reporting.log_error proc_name ~loc exn in Reporting.log_error_from_summary summary ~loc exn in
if expensive then if expensive then
PatternMatch.override_iter check_expensive_subtyping_rules tenv proc_name; PatternMatch.override_iter check_expensive_subtyping_rules tenv proc_name;
@ -361,6 +363,7 @@ module Interprocedural = struct
let f_report = let f_report =
report_annotation_stack src_annot.class_name snk_annot.class_name in report_annotation_stack src_annot.class_name snk_annot.class_name in
report_call_stack report_call_stack
summary
(method_has_annot snk_annot tenv) (method_has_annot snk_annot tenv)
(lookup_annotation_calls proc_desc snk_annot) (lookup_annotation_calls proc_desc snk_annot)
f_report f_report
@ -380,17 +383,19 @@ module Interprocedural = struct
(init_map, Domain.TrackingVar.empty) in (init_map, Domain.TrackingVar.empty) in
let compute_post proc_data = let compute_post proc_data =
Option.map ~f:fst (Analyzer.compute_post ~initial proc_data) in Option.map ~f:fst (Analyzer.compute_post ~initial proc_data) in
let updated_summary : Specs.summary =
compute_and_store_post
~compute_post:compute_post
~make_extras:ProcData.make_empty_extras
proc_data in
begin begin
match compute_and_store_post match updated_summary.payload.calls with
~compute_post:compute_post
~make_extras:ProcData.make_empty_extras
proc_data with
| Some call_map -> | Some call_map ->
List.iter ~f:(report_src_snk_paths call_map) (src_snk_pairs ()) List.iter ~f:(report_src_snk_paths call_map) (src_snk_pairs ())
| None -> | None ->
() ()
end; end;
Specs.get_summary_unsafe "AnnotationReachability.checker" proc_name updated_summary
end end

@ -91,7 +91,7 @@ let check_final_state tenv proc_name proc_desc final_s =
end end
(** Simple check for dead code. *) (** Simple check for dead code. *)
let callback_check_dead_code { Callbacks.proc_desc; tenv } = let callback_check_dead_code { Callbacks.proc_desc; tenv; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let module DFDead = MakeDF(struct let module DFDead = MakeDF(struct
@ -115,4 +115,4 @@ let callback_check_dead_code { Callbacks.proc_desc; tenv } =
end in end in
do_check (); do_check ();
Specs.get_summary_unsafe "callback_check_dead_code" proc_name summary

@ -317,7 +317,7 @@ let check_final_state tenv proc_name proc_desc exit_node final_s =
(** Check that the trace calls are balanced. (** Check that the trace calls are balanced.
This is done by using the most general control flow including exceptions. This is done by using the most general control flow including exceptions.
The begin() and end() function are assumed not to throw exceptions. *) The begin() and end() function are assumed not to throw exceptions. *)
let callback_check_trace_call_sequence { Callbacks.proc_desc; idenv; tenv } = let callback_check_trace_call_sequence { Callbacks.proc_desc; idenv; tenv; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let module DFTrace = MakeDF(struct let module DFTrace = MakeDF(struct
@ -343,4 +343,4 @@ let callback_check_trace_call_sequence { Callbacks.proc_desc; idenv; tenv } =
end in end in
if not (APIs.is_begin_or_end proc_name) then do_check (); if not (APIs.is_begin_or_end proc_name) then do_check ();
Specs.get_summary_unsafe "callback_check_trace_call_sequence" proc_name summary

@ -168,11 +168,11 @@ let report_calls_and_accesses tenv callback proc_desc instr =
| None -> () | None -> ()
(** Report all field accesses and method calls of a procedure. *) (** Report all field accesses and method calls of a procedure. *)
let callback_check_access { Callbacks.tenv; proc_desc; } = let callback_check_access { Callbacks.tenv; proc_desc; summary } =
Procdesc.iter_instrs Procdesc.iter_instrs
(fun _ instr -> report_calls_and_accesses tenv Localise.proc_callback proc_desc instr) (fun _ instr -> report_calls_and_accesses tenv Localise.proc_callback proc_desc instr)
proc_desc; proc_desc;
Specs.get_summary_unsafe "callback_check_access" (Procdesc.get_proc_name proc_desc) summary
(** Report all field accesses and method calls of a class. *) (** Report all field accesses and method calls of a class. *)
@ -317,7 +317,7 @@ let callback_check_write_to_parcel ({ Callbacks.summary } as args) =
summary summary
(** Monitor calls to Preconditions.checkNotNull and detect inconsistent uses. *) (** Monitor calls to Preconditions.checkNotNull and detect inconsistent uses. *)
let callback_monitor_nullcheck { Callbacks.proc_desc; idenv } = let callback_monitor_nullcheck { Callbacks.proc_desc; idenv; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let verbose = ref false in let verbose = ref false in
@ -396,13 +396,13 @@ let callback_monitor_nullcheck { Callbacks.proc_desc; idenv } =
| _ -> () in | _ -> () in
Procdesc.iter_instrs do_instr proc_desc; Procdesc.iter_instrs do_instr proc_desc;
summary_checks_of_formals (); summary_checks_of_formals ();
Specs.get_summary_unsafe "callback_monitor_nullcheck" proc_name summary
(** Test persistent state. *) (** Test persistent state. *)
let callback_test_state { Callbacks.summary } = let callback_test_state { Callbacks.summary } =
let proc_name = Specs.get_proc_name summary in let proc_name = Specs.get_proc_name summary in
ST.pname_add proc_name "somekey" "somevalue"; ST.pname_add proc_name "somekey" "somevalue";
Specs.get_summary_unsafe "callback_test_state" proc_name summary
(** Check the uses of VisibleForTesting *) (** Check the uses of VisibleForTesting *)
let callback_checkVisibleForTesting { Callbacks.proc_desc; summary } = let callback_checkVisibleForTesting { Callbacks.proc_desc; summary } =
@ -415,7 +415,7 @@ let callback_checkVisibleForTesting { Callbacks.proc_desc; summary } =
summary summary
(** Check for readValue and readValueAs json deserialization *) (** Check for readValue and readValueAs json deserialization *)
let callback_find_deserialization { Callbacks.proc_desc; get_proc_desc; idenv; } = let callback_find_deserialization { Callbacks.proc_desc; get_proc_desc; idenv; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let verbose = true in let verbose = true in
@ -510,7 +510,7 @@ let callback_find_deserialization { Callbacks.proc_desc; get_proc_desc; idenv; }
store_return (); store_return ();
Procdesc.iter_instrs do_instr proc_desc; Procdesc.iter_instrs do_instr proc_desc;
Specs.get_summary_unsafe "callback_find_deserialization" proc_name summary
(** Check field accesses. *) (** Check field accesses. *)
let callback_check_field_access { Callbacks.proc_desc; summary } = let callback_check_field_access { Callbacks.proc_desc; summary } =
@ -557,7 +557,7 @@ let callback_check_field_access { Callbacks.proc_desc; summary } =
summary summary
(** Print c method calls. *) (** Print c method calls. *)
let callback_print_c_method_calls { Callbacks.tenv; proc_desc } = let callback_print_c_method_calls { Callbacks.tenv; proc_desc; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let do_instr node = function let do_instr node = function
| Sil.Call (_, Exp.Const (Const.Cfun pn), (e, _):: _, loc, _) | Sil.Call (_, Exp.Const (Const.Cfun pn), (e, _):: _, loc, _)
@ -584,10 +584,10 @@ let callback_print_c_method_calls { Callbacks.tenv; proc_desc } =
description description
| _ -> () in | _ -> () in
Procdesc.iter_instrs do_instr proc_desc; Procdesc.iter_instrs do_instr proc_desc;
Specs.get_summary_unsafe "callback_print_c_method_calls" proc_name summary
(** Print access to globals. *) (** Print access to globals. *)
let callback_print_access_to_globals { Callbacks.tenv; proc_desc } = let callback_print_access_to_globals { Callbacks.tenv; proc_desc; summary } =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let do_pvar is_read pvar loc = let do_pvar is_read pvar loc =
let description = let description =
@ -614,4 +614,4 @@ let callback_print_access_to_globals { Callbacks.tenv; proc_desc } =
Option.iter ~f:(fun pvar -> do_pvar false pvar loc) (get_global_var e) Option.iter ~f:(fun pvar -> do_pvar false pvar loc) (get_global_var e)
| _ -> () in | _ -> () in
Procdesc.iter_instrs do_instr proc_desc; Procdesc.iter_instrs do_instr proc_desc;
Specs.get_summary_unsafe "callback_print_access_to_globals" proc_name summary

@ -206,10 +206,10 @@ let check_printf_args_ok tenv
| None -> ()) | None -> ())
| _ -> () | _ -> ()
let callback_printf_args { Callbacks.tenv; proc_desc } : Specs.summary = let callback_printf_args { Callbacks.tenv; proc_desc; summary } : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
Procdesc.iter_instrs (fun n i -> check_printf_args_ok tenv n i proc_name proc_desc) proc_desc; Procdesc.iter_instrs (fun n i -> check_printf_args_ok tenv n i proc_name proc_desc) proc_desc;
Specs.get_summary_unsafe "Callbacks.proc_callback_t" proc_name summary
(* (*
let printf_signature_to_string let printf_signature_to_string

@ -39,7 +39,7 @@ let active_procedure_checkers () =
PrintfArgs.callback_printf_args, Config.checkers_enabled; PrintfArgs.callback_printf_args, Config.checkers_enabled;
AnnotationReachability.checker, Config.checkers_enabled; AnnotationReachability.checker, Config.checkers_enabled;
BufferOverrunChecker.checker, Config.bufferoverrun; BufferOverrunChecker.checker, Config.bufferoverrun;
ThreadSafety.checker, Config.threadsafety || Config.checkers_enabled; ThreadSafety.analyze_procedure, Config.threadsafety || Config.checkers_enabled;
] in ] in
(* make sure SimpleChecker.ml is not dead code *) (* make sure SimpleChecker.ml is not dead code *)
if false then (let module SC = SimpleChecker.Make in ()); if false then (let module SC = SimpleChecker.Make in ());

@ -13,7 +13,7 @@ module L = Logging
(** Find SQL statements in string concatenations *) (** Find SQL statements in string concatenations *)
let callback_sql { Callbacks.proc_desc; tenv } : Specs.summary = let callback_sql { Callbacks.proc_desc; tenv; summary } : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let verbose = false in let verbose = false in
@ -71,4 +71,4 @@ let callback_sql { Callbacks.proc_desc; tenv } : Specs.summary =
Procdesc.iter_instrs (do_instr const_map) proc_desc Procdesc.iter_instrs (do_instr const_map) proc_desc
with _ -> () with _ -> ()
end; end;
Specs.get_summary_unsafe "SqlChecker.callback_sql" proc_name summary

@ -9,42 +9,34 @@
open! IStd open! IStd
module type Helper = sig module type Payload = sig
type summary type payload
(* type astate*)
(** update the specs payload with [summary] *) val update_payload : payload -> Specs.summary -> Specs.summary
val update_payload : summary -> Specs.payload -> Specs.payload
val read_payload : Specs.summary -> payload option
(** extract [summmary] from the specs payload *)
val read_from_payload : Specs.payload -> summary option
end end
module type S = sig module type S = sig
type summary type payload
(* type astate*)
val update_summary : payload -> Specs.summary -> Specs.summary
(** Write the [summary] for the procname to persistent storage. *) val read_summary : Procdesc.t -> Typ.Procname.t -> payload option
val write_summary : Typ.Procname.t -> summary -> unit
(** read and return the summary for [callee_pname] called from [caller_pdesc]. does the analysis
to create the summary if needed *)
val read_summary : Procdesc.t -> Typ.Procname.t -> summary option
end end
module Make (H : Helper) = struct module Make (P : Payload) : S with type payload = P.payload = struct
type summary = H.summary
let write_summary pname summary = type payload = P.payload
match Specs.get_summary pname with
| Some global_summary -> let update_summary payload summary =
let payload = H.update_payload summary global_summary.Specs.payload in P.update_payload payload summary
Specs.add_summary pname { global_summary with payload; }
| None ->
failwithf "Summary for %a should exist, but does not!@." Typ.Procname.pp pname
let read_summary caller_pdesc callee_pname = let read_summary caller_pdesc callee_pname =
match Ondemand.analyze_proc_name ~propagate_exceptions:false caller_pdesc callee_pname with match Ondemand.analyze_proc_name ~propagate_exceptions:false caller_pdesc callee_pname with
| None -> None | None -> None
| Some summary -> H.read_from_payload summary.Specs.payload | Some summary -> P.read_payload summary
end end

@ -7,27 +7,27 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*) *)
module type Helper = sig module type Payload = sig
type summary type payload
(** update the specs payload with [summary] *) (** Uptade the corresponding part of the payload in the procedure summary *)
val update_payload : summary -> Specs.payload -> Specs.payload val update_payload : payload -> Specs.summary -> Specs.summary
(** Read the corresponding part of the payload from the procedure summary *)
val read_payload : Specs.summary -> payload option
(** extract [summmary] from the specs payload *)
val read_from_payload : Specs.payload -> summary option
end end
module type S = sig module type S = sig
type summary type payload
(** Write the [summary] for the procname to persistent storage. Returns the summary actually (** Uptade the corresponding part of the payload in the procedure summary *)
written. *) val update_summary : payload -> Specs.summary -> Specs.summary
val write_summary : Typ.Procname.t -> summary -> unit
(** read and return the summary for [callee_pname] called from [caller_pdesc]. does the analysis (** Return the payload for the given procedure.
to create the summary if needed *) Runs the analysis on-demand if necessary *)
val read_summary : Procdesc.t -> Typ.Procname.t -> summary option val read_summary : Procdesc.t -> Typ.Procname.t -> payload option
end end
module Make (H : Helper) : S with type summary = H.summary module Make (P : Payload) : S with type payload = P.payload

@ -345,7 +345,7 @@ struct
update_summary curr_pname curr_pdesc final_typestate_opt update_summary curr_pname curr_pdesc final_typestate_opt
(** Entry point for the eradicate-based checker infrastructure. *) (** Entry point for the eradicate-based checker infrastructure. *)
let callback checks ({ Callbacks.proc_desc } as callback_args) : Specs.summary = let callback checks ({ Callbacks.proc_desc; summary } as callback_args) : Specs.summary =
let proc_name = Procdesc.get_proc_name proc_desc in let proc_name = Procdesc.get_proc_name proc_desc in
let calls_this = ref false in let calls_this = ref false in
@ -371,7 +371,7 @@ struct
callback2 callback2
calls_this checks callback_args annotated_signature linereader loc calls_this checks callback_args annotated_signature linereader loc
end; end;
Specs.get_summary_unsafe "callback" proc_name summary
end (* MkCallback *) end (* MkCallback *)

@ -20,15 +20,13 @@ module Make (TaintSpecification : TaintSpec.S) = struct
module IdMapDomain = IdAccessPathMapDomain module IdMapDomain = IdAccessPathMapDomain
module Summary = Summary.Make(struct module Summary = Summary.Make(struct
type summary = QuandarySummary.t type payload = QuandarySummary.t
let update_payload summary payload = let update_payload quandary_payload (summary : Specs.summary) =
{ payload with Specs.quandary = Some summary; } { summary with payload = { summary.payload with quandary = Some quandary_payload }}
let read_from_payload payload = let read_payload (summary : Specs.summary) =
match payload.Specs.quandary with summary.payload.quandary
| None -> Some (TaintSpecification.to_summary_access_tree TaintDomain.empty)
| summary_opt -> summary_opt
end) end)
module Domain = struct module Domain = struct
@ -505,8 +503,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
module Interprocedural = AbstractInterpreter.Interprocedural(Summary) module Interprocedural = AbstractInterpreter.Interprocedural(Summary)
let checker ({ Callbacks.tenv; summary } as callback) : Specs.summary = let checker ({ Callbacks.tenv; } as callback) : Specs.summary =
let proc_name = Specs.get_proc_name summary in
(* bind parameters to a trace with a tainted source (if applicable) *) (* bind parameters to a trace with a tainted source (if applicable) *)
let make_initial pdesc = let make_initial pdesc =
@ -541,6 +538,5 @@ module Make (TaintSpecification : TaintSpec.S) = struct
then failwith "Couldn't compute post" then failwith "Couldn't compute post"
else None in else None in
let make_extras = FormalMap.make in let make_extras = FormalMap.make in
ignore (Interprocedural.compute_and_store_post ~compute_post ~make_extras callback); Interprocedural.compute_and_store_post ~compute_post ~make_extras callback
Specs.get_summary_unsafe "taint analysis" proc_name
end end

@ -109,9 +109,7 @@ let tests =
make_load_fld ~rhs_typ:Typ.Tvoid lhs_id_str fld_str (Exp.Var (ident_of_str root_str)) in make_load_fld ~rhs_typ:Typ.Tvoid lhs_id_str fld_str (Exp.Var (ident_of_str root_str)) in
let assert_empty = invariant "{ }" in let assert_empty = invariant "{ }" in
(* hack: register an empty analyze_ondemand to prevent a crash because the callback is unset *) (* hack: register an empty analyze_ondemand to prevent a crash because the callback is unset *)
let analyze_ondemand _ proc_desc = let analyze_ondemand _ summary _ = summary in
let proc_name = Procdesc.get_proc_name proc_desc in
Specs.reset_summary proc_name None None in
let get_proc_desc _ = None in let get_proc_desc _ = None in
let callbacks = let callbacks =
{ {

@ -79,13 +79,13 @@ public abstract class UnknownCode {
InferTaint.inferSensitiveSink(launderedSource); InferTaint.inferSensitiveSink(launderedSource);
} }
void FN_propagateViaUnknownNativeCodeBad() { void propagateViaUnknownNativeCodeBad() {
Object source = InferTaint.inferSecretSource(); Object source = InferTaint.inferSecretSource();
Object launderedSource = nativeMethod(source); Object launderedSource = nativeMethod(source);
InferTaint.inferSensitiveSink(launderedSource); InferTaint.inferSensitiveSink(launderedSource);
} }
static void FN_propagateViaUnknownAbstractCodeBad() { static void propagateViaUnknownAbstractCodeBad() {
Object source = InferTaint.inferSecretSource(); Object source = InferTaint.inferSecretSource();
Object launderedSource = nativeMethod(source); Object launderedSource = nativeMethod(source);
InferTaint.inferSensitiveSink(launderedSource); InferTaint.inferSensitiveSink(launderedSource);

@ -172,7 +172,9 @@ codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.callPropagateFoot
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.callUnknownSetterBad(Intent), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.callUnknownSetterBad(Intent), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 6, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 6, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 7, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 7, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownAbstractCodeBad(), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownConstructorBad(), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownConstructorBad(), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownNativeCodeBad(), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsAlert(WebView,String,String,JsResult)] codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsAlert(WebView,String,String,JsResult)]
codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsBeforeUnload(WebView,String,String,JsResult)] codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsBeforeUnload(WebView,String,String,JsResult)]
codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 5, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsConfirm(WebView,String,String,JsResult)] codetoanalyze/java/quandary/WebViews.java, void WebViews.callWebviewChromeClientSinks(WebView,WebChromeClient), 5, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to boolean WebChromeClient.onJsConfirm(WebView,String,String,JsResult)]

Loading…
Cancel
Save